Array.h 22 KB

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