Array.h 18 KB

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