vector.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. /*
  2. * Copyright 2002, 2006 Adrian Thurston <thurston@cs.queensu.ca>
  3. */
  4. /* This file is part of Aapl.
  5. *
  6. * Aapl is free software; you can redistribute it and/or modify it under the
  7. * terms of the GNU Lesser General Public License as published by the Free
  8. * Software Foundation; either version 2.1 of the License, or (at your option)
  9. * any later version.
  10. *
  11. * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY
  12. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Aapl; if not, write to the Free Software Foundation, Inc., 59
  18. * Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #ifndef _AAPL_VECTOR_H
  21. #define _AAPL_VECTOR_H
  22. #include <new>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <assert.h>
  26. #include "table.h"
  27. #ifdef AAPL_NAMESPACE
  28. namespace Aapl {
  29. #endif
  30. /**
  31. * \addtogroup vector
  32. * @{
  33. */
  34. /** \class Vector
  35. * \brief Dynamic array.
  36. *
  37. * This is typical vector implementation. It is a dynamic array that can be
  38. * used to contain complex data structures that have constructors and
  39. * destructors as well as simple types such as integers and pointers.
  40. *
  41. * Vector supports inserting, overwriting, and removing single or multiple
  42. * elements at once. Constructors and destructors are called wherever
  43. * appropriate. For example, before an element is overwritten, it's
  44. * destructor is called.
  45. *
  46. * Vector provides automatic resizing of allocated memory as needed and offers
  47. * different allocation schemes for controlling how the automatic allocation
  48. * is done. Two senses of the the length of the data is maintained: the
  49. * amount of raw memory allocated to the vector and the number of actual
  50. * elements in the vector. The various allocation schemes control how the
  51. * allocated space is changed in relation to the number of elements in the
  52. * vector.
  53. *
  54. * \include ex_vector.cpp
  55. */
  56. /*@}*/
  57. template < class T, class Resize = ResizeExpn > class Vector
  58. : public Table<T>, public Resize
  59. {
  60. private:
  61. typedef Table<T> BaseTable;
  62. public:
  63. /**
  64. * \brief Initialize an empty vector with no space allocated.
  65. *
  66. * If a linear resizer is used, the step defaults to 256 units of T. For a
  67. * runtime vector both up and down allocation schemes default to
  68. * Exponential.
  69. */
  70. Vector() { }
  71. /**
  72. * \brief Create a vector that contains an initial element.
  73. *
  74. * The vector becomes one element in length. The element's copy
  75. * constructor is used to place the value in the vector.
  76. */
  77. Vector(const T &val) { setAs(&val, 1); }
  78. /**
  79. * \brief Create a vector that contains an array of elements.
  80. *
  81. * The vector becomes len elements in length. Copy constructors are used
  82. * to place the new elements in the vector.
  83. */
  84. Vector(const T *val, long len) { setAs(val, len); }
  85. /* Deep copy. */
  86. Vector( const Vector &v );
  87. /* Free all mem used by the vector. */
  88. ~Vector() { empty(); }
  89. /* Delete all items. */
  90. void empty();
  91. /* Abandon the contents of the vector without deleteing. */
  92. void abandon();
  93. /* Transfers the elements of another vector into this vector. First emptys
  94. * the current vector. */
  95. void transfer( Vector &v );
  96. /* Perform a deep copy of another vector into this vector. */
  97. Vector &operator=( const Vector &v );
  98. /*@{*/
  99. /**
  100. * \brief Insert one element at position pos.
  101. *
  102. * Elements in the vector from pos onward are shifted one space to the
  103. * right. The copy constructor is used to place the element into this
  104. * vector. If pos is greater than the length of the vector then undefined
  105. * behaviour results. If pos is negative then it is treated as an offset
  106. * relative to the length of the vector.
  107. */
  108. void insert(long pos, const T &val) { insert(pos, &val, 1); }
  109. /* Insert an array of values. */
  110. void insert(long pos, const T *val, long len);
  111. /**
  112. * \brief Insert all the elements from another vector at position pos.
  113. *
  114. * Elements in this vector from pos onward are shifted v.tabLen spaces to
  115. * the right. The element's copy constructor is used to copy the items
  116. * into this vector. The other vector is left unchanged. If pos is off the
  117. * end of the vector, then undefined behaviour results. If pos is negative
  118. * then it is treated as an offset relative to the length of the vector.
  119. * Equivalent to vector.insert(pos, other.data, other.tabLen).
  120. */
  121. void insert(long pos, const Vector &v) { insert(pos, v.data, v.tabLen); }
  122. /* Insert len copies of val into the vector. */
  123. void insertDup(long pos, const T &val, long len);
  124. /**
  125. * \brief Insert one new element using the default constrcutor.
  126. *
  127. * Elements in the vector from pos onward are shifted one space to the
  128. * right. The default constructor is used to init the new element. If pos
  129. * is greater than the length of the vector then undefined behaviour
  130. * results. If pos is negative then it is treated as an offset relative to
  131. * the length of the vector.
  132. */
  133. void insertNew(long pos) { insertNew(pos, 1); }
  134. /* Insert len new items using default constructor. */
  135. void insertNew(long pos, long len);
  136. /*@}*/
  137. /*@{*/
  138. /**
  139. * \brief Remove one element at position pos.
  140. *
  141. * The element's destructor is called. Elements to the right of pos are
  142. * shifted one space to the left to take up the free space. If pos is greater
  143. * than or equal to the length of the vector then undefined behavior results.
  144. * If pos is negative then it is treated as an offset relative to the length
  145. * of the vector.
  146. */
  147. void remove(long pos) { remove(pos, 1); }
  148. /* Delete a number of elements. */
  149. void remove(long pos, long len);
  150. /*@}*/
  151. /*@{*/
  152. /**
  153. * \brief Replace one element at position pos.
  154. *
  155. * If there is an existing element at position pos (if pos is less than
  156. * the length of the vector) then its destructor is called before the
  157. * space is used. The copy constructor is used to place the element into
  158. * the vector. If pos is greater than the length of the vector then
  159. * undefined behaviour results. If pos is negative then it is treated as
  160. * an offset relative to the length of the vector.
  161. */
  162. void replace(long pos, const T &val) { replace(pos, &val, 1); }
  163. /* Replace with an array of values. */
  164. void replace(long pos, const T *val, long len);
  165. /**
  166. * \brief Replace at position pos with all the elements of another vector.
  167. *
  168. * Replace at position pos with all the elements of another vector. The
  169. * other vector is left unchanged. If there are existing elements at the
  170. * positions to be replaced, then destructors are called before the space
  171. * is used. Copy constructors are used to place the elements into this
  172. * vector. It is allowable for the pos and length of the other vector to
  173. * specify a replacement that overwrites existing elements and creates new
  174. * ones. If pos is greater than the length of the vector then undefined
  175. * behaviour results. If pos is negative, then it is treated as an offset
  176. * relative to the length of the vector.
  177. */
  178. void replace(long pos, const Vector &v) { replace(pos, v.data, v.tabLen); }
  179. /* Replace len items with len copies of val. */
  180. void replaceDup(long pos, const T &val, long len);
  181. /**
  182. * \brief Replace at position pos with one new element.
  183. *
  184. * If there is an existing element at the position to be replaced (pos is
  185. * less than the length of the vector) then the element's destructor is
  186. * called before the space is used. The default constructor is used to
  187. * initialize the new element. If pos is greater than the length of the
  188. * vector then undefined behaviour results. If pos is negative, then it is
  189. * treated as an offset relative to the length of the vector.
  190. */
  191. void replaceNew(long pos) { replaceNew(pos, 1); }
  192. /* Replace len items at pos with newly constructed objects. */
  193. void replaceNew(long pos, long len);
  194. /*@}*/
  195. /*@{*/
  196. /**
  197. * \brief Set the contents of the vector to be val exactly.
  198. *
  199. * The vector becomes one element in length. Destructors are called on any
  200. * existing elements in the vector. The element's copy constructor is used
  201. * to place the val in the vector.
  202. */
  203. void setAs(const T &val) { setAs(&val, 1); }
  204. /* Set to the contents of an array. */
  205. void setAs(const T *val, long len);
  206. /**
  207. * \brief Set the vector to exactly the contents of another vector.
  208. *
  209. * The vector becomes v.tabLen elements in length. Destructors are called
  210. * on any existing elements. Copy constructors are used to place the new
  211. * elements in the vector.
  212. */
  213. void setAs(const Vector &v) { setAs(v.data, v.tabLen); }
  214. /* Set as len copies of item. */
  215. void setAsDup(const T &item, long len);
  216. /**
  217. * \brief Set the vector to exactly one new item.
  218. *
  219. * The vector becomes one element in length. Destructors are called on any
  220. * existing elements in the vector. The default constructor is used to
  221. * init the new item.
  222. */
  223. void setAsNew() { setAsNew(1); }
  224. /* Set as newly constructed objects using the default constructor. */
  225. void setAsNew(long len);
  226. /*@}*/
  227. /*@{*/
  228. /**
  229. * \brief Append one elment to the end of the vector.
  230. *
  231. * Copy constructor is used to place the element in the vector.
  232. */
  233. void append(const T &val) { replace(BaseTable::tabLen, &val, 1); }
  234. /**
  235. * \brief Append len elements to the end of the vector.
  236. *
  237. * Copy constructors are used to place the elements in the vector.
  238. */
  239. void append(const T *val, long len) { replace(BaseTable::tabLen, val, len); }
  240. /**
  241. * \brief Append the contents of another vector.
  242. *
  243. * The other vector is left unchanged. Copy constructors are used to place the
  244. * elements in the vector.
  245. */
  246. void append(const Vector &v) { replace(BaseTable::tabLen, v.data, v.tabLen); }
  247. /**
  248. * \brief Append len copies of item.
  249. *
  250. * The copy constructor is used to place the item in the vector.
  251. */
  252. void appendDup(const T &item, long len) { replaceDup(BaseTable::tabLen, item, len); }
  253. /**
  254. * \brief Append a single newly created item.
  255. *
  256. * The new element is initialized with the default constructor.
  257. */
  258. void appendNew() { replaceNew(BaseTable::tabLen, 1); }
  259. /**
  260. * \brief Append len newly created items.
  261. *
  262. * The new elements are initialized with the default constructor.
  263. */
  264. void appendNew(long len) { replaceNew(BaseTable::tabLen, len); }
  265. /*@}*/
  266. /*@{*/
  267. /** \fn Vector::prepend(const T &val)
  268. * \brief Prepend one elment to the front of the vector.
  269. *
  270. * Copy constructor is used to place the element in the vector.
  271. */
  272. void prepend(const T &val) { insert(0, &val, 1); }
  273. /**
  274. * \brief Prepend len elements to the front of the vector.
  275. *
  276. * Copy constructors are used to place the elements in the vector.
  277. */
  278. void prepend(const T *val, long len) { insert(0, val, len); }
  279. /**
  280. * \brief Prepend the contents of another vector.
  281. *
  282. * The other vector is left unchanged. Copy constructors are used to place the
  283. * elements in the vector.
  284. */
  285. void prepend(const Vector &v) { insert(0, v.data, v.tabLen); }
  286. /**
  287. * \brief Prepend len copies of item.
  288. *
  289. * The copy constructor is used to place the item in the vector.
  290. */
  291. void prependDup(const T &item, long len) { insertDup(0, item, len); }
  292. /**
  293. * \brief Prepend a single newly created item.
  294. *
  295. * The new element is initialized with the default constructor.
  296. */
  297. void prependNew() { insertNew(0, 1); }
  298. /**
  299. * \brief Prepend len newly created items.
  300. *
  301. * The new elements are initialized with the default constructor.
  302. */
  303. void prependNew(long len) { insertNew(0, len); }
  304. /*@}*/
  305. /* Convenience access. */
  306. T &operator[](int i) const { return BaseTable::data[i]; }
  307. long size() const { return BaseTable::tabLen; }
  308. /* Forward this so a ref can be used. */
  309. struct Iter;
  310. /* Various classes for setting the iterator */
  311. struct IterFirst { IterFirst( const Vector &v ) : v(v) { } const Vector &v; };
  312. struct IterLast { IterLast( const Vector &v ) : v(v) { } const Vector &v; };
  313. struct IterNext { IterNext( const Iter &i ) : i(i) { } const Iter &i; };
  314. struct IterPrev { IterPrev( const Iter &i ) : i(i) { } const Iter &i; };
  315. /**
  316. * \brief Vector Iterator.
  317. * \ingroup iterators
  318. */
  319. struct Iter
  320. {
  321. /* Construct, assign. */
  322. Iter() : ptr(0), ptrBeg(0), ptrEnd(0) { }
  323. /* Construct. */
  324. Iter( const Vector &v );
  325. Iter( const IterFirst &vf );
  326. Iter( const IterLast &vl );
  327. inline Iter( const IterNext &vn );
  328. inline Iter( const IterPrev &vp );
  329. /* Assign. */
  330. Iter &operator=( const Vector &v );
  331. Iter &operator=( const IterFirst &vf );
  332. Iter &operator=( const IterLast &vl );
  333. inline Iter &operator=( const IterNext &vf );
  334. inline Iter &operator=( const IterPrev &vl );
  335. /** \brief Less than end? */
  336. bool lte() const { return ptr != ptrEnd; }
  337. /** \brief At end? */
  338. bool end() const { return ptr == ptrEnd; }
  339. /** \brief Greater than beginning? */
  340. bool gtb() const { return ptr != ptrBeg; }
  341. /** \brief At beginning? */
  342. bool beg() const { return ptr == ptrBeg; }
  343. /** \brief At first element? */
  344. bool first() const { return ptr == ptrBeg+1; }
  345. /** \brief At last element? */
  346. bool last() const { return ptr == ptrEnd-1; }
  347. /* Return the position. */
  348. long pos() const { return ptr - ptrBeg - 1; }
  349. T &operator[](int i) const { return ptr[i]; }
  350. /** \brief Implicit cast to T*. */
  351. operator T*() const { return ptr; }
  352. /** \brief Dereference operator returns T&. */
  353. T &operator *() const { return *ptr; }
  354. /** \brief Arrow operator returns T*. */
  355. T *operator->() const { return ptr; }
  356. /** \brief Move to next item. */
  357. T *operator++() { return ++ptr; }
  358. /** \brief Move to next item. */
  359. T *operator++(int) { return ptr++; }
  360. /** \brief Move to next item. */
  361. T *increment() { return ++ptr; }
  362. /** \brief Move n items forward. */
  363. T *operator+=(long n) { return ptr+=n; }
  364. /** \brief Move to previous item. */
  365. T *operator--() { return --ptr; }
  366. /** \brief Move to previous item. */
  367. T *operator--(int) { return ptr--; }
  368. /** \brief Move to previous item. */
  369. T *decrement() { return --ptr; }
  370. /** \brief Move n items back. */
  371. T *operator-=(long n) { return ptr-=n; }
  372. /** \brief Return the next item. Does not modify this. */
  373. inline IterNext next() const { return IterNext(*this); }
  374. /** \brief Return the previous item. Does not modify this. */
  375. inline IterPrev prev() const { return IterPrev(*this); }
  376. /** \brief The iterator is simply a pointer. */
  377. T *ptr;
  378. /* For testing endpoints. */
  379. T *ptrBeg, *ptrEnd;
  380. };
  381. /** \brief Return first element. */
  382. IterFirst first() { return IterFirst( *this ); }
  383. /** \brief Return last element. */
  384. IterLast last() { return IterLast( *this ); }
  385. protected:
  386. void makeRawSpaceFor(long pos, long len);
  387. void upResize(long len);
  388. void downResize(long len);
  389. };
  390. /* Init a vector iterator with just a vector. */
  391. template <class T, class Resize> Vector<T, Resize>::Iter::Iter( const Vector &v )
  392. {
  393. if ( v.tabLen == 0 )
  394. ptr = ptrBeg = ptrEnd = 0;
  395. else {
  396. ptr = v.data;
  397. ptrBeg = v.data-1;
  398. ptrEnd = v.data+v.tabLen;
  399. }
  400. }
  401. /* Init a vector iterator with the first of a vector. */
  402. template <class T, class Resize> Vector<T, Resize>::Iter::Iter(
  403. const IterFirst &vf )
  404. {
  405. if ( vf.v.tabLen == 0 )
  406. ptr = ptrBeg = ptrEnd = 0;
  407. else {
  408. ptr = vf.v.data;
  409. ptrBeg = vf.v.data-1;
  410. ptrEnd = vf.v.data+vf.v.tabLen;
  411. }
  412. }
  413. /* Init a vector iterator with the last of a vector. */
  414. template <class T, class Resize> Vector<T, Resize>::Iter::Iter(
  415. const IterLast &vl )
  416. {
  417. if ( vl.v.tabLen == 0 )
  418. ptr = ptrBeg = ptrEnd = 0;
  419. else {
  420. ptr = vl.v.data+vl.v.tabLen-1;
  421. ptrBeg = vl.v.data-1;
  422. ptrEnd = vl.v.data+vl.v.tabLen;
  423. }
  424. }
  425. /* Init a vector iterator with the next of some other iterator. */
  426. template <class T, class Resize> Vector<T, Resize>::Iter::Iter(
  427. const IterNext &vn )
  428. :
  429. ptr(vn.i.ptr+1),
  430. ptrBeg(vn.i.ptrBeg),
  431. ptrEnd(vn.i.ptrEnd)
  432. {
  433. }
  434. /* Init a vector iterator with the prev of some other iterator. */
  435. template <class T, class Resize> Vector<T, Resize>::Iter::Iter(
  436. const IterPrev &vp )
  437. :
  438. ptr(vp.i.ptr-1),
  439. ptrBeg(vp.i.ptrBeg),
  440. ptrEnd(vp.i.ptrEnd)
  441. {
  442. }
  443. /* Set a vector iterator with some vector. */
  444. template <class T, class Resize> typename Vector<T, Resize>::Iter &
  445. Vector<T, Resize>::Iter::operator=( const Vector &v )
  446. {
  447. if ( v.tabLen == 0 )
  448. ptr = ptrBeg = ptrEnd = 0;
  449. else {
  450. ptr = v.data;
  451. ptrBeg = v.data-1;
  452. ptrEnd = v.data+v.tabLen;
  453. }
  454. return *this;
  455. }
  456. /* Set a vector iterator with the first element in a vector. */
  457. template <class T, class Resize> typename Vector<T, Resize>::Iter &
  458. Vector<T, Resize>::Iter::operator=( const IterFirst &vf )
  459. {
  460. if ( vf.v.tabLen == 0 )
  461. ptr = ptrBeg = ptrEnd = 0;
  462. else {
  463. ptr = vf.v.data;
  464. ptrBeg = vf.v.data-1;
  465. ptrEnd = vf.v.data+vf.v.tabLen;
  466. }
  467. return *this;
  468. }
  469. /* Set a vector iterator with the last element in a vector. */
  470. template <class T, class Resize> typename Vector<T, Resize>::Iter &
  471. Vector<T, Resize>::Iter::operator=( const IterLast &vl )
  472. {
  473. if ( vl.v.tabLen == 0 )
  474. ptr = ptrBeg = ptrEnd = 0;
  475. else {
  476. ptr = vl.v.data+vl.v.tabLen-1;
  477. ptrBeg = vl.v.data-1;
  478. ptrEnd = vl.v.data+vl.v.tabLen;
  479. }
  480. return *this;
  481. }
  482. /* Set a vector iterator with the next of some other iterator. */
  483. template <class T, class Resize> typename Vector<T, Resize>::Iter &
  484. Vector<T, Resize>::Iter::operator=( const IterNext &vn )
  485. {
  486. ptr = vn.i.ptr+1;
  487. ptrBeg = vn.i.ptrBeg;
  488. ptrEnd = vn.i.ptrEnd;
  489. return *this;
  490. }
  491. /* Set a vector iterator with the prev of some other iterator. */
  492. template <class T, class Resize> typename Vector<T, Resize>::Iter &
  493. Vector<T, Resize>::Iter::operator=( const IterPrev &vp )
  494. {
  495. ptr = vp.i.ptr-1;
  496. ptrBeg = vp.i.ptrBeg;
  497. ptrEnd = vp.i.ptrEnd;
  498. return *this;
  499. }
  500. /**
  501. * \brief Forget all elements in the vector.
  502. *
  503. * The contents of the vector are reset to null without without the space
  504. * being freed.
  505. */
  506. template<class T, class Resize> void Vector<T, Resize>::
  507. abandon()
  508. {
  509. BaseTable::data = 0;
  510. BaseTable::tabLen = 0;
  511. BaseTable::allocLen = 0;
  512. }
  513. /**
  514. * \brief Transfer the contents of another vector into this vector.
  515. *
  516. * The dynamic array of the other vector is moved into this vector by
  517. * reference. If this vector is non-empty then its contents are first deleted.
  518. * Afterward the other vector will be empty.
  519. */
  520. template<class T, class Resize> void Vector<T, Resize>::
  521. transfer( Vector &v )
  522. {
  523. empty();
  524. BaseTable::data = v.data;
  525. BaseTable::tabLen = v.tabLen;
  526. BaseTable::allocLen = v.allocLen;
  527. v.abandon();
  528. }
  529. /**
  530. * \brief Deep copy another vector into this vector.
  531. *
  532. * Copies the entire contents of the other vector into this vector. Any
  533. * existing contents are first deleted. Equivalent to setAs.
  534. *
  535. * \returns A reference to this.
  536. */
  537. template<class T, class Resize> Vector<T, Resize> &Vector<T, Resize>::
  538. operator=( const Vector &v )
  539. {
  540. setAs(v.data, v.tabLen);
  541. return *this;
  542. }
  543. /* Up resize the data for len elements using Resize::upResize to tell us the
  544. * new tabLen. Reads and writes allocLen. Does not read or write tabLen. */
  545. template<class T, class Resize> void Vector<T, Resize>::
  546. upResize(long len)
  547. {
  548. /* Ask the resizer what the new tabLen will be. */
  549. long newLen = Resize::upResize(BaseTable::allocLen, len);
  550. /* Did the data grow? */
  551. if ( newLen > BaseTable::allocLen ) {
  552. BaseTable::allocLen = newLen;
  553. if ( BaseTable::data != 0 ) {
  554. /* Table exists already, resize it up. */
  555. BaseTable::data = (T*) realloc( BaseTable::data, sizeof(T) * newLen );
  556. if ( BaseTable::data == 0 )
  557. throw std::bad_alloc();
  558. }
  559. else {
  560. /* Create the data. */
  561. BaseTable::data = (T*) malloc( sizeof(T) * newLen );
  562. if ( BaseTable::data == 0 )
  563. throw std::bad_alloc();
  564. }
  565. }
  566. }
  567. /* Down resize the data for len elements using Resize::downResize to determine
  568. * the new tabLen. Reads and writes allocLen. Does not read or write tabLen. */
  569. template<class T, class Resize> void Vector<T, Resize>::
  570. downResize(long len)
  571. {
  572. /* Ask the resizer what the new tabLen will be. */
  573. long newLen = Resize::downResize( BaseTable::allocLen, len );
  574. /* Did the data shrink? */
  575. if ( newLen < BaseTable::allocLen ) {
  576. BaseTable::allocLen = newLen;
  577. if ( newLen == 0 ) {
  578. /* Simply free the data. */
  579. free( BaseTable::data );
  580. BaseTable::data = 0;
  581. }
  582. else {
  583. /* Not shrinking to size zero, realloc it to the smaller size. */
  584. BaseTable::data = (T*) realloc( BaseTable::data, sizeof(T) * newLen );
  585. if ( BaseTable::data == 0 )
  586. throw std::bad_alloc();
  587. }
  588. }
  589. }
  590. /**
  591. * \brief Perform a deep copy of the vector.
  592. *
  593. * The contents of the other vector are copied into this vector. This vector
  594. * gets the same allocation size as the other vector. All items are copied
  595. * using the element's copy constructor.
  596. */
  597. template<class T, class Resize> Vector<T, Resize>::
  598. Vector(const Vector<T, Resize> &v)
  599. {
  600. BaseTable::tabLen = v.tabLen;
  601. BaseTable::allocLen = v.allocLen;
  602. if ( BaseTable::allocLen > 0 ) {
  603. /* Allocate needed space. */
  604. BaseTable::data = (T*) malloc(sizeof(T) * BaseTable::allocLen);
  605. if ( BaseTable::data == 0 )
  606. throw std::bad_alloc();
  607. /* If there are any items in the src data, copy them in. */
  608. T *dst = BaseTable::data, *src = v.data;
  609. for (long pos = 0; pos < BaseTable::tabLen; pos++, dst++, src++ )
  610. new(dst) T(*src);
  611. }
  612. else {
  613. /* Nothing allocated. */
  614. BaseTable::data = 0;
  615. }
  616. }
  617. /** \fn Vector::~Vector()
  618. * \brief Free all memory used by the vector.
  619. *
  620. * The vector is reset to zero elements. Destructors are called on all
  621. * elements in the vector. The space allocated for the vector is freed.
  622. */
  623. /**
  624. * \brief Free all memory used by the vector.
  625. *
  626. * The vector is reset to zero elements. Destructors are called on all
  627. * elements in the vector. The space allocated for the vector is freed.
  628. */
  629. template<class T, class Resize> void Vector<T, Resize>::
  630. empty()
  631. {
  632. if ( BaseTable::data != 0 ) {
  633. /* Call All destructors. */
  634. T *pos = BaseTable::data;
  635. for ( long i = 0; i < BaseTable::tabLen; pos++, i++ )
  636. pos->~T();
  637. /* Free the data space. */
  638. free( BaseTable::data );
  639. BaseTable::data = 0;
  640. BaseTable::tabLen = BaseTable::allocLen = 0;
  641. }
  642. }
  643. /**
  644. * \brief Set the contents of the vector to be len elements exactly.
  645. *
  646. * The vector becomes len elements in length. Destructors are called on any
  647. * existing elements in the vector. Copy constructors are used to place the
  648. * new elements in the vector.
  649. */
  650. template<class T, class Resize> void Vector<T, Resize>::
  651. setAs(const T *val, long len)
  652. {
  653. /* Call All destructors. */
  654. long i;
  655. T *pos = BaseTable::data;
  656. for ( i = 0; i < BaseTable::tabLen; pos++, i++ )
  657. pos->~T();
  658. /* Adjust the allocated length. */
  659. if ( len < BaseTable::tabLen )
  660. downResize( len );
  661. else if ( len > BaseTable::tabLen )
  662. upResize( len );
  663. /* Set the new data length to exactly len. */
  664. BaseTable::tabLen = len;
  665. /* Copy data in. */
  666. T *dst = BaseTable::data;
  667. const T *src = val;
  668. for ( i = 0; i < len; i++, dst++, src++ )
  669. new(dst) T(*src);
  670. }
  671. /**
  672. * \brief Set the vector to len copies of item.
  673. *
  674. * The vector becomes len elements in length. Destructors are called on any
  675. * existing elements in the vector. The element's copy constructor is used to
  676. * copy the item into the vector.
  677. */
  678. template<class T, class Resize> void Vector<T, Resize>::
  679. setAsDup(const T &item, long len)
  680. {
  681. /* Call All destructors. */
  682. T *pos = BaseTable::data;
  683. for ( long i = 0; i < BaseTable::tabLen; pos++, i++ )
  684. pos->~T();
  685. /* Adjust the allocated length. */
  686. if ( len < BaseTable::tabLen )
  687. downResize( len );
  688. else if ( len > BaseTable::tabLen )
  689. upResize( len );
  690. /* Set the new data length to exactly len. */
  691. BaseTable::tabLen = len;
  692. /* Copy item in one spot at a time. */
  693. T *dst = BaseTable::data;
  694. for ( long i = 0; i < len; i++, dst++ )
  695. new(dst) T(item);
  696. }
  697. /**
  698. * \brief Set the vector to exactly len new items.
  699. *
  700. * The vector becomes len elements in length. Destructors are called on any
  701. * existing elements in the vector. Default constructors are used to init the
  702. * new items.
  703. */
  704. template<class T, class Resize> void Vector<T, Resize>::
  705. setAsNew(long len)
  706. {
  707. /* Call All destructors. */
  708. T *pos = BaseTable::data;
  709. for ( long i = 0; i < BaseTable::tabLen; pos++, i++ )
  710. pos->~T();
  711. /* Adjust the allocated length. */
  712. if ( len < BaseTable::tabLen )
  713. downResize( len );
  714. else if ( len > BaseTable::tabLen )
  715. upResize( len );
  716. /* Set the new data length to exactly len. */
  717. BaseTable::tabLen = len;
  718. /* Create items using default constructor. */
  719. T *dst = BaseTable::data;
  720. for ( long i = 0; i < len; i++, dst++ )
  721. new(dst) T();
  722. }
  723. /**
  724. * \brief Replace len elements at position pos.
  725. *
  726. * If there are existing elements at the positions to be replaced, then
  727. * destructors are called before the space is used. Copy constructors are used
  728. * to place the elements into the vector. It is allowable for the pos and
  729. * length to specify a replacement that overwrites existing elements and
  730. * creates new ones. If pos is greater than the length of the vector then
  731. * undefined behaviour results. If pos is negative, then it is treated as an
  732. * offset relative to the length of the vector.
  733. */
  734. template<class T, class Resize> void Vector<T, Resize>::
  735. replace(long pos, const T *val, long len)
  736. {
  737. long endPos, i;
  738. T *item;
  739. /* If we are given a negative position to replace at then
  740. * treat it as a position relative to the length. */
  741. if ( pos < 0 )
  742. pos = BaseTable::tabLen + pos;
  743. /* The end is the one past the last item that we want
  744. * to write to. */
  745. endPos = pos + len;
  746. /* Make sure we have enough space. */
  747. if ( endPos > BaseTable::tabLen ) {
  748. upResize( endPos );
  749. /* Delete any objects we need to delete. */
  750. item = BaseTable::data + pos;
  751. for ( i = pos; i < BaseTable::tabLen; i++, item++ )
  752. item->~T();
  753. /* We are extending the vector, set the new data length. */
  754. BaseTable::tabLen = endPos;
  755. }
  756. else {
  757. /* Delete any objects we need to delete. */
  758. item = BaseTable::data + pos;
  759. for ( i = pos; i < endPos; i++, item++ )
  760. item->~T();
  761. }
  762. /* Copy data in using copy constructor. */
  763. T *dst = BaseTable::data + pos;
  764. const T *src = val;
  765. for ( i = 0; i < len; i++, dst++, src++ )
  766. new(dst) T(*src);
  767. }
  768. /**
  769. * \brief Replace at position pos with len copies of an item.
  770. *
  771. * If there are existing elements at the positions to be replaced, then
  772. * destructors are called before the space is used. The copy constructor is
  773. * used to place the element into this vector. It is allowable for the pos and
  774. * length to specify a replacement that overwrites existing elements and
  775. * creates new ones. If pos is greater than the length of the vector then
  776. * undefined behaviour results. If pos is negative, then it is treated as an
  777. * offset relative to the length of the vector.
  778. */
  779. template<class T, class Resize> void Vector<T, Resize>::
  780. replaceDup(long pos, const T &val, long len)
  781. {
  782. long endPos, i;
  783. T *item;
  784. /* If we are given a negative position to replace at then
  785. * treat it as a position relative to the length. */
  786. if ( pos < 0 )
  787. pos = BaseTable::tabLen + pos;
  788. /* The end is the one past the last item that we want
  789. * to write to. */
  790. endPos = pos + len;
  791. /* Make sure we have enough space. */
  792. if ( endPos > BaseTable::tabLen ) {
  793. upResize( endPos );
  794. /* Delete any objects we need to delete. */
  795. item = BaseTable::data + pos;
  796. for ( i = pos; i < BaseTable::tabLen; i++, item++ )
  797. item->~T();
  798. /* We are extending the vector, set the new data length. */
  799. BaseTable::tabLen = endPos;
  800. }
  801. else {
  802. /* Delete any objects we need to delete. */
  803. item = BaseTable::data + pos;
  804. for ( i = pos; i < endPos; i++, item++ )
  805. item->~T();
  806. }
  807. /* Copy data in using copy constructor. */
  808. T *dst = BaseTable::data + pos;
  809. for ( long i = 0; i < len; i++, dst++ )
  810. new(dst) T(val);
  811. }
  812. /**
  813. * \brief Replace at position pos with len new elements.
  814. *
  815. * If there are existing elements at the positions to be replaced, then
  816. * destructors are called before the space is used. The default constructor is
  817. * used to initialize the new elements. It is allowable for the pos and length
  818. * to specify a replacement that overwrites existing elements and creates new
  819. * ones. If pos is greater than the length of the vector then undefined
  820. * behaviour results. If pos is negative, then it is treated as an offset
  821. * relative to the length of the vector.
  822. */
  823. template<class T, class Resize> void Vector<T, Resize>::
  824. replaceNew(long pos, long len)
  825. {
  826. long endPos, i;
  827. T *item;
  828. /* If we are given a negative position to replace at then
  829. * treat it as a position relative to the length. */
  830. if ( pos < 0 )
  831. pos = BaseTable::tabLen + pos;
  832. /* The end is the one past the last item that we want
  833. * to write to. */
  834. endPos = pos + len;
  835. /* Make sure we have enough space. */
  836. if ( endPos > BaseTable::tabLen ) {
  837. upResize( endPos );
  838. /* Delete any objects we need to delete. */
  839. item = BaseTable::data + pos;
  840. for ( i = pos; i < BaseTable::tabLen; i++, item++ )
  841. item->~T();
  842. /* We are extending the vector, set the new data length. */
  843. BaseTable::tabLen = endPos;
  844. }
  845. else {
  846. /* Delete any objects we need to delete. */
  847. item = BaseTable::data + pos;
  848. for ( i = pos; i < endPos; i++, item++ )
  849. item->~T();
  850. }
  851. /* Copy data in using copy constructor. */
  852. T *dst = BaseTable::data + pos;
  853. for ( long i = 0; i < len; i++, dst++ )
  854. new(dst) T();
  855. }
  856. /**
  857. * \brief Remove len elements at position pos.
  858. *
  859. * Destructor is called on all elements removed. Elements to the right of pos
  860. * are shifted len spaces to the left to take up the free space. If pos is
  861. * greater than or equal to the length of the vector then undefined behavior
  862. * results. If pos is negative then it is treated as an offset relative to the
  863. * length of the vector.
  864. */
  865. template<class T, class Resize> void Vector<T, Resize>::
  866. remove(long pos, long len)
  867. {
  868. long newLen, lenToSlideOver, endPos;
  869. T *dst, *item;
  870. /* If we are given a negative position to remove at then
  871. * treat it as a position relative to the length. */
  872. if ( pos < 0 )
  873. pos = BaseTable::tabLen + pos;
  874. /* The first position after the last item deleted. */
  875. endPos = pos + len;
  876. /* The new data length. */
  877. newLen = BaseTable::tabLen - len;
  878. /* The place in the data we are deleting at. */
  879. dst = BaseTable::data + pos;
  880. /* Call Destructors. */
  881. item = dst;
  882. for ( long i = 0; i < len; i += 1, item += 1 )
  883. item->~T();
  884. /* Shift data over if necessary. */
  885. lenToSlideOver = BaseTable::tabLen - endPos;
  886. if ( len > 0 && lenToSlideOver > 0 )
  887. memmove(dst, dst + len, sizeof(T)*lenToSlideOver);
  888. /* Shrink the data if necessary. */
  889. downResize( newLen );
  890. /* Set the new data length. */
  891. BaseTable::tabLen = newLen;
  892. }
  893. /**
  894. * \brief Insert len elements at position pos.
  895. *
  896. * Elements in the vector from pos onward are shifted len spaces to the right.
  897. * The copy constructor is used to place the elements into this vector. If pos
  898. * is greater than the length of the vector then undefined behaviour results.
  899. * If pos is negative then it is treated as an offset relative to the length
  900. * of the vector.
  901. */
  902. template<class T, class Resize> void Vector<T, Resize>::
  903. insert(long pos, const T *val, long len)
  904. {
  905. /* If we are given a negative position to insert at then
  906. * treat it as a position relative to the length. */
  907. if ( pos < 0 )
  908. pos = BaseTable::tabLen + pos;
  909. /* Calculate the new length. */
  910. long newLen = BaseTable::tabLen + len;
  911. /* Up resize, we are growing. */
  912. upResize( newLen );
  913. /* Shift over data at insert spot if needed. */
  914. if ( len > 0 && pos < BaseTable::tabLen ) {
  915. memmove(BaseTable::data + pos + len, BaseTable::data + pos,
  916. sizeof(T)*(BaseTable::tabLen-pos));
  917. }
  918. /* Copy data in element by element. */
  919. T *dst = BaseTable::data + pos;
  920. const T *src = val;
  921. for ( long i = 0; i < len; i++, dst++, src++ )
  922. new(dst) T(*src);
  923. /* Set the new length. */
  924. BaseTable::tabLen = newLen;
  925. }
  926. /**
  927. * \brief Insert len copies of item at position pos.
  928. *
  929. * Elements in the vector from pos onward are shifted len spaces to the right.
  930. * The copy constructor is used to place the element into this vector. If pos
  931. * is greater than the length of the vector then undefined behaviour results.
  932. * If pos is negative then it is treated as an offset relative to the length
  933. * of the vector.
  934. */
  935. template<class T, class Resize> void Vector<T, Resize>::
  936. insertDup(long pos, const T &item, long len)
  937. {
  938. /* If we are given a negative position to insert at then
  939. * treat it as a position relative to the length. */
  940. if ( pos < 0 )
  941. pos = BaseTable::tabLen + pos;
  942. /* Calculate the new length. */
  943. long newLen = BaseTable::tabLen + len;
  944. /* Up resize, we are growing. */
  945. upResize( newLen );
  946. /* Shift over data at insert spot if needed. */
  947. if ( len > 0 && pos < BaseTable::tabLen ) {
  948. memmove(BaseTable::data + pos + len, BaseTable::data + pos,
  949. sizeof(T)*(BaseTable::tabLen-pos));
  950. }
  951. /* Copy the data item in one at a time. */
  952. T *dst = BaseTable::data + pos;
  953. for ( long i = 0; i < len; i++, dst++ )
  954. new(dst) T(item);
  955. /* Set the new length. */
  956. BaseTable::tabLen = newLen;
  957. }
  958. /**
  959. * \brief Insert len new elements using the default constructor.
  960. *
  961. * Elements in the vector from pos onward are shifted len spaces to the right.
  962. * Default constructors are used to init the new elements. If pos is off the
  963. * end of the vector then undefined behaviour results. If pos is negative then
  964. * it is treated as an offset relative to the length of the vector.
  965. */
  966. template<class T, class Resize> void Vector<T, Resize>::
  967. insertNew(long pos, long len)
  968. {
  969. /* If we are given a negative position to insert at then
  970. * treat it as a position relative to the length. */
  971. if ( pos < 0 )
  972. pos = BaseTable::tabLen + pos;
  973. /* Calculate the new length. */
  974. long newLen = BaseTable::tabLen + len;
  975. /* Up resize, we are growing. */
  976. upResize( newLen );
  977. /* Shift over data at insert spot if needed. */
  978. if ( len > 0 && pos < BaseTable::tabLen ) {
  979. memmove(BaseTable::data + pos + len, BaseTable::data + pos,
  980. sizeof(T)*(BaseTable::tabLen-pos));
  981. }
  982. /* Init new data with default constructors. */
  983. T *dst = BaseTable::data + pos;
  984. for ( long i = 0; i < len; i++, dst++ )
  985. new(dst) T();
  986. /* Set the new length. */
  987. BaseTable::tabLen = newLen;
  988. }
  989. /* Makes space for len items, Does not init the items in any way. If pos is
  990. * greater than the length of the vector then undefined behaviour results.
  991. * Updates the length of the vector. */
  992. template<class T, class Resize> void Vector<T, Resize>::
  993. makeRawSpaceFor(long pos, long len)
  994. {
  995. /* Calculate the new length. */
  996. long newLen = BaseTable::tabLen + len;
  997. /* Up resize, we are growing. */
  998. upResize( newLen );
  999. /* Shift over data at insert spot if needed. */
  1000. if ( len > 0 && pos < BaseTable::tabLen ) {
  1001. memmove(BaseTable::data + pos + len, BaseTable::data + pos,
  1002. sizeof(T)*(BaseTable::tabLen-pos));
  1003. }
  1004. /* Save the new length. */
  1005. BaseTable::tabLen = newLen;
  1006. }
  1007. #ifdef AAPL_NAMESPACE
  1008. }
  1009. #endif
  1010. #endif /* _AAPL_VECTOR_H */