Array.h 19 KB

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