RangeMap.C 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: RangeMap.C /main/1 1996/07/29 17:02:17 cde-hp $ */
  24. // Copyright (c) 1994 James Clark
  25. // See the file COPYING for copying permission.
  26. #ifndef RangeMap_DEF_INCLUDED
  27. #define RangeMap_DEF_INCLUDED 1
  28. #include "RangeMap.h"
  29. #include "ISet.h"
  30. #include "types.h"
  31. #ifdef SP_NAMESPACE
  32. namespace SP_NAMESPACE {
  33. #endif
  34. template<class From, class To>
  35. RangeMap<From, To>::RangeMap()
  36. {
  37. }
  38. template<class From, class To>
  39. Boolean RangeMap<From, To>::map(From from, To &to, From &alsoMax) const
  40. {
  41. // FIXME use binary search
  42. for (size_t i = 0; i < ranges_.size(); i++) {
  43. const RangeMapRange<From,To> &r = ranges_[i];
  44. if (r.fromMin <= from && from <= r.fromMax) {
  45. to = r.toMin + (from - r.fromMin);
  46. alsoMax = r.fromMax;
  47. return 1;
  48. }
  49. }
  50. return 0;
  51. }
  52. typedef ISet<WideChar> RangeMap_dummy;
  53. template<class From, class To>
  54. unsigned RangeMap<From, To>::inverseMap(To to, From &from,
  55. ISet<WideChar> &fromSet,
  56. WideChar &count) const
  57. {
  58. // FIXME use binary search
  59. unsigned ret = 0;
  60. for (size_t i = 0; i < ranges_.size(); i++) {
  61. const RangeMapRange<From,To> &r = ranges_[i];
  62. if (r.toMin <= to && to <= r.toMin + (r.fromMax - r.fromMin)) {
  63. From n = r.fromMin + (to - r.toMin);
  64. WideChar thisCount = r.fromMax - r.fromMin + 1;
  65. if (ret > 1) {
  66. fromSet.add(n);
  67. if (thisCount < count)
  68. count = thisCount;
  69. }
  70. else if (ret == 1) {
  71. fromSet.add(from);
  72. fromSet.add(n);
  73. ret = 2;
  74. if (thisCount < count)
  75. count = thisCount;
  76. }
  77. else {
  78. count = thisCount;
  79. from = n;
  80. ret = 1;
  81. }
  82. }
  83. }
  84. return ret;
  85. }
  86. template<class From, class To>
  87. RangeMapIter<From, To>::RangeMapIter(const RangeMap<From, To> &map)
  88. : count_(map.ranges_.size()), ptr_(map.ranges_.begin())
  89. {
  90. }
  91. // If the new range overlaps an existing one, the new
  92. // one takes precedence.
  93. template<class From, class To>
  94. void RangeMap<From, To>::addRange(From fromMin, From fromMax, To toMin)
  95. {
  96. // FIXME use binary search
  97. size_t i;
  98. for (i = ranges_.size(); i > 0; i--)
  99. if (fromMin > ranges_[i - 1].fromMax)
  100. break;
  101. // fromMin <= ranges[i].fromMax
  102. Boolean coalesced = 0;
  103. if (i > 0
  104. && ranges_[i - 1].fromMax + 1 == fromMin
  105. && ranges_[i - 1].toMin + (fromMin - ranges_[i - 1].fromMin) == toMin) {
  106. // coalesce with previous
  107. ranges_[i - 1].fromMax = fromMax;
  108. i--;
  109. coalesced = 1;
  110. }
  111. else if (i < ranges_.size() && fromMax >= ranges_[i].fromMin - 1) {
  112. // overlap
  113. if (fromMin <= ranges_[i].fromMin) {
  114. if (toMin + (ranges_[i].fromMin - fromMin) == ranges_[i].toMin) {
  115. ranges_[i].fromMin = fromMin;
  116. if (fromMax <= ranges_[i].fromMax)
  117. return;
  118. ranges_[i].fromMax = fromMax;
  119. coalesced = 1;
  120. }
  121. }
  122. else {
  123. // fromMin > ranges_[i].fromMin
  124. if (ranges_[i].toMin + (fromMin - ranges_[i].fromMin) == toMin) {
  125. if (fromMax < ranges_[i].fromMax)
  126. return;
  127. ranges_[i].fromMax = fromMax;
  128. coalesced = 1;
  129. }
  130. }
  131. }
  132. if (!coalesced) {
  133. // insert
  134. ranges_.resize(ranges_.size() + 1);
  135. for (size_t j = ranges_.size() - 1; j > i; j--)
  136. ranges_[j] = ranges_[j - 1];
  137. ranges_[i].fromMin = fromMin;
  138. ranges_[i].fromMax = fromMax;
  139. ranges_[i].toMin = toMin;
  140. }
  141. // Delete overlapping ranges starting at i + 1.
  142. size_t j;
  143. for (j = i + 1; j < ranges_.size(); j++) {
  144. if (fromMax < ranges_[j].fromMax) {
  145. if (fromMax >= ranges_[j].fromMin)
  146. ranges_[j].fromMin = fromMax + 1;
  147. break;
  148. }
  149. }
  150. if (j > i + 1) {
  151. // delete i + 1 ... j - 1
  152. // j -> i + 1
  153. // j - 1 -> i + 2
  154. size_t count = ranges_.size() - j;
  155. for (size_t k = 0; k < count; k++)
  156. ranges_[i + 1 + count] = ranges_[j + count];
  157. ranges_.resize(ranges_.size() - (j - (i + 1)));
  158. }
  159. }
  160. #ifdef SP_NAMESPACE
  161. }
  162. #endif
  163. #endif /* not RangeMap_DEF_INCLUDED */