Array.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. #ifndef Array_H
  2. #define Array_H
  3. #include "Errors.h"
  4. #include <stdexcept>
  5. #include "Text.h"
  6. #include "ReferenceCounter.h"
  7. namespace Framework
  8. {
  9. template< class TYP >
  10. //! Ein Eintrag in einer Linked List
  11. struct ArrayEintrag
  12. {
  13. TYP var;
  14. bool set = false;
  15. ArrayEintrag< TYP > *next = 0;
  16. //! Setzt den Eintrag auf die Werte des anderen Eintrages
  17. ArrayEintrag &operator=( ArrayEintrag &r )
  18. {
  19. var = r.var;
  20. set = r.set;
  21. next = r.next;
  22. return *this;
  23. }
  24. //! Gibt den aktuell gespeicherten Wert zurück
  25. operator TYP()
  26. {
  27. if( !set )
  28. {
  29. Text err = "Index out of Range Exception File: ";
  30. err += __FILE__;
  31. err += " Line: ";
  32. err += __LINE__;
  33. throw std::out_of_range( (char *)err );
  34. }
  35. return var;
  36. }
  37. //! inkrementiert durch die Linked List durch
  38. ArrayEintrag< TYP > &operator++() //! prefix
  39. {
  40. if( !next )
  41. {
  42. ArrayEintrag<TYP> tmp;
  43. tmp.set = 0;
  44. tmp.next = 0;
  45. *this = tmp;
  46. return *this;
  47. }
  48. *this = *next;
  49. return *next;
  50. }
  51. //! inkrementiert durch die Linked List durch
  52. ArrayEintrag< TYP > &operator++( int ) //! postfix
  53. {
  54. if( !next )
  55. {
  56. ArrayEintrag<TYP> tmp;
  57. tmp.set = 0;
  58. tmp.next = 0;
  59. *this = tmp;
  60. return *this;
  61. }
  62. *this = *next;
  63. return *next;
  64. }
  65. #ifdef WIN32
  66. #pragma warning( once : 26495 )
  67. };
  68. #else
  69. };
  70. #endif
  71. template< class TYP >
  72. class Iterator
  73. {
  74. private:
  75. ArrayEintrag< TYP > *current;
  76. public:
  77. Iterator( ArrayEintrag< TYP > *start )
  78. {
  79. current = start;
  80. while( current && !current->set )
  81. {
  82. current = current->next;
  83. }
  84. }
  85. Iterator( const Iterator &it )
  86. {
  87. current = it.current;
  88. }
  89. Iterator< TYP > &operator=( Iterator< TYP > r )
  90. {
  91. current = r.current;
  92. return *this;
  93. }
  94. bool hasNext()
  95. {
  96. ArrayEintrag< TYP > *next = current->next;
  97. while( next && !next->set )
  98. {
  99. next = next->next;
  100. }
  101. return next != 0;
  102. }
  103. TYP operator*()
  104. {
  105. return current->var;
  106. }
  107. Iterator< TYP > next()
  108. {
  109. if( !current )
  110. {
  111. Text err = "Index out of Range Exception File: ";
  112. err += __FILE__;
  113. err += " Line: ";
  114. err += __LINE__;
  115. throw std::out_of_range( (char *)err );
  116. }
  117. return Iterator( current->next );
  118. }
  119. operator bool()
  120. {
  121. return current != 0;
  122. }
  123. operator TYP()
  124. {
  125. if( !current || !current->set )
  126. {
  127. Text err = "Index out of Range Exception File: ";
  128. err += __FILE__;
  129. err += " Line: ";
  130. err += __LINE__;
  131. throw std::out_of_range( (char *)err );
  132. }
  133. return current->var;
  134. }
  135. Iterator< TYP > &operator++() //! prefix
  136. {
  137. do
  138. {
  139. if( current )
  140. current = current->next;
  141. } while( current && !current->set );
  142. return *this;
  143. }
  144. Iterator< TYP > operator++( int ) //! postfix
  145. {
  146. Iterator< TYP > temp( *this );
  147. do
  148. {
  149. if( current )
  150. current = current->next;
  151. } while( current && !current->set );
  152. return temp;
  153. }
  154. TYP operator->()
  155. {
  156. if( !current || !current->set )
  157. {
  158. Text err = "Index out of Range Exception File: ";
  159. err += __FILE__;
  160. err += " Line: ";
  161. err += __LINE__;
  162. throw std::out_of_range( (char *)err );
  163. }
  164. return current->var;
  165. }
  166. TYP val()
  167. {
  168. if( !current || !current->set )
  169. {
  170. Text err = "Index out of Range Exception File: ";
  171. err += __FILE__;
  172. err += " Line: ";
  173. err += __LINE__;
  174. throw std::out_of_range( (char *)err );
  175. }
  176. return current->var;
  177. }
  178. void set( TYP val )
  179. {
  180. if( current )
  181. {
  182. current->var = val;
  183. current->set = true;
  184. }
  185. else
  186. {
  187. Text err = "Index out of Range Exception File: ";
  188. err += __FILE__;
  189. err += " Line: ";
  190. err += __LINE__;
  191. throw std::out_of_range( (char *)err );
  192. }
  193. }
  194. bool operator!=( Iterator< TYP > &r )
  195. {
  196. return current != r.current;
  197. }
  198. };
  199. #define _ val()
  200. template< class TYP >
  201. //! Eine Linked List von Klassen, die kein Reference Counting berteiben
  202. class Array : public virtual ReferenceCounter
  203. {
  204. private:
  205. ArrayEintrag< TYP > *entries;
  206. ArrayEintrag< TYP > *last;
  207. int count;
  208. public:
  209. //! Erstellt eine neue Linked List
  210. Array() noexcept
  211. : ReferenceCounter()
  212. {
  213. entries = new ArrayEintrag< TYP >();
  214. entries->set = 0;
  215. entries->next = 0;
  216. last = entries;
  217. count = 0;
  218. }
  219. //! Kopiert eine Linked list
  220. //!
  221. Array( const Array &arr )
  222. : Array()
  223. {
  224. int anz = arr.getEintragAnzahl();
  225. for( int i = 0; i < anz; i++ )
  226. add( arr.get( i ) );
  227. }
  228. //! Leert und löscht die Linked List
  229. ~Array()
  230. {
  231. leeren();
  232. delete entries;
  233. }
  234. //! Hängt ein Element ans Ende der Liste an
  235. //! \param t Das neue Element
  236. void add( TYP t )
  237. {
  238. count++;
  239. if( !last->set )
  240. {
  241. last->var = t;
  242. last->set = 1;
  243. return;
  244. }
  245. last->next = new ArrayEintrag< TYP >();
  246. last = last->next;
  247. last->set = 0;
  248. last->next = 0;
  249. }
  250. //! Fügt ein Element bei einer bestimmten Position in die Liste ein
  251. //! \param t das neue Element
  252. //! \param i Die Position, wo das Element eingefügt wird (danach der Index des neuen Elementes)
  253. void add( TYP t, int i )
  254. {
  255. if( i < 0 || i > count )
  256. throwOutOfRange( __FILE__, __LINE__, i, count );
  257. if( i == count )
  258. {
  259. add( t );
  260. return;
  261. }
  262. count++;
  263. ArrayEintrag< TYP > *e = entries;
  264. for( int a = 0; a < i; ++a )
  265. e = e->next;
  266. ArrayEintrag< TYP > *ne = new ArrayEintrag< TYP >();
  267. ne->var = e->var;
  268. ne->set = e->set;
  269. ne->next = e->next;
  270. e->next = ne;
  271. e->var = t;
  272. e->set = 1;
  273. }
  274. //! Setzt den Wert des i-ten Eintrags
  275. //! \param t der Neue Wert
  276. //! \param i Der Index des Eintrages der gesetzt werden soll
  277. void set( TYP t, int i )
  278. {
  279. if( i < 0 || i >= count )
  280. throwOutOfRange( __FILE__, __LINE__, i, count );
  281. ArrayEintrag< TYP > *e = entries;
  282. for( int a = 0; a < i; ++a )
  283. e = e->next;
  284. e->var = t;
  285. e->set = 1;
  286. }
  287. //! Verändert die Position des i-ten Elementes in der Liste
  288. //! \param i Der Index des Elementes, welches verschoben werden soll
  289. //! \param p Die Zielposition des Elementes (danach der neue Index des Elementes)
  290. void setPosition( int i, int p )
  291. {
  292. if( i == p )
  293. return;
  294. if( i < 0 || p < 0 || i >= count || p >= count )
  295. throwOutOfRange( __FILE__, __LINE__, i, count );
  296. ArrayEintrag< TYP > *e = entries;
  297. ArrayEintrag< TYP > *ve = 0;
  298. for( int a = 0; a < i; ++a )
  299. {
  300. ve = e;
  301. e = e->next;
  302. }
  303. ArrayEintrag< TYP > *e2 = entries == e ? e->next : entries;
  304. ArrayEintrag< TYP > *ve2 = 0;
  305. for( int a = 0; a < p; ++a )
  306. {
  307. ve2 = e2;
  308. if( e2->next == e )
  309. e2 = e->next;
  310. else
  311. e2 = e2->next;
  312. }
  313. if( e == last )
  314. last = e2;
  315. else if( e2 == last )
  316. last = e;
  317. if( !ve2 )
  318. entries = e;
  319. else
  320. ve2->next = e;
  321. if( ve )
  322. ve->next = e->next;
  323. else
  324. entries = e->next;
  325. e->next = e2;
  326. }
  327. //! Löscht ein Bestimmtes Element
  328. //! \param i Der Index des Elementes das gelöscht werden soll
  329. void remove( int i )
  330. {
  331. if( i < 0 || i >= count )
  332. throwOutOfRange( __FILE__, __LINE__, i, count );
  333. ArrayEintrag< TYP > *e = entries;
  334. for( int a = 0; a < i; ++a )
  335. e = e->next;
  336. if( e->next )
  337. {
  338. e->var = e->next->var;
  339. e->set = e->next->set;
  340. }
  341. else
  342. #pragma warning( once : 28182 )
  343. e->set = 0;
  344. ArrayEintrag< TYP > *del = e->next;
  345. if( e->next )
  346. e->next = e->next->next;
  347. else
  348. e->next = 0;
  349. if( del )
  350. {
  351. del->set = 0;
  352. del->next = 0;
  353. if( last == del )
  354. last = e;
  355. delete del;
  356. }
  357. count--;
  358. }
  359. //! Löscht ein Bestimmtes Element
  360. //! \param i Der Index des Elementes das gelöscht werden soll
  361. void removeValue( TYP value )
  362. {
  363. ArrayEintrag< TYP > *e = entries;
  364. while( e->var != value )
  365. {
  366. if( !e->next )
  367. return;
  368. e = e->next;
  369. }
  370. if( !e )
  371. return;
  372. if( e->next )
  373. {
  374. e->var = e->next->var;
  375. e->set = e->next->set;
  376. }
  377. else
  378. e->set = 0;
  379. ArrayEintrag< TYP > *del = e->next;
  380. if( e->next )
  381. e->next = e->next->next;
  382. else
  383. e->next = 0;
  384. if( del )
  385. {
  386. del->set = 0;
  387. del->next = 0;
  388. if( last == del )
  389. last = e;
  390. delete del;
  391. }
  392. count--;
  393. }
  394. //! Vertauscht zwei Elemente in der Liste
  395. //! \param vi Der Index des ersten Elementes
  396. //! \param ni Der Index des zweiten Elementes
  397. void tausch( int vi, int ni )
  398. {
  399. TYP tmp = get( ni );
  400. set( get( vi ), ni );
  401. set( tmp, vi );
  402. }
  403. //! Löscht alle Elemente der Liste
  404. void leeren()
  405. {
  406. ArrayEintrag< TYP > *e2 = 0;
  407. for( ArrayEintrag< TYP > *e = entries; e; e = e->next )
  408. {
  409. delete e2;
  410. e2 = e;
  411. }
  412. delete e2;
  413. entries = new ArrayEintrag< TYP >();
  414. entries->set = 0;
  415. entries->next = 0;
  416. last = entries;
  417. count = 0;
  418. }
  419. //! Gibt einen Iterator zurück.
  420. //! Mit ++ kann durch die Liste iteriert werden
  421. Iterator< TYP > begin() const
  422. {
  423. return Iterator< TYP >( entries );
  424. }
  425. Iterator< TYP > end() const
  426. {
  427. return Iterator< TYP >( 0 );
  428. }
  429. //! Gibt zurück, wie viele Elemente in der Liste sind
  430. int getEintragAnzahl() const
  431. {
  432. return count;
  433. }
  434. //! Gibt den Wert des i-ten Elementes zurück
  435. //! \param i Der index des gesuchten Elementes
  436. //! throws:
  437. //! \param std:out_of_range wenn i < 0 oder i >= getEintragAnzahl()
  438. TYP get( int i ) const
  439. {
  440. if( i < 0 || i >= count )
  441. throwOutOfRange( __FILE__, __LINE__, i, count );
  442. ArrayEintrag< TYP > *e = entries;
  443. for( int a = 0; a < i && e; ++a )
  444. e = e->next;
  445. #pragma warning( once : 6011 )
  446. return e->var;
  447. }
  448. //! Überprüft, ob ein Element in der Liste enthalten ist
  449. //! \param i Der Index des gesuchten Elementes
  450. //! \return (true), wenn der Index vorhanden ist. (false) sonnst
  451. bool hat( int i ) const
  452. {
  453. return i >= 0 && i < count;
  454. }
  455. //! Gibt den Index eines Wertes zurück
  456. //! \param t Der Wert, nach dem gesucht werden soll
  457. int getWertIndex( TYP t ) const
  458. {
  459. int ret = 0;
  460. for( ArrayEintrag< TYP > *e = entries; e; e = e->next )
  461. {
  462. if( e->set && e->var == t )
  463. return ret;
  464. ++ret;
  465. }
  466. return -1;
  467. }
  468. Array &operator=( const Array &arr )
  469. {
  470. leeren();
  471. int anz = arr.getEintragAnzahl();
  472. for( int i = 0; i < anz; i++ )
  473. add( arr.get( i ) );
  474. return *this;
  475. }
  476. };
  477. template< class TYP >
  478. //! Eine Linked List von Zeigern auf Zeichnunge, die Reference Counting berteiben
  479. class RCArray : public virtual ReferenceCounter
  480. {
  481. private:
  482. ArrayEintrag< TYP * > *entries;
  483. ArrayEintrag< TYP * > *last;
  484. int count;
  485. public:
  486. //! Erstellt eine neue Linked List
  487. RCArray() noexcept
  488. : ReferenceCounter()
  489. {
  490. entries = new ArrayEintrag< TYP * >();
  491. entries->set = 0;
  492. entries->next = 0;
  493. last = entries;
  494. count = 0;
  495. }
  496. //! Kopiert eine Linked list
  497. RCArray( const RCArray &arr )
  498. : RCArray()
  499. {
  500. int anz = arr.getEintragAnzahl();
  501. for( int i = 0; i < anz; i++ )
  502. add( arr.get( i ) );
  503. ref = 1;
  504. }
  505. //! Leert und löscht die Linked List
  506. ~RCArray()
  507. {
  508. leeren();
  509. delete entries;
  510. }
  511. //! Hängt ein Element ans Ende der Liste an
  512. //! \param t Das neue Element
  513. void add( TYP *t )
  514. {
  515. count++;
  516. if( !last->set )
  517. {
  518. last->var = t;
  519. last->set = 1;
  520. return;
  521. }
  522. last->next = new ArrayEintrag< TYP * >();
  523. last = last->next;
  524. last->var = t;
  525. last->set = 1;
  526. }
  527. //! Fügt ein Element bei einer bestimmten Position in die Liste ein
  528. //! \param t das neue Element
  529. //! \param i Die Position, wo das Element eingefügt wird (danach der Index des neuen Elementes)
  530. void add( TYP *t, int i )
  531. {
  532. if( i < 0 || i > count )
  533. throwOutOfRange( __FILE__, __LINE__, i, count );
  534. if( i == count )
  535. {
  536. add( t );
  537. return;
  538. }
  539. ArrayEintrag< TYP * > *e = entries;
  540. for( int a = 0; a < i; ++a )
  541. e = e->next;
  542. ArrayEintrag< TYP * > *ne = new ArrayEintrag< TYP * >();
  543. ne->var = e->var;
  544. ne->set = e->set;
  545. ne->next = e->next;
  546. e->next = ne;
  547. e->var = t;
  548. e->set = 1;
  549. if( last->next )
  550. last = last->next;
  551. count++;
  552. }
  553. //! Setzt den Wert des i-ten Eintrags
  554. //! \param t der Neue Wert
  555. //! \param i Der Index des Eintrages der gesetzt werden soll
  556. void set( TYP *t, int i )
  557. {
  558. if( i < 0 || i >= count )
  559. throwOutOfRange( __FILE__, __LINE__, i, count );
  560. ArrayEintrag< TYP * > *e = entries;
  561. for( int a = 0; a < i; ++a )
  562. e = e->next;
  563. if( e->set && e->var )
  564. e->var->release();
  565. e->var = t;
  566. e->set = 1;
  567. }
  568. //! Verändert die Position des i-ten Elementes in der Liste
  569. //! \param i Der Index des Elementes, welches verschoben werden soll
  570. //! \param p Die Zielposition des Elementes (danach der neue Index des Elementes)
  571. void setPosition( int i, int p )
  572. {
  573. if( i == p )
  574. return;
  575. if( i < 0 || p < 0 || i >= count || p >= count )
  576. throwOutOfRange( __FILE__, __LINE__, i, count );
  577. ArrayEintrag< TYP * > *ve = 0;
  578. ArrayEintrag< TYP * > *e = entries;
  579. for( int a = 0; a < i; ++a )
  580. {
  581. ve = e;
  582. e = e->next;
  583. }
  584. ArrayEintrag< TYP * > *e2 = entries == e ? e->next : entries;
  585. ArrayEintrag< TYP * > *ve2 = 0;
  586. for( int a = 0; a < p; ++a )
  587. {
  588. ve2 = e2;
  589. if( e2->next == e )
  590. e2 = e->next;
  591. else
  592. e2 = e2->next;
  593. }
  594. if( last == e )
  595. last = e2;
  596. else if( last == e2 )
  597. last = e;
  598. if( !ve2 )
  599. entries = e;
  600. else
  601. ve2->next = e;
  602. if( ve )
  603. ve->next = e->next;
  604. else
  605. entries = e->next;
  606. e->next = e2;
  607. }
  608. //! Löscht ein Bestimmtes Element
  609. //! \param i Der Index des Elementes das gelöscht werden soll
  610. void remove( int i )
  611. {
  612. if( i < 0 || i >= count )
  613. throwOutOfRange( __FILE__, __LINE__, i, count );
  614. ArrayEintrag< TYP * > *e = entries;
  615. for( int a = 0; a < i; ++a )
  616. e = e->next;
  617. if( e->next )
  618. {
  619. if( e->set && e->var )
  620. e->var->release();
  621. e->var = e->next->var;
  622. e->set = e->next->set;
  623. }
  624. else
  625. {
  626. #pragma warning( once : 28182 )
  627. if( e->set && e->var )
  628. e->var->release();
  629. e->set = 0;
  630. }
  631. ArrayEintrag< TYP * > *del = e->next;
  632. if( e->next )
  633. e->next = e->next->next;
  634. else
  635. e->next = 0;
  636. if( del )
  637. {
  638. del->set = 0;
  639. del->next = 0;
  640. if( last == del )
  641. last = e;
  642. delete del;
  643. }
  644. count--;
  645. }
  646. //! Vertauscht zwei Elemente in der Liste
  647. //! \param vi Der Index des ersten Elementes
  648. //! \param ni Der Index des zweiten Elementes
  649. void tausch( int vi, int ni )
  650. {
  651. if( vi < 0 || ni < 0 )
  652. return;
  653. TYP *tmp = get( ni );
  654. set( get( vi ), ni );
  655. set( tmp, vi );
  656. }
  657. //! Löscht alle Elemente der Liste
  658. void leeren()
  659. {
  660. ArrayEintrag< TYP * > *e2 = 0;
  661. for( ArrayEintrag< TYP * > *e = entries; e; e = e->next )
  662. {
  663. if( e2 && e2->var && e2->set )
  664. e2->var->release();
  665. delete e2;
  666. e2 = e;
  667. }
  668. if( e2 && e2->var && e2->set )
  669. e2->var->release();
  670. delete e2;
  671. entries = new ArrayEintrag< TYP * >();
  672. entries->set = 0;
  673. entries->next = 0;
  674. last = entries;
  675. count = 0;
  676. }
  677. //! Gibt einen Iterator zurück.
  678. //! Mit ++ kann durch die Liste iteriert werden
  679. Iterator< TYP * > begin() const
  680. {
  681. return Iterator< TYP * >( entries );
  682. }
  683. Iterator< TYP * > end() const
  684. {
  685. return Iterator< TYP * >( 0 );
  686. }
  687. //! Gibt zurück, wie viele Elemente in der Liste sind
  688. int getEintragAnzahl() const
  689. {
  690. return count;
  691. }
  692. int getLastIndex() const
  693. {
  694. return count - 1;
  695. }
  696. //! Gibt den Wert des i-ten Elementes zurück mit erhöhtem Reference Counter
  697. //! \param i Der index des gesuchten Elementes, (0) wenn der Index nicht existiert
  698. TYP *get( int i ) const
  699. {
  700. if( i < 0 || i >= count )
  701. throwOutOfRange( __FILE__, __LINE__, i, count );
  702. ArrayEintrag< TYP * > *e = entries;
  703. for( int a = 0; a < i && e; ++a )
  704. e = e->next;
  705. if( e && e->set && e->var )
  706. return dynamic_cast<TYP *>(e->var->getThis());
  707. return (TYP *)0;
  708. }
  709. //! Gibt den Wert des i-ten Elementes zurück ohne erhöhten Reference Counter
  710. //! \param i Der index des gesuchten Elementes, (0) wenn der Index nicht existiert
  711. TYP *z( int i ) const //! gibt den index - ten T zurück
  712. {
  713. if( i < 0 || i >= count )
  714. throwOutOfRange( __FILE__, __LINE__, i, count );
  715. ArrayEintrag< TYP * > *e = entries;
  716. for( int a = 0; a < i && e; ++a )
  717. e = e->next;
  718. if( e && e->set && e->var )
  719. return (TYP *)e->var;
  720. return (TYP *)0;
  721. }
  722. //! Überprüft, ob ein Element in der Liste enthalten ist
  723. //! \param i Der Index des gesuchten Elementes
  724. //! \return (true), wenn der Index vorhanden ist. (false) sonnst
  725. bool hat( int i ) const
  726. {
  727. return i >= 0 && i < count;
  728. }
  729. RCArray &operator=( const RCArray &arr )
  730. {
  731. leeren();
  732. int anz = arr.getEintragAnzahl();
  733. for( int i = 0; i < anz; i++ )
  734. add( arr.get( i ) );
  735. return *this;
  736. }
  737. };
  738. }
  739. #endif