Array.h 23 KB

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