uvector.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  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-2013, 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 "uvector.h"
  13. #include "cmemory.h"
  14. #include "uarrsort.h"
  15. #include "uelement.h"
  16. U_NAMESPACE_BEGIN
  17. constexpr int32_t DEFAULT_CAPACITY = 8;
  18. /*
  19. * Constants for hinting whether a key is an integer
  20. * or a pointer. If a hint bit is zero, then the associated
  21. * token is assumed to be an integer. This is needed for iSeries
  22. */
  23. constexpr int8_t HINT_KEY_POINTER = 1;
  24. constexpr int8_t HINT_KEY_INTEGER = 0;
  25. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector)
  26. UVector::UVector(UErrorCode &status) :
  27. UVector(nullptr, nullptr, DEFAULT_CAPACITY, status) {
  28. }
  29. UVector::UVector(int32_t initialCapacity, UErrorCode &status) :
  30. UVector(nullptr, nullptr, initialCapacity, status) {
  31. }
  32. UVector::UVector(UObjectDeleter *d, UElementsAreEqual *c, UErrorCode &status) :
  33. UVector(d, c, DEFAULT_CAPACITY, status) {
  34. }
  35. UVector::UVector(UObjectDeleter *d, UElementsAreEqual *c, int32_t initialCapacity, UErrorCode &status) :
  36. deleter(d),
  37. comparer(c)
  38. {
  39. if (U_FAILURE(status)) {
  40. return;
  41. }
  42. // Fix bogus initialCapacity values; avoid malloc(0) and integer overflow
  43. if ((initialCapacity < 1) || (initialCapacity > static_cast<int32_t>(INT32_MAX / sizeof(UElement)))) {
  44. initialCapacity = DEFAULT_CAPACITY;
  45. }
  46. elements = static_cast<UElement*>(uprv_malloc(sizeof(UElement) * initialCapacity));
  47. if (elements == nullptr) {
  48. status = U_MEMORY_ALLOCATION_ERROR;
  49. } else {
  50. capacity = initialCapacity;
  51. }
  52. }
  53. UVector::~UVector() {
  54. removeAllElements();
  55. uprv_free(elements);
  56. elements = nullptr;
  57. }
  58. /**
  59. * Assign this object to another (make this a copy of 'other').
  60. * Use the 'assign' function to assign each element.
  61. */
  62. void UVector::assign(const UVector& other, UElementAssigner *assign, UErrorCode &ec) {
  63. if (ensureCapacity(other.count, ec)) {
  64. setSize(other.count, ec);
  65. if (U_SUCCESS(ec)) {
  66. for (int32_t i=0; i<other.count; ++i) {
  67. if (elements[i].pointer != nullptr && deleter != nullptr) {
  68. (*deleter)(elements[i].pointer);
  69. }
  70. (*assign)(&elements[i], &other.elements[i]);
  71. }
  72. }
  73. }
  74. }
  75. // This only does something sensible if this object has a non-null comparer
  76. bool UVector::operator==(const UVector& other) const {
  77. U_ASSERT(comparer != nullptr);
  78. if (count != other.count) return false;
  79. if (comparer != nullptr) {
  80. // Compare using this object's comparer
  81. for (int32_t i=0; i<count; ++i) {
  82. if (!(*comparer)(elements[i], other.elements[i])) {
  83. return false;
  84. }
  85. }
  86. }
  87. return true;
  88. }
  89. void UVector::addElement(void* obj, UErrorCode &status) {
  90. U_ASSERT(deleter == nullptr);
  91. if (ensureCapacity(count + 1, status)) {
  92. elements[count++].pointer = obj;
  93. }
  94. }
  95. void UVector::adoptElement(void* obj, UErrorCode &status) {
  96. U_ASSERT(deleter != nullptr);
  97. if (ensureCapacity(count + 1, status)) {
  98. elements[count++].pointer = obj;
  99. } else {
  100. (*deleter)(obj);
  101. }
  102. }
  103. void UVector::addElement(int32_t elem, UErrorCode &status) {
  104. U_ASSERT(deleter == nullptr); // Usage error. Mixing up ints and pointers.
  105. if (ensureCapacity(count + 1, status)) {
  106. elements[count].pointer = nullptr; // Pointers may be bigger than ints.
  107. elements[count].integer = elem;
  108. count++;
  109. }
  110. }
  111. void UVector::setElementAt(void* obj, int32_t index) {
  112. if (0 <= index && index < count) {
  113. if (elements[index].pointer != nullptr && deleter != nullptr) {
  114. (*deleter)(elements[index].pointer);
  115. }
  116. elements[index].pointer = obj;
  117. } else {
  118. /* index out of range */
  119. if (deleter != nullptr) {
  120. (*deleter)(obj);
  121. }
  122. }
  123. }
  124. void UVector::setElementAt(int32_t elem, int32_t index) {
  125. U_ASSERT(deleter == nullptr); // Usage error. Mixing up ints and pointers.
  126. if (0 <= index && index < count) {
  127. elements[index].pointer = nullptr;
  128. elements[index].integer = elem;
  129. }
  130. /* else index out of range */
  131. }
  132. void UVector::insertElementAt(void* obj, int32_t index, UErrorCode &status) {
  133. if (ensureCapacity(count + 1, status)) {
  134. if (0 <= index && index <= count) {
  135. for (int32_t i=count; i>index; --i) {
  136. elements[i] = elements[i-1];
  137. }
  138. elements[index].pointer = obj;
  139. ++count;
  140. } else {
  141. /* index out of range */
  142. status = U_ILLEGAL_ARGUMENT_ERROR;
  143. }
  144. }
  145. if (U_FAILURE(status) && deleter != nullptr) {
  146. (*deleter)(obj);
  147. }
  148. }
  149. void UVector::insertElementAt(int32_t elem, int32_t index, UErrorCode &status) {
  150. U_ASSERT(deleter == nullptr); // Usage error. Mixing up ints and pointers.
  151. // must have 0 <= index <= count
  152. if (ensureCapacity(count + 1, status)) {
  153. if (0 <= index && index <= count) {
  154. for (int32_t i=count; i>index; --i) {
  155. elements[i] = elements[i-1];
  156. }
  157. elements[index].pointer = nullptr;
  158. elements[index].integer = elem;
  159. ++count;
  160. } else {
  161. /* index out of range */
  162. status = U_ILLEGAL_ARGUMENT_ERROR;
  163. }
  164. }
  165. }
  166. void* UVector::elementAt(int32_t index) const {
  167. return (0 <= index && index < count) ? elements[index].pointer : nullptr;
  168. }
  169. int32_t UVector::elementAti(int32_t index) const {
  170. return (0 <= index && index < count) ? elements[index].integer : 0;
  171. }
  172. UBool UVector::containsAll(const UVector& other) const {
  173. for (int32_t i=0; i<other.size(); ++i) {
  174. if (indexOf(other.elements[i]) < 0) {
  175. return false;
  176. }
  177. }
  178. return true;
  179. }
  180. UBool UVector::containsNone(const UVector& other) const {
  181. for (int32_t i=0; i<other.size(); ++i) {
  182. if (indexOf(other.elements[i]) >= 0) {
  183. return false;
  184. }
  185. }
  186. return true;
  187. }
  188. UBool UVector::removeAll(const UVector& other) {
  189. UBool changed = false;
  190. for (int32_t i=0; i<other.size(); ++i) {
  191. int32_t j = indexOf(other.elements[i]);
  192. if (j >= 0) {
  193. removeElementAt(j);
  194. changed = true;
  195. }
  196. }
  197. return changed;
  198. }
  199. UBool UVector::retainAll(const UVector& other) {
  200. UBool changed = false;
  201. for (int32_t j=size()-1; j>=0; --j) {
  202. int32_t i = other.indexOf(elements[j]);
  203. if (i < 0) {
  204. removeElementAt(j);
  205. changed = true;
  206. }
  207. }
  208. return changed;
  209. }
  210. void UVector::removeElementAt(int32_t index) {
  211. void* e = orphanElementAt(index);
  212. if (e != nullptr && deleter != nullptr) {
  213. (*deleter)(e);
  214. }
  215. }
  216. UBool UVector::removeElement(void* obj) {
  217. int32_t i = indexOf(obj);
  218. if (i >= 0) {
  219. removeElementAt(i);
  220. return true;
  221. }
  222. return false;
  223. }
  224. void UVector::removeAllElements() {
  225. if (deleter != nullptr) {
  226. for (int32_t i=0; i<count; ++i) {
  227. if (elements[i].pointer != nullptr) {
  228. (*deleter)(elements[i].pointer);
  229. }
  230. }
  231. }
  232. count = 0;
  233. }
  234. UBool UVector::equals(const UVector &other) const {
  235. int i;
  236. if (this->count != other.count) {
  237. return false;
  238. }
  239. if (comparer == nullptr) {
  240. for (i=0; i<count; i++) {
  241. if (elements[i].pointer != other.elements[i].pointer) {
  242. return false;
  243. }
  244. }
  245. } else {
  246. UElement key;
  247. for (i=0; i<count; i++) {
  248. key.pointer = &other.elements[i];
  249. if (!(*comparer)(key, elements[i])) {
  250. return false;
  251. }
  252. }
  253. }
  254. return true;
  255. }
  256. int32_t UVector::indexOf(void* obj, int32_t startIndex) const {
  257. UElement key;
  258. key.pointer = obj;
  259. return indexOf(key, startIndex, HINT_KEY_POINTER);
  260. }
  261. int32_t UVector::indexOf(int32_t obj, int32_t startIndex) const {
  262. UElement key;
  263. key.integer = obj;
  264. return indexOf(key, startIndex, HINT_KEY_INTEGER);
  265. }
  266. int32_t UVector::indexOf(UElement key, int32_t startIndex, int8_t hint) const {
  267. if (comparer != nullptr) {
  268. for (int32_t i=startIndex; i<count; ++i) {
  269. if ((*comparer)(key, elements[i])) {
  270. return i;
  271. }
  272. }
  273. } else {
  274. for (int32_t i=startIndex; i<count; ++i) {
  275. /* Pointers are not always the same size as ints so to perform
  276. * a valid comparison we need to know whether we are being
  277. * provided an int or a pointer. */
  278. if (hint & HINT_KEY_POINTER) {
  279. if (key.pointer == elements[i].pointer) {
  280. return i;
  281. }
  282. } else {
  283. if (key.integer == elements[i].integer) {
  284. return i;
  285. }
  286. }
  287. }
  288. }
  289. return -1;
  290. }
  291. UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
  292. if (U_FAILURE(status)) {
  293. return false;
  294. }
  295. if (minimumCapacity < 0) {
  296. status = U_ILLEGAL_ARGUMENT_ERROR;
  297. return false;
  298. }
  299. if (capacity < minimumCapacity) {
  300. if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check
  301. status = U_ILLEGAL_ARGUMENT_ERROR;
  302. return false;
  303. }
  304. int32_t newCap = capacity * 2;
  305. if (newCap < minimumCapacity) {
  306. newCap = minimumCapacity;
  307. }
  308. if (newCap > static_cast<int32_t>(INT32_MAX / sizeof(UElement))) { // integer overflow check
  309. // We keep the original memory contents on bad minimumCapacity.
  310. status = U_ILLEGAL_ARGUMENT_ERROR;
  311. return false;
  312. }
  313. UElement* newElems = static_cast<UElement*>(uprv_realloc(elements, sizeof(UElement) * newCap));
  314. if (newElems == nullptr) {
  315. // We keep the original contents on the memory failure on realloc or bad minimumCapacity.
  316. status = U_MEMORY_ALLOCATION_ERROR;
  317. return false;
  318. }
  319. elements = newElems;
  320. capacity = newCap;
  321. }
  322. return true;
  323. }
  324. /**
  325. * Change the size of this vector as follows: If newSize is smaller,
  326. * then truncate the array, possibly deleting held elements for i >=
  327. * newSize. If newSize is larger, grow the array, filling in new
  328. * slots with nullptr.
  329. */
  330. void UVector::setSize(int32_t newSize, UErrorCode &status) {
  331. if (!ensureCapacity(newSize, status)) {
  332. return;
  333. }
  334. if (newSize > count) {
  335. UElement empty;
  336. empty.pointer = nullptr;
  337. empty.integer = 0;
  338. for (int32_t i=count; i<newSize; ++i) {
  339. elements[i] = empty;
  340. }
  341. } else {
  342. /* Most efficient to count down */
  343. for (int32_t i=count-1; i>=newSize; --i) {
  344. removeElementAt(i);
  345. }
  346. }
  347. count = newSize;
  348. }
  349. /**
  350. * Fill in the given array with all elements of this vector.
  351. */
  352. void** UVector::toArray(void** result) const {
  353. void** a = result;
  354. for (int i=0; i<count; ++i) {
  355. *a++ = elements[i].pointer;
  356. }
  357. return result;
  358. }
  359. UObjectDeleter *UVector::setDeleter(UObjectDeleter *d) {
  360. UObjectDeleter *old = deleter;
  361. deleter = d;
  362. return old;
  363. }
  364. UElementsAreEqual *UVector::setComparer(UElementsAreEqual *d) {
  365. UElementsAreEqual *old = comparer;
  366. comparer = d;
  367. return old;
  368. }
  369. /**
  370. * Removes the element at the given index from this vector and
  371. * transfer ownership of it to the caller. After this call, the
  372. * caller owns the result and must delete it and the vector entry
  373. * at 'index' is removed, shifting all subsequent entries back by
  374. * one index and shortening the size of the vector by one. If the
  375. * index is out of range or if there is no item at the given index
  376. * then 0 is returned and the vector is unchanged.
  377. */
  378. void* UVector::orphanElementAt(int32_t index) {
  379. void* e = nullptr;
  380. if (0 <= index && index < count) {
  381. e = elements[index].pointer;
  382. for (int32_t i=index; i<count-1; ++i) {
  383. elements[i] = elements[i+1];
  384. }
  385. --count;
  386. }
  387. /* else index out of range */
  388. return e;
  389. }
  390. /**
  391. * Insert the given object into this vector at its sorted position
  392. * as defined by 'compare'. The current elements are assumed to
  393. * be sorted already.
  394. */
  395. void UVector::sortedInsert(void* obj, UElementComparator *compare, UErrorCode& ec) {
  396. UElement e;
  397. e.pointer = obj;
  398. sortedInsert(e, compare, ec);
  399. }
  400. /**
  401. * Insert the given integer into this vector at its sorted position
  402. * as defined by 'compare'. The current elements are assumed to
  403. * be sorted already.
  404. */
  405. void UVector::sortedInsert(int32_t obj, UElementComparator *compare, UErrorCode& ec) {
  406. U_ASSERT(deleter == nullptr);
  407. UElement e {};
  408. e.integer = obj;
  409. sortedInsert(e, compare, ec);
  410. }
  411. // ASSUME elements[] IS CURRENTLY SORTED
  412. void UVector::sortedInsert(UElement e, UElementComparator *compare, UErrorCode& ec) {
  413. // Perform a binary search for the location to insert tok at. Tok
  414. // will be inserted between two elements a and b such that a <=
  415. // tok && tok < b, where there is a 'virtual' elements[-1] always
  416. // less than tok and a 'virtual' elements[count] always greater
  417. // than tok.
  418. if (!ensureCapacity(count + 1, ec)) {
  419. if (deleter != nullptr) {
  420. (*deleter)(e.pointer);
  421. }
  422. return;
  423. }
  424. int32_t min = 0, max = count;
  425. while (min != max) {
  426. int32_t probe = (min + max) / 2;
  427. int32_t c = (*compare)(elements[probe], e);
  428. if (c > 0) {
  429. max = probe;
  430. } else {
  431. // assert(c <= 0);
  432. min = probe + 1;
  433. }
  434. }
  435. for (int32_t i=count; i>min; --i) {
  436. elements[i] = elements[i-1];
  437. }
  438. elements[min] = e;
  439. ++count;
  440. }
  441. /**
  442. * Array sort comparator function.
  443. * Used from UVector::sort()
  444. * Conforms to function signature required for uprv_sortArray().
  445. * This function is essentially just a wrapper, to make a
  446. * UVector style comparator function usable with uprv_sortArray().
  447. *
  448. * The context pointer to this function is a pointer back
  449. * (with some extra indirection) to the user supplied comparator.
  450. *
  451. */
  452. static int32_t U_CALLCONV
  453. sortComparator(const void *context, const void *left, const void *right) {
  454. UElementComparator *compare = *static_cast<UElementComparator * const *>(context);
  455. UElement e1 = *static_cast<const UElement *>(left);
  456. UElement e2 = *static_cast<const UElement *>(right);
  457. int32_t result = (*compare)(e1, e2);
  458. return result;
  459. }
  460. /**
  461. * Array sort comparison function for use from UVector::sorti()
  462. * Compares int32_t vector elements.
  463. */
  464. static int32_t U_CALLCONV
  465. sortiComparator(const void * /*context */, const void *left, const void *right) {
  466. const UElement *e1 = static_cast<const UElement *>(left);
  467. const UElement *e2 = static_cast<const UElement *>(right);
  468. int32_t result = e1->integer < e2->integer? -1 :
  469. e1->integer == e2->integer? 0 : 1;
  470. return result;
  471. }
  472. /**
  473. * Sort the vector, assuming it contains ints.
  474. * (A more general sort would take a comparison function, but it's
  475. * not clear whether UVector's UElementComparator or
  476. * UComparator from uprv_sortAray would be more appropriate.)
  477. */
  478. void UVector::sorti(UErrorCode &ec) {
  479. if (U_SUCCESS(ec)) {
  480. uprv_sortArray(elements, count, sizeof(UElement),
  481. sortiComparator, nullptr, false, &ec);
  482. }
  483. }
  484. /**
  485. * Sort with a user supplied comparator.
  486. *
  487. * The comparator function handling is confusing because the function type
  488. * for UVector (as defined for sortedInsert()) is different from the signature
  489. * required by uprv_sortArray(). This is handled by passing the
  490. * the UVector sort function pointer via the context pointer to a
  491. * sortArray() comparator function, which can then call back to
  492. * the original user function.
  493. *
  494. * An additional twist is that it's not safe to pass a pointer-to-function
  495. * as a (void *) data pointer, so instead we pass a (data) pointer to a
  496. * pointer-to-function variable.
  497. */
  498. void UVector::sort(UElementComparator *compare, UErrorCode &ec) {
  499. if (U_SUCCESS(ec)) {
  500. uprv_sortArray(elements, count, sizeof(UElement),
  501. sortComparator, &compare, false, &ec);
  502. }
  503. }
  504. /**
  505. * Stable sort with a user supplied comparator of type UComparator.
  506. */
  507. void UVector::sortWithUComparator(UComparator *compare, const void *context, UErrorCode &ec) {
  508. if (U_SUCCESS(ec)) {
  509. uprv_sortArray(elements, count, sizeof(UElement),
  510. compare, context, true, &ec);
  511. }
  512. }
  513. U_NAMESPACE_END