Array.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. #pragma once
  2. #include <functional>
  3. #include <stdexcept>
  4. #include "Errors.h"
  5. #include "ReferenceCounter.h"
  6. #include "Stream.h"
  7. #include "Supplier.h"
  8. #include "Text.h"
  9. namespace Framework
  10. {
  11. template<class TYP>
  12. //! An entry in a linked list
  13. struct ArrayEntry
  14. {
  15. TYP var;
  16. bool set;
  17. ArrayEntry<TYP>* next;
  18. ArrayEntry()
  19. : var(),
  20. set(0),
  21. next(0)
  22. {}
  23. //! Sets the entry to the values of the other entry
  24. ArrayEntry& operator=(ArrayEntry& r)
  25. {
  26. var = r.var;
  27. set = r.set;
  28. next = r.next;
  29. return *this;
  30. }
  31. //! Returns the currently stored value
  32. operator TYP()
  33. {
  34. if (!set)
  35. {
  36. Text err = "Index out of Range Exception File: ";
  37. err += __FILE__;
  38. err += " Line: ";
  39. err += __LINE__;
  40. throw std::out_of_range(err);
  41. }
  42. return var;
  43. }
  44. //! Increments through the linked list
  45. ArrayEntry<TYP>& operator++() //! prefix
  46. {
  47. if (!next)
  48. {
  49. ArrayEntry<TYP> tmp;
  50. tmp.set = 0;
  51. tmp.next = 0;
  52. *this = tmp;
  53. return *this;
  54. }
  55. *this = *next;
  56. return *next;
  57. }
  58. //! Increments through the linked list
  59. ArrayEntry<TYP>& operator++(int) //! postfix
  60. {
  61. if (!next)
  62. {
  63. ArrayEntry<TYP> tmp;
  64. tmp.set = 0;
  65. tmp.next = 0;
  66. *this = tmp;
  67. return *this;
  68. }
  69. *this = *next;
  70. return *next;
  71. }
  72. #ifdef WIN32
  73. # pragma warning(once : 26495)
  74. };
  75. #else
  76. };
  77. #endif
  78. template<class TYP> class ArrayIterator
  79. : public Iterator<TYP, ArrayIterator<TYP>>
  80. {
  81. private:
  82. ArrayEntry<TYP>* current;
  83. const std::function<void(TYP& removed)>* onRemove;
  84. const std::function<void(int change)>* onSizeChanged;
  85. const std::function<void(ArrayEntry<TYP>* last)>* onLastChanged;
  86. public:
  87. ArrayIterator(ArrayEntry<TYP>* start,
  88. const std::function<void(TYP& removed)>* onRemove,
  89. const std::function<void(int change)>* onSizeChanged,
  90. const std::function<void(ArrayEntry<TYP>* last)>* onLastChanged)
  91. {
  92. this->onRemove = onRemove;
  93. this->onSizeChanged = onSizeChanged;
  94. this->onLastChanged = onLastChanged;
  95. current = start;
  96. while (current && !current->set)
  97. {
  98. current = current->next;
  99. }
  100. }
  101. ArrayIterator(const ArrayIterator& it)
  102. {
  103. onRemove = it.onRemove;
  104. onSizeChanged = it.onSizeChanged;
  105. onLastChanged = it.onLastChanged;
  106. current = it.current;
  107. }
  108. virtual ~ArrayIterator()
  109. {
  110. current = 0;
  111. }
  112. ArrayIterator<TYP>& operator=(ArrayIterator<TYP> r)
  113. {
  114. onRemove = r.onRemove;
  115. onSizeChanged = r.onSizeChanged;
  116. onLastChanged = r.onLastChanged;
  117. current = r.current;
  118. return *this;
  119. }
  120. bool hasNext() override
  121. {
  122. ArrayEntry<TYP>* next = current->next;
  123. while (next && !next->set)
  124. {
  125. next = next->next;
  126. }
  127. return next != 0;
  128. }
  129. ArrayIterator<TYP> next() override
  130. {
  131. if (!current)
  132. {
  133. Text err = "Index out of Range Exception File: ";
  134. err += __FILE__;
  135. err += " Line: ";
  136. err += __LINE__;
  137. throw std::out_of_range(err);
  138. }
  139. return ArrayIterator(
  140. current->next, onRemove, onSizeChanged, onLastChanged);
  141. }
  142. operator bool() override
  143. {
  144. return current != 0;
  145. }
  146. ArrayIterator<TYP>& operator++() override //! prefix
  147. {
  148. do
  149. {
  150. if (current) current = current->next;
  151. } while (current && !current->set);
  152. return *this;
  153. }
  154. ArrayIterator<TYP> operator++(int) override //! postfix
  155. {
  156. ArrayIterator<TYP> temp(*this);
  157. do
  158. {
  159. if (current) current = current->next;
  160. } while (current && !current->set);
  161. return temp;
  162. }
  163. TYP val() override
  164. {
  165. #ifdef _DEBUG
  166. if (!current || !current->set)
  167. {
  168. Text err = "Index out of Range Exception File: ";
  169. err += __FILE__;
  170. err += " Line: ";
  171. err += __LINE__;
  172. throw std::out_of_range(err);
  173. }
  174. #endif
  175. return current->var;
  176. }
  177. void addBefore(TYP val) override
  178. {
  179. if (current)
  180. {
  181. ArrayEntry<TYP>* newEntry = new ArrayEntry<TYP>();
  182. newEntry->var = current->var;
  183. newEntry->set = current->set;
  184. newEntry->next = current->next;
  185. if (!current->next)
  186. {
  187. (*onLastChanged)(newEntry);
  188. }
  189. current->var = val;
  190. current->set = true;
  191. current->next = newEntry;
  192. (*onSizeChanged)(1);
  193. }
  194. else
  195. {
  196. Text err = "Index out of Range Exception File: ";
  197. err += __FILE__;
  198. err += " Line: ";
  199. err += __LINE__;
  200. throw std::out_of_range(err);
  201. }
  202. }
  203. void set(TYP val) override
  204. {
  205. if (current)
  206. {
  207. if (onRemove) (*onRemove)(current->var);
  208. current->var = val;
  209. current->set = true;
  210. }
  211. else
  212. {
  213. Text err = "Index out of Range Exception File: ";
  214. err += __FILE__;
  215. err += " Line: ";
  216. err += __LINE__;
  217. throw std::out_of_range(err);
  218. }
  219. }
  220. bool operator!=(ArrayIterator<TYP>& r)
  221. {
  222. return current != r.current;
  223. }
  224. bool operator==(ArrayIterator<TYP>& r)
  225. {
  226. return current == r.current;
  227. }
  228. void remove() override
  229. {
  230. if (!current)
  231. {
  232. Text err = "Index out of Range Exception File: ";
  233. err += __FILE__;
  234. err += " Line: ";
  235. err += __LINE__;
  236. throw std::out_of_range(err);
  237. }
  238. if (current->next)
  239. {
  240. if (onRemove) (*onRemove)(current->var);
  241. current->var = current->next->var;
  242. current->set = current->next->set;
  243. }
  244. else
  245. {
  246. if (onRemove) (*onRemove)(current->var);
  247. current->set = 0;
  248. }
  249. ArrayEntry<TYP>* del = current->next;
  250. if (current->next)
  251. current->next = current->next->next;
  252. else
  253. {
  254. (*onLastChanged)(current);
  255. current->next = 0;
  256. }
  257. if (del)
  258. {
  259. del->set = 0;
  260. del->next = 0;
  261. delete del;
  262. }
  263. (*onSizeChanged)(-1);
  264. }
  265. };
  266. #define _ val()
  267. template<class TYP>
  268. //! A linked list of classes that do not use reference counting
  269. class Array : public virtual ReferenceCounter
  270. {
  271. private:
  272. ArrayEntry<TYP>* entries;
  273. ArrayEntry<TYP>* last;
  274. int count;
  275. std::function<void(int change)> onSizeChanged;
  276. std::function<void(ArrayEntry<TYP>* last)> onLastChanged;
  277. public:
  278. //! Creates a new linked list
  279. Array() noexcept
  280. : ReferenceCounter()
  281. {
  282. entries = new ArrayEntry<TYP>();
  283. entries->set = 0;
  284. entries->next = 0;
  285. last = entries;
  286. count = 0;
  287. onSizeChanged = [this](int change) { this->count += change; };
  288. onLastChanged
  289. = [this](ArrayEntry<TYP>* last) { this->last = last; };
  290. }
  291. //! Copies a linked list
  292. //!
  293. Array(const Array& arr)
  294. : Array()
  295. {
  296. int anz = arr.getEntryCount();
  297. for (int i = 0; i < anz; i++)
  298. add(arr.get(i));
  299. }
  300. //! Clears and deletes the linked list
  301. ~Array()
  302. {
  303. clear();
  304. delete entries;
  305. }
  306. //! Appends an element to the end of the list
  307. //! \param t The new element
  308. void add(TYP t)
  309. {
  310. if (!last->set)
  311. {
  312. last->var = t;
  313. last->set = 1;
  314. count++;
  315. return;
  316. }
  317. last->next = new ArrayEntry<TYP>();
  318. last = last->next;
  319. last->set = 1;
  320. last->var = t;
  321. count++;
  322. }
  323. //! Inserts an element at a specific position in the list
  324. //! \param t The new element
  325. //! \param i The position where the element is inserted (afterwards the
  326. //! index of the new element)
  327. void add(TYP t, int i)
  328. {
  329. if (i < 0 || i > count)
  330. throwOutOfRange(__FILE__, __LINE__, i, count);
  331. if (i == count)
  332. {
  333. add(t);
  334. return;
  335. }
  336. ArrayEntry<TYP>* e = entries;
  337. for (int a = 0; a < i; ++a)
  338. e = e->next;
  339. ArrayEntry<TYP>* ne = new ArrayEntry<TYP>();
  340. ne->var = e->var;
  341. ne->set = e->set;
  342. ne->next = e->next;
  343. e->next = ne;
  344. e->var = t;
  345. e->set = 1;
  346. if (last->next) last = last->next;
  347. count++;
  348. }
  349. //! Sets the value of the i-th entry
  350. //! \param t The new value
  351. //! \param i The index of the entry to be set
  352. void set(TYP t, int i)
  353. {
  354. if (i < 0 || i >= count)
  355. throwOutOfRange(__FILE__, __LINE__, i, count);
  356. ArrayEntry<TYP>* e = entries;
  357. for (int a = 0; a < i; ++a)
  358. e = e->next;
  359. e->var = t;
  360. e->set = 1;
  361. }
  362. //! Changes the position of the i-th element in the list
  363. //! \param i The index of the element to be moved
  364. //! \param p The target position of the element (afterwards the new
  365. //! index of the element)
  366. void setPosition(int i, int p)
  367. {
  368. if (i == p) return;
  369. if (i < 0 || p < 0 || i >= count || p >= count)
  370. throwOutOfRange(__FILE__, __LINE__, i, count);
  371. TYP t = get(i);
  372. remove(i);
  373. add(t, p);
  374. }
  375. //! Deletes a specific element
  376. //! \param i The index of the element to be deleted
  377. void remove(int i)
  378. {
  379. if (i < 0 || i >= count)
  380. throwOutOfRange(__FILE__, __LINE__, i, count);
  381. ArrayEntry<TYP>* e = entries;
  382. for (int a = 0; a < i; ++a)
  383. e = e->next;
  384. if (e->next)
  385. {
  386. e->var = e->next->var;
  387. e->set = e->next->set;
  388. }
  389. else
  390. e->set = 0;
  391. ArrayEntry<TYP>* del = e->next;
  392. if (e->next)
  393. e->next = e->next->next;
  394. else
  395. e->next = 0;
  396. if (del)
  397. {
  398. del->set = 0;
  399. del->next = 0;
  400. if (last == del) last = e;
  401. delete del;
  402. }
  403. count--;
  404. }
  405. //! Deletes a specific element by value
  406. //! \param value The value of the element to be deleted
  407. void removeValue(TYP value)
  408. {
  409. ArrayEntry<TYP>* e = entries;
  410. while (e->var != value)
  411. {
  412. if (!e->next) return;
  413. e = e->next;
  414. }
  415. if (e->next)
  416. {
  417. e->var = e->next->var;
  418. e->set = e->next->set;
  419. }
  420. else
  421. e->set = 0;
  422. ArrayEntry<TYP>* del = e->next;
  423. if (e->next)
  424. e->next = e->next->next;
  425. else
  426. e->next = 0;
  427. if (del)
  428. {
  429. del->set = 0;
  430. del->next = 0;
  431. if (last == del) last = e;
  432. delete del;
  433. }
  434. count--;
  435. }
  436. //! Swaps two elements in the list
  437. //! \param vi The index of the first element
  438. //! \param ni The index of the second element
  439. void swap(int vi, int ni)
  440. {
  441. TYP tmp = get(ni);
  442. set(get(vi), ni);
  443. set(tmp, vi);
  444. }
  445. //! Deletes all elements of the list
  446. void clear()
  447. {
  448. ArrayEntry<TYP>* e2 = 0;
  449. for (ArrayEntry<TYP>* e = entries->next; e; e = e->next)
  450. {
  451. delete e2;
  452. e2 = e;
  453. }
  454. delete e2;
  455. entries->set = 0;
  456. entries->next = 0;
  457. last = entries;
  458. count = 0;
  459. }
  460. //! Returns an iterator.
  461. //! Use ++ to iterate through the list
  462. ArrayIterator<TYP> begin() const
  463. {
  464. return ArrayIterator<TYP>(
  465. entries, 0, &onSizeChanged, &onLastChanged);
  466. }
  467. ArrayIterator<TYP> end() const
  468. {
  469. return ArrayIterator<TYP>(0, 0, &onSizeChanged, &onLastChanged);
  470. }
  471. //! Returns how many elements are in the list
  472. int getEntryCount() const
  473. {
  474. return count;
  475. }
  476. //! Returns the value of the i-th element
  477. //! \param i The index of the sought element
  478. //! throws:
  479. //! \param std:out_of_range if i < 0 or i >= getEntryCount()
  480. TYP get(int i) const
  481. {
  482. if (i < 0 || i >= count)
  483. throwOutOfRange(__FILE__, __LINE__, i, count);
  484. ArrayEntry<TYP>* e = entries;
  485. for (int a = 0; a < i && e; ++a)
  486. e = e->next;
  487. return e->var;
  488. }
  489. //! Checks whether an element exists in the list
  490. //! \param i The index of the sought element
  491. //! \return (true) if the index exists. (false) otherwise
  492. bool has(int i) const
  493. {
  494. return i >= 0 && i < count;
  495. }
  496. //! Returns the index of a value
  497. //! \param t The value to search for
  498. int getValueIndex(TYP t) const
  499. {
  500. int ret = 0;
  501. for (ArrayEntry<TYP>* e = entries; e; e = e->next)
  502. {
  503. if (e->set && e->var == t) return ret;
  504. ++ret;
  505. }
  506. return -1;
  507. }
  508. bool anyMatch(std::function<bool(const TYP element)> predicate) const
  509. {
  510. for (TYP t : *this)
  511. {
  512. if (predicate(t)) return 1;
  513. }
  514. return 0;
  515. }
  516. bool allMatch(std::function<bool(const TYP element)> predicate) const
  517. {
  518. for (TYP t : *this)
  519. {
  520. if (!predicate(t)) return 0;
  521. }
  522. return 1;
  523. }
  524. int findIndex(std::function<bool(const TYP element)> predicate) const
  525. {
  526. int index = 0;
  527. for (TYP t : *this)
  528. {
  529. if (predicate(t)) return index;
  530. index++;
  531. }
  532. return -1;
  533. }
  534. Array& operator=(const Array& arr)
  535. {
  536. clear();
  537. int anz = arr.getEntryCount();
  538. for (int i = 0; i < anz; i++)
  539. add(arr.get(i));
  540. return *this;
  541. }
  542. Stream<TYP> stream()
  543. {
  544. return Stream<TYP>(new IteratorSupplier<TYP>(new ArrayIterator<TYP>(
  545. entries, 0, &onSizeChanged, &onLastChanged)));
  546. }
  547. };
  548. template<class TYP>
  549. //! A linked list of pointers to objects that use reference counting
  550. class RCArray : public virtual ReferenceCounter
  551. {
  552. private:
  553. ArrayEntry<TYP*>* entries;
  554. ArrayEntry<TYP*>* last;
  555. int count;
  556. std::function<void(TYP*& removed)> onRemove;
  557. std::function<void(int change)> onSizeChanged;
  558. std::function<void(ArrayEntry<TYP*>* last)> onLastChanged;
  559. public:
  560. //! Creates a new linked list
  561. RCArray() noexcept
  562. : ReferenceCounter()
  563. {
  564. entries = new ArrayEntry<TYP*>();
  565. entries->var = 0;
  566. entries->set = 0;
  567. entries->next = 0;
  568. last = entries;
  569. count = 0;
  570. onRemove = [](TYP*& removed) { removed->release(); };
  571. onSizeChanged = [this](int change) { this->count += change; };
  572. onLastChanged
  573. = [this](ArrayEntry<TYP*>* last) { this->last = last; };
  574. }
  575. //! Copies a linked list
  576. RCArray(const RCArray& arr)
  577. : RCArray()
  578. {
  579. int anz = arr.getEntryCount();
  580. for (int i = 0; i < anz; i++)
  581. add(arr.get(i));
  582. }
  583. //! Clears and deletes the linked list
  584. ~RCArray()
  585. {
  586. clear();
  587. delete entries;
  588. }
  589. //! Appends an element to the end of the list
  590. //! \param t The new element
  591. void add(TYP* t)
  592. {
  593. count++;
  594. if (!last->set)
  595. {
  596. last->var = t;
  597. last->set = 1;
  598. return;
  599. }
  600. last->next = new ArrayEntry<TYP*>();
  601. last = last->next;
  602. last->var = t;
  603. last->set = 1;
  604. }
  605. //! Inserts an element at a specific position in the list
  606. //! \param t The new element
  607. //! \param i The position where the element is inserted (afterwards the
  608. //! index of the new element)
  609. void add(TYP* t, int i)
  610. {
  611. if (i < 0 || i > count)
  612. throwOutOfRange(__FILE__, __LINE__, i, count);
  613. if (i == count)
  614. {
  615. add(t);
  616. return;
  617. }
  618. ArrayEntry<TYP*>* e = entries;
  619. for (int a = 0; a < i; ++a)
  620. e = e->next;
  621. ArrayEntry<TYP*>* ne = new ArrayEntry<TYP*>();
  622. ne->var = e->var;
  623. ne->set = e->set;
  624. ne->next = e->next;
  625. e->next = ne;
  626. e->var = t;
  627. e->set = 1;
  628. if (last->next) last = last->next;
  629. count++;
  630. }
  631. //! Sets the value of the i-th entry
  632. //! \param t The new value
  633. //! \param i The index of the entry to be set
  634. void set(TYP* t, int i)
  635. {
  636. if (i < 0 || i >= count)
  637. throwOutOfRange(__FILE__, __LINE__, i, count);
  638. ArrayEntry<TYP*>* e = entries;
  639. for (int a = 0; a < i; ++a)
  640. e = e->next;
  641. if (e->set && e->var) e->var->release();
  642. e->var = t;
  643. e->set = 1;
  644. }
  645. //! Changes the position of the i-th element in the list
  646. //! \param i The index of the element to be moved
  647. //! \param p The target position of the element (afterwards the new
  648. //! index of the element)
  649. void setPosition(int i, int p)
  650. {
  651. if (i == p) return;
  652. if (i < 0 || p < 0 || i >= count || p >= count)
  653. throwOutOfRange(__FILE__, __LINE__, i, count);
  654. TYP* t = get(i);
  655. remove(i);
  656. add(t, p);
  657. }
  658. //! Deletes a specific element
  659. //! \param i The index of the element to be deleted
  660. void remove(int i)
  661. {
  662. if (i < 0 || i >= count)
  663. throwOutOfRange(__FILE__, __LINE__, i, count);
  664. ArrayEntry<TYP*>* e = entries;
  665. for (int a = 0; a < i; ++a)
  666. e = e->next;
  667. if (e->next)
  668. {
  669. if (e->set && e->var) e->var->release();
  670. e->var = e->next->var;
  671. e->set = e->next->set;
  672. }
  673. else
  674. {
  675. if (e->set && e->var) e->var->release();
  676. e->set = 0;
  677. }
  678. ArrayEntry<TYP*>* del = e->next;
  679. if (e->next)
  680. e->next = e->next->next;
  681. else
  682. e->next = 0;
  683. if (del)
  684. {
  685. del->set = 0;
  686. del->next = 0;
  687. if (last == del) last = e;
  688. delete del;
  689. }
  690. count--;
  691. }
  692. //! Swaps two elements in the list
  693. //! \param vi The index of the first element
  694. //! \param ni The index of the second element
  695. void swap(int vi, int ni)
  696. {
  697. if (vi < 0 || ni < 0) return;
  698. TYP* tmp = get(ni);
  699. set(get(vi), ni);
  700. set(tmp, vi);
  701. }
  702. //! Deletes all elements of the list
  703. void clear()
  704. {
  705. for (ArrayEntry<TYP*>* e = entries->next; e;)
  706. {
  707. if (e && e->var && e->set) e->var->release();
  708. auto tmp = e->next;
  709. delete e;
  710. e = tmp;
  711. }
  712. if (entries->var && entries->set) entries->var->release();
  713. entries->set = 0;
  714. entries->next = 0;
  715. last = entries;
  716. count = 0;
  717. }
  718. //! Returns an iterator.
  719. //! Use ++ to iterate through the list
  720. ArrayIterator<TYP*> begin() const
  721. {
  722. return ArrayIterator<TYP*>(
  723. entries, &onRemove, &onSizeChanged, &onLastChanged);
  724. }
  725. ArrayIterator<TYP*> end() const
  726. {
  727. return ArrayIterator<TYP*>(
  728. 0, &onRemove, &onSizeChanged, &onLastChanged);
  729. }
  730. //! Returns how many elements are in the list
  731. int getEntryCount() const
  732. {
  733. return count;
  734. }
  735. int getLastIndex() const
  736. {
  737. return count - 1;
  738. }
  739. //! Returns the value of the i-th element with increased reference
  740. //! counter \param i The index of the sought element, (0) if the
  741. //! index does not exist
  742. TYP* get(int i) const
  743. {
  744. if (i < 0 || i >= count)
  745. throwOutOfRange(__FILE__, __LINE__, i, count);
  746. ArrayEntry<TYP*>* e = entries;
  747. for (int a = 0; a < i && e; ++a)
  748. e = e->next;
  749. if (e && e->set && e->var)
  750. return dynamic_cast<TYP*>(e->var->getThis());
  751. return (TYP*)0;
  752. }
  753. //! Returns the value of the i-th element without increased reference
  754. //! counter \param i The index of the sought element, (0) if the
  755. //! index does not exist
  756. TYP* z(int i) const //! returns the index-th T
  757. {
  758. if (i < 0 || i >= count)
  759. throwOutOfRange(__FILE__, __LINE__, i, count);
  760. ArrayEntry<TYP*>* e = entries;
  761. for (int a = 0; a < i && e; ++a)
  762. e = e->next;
  763. if (e && e->set && e->var) return (TYP*)e->var;
  764. return (TYP*)0;
  765. }
  766. //! Checks whether an element exists in the list
  767. //! \param i The index of the sought element
  768. //! \return (true) if the index exists. (false) otherwise
  769. bool has(int i) const
  770. {
  771. return i >= 0 && i < count;
  772. }
  773. //! returns the index of the first element that matches zT or -1 if not
  774. //! found
  775. int indexOf(TYP* zT) const
  776. {
  777. int i = 0;
  778. for (TYP* t : *this)
  779. {
  780. if (t == zT) return i;
  781. ++i;
  782. }
  783. return -1;
  784. }
  785. bool anyMatch(std::function<bool(const TYP* zElement)> predicate) const
  786. {
  787. for (TYP* t : *this)
  788. {
  789. if (predicate(t)) return 1;
  790. }
  791. return 0;
  792. }
  793. bool allMatch(std::function<bool(const TYP* zElement)> predicate) const
  794. {
  795. for (TYP* t : *this)
  796. {
  797. if (!predicate(t)) return 0;
  798. }
  799. return 1;
  800. }
  801. int findIndex(std::function<bool(const TYP* zElement)> predicate) const
  802. {
  803. int index = 0;
  804. for (TYP* t : *this)
  805. {
  806. if (predicate(t)) return index;
  807. index++;
  808. }
  809. return -1;
  810. }
  811. RCArray& operator=(const RCArray& arr)
  812. {
  813. clear();
  814. int anz = arr.getEntryCount();
  815. for (int i = 0; i < anz; i++)
  816. add(arr.get(i));
  817. return *this;
  818. }
  819. Stream<TYP*> stream()
  820. {
  821. return Stream<TYP*>(
  822. new IteratorSupplier<TYP*>(new ArrayIterator<TYP*>(
  823. entries, &onRemove, &onSizeChanged, &onLastChanged)));
  824. }
  825. };
  826. } // namespace Framework