Array.h 19 KB

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