ISet.C 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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: ISet.C /main/1 1996/07/29 16:54:10 cde-hp $ */
  24. // Copyright (c) 1994 James Clark
  25. // See the file COPYING for copying permission.
  26. #ifndef ISet_DEF_INCLUDED
  27. #define ISet_DEF_INCLUDED 1
  28. #include <stdlib.h>
  29. #ifdef SP_NAMESPACE
  30. namespace SP_NAMESPACE {
  31. #endif
  32. template<class T>
  33. ISet<T>::ISet()
  34. {
  35. }
  36. template<class T>
  37. ISet<T>::~ISet()
  38. {
  39. }
  40. template<class T>
  41. ISet<T>::ISet(const T *v, size_t n)
  42. {
  43. for (size_t i = 0; i < n; i++)
  44. add(v[i]);
  45. }
  46. template<class T>
  47. Boolean ISet<T>::contains(T x) const
  48. {
  49. for (size_t i = 0; i < r_.size(); i++)
  50. if (r_[i].max >= x)
  51. return r_[i].min <= x ? 1 : 0;
  52. return 0;
  53. }
  54. template<class T>
  55. void ISet<T>::addRange(T min, T max)
  56. {
  57. size_t i;
  58. if (min == 0)
  59. i = 0;
  60. else {
  61. for (i = r_.size(); i > 0 && min - 1 <= r_[i - 1].max; i--)
  62. ;
  63. }
  64. // r_[i - 1].max < min - 1 <= r_[i].max
  65. if (i < r_.size() && (r_[i].min == 0 || max >= r_[i].min - 1)) {
  66. // we can coelesce
  67. if (min < r_[i].min)
  68. r_[i].min = min;
  69. if (max > r_[i].max) {
  70. r_[i].max = max;
  71. size_t j;
  72. for (j = i + 1; j < r_.size() && r_[i].max >= r_[j].min - 1; j++)
  73. r_[i].max = r_[j].max;
  74. // get rid of i + 1 ... j - 1
  75. if (j > i + 1) {
  76. for (size_t k = j; k < r_.size(); k++)
  77. r_[k - (j - i - 1)] = r_[k];
  78. r_.resize(r_.size() - (j - i - 1));
  79. }
  80. }
  81. }
  82. else {
  83. // r_[i - 1].max < min - 1
  84. // max + 1 < r_[i].min
  85. r_.resize(r_.size() + 1);
  86. for (size_t j = r_.size() - 1; j > i; j--)
  87. r_[j] = r_[j - 1];
  88. r_[i].max = max;
  89. r_[i].min = min;
  90. }
  91. }
  92. template<class T>
  93. void ISet<T>::remove(T c)
  94. {
  95. for (size_t i = 0; i < r_.size(); i++)
  96. if (r_[i].max >= c) {
  97. if (r_[i].min <= c) {
  98. if (r_[i].min == r_[i].max) {
  99. while (++i < r_.size())
  100. r_[i - 1] = r_[i];
  101. r_.resize(r_.size() - 1);
  102. }
  103. else if (c == r_[i].min)
  104. r_[i].min += 1;
  105. else if (c == r_[i].max)
  106. r_[i].max -= 1;
  107. else {
  108. r_.resize(r_.size() + 1);
  109. // split the range
  110. // subtracting 2 is safe since we know that the length is >= 2
  111. for (size_t j = r_.size() - 2; j > i; j--)
  112. r_[j + 1] = r_[j];
  113. r_[i + 1].max = r_[i].max;
  114. r_[i + 1].min = c + 1;
  115. r_[i].max = c - 1;
  116. }
  117. }
  118. break;
  119. }
  120. }
  121. template<class T>
  122. void ISet<T>::check()
  123. {
  124. for (size_t i = 0; i < r_.size(); i++) {
  125. if (r_[i].min > r_[i].max)
  126. abort();
  127. // adjacent ranges must be coalesced
  128. if (i > 0 && r_[i].min - 1 <= r_[i - 1].max)
  129. abort();
  130. }
  131. }
  132. template<class T>
  133. void ISet<T>::clear()
  134. {
  135. r_.resize(0);
  136. }
  137. #ifdef SP_NAMESPACE
  138. }
  139. #endif
  140. #endif /* not ISet_DEF_INCLUDED */