uvectr32.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. ******************************************************************************
  5. * Copyright (C) 1999-2015, International Business Machines Corporation and
  6. * others. All Rights Reserved.
  7. ******************************************************************************
  8. * Date Name Description
  9. * 10/22/99 alan Creation.
  10. **********************************************************************
  11. */
  12. #include "uvectr32.h"
  13. #include "cmemory.h"
  14. #include "putilimp.h"
  15. U_NAMESPACE_BEGIN
  16. #define DEFAULT_CAPACITY 8
  17. /*
  18. * Constants for hinting whether a key is an integer
  19. * or a pointer. If a hint bit is zero, then the associated
  20. * token is assumed to be an integer. This is needed for iSeries
  21. */
  22. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector32)
  23. UVector32::UVector32(UErrorCode &status) :
  24. count(0),
  25. capacity(0),
  26. maxCapacity(0),
  27. elements(nullptr)
  28. {
  29. _init(DEFAULT_CAPACITY, status);
  30. }
  31. UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
  32. count(0),
  33. capacity(0),
  34. maxCapacity(0),
  35. elements(nullptr)
  36. {
  37. _init(initialCapacity, status);
  38. }
  39. void UVector32::_init(int32_t initialCapacity, UErrorCode &status) {
  40. // Fix bogus initialCapacity values; avoid malloc(0)
  41. if (initialCapacity < 1) {
  42. initialCapacity = DEFAULT_CAPACITY;
  43. }
  44. if (maxCapacity>0 && maxCapacity<initialCapacity) {
  45. initialCapacity = maxCapacity;
  46. }
  47. if (initialCapacity > static_cast<int32_t>(INT32_MAX / sizeof(int32_t))) {
  48. initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity);
  49. }
  50. elements = static_cast<int32_t*>(uprv_malloc(sizeof(int32_t) * initialCapacity));
  51. if (elements == nullptr) {
  52. status = U_MEMORY_ALLOCATION_ERROR;
  53. } else {
  54. capacity = initialCapacity;
  55. }
  56. }
  57. UVector32::~UVector32() {
  58. uprv_free(elements);
  59. elements = nullptr;
  60. }
  61. /**
  62. * Assign this object to another (make this a copy of 'other').
  63. */
  64. void UVector32::assign(const UVector32& other, UErrorCode &ec) {
  65. if (ensureCapacity(other.count, ec)) {
  66. setSize(other.count);
  67. for (int32_t i=0; i<other.count; ++i) {
  68. elements[i] = other.elements[i];
  69. }
  70. }
  71. }
  72. bool UVector32::operator==(const UVector32& other) const {
  73. int32_t i;
  74. if (count != other.count) return false;
  75. for (i=0; i<count; ++i) {
  76. if (elements[i] != other.elements[i]) {
  77. return false;
  78. }
  79. }
  80. return true;
  81. }
  82. void UVector32::setElementAt(int32_t elem, int32_t index) {
  83. if (0 <= index && index < count) {
  84. elements[index] = elem;
  85. }
  86. /* else index out of range */
  87. }
  88. void UVector32::insertElementAt(int32_t elem, int32_t index, UErrorCode &status) {
  89. // must have 0 <= index <= count
  90. if (0 <= index && index <= count && ensureCapacity(count + 1, status)) {
  91. for (int32_t i=count; i>index; --i) {
  92. elements[i] = elements[i-1];
  93. }
  94. elements[index] = elem;
  95. ++count;
  96. }
  97. /* else index out of range */
  98. }
  99. UBool UVector32::containsAll(const UVector32& other) const {
  100. for (int32_t i=0; i<other.size(); ++i) {
  101. if (indexOf(other.elements[i]) < 0) {
  102. return false;
  103. }
  104. }
  105. return true;
  106. }
  107. UBool UVector32::containsNone(const UVector32& other) const {
  108. for (int32_t i=0; i<other.size(); ++i) {
  109. if (indexOf(other.elements[i]) >= 0) {
  110. return false;
  111. }
  112. }
  113. return true;
  114. }
  115. UBool UVector32::removeAll(const UVector32& other) {
  116. UBool changed = false;
  117. for (int32_t i=0; i<other.size(); ++i) {
  118. int32_t j = indexOf(other.elements[i]);
  119. if (j >= 0) {
  120. removeElementAt(j);
  121. changed = true;
  122. }
  123. }
  124. return changed;
  125. }
  126. UBool UVector32::retainAll(const UVector32& other) {
  127. UBool changed = false;
  128. for (int32_t j=size()-1; j>=0; --j) {
  129. int32_t i = other.indexOf(elements[j]);
  130. if (i < 0) {
  131. removeElementAt(j);
  132. changed = true;
  133. }
  134. }
  135. return changed;
  136. }
  137. void UVector32::removeElementAt(int32_t index) {
  138. if (index >= 0) {
  139. for (int32_t i=index; i<count-1; ++i) {
  140. elements[i] = elements[i+1];
  141. }
  142. --count;
  143. }
  144. }
  145. void UVector32::removeAllElements() {
  146. count = 0;
  147. }
  148. UBool UVector32::equals(const UVector32 &other) const {
  149. int i;
  150. if (this->count != other.count) {
  151. return false;
  152. }
  153. for (i=0; i<count; i++) {
  154. if (elements[i] != other.elements[i]) {
  155. return false;
  156. }
  157. }
  158. return true;
  159. }
  160. int32_t UVector32::indexOf(int32_t key, int32_t startIndex) const {
  161. int32_t i;
  162. for (i=startIndex; i<count; ++i) {
  163. if (key == elements[i]) {
  164. return i;
  165. }
  166. }
  167. return -1;
  168. }
  169. UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
  170. if (U_FAILURE(status)) {
  171. return false;
  172. }
  173. if (minimumCapacity < 0) {
  174. status = U_ILLEGAL_ARGUMENT_ERROR;
  175. return false;
  176. }
  177. if (capacity >= minimumCapacity) {
  178. return true;
  179. }
  180. if (maxCapacity>0 && minimumCapacity>maxCapacity) {
  181. status = U_BUFFER_OVERFLOW_ERROR;
  182. return false;
  183. }
  184. if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check
  185. status = U_ILLEGAL_ARGUMENT_ERROR;
  186. return false;
  187. }
  188. int32_t newCap = capacity * 2;
  189. if (newCap < minimumCapacity) {
  190. newCap = minimumCapacity;
  191. }
  192. if (maxCapacity > 0 && newCap > maxCapacity) {
  193. newCap = maxCapacity;
  194. }
  195. if (newCap > static_cast<int32_t>(INT32_MAX / sizeof(int32_t))) { // integer overflow check
  196. // We keep the original memory contents on bad minimumCapacity/maxCapacity.
  197. status = U_ILLEGAL_ARGUMENT_ERROR;
  198. return false;
  199. }
  200. int32_t* newElems = static_cast<int32_t*>(uprv_realloc(elements, sizeof(int32_t) * newCap));
  201. if (newElems == nullptr) {
  202. // We keep the original contents on the memory failure on realloc.
  203. status = U_MEMORY_ALLOCATION_ERROR;
  204. return false;
  205. }
  206. elements = newElems;
  207. capacity = newCap;
  208. return true;
  209. }
  210. void UVector32::setMaxCapacity(int32_t limit) {
  211. U_ASSERT(limit >= 0);
  212. if (limit < 0) {
  213. limit = 0;
  214. }
  215. if (limit > static_cast<int32_t>(INT32_MAX / sizeof(int32_t))) { // integer overflow check for realloc
  216. // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged
  217. return;
  218. }
  219. maxCapacity = limit;
  220. if (capacity <= maxCapacity || maxCapacity == 0) {
  221. // Current capacity is within the new limit.
  222. return;
  223. }
  224. // New maximum capacity is smaller than the current size.
  225. // Realloc the storage to the new, smaller size.
  226. int32_t* newElems = static_cast<int32_t*>(uprv_realloc(elements, sizeof(int32_t) * maxCapacity));
  227. if (newElems == nullptr) {
  228. // Realloc to smaller failed.
  229. // Just keep what we had. No need to call it a failure.
  230. return;
  231. }
  232. elements = newElems;
  233. capacity = maxCapacity;
  234. if (count > capacity) {
  235. count = capacity;
  236. }
  237. }
  238. /**
  239. * Change the size of this vector as follows: If newSize is smaller,
  240. * then truncate the array, possibly deleting held elements for i >=
  241. * newSize. If newSize is larger, grow the array, filling in new
  242. * slots with nullptr.
  243. */
  244. void UVector32::setSize(int32_t newSize) {
  245. int32_t i;
  246. if (newSize < 0) {
  247. return;
  248. }
  249. if (newSize > count) {
  250. UErrorCode ec = U_ZERO_ERROR;
  251. if (!ensureCapacity(newSize, ec)) {
  252. return;
  253. }
  254. for (i=count; i<newSize; ++i) {
  255. elements[i] = 0;
  256. }
  257. }
  258. count = newSize;
  259. }
  260. /**
  261. * Insert the given integer into this vector at its sorted position
  262. * as defined by 'compare'. The current elements are assumed to
  263. * be sorted already.
  264. */
  265. void UVector32::sortedInsert(int32_t tok, UErrorCode& ec) {
  266. // Perform a binary search for the location to insert tok at. Tok
  267. // will be inserted between two elements a and b such that a <=
  268. // tok && tok < b, where there is a 'virtual' elements[-1] always
  269. // less than tok and a 'virtual' elements[count] always greater
  270. // than tok.
  271. int32_t min = 0, max = count;
  272. while (min != max) {
  273. int32_t probe = (min + max) / 2;
  274. //int8_t c = (*compare)(elements[probe], tok);
  275. //if (c > 0) {
  276. if (elements[probe] > tok) {
  277. max = probe;
  278. } else {
  279. // assert(c <= 0);
  280. min = probe + 1;
  281. }
  282. }
  283. if (ensureCapacity(count + 1, ec)) {
  284. for (int32_t i=count; i>min; --i) {
  285. elements[i] = elements[i-1];
  286. }
  287. elements[min] = tok;
  288. ++count;
  289. }
  290. }
  291. U_NAMESPACE_END