vector.hpp 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077
  1. //
  2. // Copyright (c) 2000-2010
  3. // Joerg Walter, Mathias Koch, David Bellot
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // The authors gratefully acknowledge the support of
  10. // GeNeSys mbH & Co. KG in producing this work.
  11. //
  12. // And we acknowledge the support from all contributors.
  13. /// \file vector.hpp Definition for the class vector and its derivative
  14. #ifndef _BOOST_UBLAS_VECTOR_
  15. #define _BOOST_UBLAS_VECTOR_
  16. #include <boost/numeric/ublas/storage.hpp>
  17. #include <boost/numeric/ublas/vector_expression.hpp>
  18. #include <boost/numeric/ublas/detail/vector_assign.hpp>
  19. #include <boost/serialization/collection_size_type.hpp>
  20. #include <boost/serialization/nvp.hpp>
  21. // Iterators based on ideas of Jeremy Siek
  22. namespace boost { namespace numeric { namespace ublas {
  23. /** \brief A dense vector of values of type \c T.
  24. *
  25. * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
  26. * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array.
  27. * Elements are constructed by \c A, which need not initialise their value.
  28. *
  29. * \tparam T type of the objects stored in the vector (like int, double, complex,...)
  30. * \tparam A The type of the storage array of the vector. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
  31. */
  32. template<class T, class A>
  33. class vector:
  34. public vector_container<vector<T, A> > {
  35. typedef vector<T, A> self_type;
  36. public:
  37. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  38. using vector_container<self_type>::operator ();
  39. #endif
  40. typedef typename A::size_type size_type;
  41. typedef typename A::difference_type difference_type;
  42. typedef T value_type;
  43. typedef typename type_traits<T>::const_reference const_reference;
  44. typedef T &reference;
  45. typedef T *pointer;
  46. typedef const T *const_pointer;
  47. typedef A array_type;
  48. typedef const vector_reference<const self_type> const_closure_type;
  49. typedef vector_reference<self_type> closure_type;
  50. typedef self_type vector_temporary_type;
  51. typedef dense_tag storage_category;
  52. // Construction and destruction
  53. /// \brief Constructor of a vector
  54. /// By default it is empty, i.e. \c size()==0.
  55. BOOST_UBLAS_INLINE
  56. vector ():
  57. vector_container<self_type> (),
  58. data_ () {}
  59. /// \brief Constructor of a vector with a predefined size
  60. /// By default, its elements are initialized to 0.
  61. /// \param size initial size of the vector
  62. explicit BOOST_UBLAS_INLINE
  63. vector (size_type size):
  64. vector_container<self_type> (),
  65. data_ (size) {
  66. }
  67. /// \brief Constructor of a vector by copying from another container
  68. /// This type has the generic name \c array_typ within the vector definition.
  69. /// \param size initial size of the vector \bug this value is not used
  70. /// \param data container of type \c A
  71. /// \todo remove this definition because \c size is not used
  72. BOOST_UBLAS_INLINE
  73. vector (size_type size, const array_type &data):
  74. vector_container<self_type> (),
  75. data_ (data) {}
  76. /// \brief Constructor of a vector by copying from another container
  77. /// This type has the generic name \c array_typ within the vector definition.
  78. /// \param data container of type \c A
  79. BOOST_UBLAS_INLINE
  80. vector (const array_type &data):
  81. vector_container<self_type> (),
  82. data_ (data) {}
  83. /// \brief Constructor of a vector with a predefined size and a unique initial value
  84. /// \param size of the vector
  85. /// \param init value to assign to each element of the vector
  86. BOOST_UBLAS_INLINE
  87. vector (size_type size, const value_type &init):
  88. vector_container<self_type> (),
  89. data_ (size, init) {}
  90. /// \brief Copy-constructor of a vector
  91. /// \param v is the vector to be duplicated
  92. BOOST_UBLAS_INLINE
  93. vector (const vector &v):
  94. vector_container<self_type> (),
  95. data_ (v.data_) {}
  96. /// \brief Copy-constructor of a vector from a vector_expression
  97. /// Depending on the vector_expression, this constructor can have the cost of the computations
  98. /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
  99. /// \param ae the vector_expression which values will be duplicated into the vector
  100. template<class AE>
  101. BOOST_UBLAS_INLINE
  102. vector (const vector_expression<AE> &ae):
  103. vector_container<self_type> (),
  104. data_ (ae ().size ()) {
  105. vector_assign<scalar_assign> (*this, ae);
  106. }
  107. // -----------------------
  108. // Random Access Container
  109. // -----------------------
  110. /// \brief Return the maximum size of the data container.
  111. /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
  112. BOOST_UBLAS_INLINE
  113. size_type max_size () const {
  114. return data_.max_size ();
  115. }
  116. /// \brief Return true if the vector is empty (\c size==0)
  117. /// \return \c true if empty, \c false otherwise
  118. BOOST_UBLAS_INLINE
  119. bool empty () const {
  120. return data_.size () == 0;
  121. }
  122. // ---------
  123. // Accessors
  124. // ---------
  125. /// \brief Return the size of the vector
  126. BOOST_UBLAS_INLINE
  127. size_type size () const {
  128. return data_.size ();
  129. }
  130. // -----------------
  131. // Storage accessors
  132. // -----------------
  133. /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
  134. BOOST_UBLAS_INLINE
  135. const array_type &data () const {
  136. return data_;
  137. }
  138. /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
  139. BOOST_UBLAS_INLINE
  140. array_type &data () {
  141. return data_;
  142. }
  143. // --------
  144. // Resizing
  145. // --------
  146. /// \brief Resize the vector
  147. /// Resize the vector to a new size. If \c preserve is true, data are copied otherwise data are lost. If the new size is bigger, the remaining values are filled in with the initial value (0 by default) in the case of \c unbounded_array, which is the container by default. If the new size is smaller, last values are lost. This behaviour can be different if you explicitely specify another type of container.
  148. /// \param size new size of the vector
  149. /// \param preserve if true, keep values
  150. BOOST_UBLAS_INLINE
  151. void resize (size_type size, bool preserve = true) {
  152. if (preserve)
  153. data ().resize (size, typename A::value_type ());
  154. else
  155. data ().resize (size);
  156. }
  157. // ---------------
  158. // Element support
  159. // ---------------
  160. /// \brief Return a pointer to the element \f$i\f$
  161. /// \param i index of the element
  162. // XXX this semantic is not the one expected by the name of this method
  163. BOOST_UBLAS_INLINE
  164. pointer find_element (size_type i) {
  165. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  166. }
  167. /// \brief Return a const pointer to the element \f$i\f$
  168. /// \param i index of the element
  169. // XXX this semantic is not the one expected by the name of this method
  170. BOOST_UBLAS_INLINE
  171. const_pointer find_element (size_type i) const {
  172. return & (data () [i]);
  173. }
  174. // --------------
  175. // Element access
  176. // --------------
  177. /// \brief Return a const reference to the element \f$i\f$
  178. /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  179. /// \param i index of the element
  180. BOOST_UBLAS_INLINE
  181. const_reference operator () (size_type i) const {
  182. return data () [i];
  183. }
  184. /// \brief Return a reference to the element \f$i\f$
  185. /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  186. /// \param i index of the element
  187. BOOST_UBLAS_INLINE
  188. reference operator () (size_type i) {
  189. return data () [i];
  190. }
  191. /// \brief Return a const reference to the element \f$i\f$
  192. /// \param i index of the element
  193. BOOST_UBLAS_INLINE
  194. const_reference operator [] (size_type i) const {
  195. return (*this) (i);
  196. }
  197. /// \brief Return a reference to the element \f$i\f$
  198. /// \param i index of the element
  199. BOOST_UBLAS_INLINE
  200. reference operator [] (size_type i) {
  201. return (*this) (i);
  202. }
  203. // ------------------
  204. // Element assignment
  205. // ------------------
  206. /// \brief Set element \f$i\f$ to the value \c t
  207. /// \param i index of the element
  208. /// \param t reference to the value to be set
  209. // XXX semantic of this is to insert a new element and therefore size=size+1 ?
  210. BOOST_UBLAS_INLINE
  211. reference insert_element (size_type i, const_reference t) {
  212. return (data () [i] = t);
  213. }
  214. /// \brief Set element \f$i\f$ to the \e zero value
  215. /// \param i index of the element
  216. BOOST_UBLAS_INLINE
  217. void erase_element (size_type i) {
  218. data () [i] = value_type/*zero*/();
  219. }
  220. // -------
  221. // Zeroing
  222. // -------
  223. /// \brief Clear the vector, i.e. set all values to the \c zero value.
  224. BOOST_UBLAS_INLINE
  225. void clear () {
  226. std::fill (data ().begin (), data ().end (), value_type/*zero*/());
  227. }
  228. // Assignment
  229. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  230. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  231. /// \param v is the source vector
  232. /// \return a reference to a vector (i.e. the destination vector)
  233. /*! @note "pass by value" the key idea to enable move semantics */
  234. BOOST_UBLAS_INLINE
  235. vector &operator = (vector v) {
  236. assign_temporary(v);
  237. return *this;
  238. }
  239. #else
  240. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  241. /// \param v is the source vector
  242. /// \return a reference to a vector (i.e. the destination vector)
  243. BOOST_UBLAS_INLINE
  244. vector &operator = (const vector &v) {
  245. data () = v.data ();
  246. return *this;
  247. }
  248. #endif
  249. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  250. /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
  251. /// \param v is the source vector container
  252. /// \return a reference to a vector (i.e. the destination vector)
  253. template<class C> // Container assignment without temporary
  254. BOOST_UBLAS_INLINE
  255. vector &operator = (const vector_container<C> &v) {
  256. resize (v ().size (), false);
  257. assign (v);
  258. return *this;
  259. }
  260. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  261. /// \param v is the source vector
  262. /// \return a reference to a vector (i.e. the destination vector)
  263. BOOST_UBLAS_INLINE
  264. vector &assign_temporary (vector &v) {
  265. swap (v);
  266. return *this;
  267. }
  268. /// \brief Assign the result of a vector_expression to the vector
  269. /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  270. /// \tparam AE is the type of the vector_expression
  271. /// \param ae is a const reference to the vector_expression
  272. /// \return a reference to the resulting vector
  273. template<class AE>
  274. BOOST_UBLAS_INLINE
  275. vector &operator = (const vector_expression<AE> &ae) {
  276. self_type temporary (ae);
  277. return assign_temporary (temporary);
  278. }
  279. /// \brief Assign the result of a vector_expression to the vector
  280. /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  281. /// \tparam AE is the type of the vector_expression
  282. /// \param ae is a const reference to the vector_expression
  283. /// \return a reference to the resulting vector
  284. template<class AE>
  285. BOOST_UBLAS_INLINE
  286. vector &assign (const vector_expression<AE> &ae) {
  287. vector_assign<scalar_assign> (*this, ae);
  288. return *this;
  289. }
  290. // -------------------
  291. // Computed assignment
  292. // -------------------
  293. /// \brief Assign the sum of the vector and a vector_expression to the vector
  294. /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  295. /// A temporary is created for the computations.
  296. /// \tparam AE is the type of the vector_expression
  297. /// \param ae is a const reference to the vector_expression
  298. /// \return a reference to the resulting vector
  299. template<class AE>
  300. BOOST_UBLAS_INLINE
  301. vector &operator += (const vector_expression<AE> &ae) {
  302. self_type temporary (*this + ae);
  303. return assign_temporary (temporary);
  304. }
  305. /// \brief Assign the sum of the vector and a vector_expression to the vector
  306. /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  307. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  308. /// \tparam AE is the type of the vector_expression
  309. /// \param ae is a const reference to the vector_expression
  310. /// \return a reference to the resulting vector
  311. template<class C> // Container assignment without temporary
  312. BOOST_UBLAS_INLINE
  313. vector &operator += (const vector_container<C> &v) {
  314. plus_assign (v);
  315. return *this;
  316. }
  317. /// \brief Assign the sum of the vector and a vector_expression to the vector
  318. /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  319. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  320. /// \tparam AE is the type of the vector_expression
  321. /// \param ae is a const reference to the vector_expression
  322. /// \return a reference to the resulting vector
  323. template<class AE>
  324. BOOST_UBLAS_INLINE
  325. vector &plus_assign (const vector_expression<AE> &ae) {
  326. vector_assign<scalar_plus_assign> (*this, ae);
  327. return *this;
  328. }
  329. /// \brief Assign the difference of the vector and a vector_expression to the vector
  330. /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  331. /// A temporary is created for the computations.
  332. /// \tparam AE is the type of the vector_expression
  333. /// \param ae is a const reference to the vector_expression
  334. template<class AE>
  335. BOOST_UBLAS_INLINE
  336. vector &operator -= (const vector_expression<AE> &ae) {
  337. self_type temporary (*this - ae);
  338. return assign_temporary (temporary);
  339. }
  340. /// \brief Assign the difference of the vector and a vector_expression to the vector
  341. /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  342. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  343. /// \tparam AE is the type of the vector_expression
  344. /// \param ae is a const reference to the vector_expression
  345. /// \return a reference to the resulting vector
  346. template<class C> // Container assignment without temporary
  347. BOOST_UBLAS_INLINE
  348. vector &operator -= (const vector_container<C> &v) {
  349. minus_assign (v);
  350. return *this;
  351. }
  352. /// \brief Assign the difference of the vector and a vector_expression to the vector
  353. /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  354. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  355. /// \tparam AE is the type of the vector_expression
  356. /// \param ae is a const reference to the vector_expression
  357. /// \return a reference to the resulting vector
  358. template<class AE>
  359. BOOST_UBLAS_INLINE
  360. vector &minus_assign (const vector_expression<AE> &ae) {
  361. vector_assign<scalar_minus_assign> (*this, ae);
  362. return *this;
  363. }
  364. /// \brief Assign the product of the vector and a scalar to the vector
  365. /// Assign the product of the vector and a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  366. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  367. /// \tparam AE is the type of the vector_expression
  368. /// \param at is a const reference to the scalar
  369. /// \return a reference to the resulting vector
  370. template<class AT>
  371. BOOST_UBLAS_INLINE
  372. vector &operator *= (const AT &at) {
  373. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  374. return *this;
  375. }
  376. /// \brief Assign the division of the vector by a scalar to the vector
  377. /// Assign the division of the vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  378. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  379. /// \tparam AE is the type of the vector_expression
  380. /// \param at is a const reference to the scalar
  381. /// \return a reference to the resulting vector
  382. template<class AT>
  383. BOOST_UBLAS_INLINE
  384. vector &operator /= (const AT &at) {
  385. vector_assign_scalar<scalar_divides_assign> (*this, at);
  386. return *this;
  387. }
  388. // --------
  389. // Swapping
  390. // --------
  391. /// \brief Swap the content of the vector with another vector
  392. /// \param v is the vector to be swapped with
  393. BOOST_UBLAS_INLINE
  394. void swap (vector &v) {
  395. if (this != &v) {
  396. data ().swap (v.data ());
  397. }
  398. }
  399. /// \brief Swap the content of two vectors
  400. /// \param v1 is the first vector. It takes values from v2
  401. /// \param v2 is the second vector It takes values from v1
  402. BOOST_UBLAS_INLINE
  403. friend void swap (vector &v1, vector &v2) {
  404. v1.swap (v2);
  405. }
  406. // Iterator types
  407. private:
  408. // Use the storage array iterator
  409. typedef typename A::const_iterator const_subiterator_type;
  410. typedef typename A::iterator subiterator_type;
  411. public:
  412. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  413. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  414. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  415. #else
  416. class const_iterator;
  417. class iterator;
  418. #endif
  419. // --------------
  420. // Element lookup
  421. // --------------
  422. /// \brief Return a const iterator to the element \e i
  423. /// \param i index of the element
  424. BOOST_UBLAS_INLINE
  425. const_iterator find (size_type i) const {
  426. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  427. return const_iterator (*this, data ().begin () + i);
  428. #else
  429. return const_iterator (*this, i);
  430. #endif
  431. }
  432. /// \brief Return an iterator to the element \e i
  433. /// \param i index of the element
  434. BOOST_UBLAS_INLINE
  435. iterator find (size_type i) {
  436. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  437. return iterator (*this, data ().begin () + i);
  438. #else
  439. return iterator (*this, i);
  440. #endif
  441. }
  442. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  443. class const_iterator:
  444. public container_const_reference<vector>,
  445. public random_access_iterator_base<dense_random_access_iterator_tag,
  446. const_iterator, value_type, difference_type> {
  447. public:
  448. typedef typename vector::difference_type difference_type;
  449. typedef typename vector::value_type value_type;
  450. typedef typename vector::const_reference reference;
  451. typedef const typename vector::pointer pointer;
  452. // ----------------------------
  453. // Construction and destruction
  454. // ----------------------------
  455. BOOST_UBLAS_INLINE
  456. const_iterator ():
  457. container_const_reference<self_type> (), it_ () {}
  458. BOOST_UBLAS_INLINE
  459. const_iterator (const self_type &v, const const_subiterator_type &it):
  460. container_const_reference<self_type> (v), it_ (it) {}
  461. BOOST_UBLAS_INLINE
  462. const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
  463. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  464. // ----------
  465. // Arithmetic
  466. // ----------
  467. /// \brief Increment by 1 the position of the iterator
  468. /// \return a reference to the const iterator
  469. BOOST_UBLAS_INLINE
  470. const_iterator &operator ++ () {
  471. ++ it_;
  472. return *this;
  473. }
  474. /// \brief Decrement by 1 the position of the iterator
  475. /// \return a reference to the const iterator
  476. BOOST_UBLAS_INLINE
  477. const_iterator &operator -- () {
  478. -- it_;
  479. return *this;
  480. }
  481. /// \brief Increment by \e n the position of the iterator
  482. /// \return a reference to the const iterator
  483. BOOST_UBLAS_INLINE
  484. const_iterator &operator += (difference_type n) {
  485. it_ += n;
  486. return *this;
  487. }
  488. /// \brief Decrement by \e n the position of the iterator
  489. /// \return a reference to the const iterator
  490. BOOST_UBLAS_INLINE
  491. const_iterator &operator -= (difference_type n) {
  492. it_ -= n;
  493. return *this;
  494. }
  495. /// \brief Return the different in number of positions between 2 iterators
  496. BOOST_UBLAS_INLINE
  497. difference_type operator - (const const_iterator &it) const {
  498. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  499. return it_ - it.it_;
  500. }
  501. /// \brief Dereference an iterator
  502. /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  503. /// \return a const reference to the value pointed by the iterator
  504. BOOST_UBLAS_INLINE
  505. const_reference operator * () const {
  506. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  507. return *it_;
  508. }
  509. /// \brief Dereference an iterator at the n-th forward value
  510. /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
  511. /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  512. /// \return a const reference
  513. BOOST_UBLAS_INLINE
  514. const_reference operator [] (difference_type n) const {
  515. return *(it_ + n);
  516. }
  517. // Index
  518. /// \brief return the index of the element referenced by the iterator
  519. BOOST_UBLAS_INLINE
  520. size_type index () const {
  521. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  522. return it_ - (*this) ().begin ().it_;
  523. }
  524. // Assignment
  525. BOOST_UBLAS_INLINE
  526. /// \brief assign the value of an iterator to the iterator
  527. const_iterator &operator = (const const_iterator &it) {
  528. container_const_reference<self_type>::assign (&it ());
  529. it_ = it.it_;
  530. return *this;
  531. }
  532. // Comparison
  533. /// \brief compare the value of two itetarors
  534. /// \return true if they reference the same element
  535. BOOST_UBLAS_INLINE
  536. bool operator == (const const_iterator &it) const {
  537. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  538. return it_ == it.it_;
  539. }
  540. /// \brief compare the value of two iterators
  541. /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
  542. BOOST_UBLAS_INLINE
  543. bool operator < (const const_iterator &it) const {
  544. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  545. return it_ < it.it_;
  546. }
  547. private:
  548. const_subiterator_type it_;
  549. friend class iterator;
  550. };
  551. #endif
  552. /// \brief return an iterator on the first element of the vector
  553. BOOST_UBLAS_INLINE
  554. const_iterator begin () const {
  555. return find (0);
  556. }
  557. /// \brief return an iterator after the last element of the vector
  558. BOOST_UBLAS_INLINE
  559. const_iterator end () const {
  560. return find (data_.size ());
  561. }
  562. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  563. class iterator:
  564. public container_reference<vector>,
  565. public random_access_iterator_base<dense_random_access_iterator_tag,
  566. iterator, value_type, difference_type> {
  567. public:
  568. typedef typename vector::difference_type difference_type;
  569. typedef typename vector::value_type value_type;
  570. typedef typename vector::reference reference;
  571. typedef typename vector::pointer pointer;
  572. // Construction and destruction
  573. BOOST_UBLAS_INLINE
  574. iterator ():
  575. container_reference<self_type> (), it_ () {}
  576. BOOST_UBLAS_INLINE
  577. iterator (self_type &v, const subiterator_type &it):
  578. container_reference<self_type> (v), it_ (it) {}
  579. // Arithmetic
  580. BOOST_UBLAS_INLINE
  581. iterator &operator ++ () {
  582. ++ it_;
  583. return *this;
  584. }
  585. BOOST_UBLAS_INLINE
  586. iterator &operator -- () {
  587. -- it_;
  588. return *this;
  589. }
  590. BOOST_UBLAS_INLINE
  591. iterator &operator += (difference_type n) {
  592. it_ += n;
  593. return *this;
  594. }
  595. BOOST_UBLAS_INLINE
  596. iterator &operator -= (difference_type n) {
  597. it_ -= n;
  598. return *this;
  599. }
  600. BOOST_UBLAS_INLINE
  601. difference_type operator - (const iterator &it) const {
  602. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  603. return it_ - it.it_;
  604. }
  605. // Dereference
  606. BOOST_UBLAS_INLINE
  607. reference operator * () const {
  608. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  609. return *it_;
  610. }
  611. BOOST_UBLAS_INLINE
  612. reference operator [] (difference_type n) const {
  613. return *(it_ + n);
  614. }
  615. // Index
  616. BOOST_UBLAS_INLINE
  617. size_type index () const {
  618. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  619. return it_ - (*this) ().begin ().it_;
  620. }
  621. // Assignment
  622. BOOST_UBLAS_INLINE
  623. iterator &operator = (const iterator &it) {
  624. container_reference<self_type>::assign (&it ());
  625. it_ = it.it_;
  626. return *this;
  627. }
  628. // Comparison
  629. BOOST_UBLAS_INLINE
  630. bool operator == (const iterator &it) const {
  631. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  632. return it_ == it.it_;
  633. }
  634. BOOST_UBLAS_INLINE
  635. bool operator < (const iterator &it) const {
  636. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  637. return it_ < it.it_;
  638. }
  639. private:
  640. subiterator_type it_;
  641. friend class const_iterator;
  642. };
  643. #endif
  644. /// \brief Return an iterator on the first element of the vector
  645. BOOST_UBLAS_INLINE
  646. iterator begin () {
  647. return find (0);
  648. }
  649. /// \brief Return an iterator at the end of the vector
  650. BOOST_UBLAS_INLINE
  651. iterator end () {
  652. return find (data_.size ());
  653. }
  654. // Reverse iterator
  655. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  656. typedef reverse_iterator_base<iterator> reverse_iterator;
  657. /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
  658. BOOST_UBLAS_INLINE
  659. const_reverse_iterator rbegin () const {
  660. return const_reverse_iterator (end ());
  661. }
  662. /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
  663. BOOST_UBLAS_INLINE
  664. const_reverse_iterator rend () const {
  665. return const_reverse_iterator (begin ());
  666. }
  667. /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
  668. BOOST_UBLAS_INLINE
  669. reverse_iterator rbegin () {
  670. return reverse_iterator (end ());
  671. }
  672. /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
  673. BOOST_UBLAS_INLINE
  674. reverse_iterator rend () {
  675. return reverse_iterator (begin ());
  676. }
  677. // -------------
  678. // Serialization
  679. // -------------
  680. /// Serialize a vector into and archive as defined in Boost
  681. /// \param ar Archive object. Can be a flat file, an XML file or any other stream
  682. /// \param file_version Optional file version (not yet used)
  683. template<class Archive>
  684. void serialize(Archive & ar, const unsigned int /* file_version */){
  685. ar & serialization::make_nvp("data",data_);
  686. }
  687. private:
  688. array_type data_;
  689. };
  690. // --------------------
  691. // Bounded vector class
  692. // --------------------
  693. /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
  694. /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor
  695. /// creates the vector with size \f$N\f$. Elements are constructed by the storage type \c bounded_array, which \b need \b not \b initialise their value.
  696. template<class T, std::size_t N>
  697. class bounded_vector:
  698. public vector<T, bounded_array<T, N> > {
  699. typedef vector<T, bounded_array<T, N> > vector_type;
  700. public:
  701. typedef typename vector_type::size_type size_type;
  702. static const size_type max_size = N;
  703. // Construction and destruction
  704. BOOST_UBLAS_INLINE
  705. bounded_vector ():
  706. vector_type (N) {}
  707. BOOST_UBLAS_INLINE
  708. bounded_vector (size_type size):
  709. vector_type (size) {}
  710. BOOST_UBLAS_INLINE
  711. bounded_vector (const bounded_vector &v):
  712. vector_type (v) {}
  713. template<class A2> // Allow vector<T,bounded_array<N> construction
  714. BOOST_UBLAS_INLINE
  715. bounded_vector (const vector<T, A2> &v):
  716. vector_type (v) {}
  717. template<class AE>
  718. BOOST_UBLAS_INLINE
  719. bounded_vector (const vector_expression<AE> &ae):
  720. vector_type (ae) {}
  721. BOOST_UBLAS_INLINE
  722. ~bounded_vector () {}
  723. // Assignment
  724. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  725. /*! @note "pass by value" the key idea to enable move semantics */
  726. BOOST_UBLAS_INLINE
  727. bounded_vector &operator = (bounded_vector v) {
  728. vector_type::operator = (v);
  729. return *this;
  730. }
  731. #else
  732. BOOST_UBLAS_INLINE
  733. bounded_vector &operator = (const bounded_vector &v) {
  734. vector_type::operator = (v);
  735. return *this;
  736. }
  737. #endif
  738. template<class A2> // Generic vector assignment
  739. BOOST_UBLAS_INLINE
  740. bounded_vector &operator = (const vector<T, A2> &v) {
  741. vector_type::operator = (v);
  742. return *this;
  743. }
  744. template<class C> // Container assignment without temporary
  745. BOOST_UBLAS_INLINE
  746. bounded_vector &operator = (const vector_container<C> &v) {
  747. vector_type::operator = (v);
  748. return *this;
  749. }
  750. template<class AE>
  751. BOOST_UBLAS_INLINE
  752. bounded_vector &operator = (const vector_expression<AE> &ae) {
  753. vector_type::operator = (ae);
  754. return *this;
  755. }
  756. };
  757. // -----------------
  758. // Zero vector class
  759. // -----------------
  760. /// \brief A zero vector of type \c T and a given \c size
  761. /// A zero vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated
  762. /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
  763. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  764. template<class T, class ALLOC>
  765. class zero_vector:
  766. public vector_container<zero_vector<T, ALLOC> > {
  767. typedef const T *const_pointer;
  768. typedef zero_vector<T, ALLOC> self_type;
  769. public:
  770. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  771. using vector_container<self_type>::operator ();
  772. #endif
  773. typedef typename ALLOC::size_type size_type;
  774. typedef typename ALLOC::difference_type difference_type;
  775. typedef T value_type;
  776. typedef const T &const_reference;
  777. typedef T &reference;
  778. typedef const vector_reference<const self_type> const_closure_type;
  779. typedef vector_reference<self_type> closure_type;
  780. typedef sparse_tag storage_category;
  781. // Construction and destruction
  782. BOOST_UBLAS_INLINE
  783. zero_vector ():
  784. vector_container<self_type> (),
  785. size_ (0) {}
  786. explicit BOOST_UBLAS_INLINE
  787. zero_vector (size_type size):
  788. vector_container<self_type> (),
  789. size_ (size) {}
  790. BOOST_UBLAS_INLINE
  791. zero_vector (const zero_vector &v):
  792. vector_container<self_type> (),
  793. size_ (v.size_) {}
  794. // Accessors
  795. BOOST_UBLAS_INLINE
  796. size_type size () const {
  797. return size_;
  798. }
  799. // Resizing
  800. BOOST_UBLAS_INLINE
  801. void resize (size_type size, bool /*preserve*/ = true) {
  802. size_ = size;
  803. }
  804. // Element support
  805. BOOST_UBLAS_INLINE
  806. const_pointer find_element (size_type i) const {
  807. return & zero_;
  808. }
  809. // Element access
  810. BOOST_UBLAS_INLINE
  811. const_reference operator () (size_type /* i */) const {
  812. return zero_;
  813. }
  814. BOOST_UBLAS_INLINE
  815. const_reference operator [] (size_type i) const {
  816. return (*this) (i);
  817. }
  818. // Assignment
  819. BOOST_UBLAS_INLINE
  820. zero_vector &operator = (const zero_vector &v) {
  821. size_ = v.size_;
  822. return *this;
  823. }
  824. BOOST_UBLAS_INLINE
  825. zero_vector &assign_temporary (zero_vector &v) {
  826. swap (v);
  827. return *this;
  828. }
  829. // Swapping
  830. BOOST_UBLAS_INLINE
  831. void swap (zero_vector &v) {
  832. if (this != &v) {
  833. std::swap (size_, v.size_);
  834. }
  835. }
  836. BOOST_UBLAS_INLINE
  837. friend void swap (zero_vector &v1, zero_vector &v2) {
  838. v1.swap (v2);
  839. }
  840. // Iterator types
  841. public:
  842. class const_iterator;
  843. // Element lookup
  844. BOOST_UBLAS_INLINE
  845. const_iterator find (size_type /*i*/) const {
  846. return const_iterator (*this);
  847. }
  848. class const_iterator:
  849. public container_const_reference<zero_vector>,
  850. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  851. const_iterator, value_type> {
  852. public:
  853. typedef typename zero_vector::difference_type difference_type;
  854. typedef typename zero_vector::value_type value_type;
  855. typedef typename zero_vector::const_reference reference;
  856. typedef typename zero_vector::const_pointer pointer;
  857. // Construction and destruction
  858. BOOST_UBLAS_INLINE
  859. const_iterator ():
  860. container_const_reference<self_type> () {}
  861. BOOST_UBLAS_INLINE
  862. const_iterator (const self_type &v):
  863. container_const_reference<self_type> (v) {}
  864. // Arithmetic
  865. BOOST_UBLAS_INLINE
  866. const_iterator &operator ++ () {
  867. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  868. return *this;
  869. }
  870. BOOST_UBLAS_INLINE
  871. const_iterator &operator -- () {
  872. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  873. return *this;
  874. }
  875. // Dereference
  876. BOOST_UBLAS_INLINE
  877. const_reference operator * () const {
  878. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  879. return zero_; // arbitary return value
  880. }
  881. // Index
  882. BOOST_UBLAS_INLINE
  883. size_type index () const {
  884. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  885. return 0; // arbitary return value
  886. }
  887. // Assignment
  888. BOOST_UBLAS_INLINE
  889. const_iterator &operator = (const const_iterator &it) {
  890. container_const_reference<self_type>::assign (&it ());
  891. return *this;
  892. }
  893. // Comparison
  894. BOOST_UBLAS_INLINE
  895. bool operator == (const const_iterator &it) const {
  896. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  897. detail::ignore_unused_variable_warning(it);
  898. return true;
  899. }
  900. };
  901. typedef const_iterator iterator;
  902. BOOST_UBLAS_INLINE
  903. const_iterator begin () const {
  904. return const_iterator (*this);
  905. }
  906. BOOST_UBLAS_INLINE
  907. const_iterator end () const {
  908. return const_iterator (*this);
  909. }
  910. // Reverse iterator
  911. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  912. BOOST_UBLAS_INLINE
  913. const_reverse_iterator rbegin () const {
  914. return const_reverse_iterator (end ());
  915. }
  916. BOOST_UBLAS_INLINE
  917. const_reverse_iterator rend () const {
  918. return const_reverse_iterator (begin ());
  919. }
  920. // Serialization
  921. template<class Archive>
  922. void serialize(Archive & ar, const unsigned int /* file_version */){
  923. serialization::collection_size_type s (size_);
  924. ar & serialization::make_nvp("size",s);
  925. if (Archive::is_loading::value) {
  926. size_ = s;
  927. }
  928. }
  929. private:
  930. size_type size_;
  931. typedef const value_type const_value_type;
  932. static const_value_type zero_;
  933. };
  934. template<class T, class ALLOC>
  935. typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
  936. // Unit vector class
  937. /// \brief unit_vector represents a canonical unit vector
  938. /// unit_vector represents a canonical unit vector. The \e k-th unit vector of dimension \f$n\f$ holds 0 for every value \f$u_i\f$ s.t. \f$i \neq k\f$ and 1 when \f$i=k\f$.
  939. /// At construction, the value \e k is given after the dimension of the vector.
  940. /// \tparam T is the type of elements in the vector. They must be 0 and 1 assignable in order for the vector to have its unit-vector semantic.
  941. /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
  942. template<class T, class ALLOC>
  943. class unit_vector:
  944. public vector_container<unit_vector<T, ALLOC> > {
  945. typedef const T *const_pointer;
  946. typedef unit_vector<T, ALLOC> self_type;
  947. public:
  948. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  949. using vector_container<self_type>::operator ();
  950. #endif
  951. typedef typename ALLOC::size_type size_type;
  952. typedef typename ALLOC::difference_type difference_type;
  953. typedef T value_type;
  954. typedef const T &const_reference;
  955. typedef T &reference;
  956. typedef const vector_reference<const self_type> const_closure_type;
  957. typedef vector_reference<self_type> closure_type;
  958. typedef sparse_tag storage_category;
  959. // Construction and destruction
  960. /// \brief Simple constructor with dimension and index 0
  961. BOOST_UBLAS_INLINE
  962. unit_vector ():
  963. vector_container<self_type> (),
  964. size_ (0), index_ (0) {}
  965. /// \brief Constructor of unit_vector
  966. /// \param size is the dimension of the vector
  967. /// \param index is the order of the vector
  968. BOOST_UBLAS_INLINE
  969. explicit unit_vector (size_type size, size_type index = 0):
  970. vector_container<self_type> (),
  971. size_ (size), index_ (index) {}
  972. /// \brief Copy-constructor
  973. BOOST_UBLAS_INLINE
  974. unit_vector (const unit_vector &v):
  975. vector_container<self_type> (),
  976. size_ (v.size_), index_ (v.index_) {}
  977. // Accessors
  978. //----------
  979. /// \brief Return the size (dimension) of the vector
  980. BOOST_UBLAS_INLINE
  981. size_type size () const {
  982. return size_;
  983. }
  984. /// \brief Return the order of the unit vector
  985. BOOST_UBLAS_INLINE
  986. size_type index () const {
  987. return index_;
  988. }
  989. // Resizing
  990. // --------
  991. /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
  992. /// \param size is the new size of the vector
  993. BOOST_UBLAS_INLINE
  994. void resize (size_type size, bool /*preserve*/ = true) {
  995. size_ = size;
  996. }
  997. // Element support
  998. // ---------------
  999. /// \brief Return a const pointer to the element of index i
  1000. BOOST_UBLAS_INLINE
  1001. const_pointer find_element (size_type i) const {
  1002. if (i == index_)
  1003. return & one_;
  1004. else
  1005. return & zero_;
  1006. }
  1007. // Element access
  1008. BOOST_UBLAS_INLINE
  1009. const_reference operator () (size_type i) const {
  1010. if (i == index_)
  1011. return one_;
  1012. else
  1013. return zero_;
  1014. }
  1015. BOOST_UBLAS_INLINE
  1016. const_reference operator [] (size_type i) const {
  1017. return (*this) (i);
  1018. }
  1019. // Assignment
  1020. BOOST_UBLAS_INLINE
  1021. unit_vector &operator = (const unit_vector &v) {
  1022. size_ = v.size_;
  1023. index_ = v.index_;
  1024. return *this;
  1025. }
  1026. BOOST_UBLAS_INLINE
  1027. unit_vector &assign_temporary (unit_vector &v) {
  1028. swap (v);
  1029. return *this;
  1030. }
  1031. // Swapping
  1032. BOOST_UBLAS_INLINE
  1033. void swap (unit_vector &v) {
  1034. if (this != &v) {
  1035. std::swap (size_, v.size_);
  1036. std::swap (index_, v.index_);
  1037. }
  1038. }
  1039. BOOST_UBLAS_INLINE
  1040. friend void swap (unit_vector &v1, unit_vector &v2) {
  1041. v1.swap (v2);
  1042. }
  1043. // Iterator types
  1044. private:
  1045. // Use bool to indicate begin (one_ as value)
  1046. typedef bool const_subiterator_type;
  1047. public:
  1048. class const_iterator;
  1049. // Element lookup
  1050. BOOST_UBLAS_INLINE
  1051. const_iterator find (size_type i) const {
  1052. return const_iterator (*this, i <= index_);
  1053. }
  1054. class const_iterator:
  1055. public container_const_reference<unit_vector>,
  1056. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1057. const_iterator, value_type> {
  1058. public:
  1059. typedef typename unit_vector::difference_type difference_type;
  1060. typedef typename unit_vector::value_type value_type;
  1061. typedef typename unit_vector::const_reference reference;
  1062. typedef typename unit_vector::const_pointer pointer;
  1063. // Construction and destruction
  1064. BOOST_UBLAS_INLINE
  1065. const_iterator ():
  1066. container_const_reference<unit_vector> (), it_ () {}
  1067. BOOST_UBLAS_INLINE
  1068. const_iterator (const unit_vector &v, const const_subiterator_type &it):
  1069. container_const_reference<unit_vector> (v), it_ (it) {}
  1070. // Arithmetic
  1071. BOOST_UBLAS_INLINE
  1072. const_iterator &operator ++ () {
  1073. BOOST_UBLAS_CHECK (it_, bad_index ());
  1074. it_ = !it_;
  1075. return *this;
  1076. }
  1077. BOOST_UBLAS_INLINE
  1078. const_iterator &operator -- () {
  1079. BOOST_UBLAS_CHECK (!it_, bad_index ());
  1080. it_ = !it_;
  1081. return *this;
  1082. }
  1083. // Dereference
  1084. BOOST_UBLAS_INLINE
  1085. const_reference operator * () const {
  1086. BOOST_UBLAS_CHECK (it_, bad_index ());
  1087. return one_;
  1088. }
  1089. // Index
  1090. BOOST_UBLAS_INLINE
  1091. size_type index () const {
  1092. BOOST_UBLAS_CHECK (it_, bad_index ());
  1093. return (*this) ().index_;
  1094. }
  1095. // Assignment
  1096. BOOST_UBLAS_INLINE
  1097. const_iterator &operator = (const const_iterator &it) {
  1098. container_const_reference<unit_vector>::assign (&it ());
  1099. it_ = it.it_;
  1100. return *this;
  1101. }
  1102. // Comparison
  1103. BOOST_UBLAS_INLINE
  1104. bool operator == (const const_iterator &it) const {
  1105. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1106. return it_ == it.it_;
  1107. }
  1108. private:
  1109. const_subiterator_type it_;
  1110. };
  1111. typedef const_iterator iterator;
  1112. BOOST_UBLAS_INLINE
  1113. const_iterator begin () const {
  1114. return const_iterator (*this, true);
  1115. }
  1116. BOOST_UBLAS_INLINE
  1117. const_iterator end () const {
  1118. return const_iterator (*this, false);
  1119. }
  1120. // Reverse iterator
  1121. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1122. BOOST_UBLAS_INLINE
  1123. const_reverse_iterator rbegin () const {
  1124. return const_reverse_iterator (end ());
  1125. }
  1126. BOOST_UBLAS_INLINE
  1127. const_reverse_iterator rend () const {
  1128. return const_reverse_iterator (begin ());
  1129. }
  1130. // Serialization
  1131. template<class Archive>
  1132. void serialize(Archive & ar, const unsigned int /* file_version */){
  1133. serialization::collection_size_type s (size_);
  1134. ar & serialization::make_nvp("size",s);
  1135. if (Archive::is_loading::value) {
  1136. size_ = s;
  1137. }
  1138. ar & serialization::make_nvp("index", index_);
  1139. }
  1140. private:
  1141. size_type size_;
  1142. size_type index_;
  1143. typedef const value_type const_value_type;
  1144. static const_value_type zero_;
  1145. static const_value_type one_;
  1146. };
  1147. template<class T, class ALLOC>
  1148. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
  1149. template<class T, class ALLOC>
  1150. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
  1151. /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
  1152. /// A scalar (i.e. unique value) vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated
  1153. /// for storing the unique value more than once: it still acts like any other vector. However assigning a new value will change all the value at once.
  1154. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  1155. /// \tparam T type of the objects stored in the vector: it can be anything even if most of the time, scalar types will be used like \c double or \c int. Complex types can be used, or even classes like boost::interval.
  1156. template<class T, class ALLOC>
  1157. class scalar_vector:
  1158. public vector_container<scalar_vector<T, ALLOC> > {
  1159. typedef const T *const_pointer;
  1160. typedef scalar_vector<T, ALLOC> self_type;
  1161. public:
  1162. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1163. using vector_container<self_type>::operator ();
  1164. #endif
  1165. typedef typename ALLOC::size_type size_type;
  1166. typedef typename ALLOC::difference_type difference_type;
  1167. typedef T value_type;
  1168. typedef const T &const_reference;
  1169. typedef T &reference;
  1170. typedef const vector_reference<const self_type> const_closure_type;
  1171. typedef vector_reference<self_type> closure_type;
  1172. typedef dense_tag storage_category;
  1173. // Construction and destruction
  1174. BOOST_UBLAS_INLINE
  1175. scalar_vector ():
  1176. vector_container<self_type> (),
  1177. size_ (0), value_ () {}
  1178. BOOST_UBLAS_INLINE
  1179. explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
  1180. vector_container<self_type> (),
  1181. size_ (size), value_ (value) {}
  1182. BOOST_UBLAS_INLINE
  1183. scalar_vector (const scalar_vector &v):
  1184. vector_container<self_type> (),
  1185. size_ (v.size_), value_ (v.value_) {}
  1186. // Accessors
  1187. BOOST_UBLAS_INLINE
  1188. size_type size () const {
  1189. return size_;
  1190. }
  1191. // Resizing
  1192. BOOST_UBLAS_INLINE
  1193. void resize (size_type size, bool /*preserve*/ = true) {
  1194. size_ = size;
  1195. }
  1196. // Element support
  1197. BOOST_UBLAS_INLINE
  1198. const_pointer find_element (size_type /*i*/) const {
  1199. return & value_;
  1200. }
  1201. // Element access
  1202. BOOST_UBLAS_INLINE
  1203. const_reference operator () (size_type /*i*/) const {
  1204. return value_;
  1205. }
  1206. BOOST_UBLAS_INLINE
  1207. const_reference operator [] (size_type /*i*/) const {
  1208. return value_;
  1209. }
  1210. // Assignment
  1211. BOOST_UBLAS_INLINE
  1212. scalar_vector &operator = (const scalar_vector &v) {
  1213. size_ = v.size_;
  1214. value_ = v.value_;
  1215. return *this;
  1216. }
  1217. BOOST_UBLAS_INLINE
  1218. scalar_vector &assign_temporary (scalar_vector &v) {
  1219. swap (v);
  1220. return *this;
  1221. }
  1222. // Swapping
  1223. BOOST_UBLAS_INLINE
  1224. void swap (scalar_vector &v) {
  1225. if (this != &v) {
  1226. std::swap (size_, v.size_);
  1227. std::swap (value_, v.value_);
  1228. }
  1229. }
  1230. BOOST_UBLAS_INLINE
  1231. friend void swap (scalar_vector &v1, scalar_vector &v2) {
  1232. v1.swap (v2);
  1233. }
  1234. // Iterator types
  1235. private:
  1236. // Use an index
  1237. typedef size_type const_subiterator_type;
  1238. public:
  1239. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1240. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1241. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1242. #else
  1243. class const_iterator;
  1244. #endif
  1245. // Element lookup
  1246. BOOST_UBLAS_INLINE
  1247. const_iterator find (size_type i) const {
  1248. return const_iterator (*this, i);
  1249. }
  1250. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1251. class const_iterator:
  1252. public container_const_reference<scalar_vector>,
  1253. public random_access_iterator_base<dense_random_access_iterator_tag,
  1254. const_iterator, value_type> {
  1255. public:
  1256. typedef typename scalar_vector::difference_type difference_type;
  1257. typedef typename scalar_vector::value_type value_type;
  1258. typedef typename scalar_vector::const_reference reference;
  1259. typedef typename scalar_vector::const_pointer pointer;
  1260. // Construction and destruction
  1261. BOOST_UBLAS_INLINE
  1262. const_iterator ():
  1263. container_const_reference<scalar_vector> (), it_ () {}
  1264. BOOST_UBLAS_INLINE
  1265. const_iterator (const scalar_vector &v, const const_subiterator_type &it):
  1266. container_const_reference<scalar_vector> (v), it_ (it) {}
  1267. // Arithmetic
  1268. BOOST_UBLAS_INLINE
  1269. const_iterator &operator ++ () {
  1270. ++ it_;
  1271. return *this;
  1272. }
  1273. BOOST_UBLAS_INLINE
  1274. const_iterator &operator -- () {
  1275. -- it_;
  1276. return *this;
  1277. }
  1278. BOOST_UBLAS_INLINE
  1279. const_iterator &operator += (difference_type n) {
  1280. it_ += n;
  1281. return *this;
  1282. }
  1283. BOOST_UBLAS_INLINE
  1284. const_iterator &operator -= (difference_type n) {
  1285. it_ -= n;
  1286. return *this;
  1287. }
  1288. BOOST_UBLAS_INLINE
  1289. difference_type operator - (const const_iterator &it) const {
  1290. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1291. return it_ - it.it_;
  1292. }
  1293. // Dereference
  1294. BOOST_UBLAS_INLINE
  1295. const_reference operator * () const {
  1296. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  1297. return (*this) () (index ());
  1298. }
  1299. BOOST_UBLAS_INLINE
  1300. const_reference operator [] (difference_type n) const {
  1301. return *(*this + n);
  1302. }
  1303. // Index
  1304. BOOST_UBLAS_INLINE
  1305. size_type index () const {
  1306. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  1307. return it_;
  1308. }
  1309. // Assignment
  1310. BOOST_UBLAS_INLINE
  1311. const_iterator &operator = (const const_iterator &it) {
  1312. container_const_reference<scalar_vector>::assign (&it ());
  1313. it_ = it.it_;
  1314. return *this;
  1315. }
  1316. // Comparison
  1317. BOOST_UBLAS_INLINE
  1318. bool operator == (const const_iterator &it) const {
  1319. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1320. return it_ == it.it_;
  1321. }
  1322. BOOST_UBLAS_INLINE
  1323. bool operator < (const const_iterator &it) const {
  1324. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1325. return it_ < it.it_;
  1326. }
  1327. private:
  1328. const_subiterator_type it_;
  1329. };
  1330. typedef const_iterator iterator;
  1331. #endif
  1332. BOOST_UBLAS_INLINE
  1333. const_iterator begin () const {
  1334. return find (0);
  1335. }
  1336. BOOST_UBLAS_INLINE
  1337. const_iterator end () const {
  1338. return find (size_);
  1339. }
  1340. // Reverse iterator
  1341. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1342. BOOST_UBLAS_INLINE
  1343. const_reverse_iterator rbegin () const {
  1344. return const_reverse_iterator (end ());
  1345. }
  1346. BOOST_UBLAS_INLINE
  1347. const_reverse_iterator rend () const {
  1348. return const_reverse_iterator (begin ());
  1349. }
  1350. // Serialization
  1351. template<class Archive>
  1352. void serialize(Archive & ar, const unsigned int /* file_version */){
  1353. serialization::collection_size_type s (size_);
  1354. ar & serialization::make_nvp("size",s);
  1355. if (Archive::is_loading::value) {
  1356. size_ = s;
  1357. }
  1358. ar & serialization::make_nvp("value", value_);
  1359. }
  1360. private:
  1361. size_type size_;
  1362. value_type value_;
  1363. };
  1364. // ------------------------
  1365. // Array based vector class
  1366. // ------------------------
  1367. /// \brief A dense vector of values of type \c T with the given \c size. The data is stored as an ordinary C++ array \c T \c data_[M]
  1368. template<class T, std::size_t N>
  1369. class c_vector:
  1370. public vector_container<c_vector<T, N> > {
  1371. typedef c_vector<T, N> self_type;
  1372. public:
  1373. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1374. using vector_container<self_type>::operator ();
  1375. #endif
  1376. typedef std::size_t size_type;
  1377. typedef std::ptrdiff_t difference_type;
  1378. typedef T value_type;
  1379. typedef const T &const_reference;
  1380. typedef T &reference;
  1381. typedef value_type array_type[N];
  1382. typedef T *pointer;
  1383. typedef const T *const_pointer;
  1384. typedef const vector_reference<const self_type> const_closure_type;
  1385. typedef vector_reference<self_type> closure_type;
  1386. typedef self_type vector_temporary_type;
  1387. typedef dense_tag storage_category;
  1388. // Construction and destruction
  1389. BOOST_UBLAS_INLINE
  1390. c_vector ():
  1391. size_ (N) /* , data_ () */ {}
  1392. explicit BOOST_UBLAS_INLINE
  1393. c_vector (size_type size):
  1394. size_ (size) /* , data_ () */ {
  1395. if (size_ > N)
  1396. bad_size ().raise ();
  1397. }
  1398. BOOST_UBLAS_INLINE
  1399. c_vector (const c_vector &v):
  1400. size_ (v.size_) /* , data_ () */ {
  1401. if (size_ > N)
  1402. bad_size ().raise ();
  1403. assign(v);
  1404. }
  1405. template<class AE>
  1406. BOOST_UBLAS_INLINE
  1407. c_vector (const vector_expression<AE> &ae):
  1408. size_ (ae ().size ()) /* , data_ () */ {
  1409. if (size_ > N)
  1410. bad_size ().raise ();
  1411. vector_assign<scalar_assign> (*this, ae);
  1412. }
  1413. // Accessors
  1414. BOOST_UBLAS_INLINE
  1415. size_type size () const {
  1416. return size_;
  1417. }
  1418. BOOST_UBLAS_INLINE
  1419. const_pointer data () const {
  1420. return data_;
  1421. }
  1422. BOOST_UBLAS_INLINE
  1423. pointer data () {
  1424. return data_;
  1425. }
  1426. // Resizing
  1427. BOOST_UBLAS_INLINE
  1428. void resize (size_type size, bool preserve = true) {
  1429. if (size > N)
  1430. bad_size ().raise ();
  1431. size_ = size;
  1432. }
  1433. // Element support
  1434. BOOST_UBLAS_INLINE
  1435. pointer find_element (size_type i) {
  1436. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  1437. }
  1438. BOOST_UBLAS_INLINE
  1439. const_pointer find_element (size_type i) const {
  1440. return & data_ [i];
  1441. }
  1442. // Element access
  1443. BOOST_UBLAS_INLINE
  1444. const_reference operator () (size_type i) const {
  1445. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  1446. return data_ [i];
  1447. }
  1448. BOOST_UBLAS_INLINE
  1449. reference operator () (size_type i) {
  1450. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  1451. return data_ [i];
  1452. }
  1453. BOOST_UBLAS_INLINE
  1454. const_reference operator [] (size_type i) const {
  1455. return (*this) (i);
  1456. }
  1457. BOOST_UBLAS_INLINE
  1458. reference operator [] (size_type i) {
  1459. return (*this) (i);
  1460. }
  1461. // Element assignment
  1462. BOOST_UBLAS_INLINE
  1463. reference insert_element (size_type i, const_reference t) {
  1464. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  1465. return (data_ [i] = t);
  1466. }
  1467. BOOST_UBLAS_INLINE
  1468. void erase_element (size_type i) {
  1469. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  1470. data_ [i] = value_type/*zero*/();
  1471. }
  1472. // Zeroing
  1473. BOOST_UBLAS_INLINE
  1474. void clear () {
  1475. std::fill (data_, data_ + size_, value_type/*zero*/());
  1476. }
  1477. // Assignment
  1478. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  1479. /*! @note "pass by value" the key idea to enable move semantics */
  1480. BOOST_UBLAS_INLINE
  1481. c_vector &operator = (c_vector v) {
  1482. assign_temporary(v);
  1483. return *this;
  1484. }
  1485. #else
  1486. BOOST_UBLAS_INLINE
  1487. c_vector &operator = (const c_vector &v) {
  1488. size_ = v.size_;
  1489. std::copy (v.data_, v.data_ + v.size_, data_);
  1490. return *this;
  1491. }
  1492. #endif
  1493. template<class C> // Container assignment without temporary
  1494. BOOST_UBLAS_INLINE
  1495. c_vector &operator = (const vector_container<C> &v) {
  1496. resize (v ().size (), false);
  1497. assign (v);
  1498. return *this;
  1499. }
  1500. BOOST_UBLAS_INLINE
  1501. c_vector &assign_temporary (c_vector &v) {
  1502. swap (v);
  1503. return *this;
  1504. }
  1505. template<class AE>
  1506. BOOST_UBLAS_INLINE
  1507. c_vector &operator = (const vector_expression<AE> &ae) {
  1508. self_type temporary (ae);
  1509. return assign_temporary (temporary);
  1510. }
  1511. template<class AE>
  1512. BOOST_UBLAS_INLINE
  1513. c_vector &assign (const vector_expression<AE> &ae) {
  1514. vector_assign<scalar_assign> (*this, ae);
  1515. return *this;
  1516. }
  1517. // Computed assignment
  1518. template<class AE>
  1519. BOOST_UBLAS_INLINE
  1520. c_vector &operator += (const vector_expression<AE> &ae) {
  1521. self_type temporary (*this + ae);
  1522. return assign_temporary (temporary);
  1523. }
  1524. template<class C> // Container assignment without temporary
  1525. BOOST_UBLAS_INLINE
  1526. c_vector &operator += (const vector_container<C> &v) {
  1527. plus_assign (v);
  1528. return *this;
  1529. }
  1530. template<class AE>
  1531. BOOST_UBLAS_INLINE
  1532. c_vector &plus_assign (const vector_expression<AE> &ae) {
  1533. vector_assign<scalar_plus_assign> ( *this, ae);
  1534. return *this;
  1535. }
  1536. template<class AE>
  1537. BOOST_UBLAS_INLINE
  1538. c_vector &operator -= (const vector_expression<AE> &ae) {
  1539. self_type temporary (*this - ae);
  1540. return assign_temporary (temporary);
  1541. }
  1542. template<class C> // Container assignment without temporary
  1543. BOOST_UBLAS_INLINE
  1544. c_vector &operator -= (const vector_container<C> &v) {
  1545. minus_assign (v);
  1546. return *this;
  1547. }
  1548. template<class AE>
  1549. BOOST_UBLAS_INLINE
  1550. c_vector &minus_assign (const vector_expression<AE> &ae) {
  1551. vector_assign<scalar_minus_assign> (*this, ae);
  1552. return *this;
  1553. }
  1554. template<class AT>
  1555. BOOST_UBLAS_INLINE
  1556. c_vector &operator *= (const AT &at) {
  1557. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  1558. return *this;
  1559. }
  1560. template<class AT>
  1561. BOOST_UBLAS_INLINE
  1562. c_vector &operator /= (const AT &at) {
  1563. vector_assign_scalar<scalar_divides_assign> (*this, at);
  1564. return *this;
  1565. }
  1566. // Swapping
  1567. BOOST_UBLAS_INLINE
  1568. void swap (c_vector &v) {
  1569. if (this != &v) {
  1570. BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
  1571. std::swap (size_, v.size_);
  1572. std::swap_ranges (data_, data_ + size_, v.data_);
  1573. }
  1574. }
  1575. BOOST_UBLAS_INLINE
  1576. friend void swap (c_vector &v1, c_vector &v2) {
  1577. v1.swap (v2);
  1578. }
  1579. // Iterator types
  1580. private:
  1581. // Use pointers for iterator
  1582. typedef const_pointer const_subiterator_type;
  1583. typedef pointer subiterator_type;
  1584. public:
  1585. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1586. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1587. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1588. #else
  1589. class const_iterator;
  1590. class iterator;
  1591. #endif
  1592. // Element lookup
  1593. BOOST_UBLAS_INLINE
  1594. const_iterator find (size_type i) const {
  1595. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1596. return const_iterator (*this, &data_ [i]);
  1597. #else
  1598. return const_iterator (*this, i);
  1599. #endif
  1600. }
  1601. BOOST_UBLAS_INLINE
  1602. iterator find (size_type i) {
  1603. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1604. return iterator (*this, &data_ [i]);
  1605. #else
  1606. return iterator (*this, i);
  1607. #endif
  1608. }
  1609. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1610. class const_iterator:
  1611. public container_const_reference<c_vector>,
  1612. public random_access_iterator_base<dense_random_access_iterator_tag,
  1613. const_iterator, value_type> {
  1614. public:
  1615. typedef typename c_vector::difference_type difference_type;
  1616. typedef typename c_vector::value_type value_type;
  1617. typedef typename c_vector::const_reference reference;
  1618. typedef typename c_vector::const_pointer pointer;
  1619. // Construction and destruction
  1620. BOOST_UBLAS_INLINE
  1621. const_iterator ():
  1622. container_const_reference<self_type> (), it_ () {}
  1623. BOOST_UBLAS_INLINE
  1624. const_iterator (const self_type &v, const const_subiterator_type &it):
  1625. container_const_reference<self_type> (v), it_ (it) {}
  1626. BOOST_UBLAS_INLINE
  1627. const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
  1628. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  1629. // Arithmetic
  1630. BOOST_UBLAS_INLINE
  1631. const_iterator &operator ++ () {
  1632. ++ it_;
  1633. return *this;
  1634. }
  1635. BOOST_UBLAS_INLINE
  1636. const_iterator &operator -- () {
  1637. -- it_;
  1638. return *this;
  1639. }
  1640. BOOST_UBLAS_INLINE
  1641. const_iterator &operator += (difference_type n) {
  1642. it_ += n;
  1643. return *this;
  1644. }
  1645. BOOST_UBLAS_INLINE
  1646. const_iterator &operator -= (difference_type n) {
  1647. it_ -= n;
  1648. return *this;
  1649. }
  1650. BOOST_UBLAS_INLINE
  1651. difference_type operator - (const const_iterator &it) const {
  1652. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1653. return it_ - it.it_;
  1654. }
  1655. // Dereference
  1656. BOOST_UBLAS_INLINE
  1657. const_reference operator * () const {
  1658. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1659. return *it_;
  1660. }
  1661. BOOST_UBLAS_INLINE
  1662. const_reference operator [] (difference_type n) const {
  1663. return *(it_ + n);
  1664. }
  1665. // Index
  1666. BOOST_UBLAS_INLINE
  1667. size_type index () const {
  1668. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1669. const self_type &v = (*this) ();
  1670. return it_ - v.begin ().it_;
  1671. }
  1672. // Assignment
  1673. BOOST_UBLAS_INLINE
  1674. const_iterator &operator = (const const_iterator &it) {
  1675. container_const_reference<self_type>::assign (&it ());
  1676. it_ = it.it_;
  1677. return *this;
  1678. }
  1679. // Comparison
  1680. BOOST_UBLAS_INLINE
  1681. bool operator == (const const_iterator &it) const {
  1682. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1683. return it_ == it.it_;
  1684. }
  1685. BOOST_UBLAS_INLINE
  1686. bool operator < (const const_iterator &it) const {
  1687. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1688. return it_ < it.it_;
  1689. }
  1690. private:
  1691. const_subiterator_type it_;
  1692. friend class iterator;
  1693. };
  1694. #endif
  1695. BOOST_UBLAS_INLINE
  1696. const_iterator begin () const {
  1697. return find (0);
  1698. }
  1699. BOOST_UBLAS_INLINE
  1700. const_iterator end () const {
  1701. return find (size_);
  1702. }
  1703. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1704. class iterator:
  1705. public container_reference<c_vector>,
  1706. public random_access_iterator_base<dense_random_access_iterator_tag,
  1707. iterator, value_type> {
  1708. public:
  1709. typedef typename c_vector::difference_type difference_type;
  1710. typedef typename c_vector::value_type value_type;
  1711. typedef typename c_vector::reference reference;
  1712. typedef typename c_vector::pointer pointer;
  1713. // Construction and destruction
  1714. BOOST_UBLAS_INLINE
  1715. iterator ():
  1716. container_reference<self_type> (), it_ () {}
  1717. BOOST_UBLAS_INLINE
  1718. iterator (self_type &v, const subiterator_type &it):
  1719. container_reference<self_type> (v), it_ (it) {}
  1720. // Arithmetic
  1721. BOOST_UBLAS_INLINE
  1722. iterator &operator ++ () {
  1723. ++ it_;
  1724. return *this;
  1725. }
  1726. BOOST_UBLAS_INLINE
  1727. iterator &operator -- () {
  1728. -- it_;
  1729. return *this;
  1730. }
  1731. BOOST_UBLAS_INLINE
  1732. iterator &operator += (difference_type n) {
  1733. it_ += n;
  1734. return *this;
  1735. }
  1736. BOOST_UBLAS_INLINE
  1737. iterator &operator -= (difference_type n) {
  1738. it_ -= n;
  1739. return *this;
  1740. }
  1741. BOOST_UBLAS_INLINE
  1742. difference_type operator - (const iterator &it) const {
  1743. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1744. return it_ - it.it_;
  1745. }
  1746. // Dereference
  1747. BOOST_UBLAS_INLINE
  1748. reference operator * () const {
  1749. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1750. return *it_;
  1751. }
  1752. BOOST_UBLAS_INLINE
  1753. reference operator [] (difference_type n) const {
  1754. return *(it_ + n);
  1755. }
  1756. // Index
  1757. BOOST_UBLAS_INLINE
  1758. size_type index () const {
  1759. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1760. // EDG won't allow const self_type it doesn't allow friend access to it_
  1761. self_type &v = (*this) ();
  1762. return it_ - v.begin ().it_;
  1763. }
  1764. // Assignment
  1765. BOOST_UBLAS_INLINE
  1766. iterator &operator = (const iterator &it) {
  1767. container_reference<self_type>::assign (&it ());
  1768. it_ = it.it_;
  1769. return *this;
  1770. }
  1771. // Comparison
  1772. BOOST_UBLAS_INLINE
  1773. bool operator == (const iterator &it) const {
  1774. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1775. return it_ == it.it_;
  1776. }
  1777. BOOST_UBLAS_INLINE
  1778. bool operator < (const iterator &it) const {
  1779. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1780. return it_ < it.it_;
  1781. }
  1782. private:
  1783. subiterator_type it_;
  1784. friend class const_iterator;
  1785. };
  1786. #endif
  1787. BOOST_UBLAS_INLINE
  1788. iterator begin () {
  1789. return find (0);
  1790. }
  1791. BOOST_UBLAS_INLINE
  1792. iterator end () {
  1793. return find (size_);
  1794. }
  1795. // Reverse iterator
  1796. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1797. typedef reverse_iterator_base<iterator> reverse_iterator;
  1798. BOOST_UBLAS_INLINE
  1799. const_reverse_iterator rbegin () const {
  1800. return const_reverse_iterator (end ());
  1801. }
  1802. BOOST_UBLAS_INLINE
  1803. const_reverse_iterator rend () const {
  1804. return const_reverse_iterator (begin ());
  1805. }
  1806. BOOST_UBLAS_INLINE
  1807. reverse_iterator rbegin () {
  1808. return reverse_iterator (end ());
  1809. }
  1810. BOOST_UBLAS_INLINE
  1811. reverse_iterator rend () {
  1812. return reverse_iterator (begin ());
  1813. }
  1814. // Serialization
  1815. template<class Archive>
  1816. void serialize(Archive & ar, const unsigned int /* file_version */){
  1817. serialization::collection_size_type s (size_);
  1818. ar & serialization::make_nvp("size",s);
  1819. // copy the value back if loading
  1820. if (Archive::is_loading::value) {
  1821. if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
  1822. size_ = s;
  1823. }
  1824. // ISSUE: this writes the full array
  1825. ar & serialization::make_nvp("data",data_);
  1826. }
  1827. private:
  1828. size_type size_;
  1829. array_type data_;
  1830. };
  1831. }}}
  1832. #endif