vector.hpp 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947
  1. //
  2. // Copyright (c) 2000-2010
  3. // Joerg Walter, Mathias Koch, David Bellot
  4. // Copyright (c) 2014, Athanasios Iliopoulos
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // The authors gratefully acknowledge the support of
  11. // GeNeSys mbH & Co. KG in producing this work.
  12. //
  13. // And we acknowledge the support from all contributors.
  14. /// \file vector.hpp Definition for the class vector and its derivative
  15. #ifndef _BOOST_UBLAS_VECTOR_
  16. #define _BOOST_UBLAS_VECTOR_
  17. #include <boost/config.hpp>
  18. #include <boost/numeric/ublas/storage.hpp>
  19. #include <boost/numeric/ublas/vector_expression.hpp>
  20. #include <boost/numeric/ublas/detail/vector_assign.hpp>
  21. #include <boost/serialization/collection_size_type.hpp>
  22. #include <boost/serialization/nvp.hpp>
  23. #ifdef BOOST_UBLAS_CPP_GE_2011
  24. #include <array>
  25. #include <initializer_list>
  26. #if defined(BOOST_MSVC) // For std::forward in fixed_vector
  27. #include <utility>
  28. #endif
  29. #endif
  30. // Iterators based on ideas of Jeremy Siek
  31. namespace boost { namespace numeric { namespace ublas {
  32. /** \brief A dense vector of values of type \c T.
  33. *
  34. * 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
  35. * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array.
  36. * Elements are constructed by \c A, which need not initialise their value.
  37. *
  38. * \tparam T type of the objects stored in the vector (like int, double, complex,...)
  39. * \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
  40. */
  41. template<class T, class A>
  42. class vector:
  43. public vector_container<vector<T, A> > {
  44. typedef vector<T, A> self_type;
  45. public:
  46. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  47. using vector_container<self_type>::operator ();
  48. #endif
  49. typedef typename A::size_type size_type;
  50. typedef typename A::difference_type difference_type;
  51. typedef T value_type;
  52. typedef typename type_traits<T>::const_reference const_reference;
  53. typedef T &reference;
  54. typedef T *pointer;
  55. typedef const T *const_pointer;
  56. typedef A array_type;
  57. typedef const vector_reference<const self_type> const_closure_type;
  58. typedef vector_reference<self_type> closure_type;
  59. typedef self_type vector_temporary_type;
  60. typedef dense_tag storage_category;
  61. // Construction and destruction
  62. /// \brief Constructor of a vector
  63. /// By default it is empty, i.e. \c size()==0.
  64. BOOST_UBLAS_INLINE
  65. vector ():
  66. vector_container<self_type> (),
  67. data_ () {}
  68. /// \brief Constructor of a vector with a predefined size
  69. /// By default, its elements are initialized to 0.
  70. /// \param size initial size of the vector
  71. explicit BOOST_UBLAS_INLINE
  72. vector (size_type size):
  73. vector_container<self_type> (),
  74. data_ (size) {
  75. }
  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 size initial size of the vector \bug this value is not used
  79. /// \param data container of type \c A
  80. /// \todo remove this definition because \c size is not used
  81. BOOST_UBLAS_INLINE
  82. vector (size_type /*size*/, const array_type &data):
  83. vector_container<self_type> (),
  84. data_ (data) {}
  85. /// \brief Constructor of a vector by copying from another container
  86. /// This type has the generic name \c array_typ within the vector definition.
  87. /// \param data container of type \c A
  88. BOOST_UBLAS_INLINE
  89. vector (const array_type &data):
  90. vector_container<self_type> (),
  91. data_ (data) {}
  92. /// \brief Constructor of a vector with a predefined size and a unique initial value
  93. /// \param size of the vector
  94. /// \param init value to assign to each element of the vector
  95. BOOST_UBLAS_INLINE
  96. vector (size_type size, const value_type &init):
  97. vector_container<self_type> (),
  98. data_ (size, init) {}
  99. /// \brief Copy-constructor of a vector
  100. /// \param v is the vector to be duplicated
  101. BOOST_UBLAS_INLINE
  102. vector (const vector &v):
  103. vector_container<self_type> (),
  104. data_ (v.data_) {}
  105. /// \brief Copy-constructor of a vector from a vector_expression
  106. /// Depending on the vector_expression, this constructor can have the cost of the computations
  107. /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
  108. /// \param ae the vector_expression which values will be duplicated into the vector
  109. template<class AE>
  110. BOOST_UBLAS_INLINE
  111. vector (const vector_expression<AE> &ae):
  112. vector_container<self_type> (),
  113. data_ (ae ().size ()) {
  114. vector_assign<scalar_assign> (*this, ae);
  115. }
  116. // -----------------------
  117. // Random Access Container
  118. // -----------------------
  119. /// \brief Return the maximum size of the data container.
  120. /// 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.
  121. BOOST_UBLAS_INLINE
  122. size_type max_size () const {
  123. return data_.max_size ();
  124. }
  125. /// \brief Return true if the vector is empty (\c size==0)
  126. /// \return \c true if empty, \c false otherwise
  127. BOOST_UBLAS_INLINE
  128. bool empty () const {
  129. return data_.size () == 0;
  130. }
  131. // ---------
  132. // Accessors
  133. // ---------
  134. /// \brief Return the size of the vector
  135. BOOST_UBLAS_INLINE
  136. size_type size () const {
  137. return data_.size ();
  138. }
  139. // -----------------
  140. // Storage accessors
  141. // -----------------
  142. /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
  143. BOOST_UBLAS_INLINE
  144. const array_type &data () const {
  145. return data_;
  146. }
  147. /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
  148. BOOST_UBLAS_INLINE
  149. array_type &data () {
  150. return data_;
  151. }
  152. // --------
  153. // Resizing
  154. // --------
  155. /// \brief Resize the vector
  156. /// 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.
  157. /// \param size new size of the vector
  158. /// \param preserve if true, keep values
  159. BOOST_UBLAS_INLINE
  160. void resize (size_type size, bool preserve = true) {
  161. if (preserve)
  162. data ().resize (size, typename A::value_type ());
  163. else
  164. data ().resize (size);
  165. }
  166. // ---------------
  167. // Element support
  168. // ---------------
  169. /// \brief Return a pointer to the element \f$i\f$
  170. /// \param i index of the element
  171. // XXX this semantic is not the one expected by the name of this method
  172. BOOST_UBLAS_INLINE
  173. pointer find_element (size_type i) {
  174. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  175. }
  176. /// \brief Return a const pointer to the element \f$i\f$
  177. /// \param i index of the element
  178. // XXX this semantic is not the one expected by the name of this method
  179. BOOST_UBLAS_INLINE
  180. const_pointer find_element (size_type i) const {
  181. return & (data () [i]);
  182. }
  183. // --------------
  184. // Element access
  185. // --------------
  186. /// \brief Return a const reference to the element \f$i\f$
  187. /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  188. /// \param i index of the element
  189. BOOST_UBLAS_INLINE
  190. const_reference operator () (size_type i) const {
  191. return data () [i];
  192. }
  193. /// \brief Return a reference to the element \f$i\f$
  194. /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  195. /// \param i index of the element
  196. BOOST_UBLAS_INLINE
  197. reference operator () (size_type i) {
  198. return data () [i];
  199. }
  200. /// \brief Return a const reference to the element \f$i\f$
  201. /// \param i index of the element
  202. BOOST_UBLAS_INLINE
  203. const_reference operator [] (size_type i) const {
  204. return (*this) (i);
  205. }
  206. /// \brief Return a reference to the element \f$i\f$
  207. /// \param i index of the element
  208. BOOST_UBLAS_INLINE
  209. reference operator [] (size_type i) {
  210. return (*this) (i);
  211. }
  212. // ------------------
  213. // Element assignment
  214. // ------------------
  215. /// \brief Set element \f$i\f$ to the value \c t
  216. /// \param i index of the element
  217. /// \param t reference to the value to be set
  218. // XXX semantic of this is to insert a new element and therefore size=size+1 ?
  219. BOOST_UBLAS_INLINE
  220. reference insert_element (size_type i, const_reference t) {
  221. return (data () [i] = t);
  222. }
  223. /// \brief Set element \f$i\f$ to the \e zero value
  224. /// \param i index of the element
  225. BOOST_UBLAS_INLINE
  226. void erase_element (size_type i) {
  227. data () [i] = value_type/*zero*/();
  228. }
  229. // -------
  230. // Zeroing
  231. // -------
  232. /// \brief Clear the vector, i.e. set all values to the \c zero value.
  233. BOOST_UBLAS_INLINE
  234. void clear () {
  235. std::fill (data ().begin (), data ().end (), value_type/*zero*/());
  236. }
  237. // Assignment
  238. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  239. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  240. /// \param v is the source vector
  241. /// \return a reference to a vector (i.e. the destination vector)
  242. /*! @note "pass by value" the key idea to enable move semantics */
  243. BOOST_UBLAS_INLINE
  244. vector &operator = (vector v) {
  245. assign_temporary(v);
  246. return *this;
  247. }
  248. #else
  249. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  250. /// \param v is the source vector
  251. /// \return a reference to a vector (i.e. the destination vector)
  252. BOOST_UBLAS_INLINE
  253. vector &operator = (const vector &v) {
  254. data () = v.data ();
  255. return *this;
  256. }
  257. #endif
  258. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  259. /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
  260. /// \param v is the source vector container
  261. /// \return a reference to a vector (i.e. the destination vector)
  262. template<class C> // Container assignment without temporary
  263. BOOST_UBLAS_INLINE
  264. vector &operator = (const vector_container<C> &v) {
  265. resize (v ().size (), false);
  266. assign (v);
  267. return *this;
  268. }
  269. /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
  270. /// \param v is the source vector
  271. /// \return a reference to a vector (i.e. the destination vector)
  272. BOOST_UBLAS_INLINE
  273. vector &assign_temporary (vector &v) {
  274. swap (v);
  275. return *this;
  276. }
  277. /// \brief Assign the result of a vector_expression to the vector
  278. /// 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.
  279. /// \tparam AE is the type of the vector_expression
  280. /// \param ae is a const reference to the vector_expression
  281. /// \return a reference to the resulting vector
  282. template<class AE>
  283. BOOST_UBLAS_INLINE
  284. vector &operator = (const vector_expression<AE> &ae) {
  285. self_type temporary (ae);
  286. return assign_temporary (temporary);
  287. }
  288. /// \brief Assign the result of a vector_expression to the vector
  289. /// 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.
  290. /// \tparam AE is the type of the vector_expression
  291. /// \param ae is a const reference to the vector_expression
  292. /// \return a reference to the resulting vector
  293. template<class AE>
  294. BOOST_UBLAS_INLINE
  295. vector &assign (const vector_expression<AE> &ae) {
  296. vector_assign<scalar_assign> (*this, ae);
  297. return *this;
  298. }
  299. // -------------------
  300. // Computed assignment
  301. // -------------------
  302. /// \brief Assign the sum of the vector and a vector_expression to the vector
  303. /// 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.
  304. /// A temporary is created for the computations.
  305. /// \tparam AE is the type of the vector_expression
  306. /// \param ae is a const reference to the vector_expression
  307. /// \return a reference to the resulting vector
  308. template<class AE>
  309. BOOST_UBLAS_INLINE
  310. vector &operator += (const vector_expression<AE> &ae) {
  311. self_type temporary (*this + ae);
  312. return assign_temporary (temporary);
  313. }
  314. /// \brief Assign the sum of the vector and a vector_expression to the vector
  315. /// 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.
  316. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  317. /// \tparam AE is the type of the vector_expression
  318. /// \param ae is a const reference to the vector_expression
  319. /// \return a reference to the resulting vector
  320. template<class C> // Container assignment without temporary
  321. BOOST_UBLAS_INLINE
  322. vector &operator += (const vector_container<C> &v) {
  323. plus_assign (v);
  324. return *this;
  325. }
  326. /// \brief Assign the sum of the vector and a vector_expression to the vector
  327. /// 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.
  328. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  329. /// \tparam AE is the type of the vector_expression
  330. /// \param ae is a const reference to the vector_expression
  331. /// \return a reference to the resulting vector
  332. template<class AE>
  333. BOOST_UBLAS_INLINE
  334. vector &plus_assign (const vector_expression<AE> &ae) {
  335. vector_assign<scalar_plus_assign> (*this, ae);
  336. return *this;
  337. }
  338. /// \brief Assign the difference of the vector and a vector_expression to the vector
  339. /// 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.
  340. /// A temporary is created for the computations.
  341. /// \tparam AE is the type of the vector_expression
  342. /// \param ae is a const reference to the vector_expression
  343. template<class AE>
  344. BOOST_UBLAS_INLINE
  345. vector &operator -= (const vector_expression<AE> &ae) {
  346. self_type temporary (*this - ae);
  347. return assign_temporary (temporary);
  348. }
  349. /// \brief Assign the difference of the vector and a vector_expression to the vector
  350. /// 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.
  351. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  352. /// \tparam AE is the type of the vector_expression
  353. /// \param ae is a const reference to the vector_expression
  354. /// \return a reference to the resulting vector
  355. template<class C> // Container assignment without temporary
  356. BOOST_UBLAS_INLINE
  357. vector &operator -= (const vector_container<C> &v) {
  358. minus_assign (v);
  359. return *this;
  360. }
  361. /// \brief Assign the difference of the vector and a vector_expression to the vector
  362. /// 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.
  363. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  364. /// \tparam AE is the type of the vector_expression
  365. /// \param ae is a const reference to the vector_expression
  366. /// \return a reference to the resulting vector
  367. template<class AE>
  368. BOOST_UBLAS_INLINE
  369. vector &minus_assign (const vector_expression<AE> &ae) {
  370. vector_assign<scalar_minus_assign> (*this, ae);
  371. return *this;
  372. }
  373. /// \brief Assign the product of the vector and a scalar to the vector
  374. /// 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.
  375. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  376. /// \tparam AE is the type of the vector_expression
  377. /// \param at is a const reference to the scalar
  378. /// \return a reference to the resulting vector
  379. template<class AT>
  380. BOOST_UBLAS_INLINE
  381. vector &operator *= (const AT &at) {
  382. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  383. return *this;
  384. }
  385. /// \brief Assign the division of the vector by a scalar to the vector
  386. /// 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.
  387. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  388. /// \tparam AE is the type of the vector_expression
  389. /// \param at is a const reference to the scalar
  390. /// \return a reference to the resulting vector
  391. template<class AT>
  392. BOOST_UBLAS_INLINE
  393. vector &operator /= (const AT &at) {
  394. vector_assign_scalar<scalar_divides_assign> (*this, at);
  395. return *this;
  396. }
  397. // --------
  398. // Swapping
  399. // --------
  400. /// \brief Swap the content of the vector with another vector
  401. /// \param v is the vector to be swapped with
  402. BOOST_UBLAS_INLINE
  403. void swap (vector &v) {
  404. if (this != &v) {
  405. data ().swap (v.data ());
  406. }
  407. }
  408. /// \brief Swap the content of two vectors
  409. /// \param v1 is the first vector. It takes values from v2
  410. /// \param v2 is the second vector It takes values from v1
  411. BOOST_UBLAS_INLINE
  412. friend void swap (vector &v1, vector &v2) {
  413. v1.swap (v2);
  414. }
  415. // Iterator types
  416. private:
  417. // Use the storage array iterator
  418. typedef typename A::const_iterator const_subiterator_type;
  419. typedef typename A::iterator subiterator_type;
  420. public:
  421. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  422. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  423. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  424. #else
  425. class const_iterator;
  426. class iterator;
  427. #endif
  428. // --------------
  429. // Element lookup
  430. // --------------
  431. /// \brief Return a const iterator to the element \e i
  432. /// \param i index of the element
  433. BOOST_UBLAS_INLINE
  434. const_iterator find (size_type i) const {
  435. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  436. return const_iterator (*this, data ().begin () + i);
  437. #else
  438. return const_iterator (*this, i);
  439. #endif
  440. }
  441. /// \brief Return an iterator to the element \e i
  442. /// \param i index of the element
  443. BOOST_UBLAS_INLINE
  444. iterator find (size_type i) {
  445. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  446. return iterator (*this, data ().begin () + i);
  447. #else
  448. return iterator (*this, i);
  449. #endif
  450. }
  451. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  452. class const_iterator:
  453. public container_const_reference<vector>,
  454. public random_access_iterator_base<dense_random_access_iterator_tag,
  455. const_iterator, value_type, difference_type> {
  456. public:
  457. typedef typename vector::difference_type difference_type;
  458. typedef typename vector::value_type value_type;
  459. typedef typename vector::const_reference reference;
  460. typedef const typename vector::pointer pointer;
  461. // ----------------------------
  462. // Construction and destruction
  463. // ----------------------------
  464. BOOST_UBLAS_INLINE
  465. const_iterator ():
  466. container_const_reference<self_type> (), it_ () {}
  467. BOOST_UBLAS_INLINE
  468. const_iterator (const self_type &v, const const_subiterator_type &it):
  469. container_const_reference<self_type> (v), it_ (it) {}
  470. BOOST_UBLAS_INLINE
  471. const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
  472. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  473. // ----------
  474. // Arithmetic
  475. // ----------
  476. /// \brief Increment by 1 the position of the iterator
  477. /// \return a reference to the const iterator
  478. BOOST_UBLAS_INLINE
  479. const_iterator &operator ++ () {
  480. ++ it_;
  481. return *this;
  482. }
  483. /// \brief Decrement by 1 the position of the iterator
  484. /// \return a reference to the const iterator
  485. BOOST_UBLAS_INLINE
  486. const_iterator &operator -- () {
  487. -- it_;
  488. return *this;
  489. }
  490. /// \brief Increment by \e n the position of the iterator
  491. /// \return a reference to the const iterator
  492. BOOST_UBLAS_INLINE
  493. const_iterator &operator += (difference_type n) {
  494. it_ += n;
  495. return *this;
  496. }
  497. /// \brief Decrement by \e n the position of the iterator
  498. /// \return a reference to the const iterator
  499. BOOST_UBLAS_INLINE
  500. const_iterator &operator -= (difference_type n) {
  501. it_ -= n;
  502. return *this;
  503. }
  504. /// \brief Return the different in number of positions between 2 iterators
  505. BOOST_UBLAS_INLINE
  506. difference_type operator - (const const_iterator &it) const {
  507. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  508. return it_ - it.it_;
  509. }
  510. /// \brief Dereference an iterator
  511. /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  512. /// \return a const reference to the value pointed by the iterator
  513. BOOST_UBLAS_INLINE
  514. const_reference operator * () const {
  515. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  516. return *it_;
  517. }
  518. /// \brief Dereference an iterator at the n-th forward value
  519. /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
  520. /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  521. /// \return a const reference
  522. BOOST_UBLAS_INLINE
  523. const_reference operator [] (difference_type n) const {
  524. return *(it_ + n);
  525. }
  526. // Index
  527. /// \brief return the index of the element referenced by the iterator
  528. BOOST_UBLAS_INLINE
  529. size_type index () const {
  530. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  531. return it_ - (*this) ().begin ().it_;
  532. }
  533. // Assignment
  534. BOOST_UBLAS_INLINE
  535. /// \brief assign the value of an iterator to the iterator
  536. const_iterator &operator = (const const_iterator &it) {
  537. container_const_reference<self_type>::assign (&it ());
  538. it_ = it.it_;
  539. return *this;
  540. }
  541. // Comparison
  542. /// \brief compare the value of two itetarors
  543. /// \return true if they reference the same element
  544. BOOST_UBLAS_INLINE
  545. bool operator == (const const_iterator &it) const {
  546. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  547. return it_ == it.it_;
  548. }
  549. /// \brief compare the value of two iterators
  550. /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
  551. BOOST_UBLAS_INLINE
  552. bool operator < (const const_iterator &it) const {
  553. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  554. return it_ < it.it_;
  555. }
  556. private:
  557. const_subiterator_type it_;
  558. friend class iterator;
  559. };
  560. #endif
  561. /// \brief return an iterator on the first element of the vector
  562. BOOST_UBLAS_INLINE
  563. const_iterator begin () const {
  564. return find (0);
  565. }
  566. /// \brief return an iterator on the first element of the vector
  567. BOOST_UBLAS_INLINE
  568. const_iterator cbegin () const {
  569. return begin ();
  570. }
  571. /// \brief return an iterator after the last element of the vector
  572. BOOST_UBLAS_INLINE
  573. const_iterator end () const {
  574. return find (data_.size ());
  575. }
  576. /// \brief return an iterator after the last element of the vector
  577. BOOST_UBLAS_INLINE
  578. const_iterator cend () const {
  579. return end ();
  580. }
  581. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  582. class iterator:
  583. public container_reference<vector>,
  584. public random_access_iterator_base<dense_random_access_iterator_tag,
  585. iterator, value_type, difference_type> {
  586. public:
  587. typedef typename vector::difference_type difference_type;
  588. typedef typename vector::value_type value_type;
  589. typedef typename vector::reference reference;
  590. typedef typename vector::pointer pointer;
  591. // Construction and destruction
  592. BOOST_UBLAS_INLINE
  593. iterator ():
  594. container_reference<self_type> (), it_ () {}
  595. BOOST_UBLAS_INLINE
  596. iterator (self_type &v, const subiterator_type &it):
  597. container_reference<self_type> (v), it_ (it) {}
  598. // Arithmetic
  599. BOOST_UBLAS_INLINE
  600. iterator &operator ++ () {
  601. ++ it_;
  602. return *this;
  603. }
  604. BOOST_UBLAS_INLINE
  605. iterator &operator -- () {
  606. -- it_;
  607. return *this;
  608. }
  609. BOOST_UBLAS_INLINE
  610. iterator &operator += (difference_type n) {
  611. it_ += n;
  612. return *this;
  613. }
  614. BOOST_UBLAS_INLINE
  615. iterator &operator -= (difference_type n) {
  616. it_ -= n;
  617. return *this;
  618. }
  619. BOOST_UBLAS_INLINE
  620. difference_type operator - (const iterator &it) const {
  621. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  622. return it_ - it.it_;
  623. }
  624. // Dereference
  625. BOOST_UBLAS_INLINE
  626. reference operator * () const {
  627. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  628. return *it_;
  629. }
  630. BOOST_UBLAS_INLINE
  631. reference operator [] (difference_type n) const {
  632. return *(it_ + n);
  633. }
  634. // Index
  635. BOOST_UBLAS_INLINE
  636. size_type index () const {
  637. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  638. return it_ - (*this) ().begin ().it_;
  639. }
  640. // Assignment
  641. BOOST_UBLAS_INLINE
  642. iterator &operator = (const iterator &it) {
  643. container_reference<self_type>::assign (&it ());
  644. it_ = it.it_;
  645. return *this;
  646. }
  647. // Comparison
  648. BOOST_UBLAS_INLINE
  649. bool operator == (const iterator &it) const {
  650. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  651. return it_ == it.it_;
  652. }
  653. BOOST_UBLAS_INLINE
  654. bool operator < (const iterator &it) const {
  655. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  656. return it_ < it.it_;
  657. }
  658. private:
  659. subiterator_type it_;
  660. friend class const_iterator;
  661. };
  662. #endif
  663. /// \brief Return an iterator on the first element of the vector
  664. BOOST_UBLAS_INLINE
  665. iterator begin () {
  666. return find (0);
  667. }
  668. /// \brief Return an iterator at the end of the vector
  669. BOOST_UBLAS_INLINE
  670. iterator end () {
  671. return find (data_.size ());
  672. }
  673. // Reverse iterator
  674. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  675. typedef reverse_iterator_base<iterator> reverse_iterator;
  676. /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
  677. BOOST_UBLAS_INLINE
  678. const_reverse_iterator rbegin () const {
  679. return const_reverse_iterator (end ());
  680. }
  681. /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
  682. BOOST_UBLAS_INLINE
  683. const_reverse_iterator crbegin () const {
  684. return rbegin ();
  685. }
  686. /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
  687. BOOST_UBLAS_INLINE
  688. const_reverse_iterator rend () const {
  689. return const_reverse_iterator (begin ());
  690. }
  691. /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
  692. BOOST_UBLAS_INLINE
  693. const_reverse_iterator crend () const {
  694. return rend ();
  695. }
  696. /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
  697. BOOST_UBLAS_INLINE
  698. reverse_iterator rbegin () {
  699. return reverse_iterator (end ());
  700. }
  701. /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
  702. BOOST_UBLAS_INLINE
  703. reverse_iterator rend () {
  704. return reverse_iterator (begin ());
  705. }
  706. // -------------
  707. // Serialization
  708. // -------------
  709. /// Serialize a vector into and archive as defined in Boost
  710. /// \param ar Archive object. Can be a flat file, an XML file or any other stream
  711. /// \param file_version Optional file version (not yet used)
  712. template<class Archive>
  713. void serialize(Archive & ar, const unsigned int /* file_version */){
  714. ar & serialization::make_nvp("data",data_);
  715. }
  716. private:
  717. array_type data_;
  718. };
  719. #ifdef BOOST_UBLAS_CPP_GE_2011
  720. /** \brief A dense vector of values of type \c T.
  721. *
  722. * 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
  723. * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array.
  724. * Elements are constructed by \c A, which need not initialise their value.
  725. *
  726. * \tparam T type of the objects stored in the vector (like int, double, complex,...)
  727. * \tparam A The type of the storage array of the vector. Default is \c std::array<T>.
  728. */
  729. template<class T, std::size_t N, class A>
  730. class fixed_vector:
  731. public vector_container<fixed_vector<T, N, A> > {
  732. typedef fixed_vector<T, N, A> self_type;
  733. public:
  734. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  735. using vector_container<self_type>::operator ();
  736. #endif
  737. typedef typename A::size_type size_type;
  738. typedef typename A::difference_type difference_type;
  739. typedef T value_type;
  740. typedef typename type_traits<T>::const_reference const_reference;
  741. typedef T &reference;
  742. typedef T *pointer;
  743. typedef const T *const_pointer;
  744. typedef A array_type;
  745. typedef const vector_reference<const self_type> const_closure_type;
  746. typedef vector_reference<self_type> closure_type;
  747. typedef self_type vector_temporary_type;
  748. typedef dense_tag storage_category;
  749. // Construction and destruction
  750. /// \brief Constructor of a fixed_vector
  751. BOOST_UBLAS_INLINE
  752. fixed_vector ():
  753. vector_container<self_type> (),
  754. data_ () {}
  755. /// \brief Constructor of a fixed_vector by copying from another container
  756. /// This type uses the generic name \c array_type within the vector definition.
  757. /// \param data container of type \c A
  758. BOOST_UBLAS_INLINE
  759. fixed_vector (const array_type &data):
  760. vector_container<self_type> (),
  761. data_ (data) {}
  762. /// \brief Constructor of a fixed_vector with a unique initial value
  763. /// \param init value to assign to each element of the vector
  764. BOOST_UBLAS_INLINE
  765. fixed_vector (const value_type &init):
  766. vector_container<self_type> (),
  767. data_ () {
  768. data_.fill( init );
  769. }
  770. /// \brief Copy-constructor of a fixed_vector
  771. /// \param v is the fixed_vector to be duplicated
  772. BOOST_UBLAS_INLINE
  773. fixed_vector (const fixed_vector &v):
  774. vector_container<self_type> (),
  775. data_ (v.data_) {}
  776. /// \brief Copy-constructor of a vector from a vector_expression
  777. /// Depending on the vector_expression, this constructor can have the cost of the computations
  778. /// of the expression (trivial to say it, but take it must be taken into account in your complexity calculations).
  779. /// \param ae the vector_expression which values will be duplicated into the vector
  780. template<class AE>
  781. BOOST_UBLAS_INLINE
  782. fixed_vector (const vector_expression<AE> &ae):
  783. vector_container<self_type> (),
  784. data_ ( ) {
  785. vector_assign<scalar_assign> (*this, ae);
  786. }
  787. /// \brief Construct a fixed_vector from a list of values
  788. /// This constructor enables initialization by using any of:
  789. /// fixed_vector<double, 3> v = { 1, 2, 3 } or fixed_vector<double,3> v( {1, 2, 3} ) or fixed_vector<double,3> v( 1, 2, 3 )
  790. template <typename... Types>
  791. BOOST_UBLAS_INLINE
  792. fixed_vector(value_type v0, Types... vrest) :
  793. vector_container<self_type> (),
  794. data_( array_type{ v0, vrest... } ) {}
  795. // -----------------------
  796. // Random Access Container
  797. // -----------------------
  798. /// \brief Return the maximum size of the data container.
  799. /// 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.
  800. BOOST_UBLAS_INLINE
  801. size_type max_size () const {
  802. return data_.max_size ();
  803. }
  804. /// \brief Return true if the vector is empty (\c size==0)
  805. /// \return \c true if empty, \c false otherwise
  806. BOOST_UBLAS_INLINE
  807. const bool &empty () const {
  808. return data_.empty();
  809. }
  810. // ---------
  811. // Accessors
  812. // ---------
  813. /// \brief Return the size of the vector
  814. BOOST_UBLAS_INLINE
  815. BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14
  816. return data_.size ();
  817. }
  818. // -----------------
  819. // Storage accessors
  820. // -----------------
  821. /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
  822. BOOST_UBLAS_INLINE
  823. const array_type &data () const {
  824. return data_;
  825. }
  826. /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
  827. BOOST_UBLAS_INLINE
  828. array_type &data () {
  829. return data_;
  830. }
  831. // ---------------
  832. // Element support
  833. // ---------------
  834. /// \brief Return a pointer to the element \f$i\f$
  835. /// \param i index of the element
  836. // XXX this semantic is not the one expected by the name of this method
  837. BOOST_UBLAS_INLINE
  838. pointer find_element (size_type i) {
  839. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  840. }
  841. /// \brief Return a const pointer to the element \f$i\f$
  842. /// \param i index of the element
  843. // XXX this semantic is not the one expected by the name of this method
  844. BOOST_UBLAS_INLINE
  845. const_pointer find_element (size_type i) const {
  846. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds
  847. return & (data () [i]);
  848. }
  849. // --------------
  850. // Element access
  851. // --------------
  852. /// \brief Return a const reference to the element \f$i\f$
  853. /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  854. /// \param i index of the element
  855. BOOST_UBLAS_INLINE
  856. const_reference operator () (size_type i) const {
  857. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  858. return data () [i];
  859. }
  860. /// \brief Return a reference to the element \f$i\f$
  861. /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  862. /// \param i index of the element
  863. BOOST_UBLAS_INLINE
  864. reference operator () (size_type i) {
  865. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  866. return data () [i];
  867. }
  868. /// \brief Return a const reference to the element \f$i\f$
  869. /// \param i index of the element
  870. BOOST_UBLAS_INLINE
  871. const_reference operator [] (size_type i) const {
  872. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  873. return (*this) (i);
  874. }
  875. /// \brief Return a reference to the element \f$i\f$
  876. /// \param i index of the element
  877. BOOST_UBLAS_INLINE
  878. reference operator [] (size_type i) {
  879. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  880. return (*this) (i);
  881. }
  882. // ------------------
  883. // Element assignment
  884. // ------------------
  885. /// \brief Set element \f$i\f$ to the value \c t
  886. /// \param i index of the element
  887. /// \param t reference to the value to be set
  888. // XXX semantic of this is to insert a new element and therefore size=size+1 ?
  889. BOOST_UBLAS_INLINE
  890. reference insert_element (size_type i, const_reference t) {
  891. BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
  892. return (data () [i] = t);
  893. }
  894. /// \brief Set element \f$i\f$ to the \e zero value
  895. /// \param i index of the element
  896. BOOST_UBLAS_INLINE
  897. void erase_element (size_type i) {
  898. BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
  899. data () [i] = value_type/*zero*/();
  900. }
  901. // -------
  902. // Zeroing
  903. // -------
  904. /// \brief Clear the vector, i.e. set all values to the \c zero value.
  905. BOOST_UBLAS_INLINE
  906. void clear () {
  907. std::fill (data ().begin (), data ().end (), value_type/*zero*/());
  908. }
  909. // Assignment
  910. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  911. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  912. /// \param v is the source vector
  913. /// \return a reference to a fixed_vector (i.e. the destination vector)
  914. /*! @note "pass by value" the key idea to enable move semantics */
  915. BOOST_UBLAS_INLINE
  916. fixed_vector &operator = (fixed_vector v) {
  917. assign_temporary(v);
  918. return *this;
  919. }
  920. #else
  921. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  922. /// \param v is the source fixed_vector
  923. /// \return a reference to a fixed_vector (i.e. the destination vector)
  924. BOOST_UBLAS_INLINE
  925. fixed_vector &operator = (const fixed_vector &v) {
  926. data () = v.data ();
  927. return *this;
  928. }
  929. #endif
  930. /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  931. /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary.
  932. /// \param v is the source vector container
  933. /// \return a reference to a vector (i.e. the destination vector)
  934. template<class C> // Container assignment without temporary
  935. BOOST_UBLAS_INLINE
  936. fixed_vector &operator = (const vector_container<C> &v) {
  937. assign (v);
  938. return *this;
  939. }
  940. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  941. /// \param v is the source fixed_vector
  942. /// \return a reference to a fixed_vector (i.e. the destination fixed_vector)
  943. BOOST_UBLAS_INLINE
  944. fixed_vector &assign_temporary (fixed_vector &v) {
  945. swap ( v );
  946. return *this;
  947. }
  948. /// \brief Assign the result of a vector_expression to the fixed_vector
  949. /// 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.
  950. /// \tparam AE is the type of the vector_expression
  951. /// \param ae is a const reference to the vector_expression
  952. /// \return a reference to the resulting fixed_vector
  953. template<class AE>
  954. BOOST_UBLAS_INLINE
  955. fixed_vector &operator = (const vector_expression<AE> &ae) {
  956. self_type temporary (ae);
  957. return assign_temporary (temporary);
  958. }
  959. /// \brief Assign the result of a vector_expression to the fixed_vector
  960. /// 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.
  961. /// \tparam AE is the type of the vector_expression
  962. /// \param ae is a const reference to the vector_expression
  963. /// \return a reference to the resulting fixed_vector
  964. template<class AE>
  965. BOOST_UBLAS_INLINE
  966. fixed_vector &assign (const vector_expression<AE> &ae) {
  967. vector_assign<scalar_assign> (*this, ae);
  968. return *this;
  969. }
  970. // -------------------
  971. // Computed assignment
  972. // -------------------
  973. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  974. /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  975. /// A temporary is created for the computations.
  976. /// \tparam AE is the type of the vector_expression
  977. /// \param ae is a const reference to the vector_expression
  978. /// \return a reference to the resulting fixed_vector
  979. template<class AE>
  980. BOOST_UBLAS_INLINE
  981. fixed_vector &operator += (const vector_expression<AE> &ae) {
  982. self_type temporary (*this + ae);
  983. return assign_temporary (temporary);
  984. }
  985. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  986. /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  987. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  988. /// \tparam AE is the type of the vector_expression
  989. /// \param ae is a const reference to the vector_expression
  990. /// \return a reference to the resulting vector
  991. template<class C> // Container assignment without temporary
  992. BOOST_UBLAS_INLINE
  993. fixed_vector &operator += (const vector_container<C> &v) {
  994. plus_assign (v);
  995. return *this;
  996. }
  997. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  998. /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  999. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1000. /// \tparam AE is the type of the vector_expression
  1001. /// \param ae is a const reference to the vector_expression
  1002. /// \return a reference to the resulting vector
  1003. template<class AE>
  1004. BOOST_UBLAS_INLINE
  1005. fixed_vector &plus_assign (const vector_expression<AE> &ae) {
  1006. vector_assign<scalar_plus_assign> (*this, ae);
  1007. return *this;
  1008. }
  1009. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1010. /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  1011. /// A temporary is created for the computations.
  1012. /// \tparam AE is the type of the vector_expression
  1013. /// \param ae is a const reference to the vector_expression
  1014. template<class AE>
  1015. BOOST_UBLAS_INLINE
  1016. fixed_vector &operator -= (const vector_expression<AE> &ae) {
  1017. self_type temporary (*this - ae);
  1018. return assign_temporary (temporary);
  1019. }
  1020. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1021. /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  1022. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1023. /// \tparam AE is the type of the vector_expression
  1024. /// \param ae is a const reference to the vector_expression
  1025. /// \return a reference to the resulting vector
  1026. template<class C> // Container assignment without temporary
  1027. BOOST_UBLAS_INLINE
  1028. fixed_vector &operator -= (const vector_container<C> &v) {
  1029. minus_assign (v);
  1030. return *this;
  1031. }
  1032. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1033. /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  1034. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1035. /// \tparam AE is the type of the vector_expression
  1036. /// \param ae is a const reference to the vector_expression
  1037. /// \return a reference to the resulting fixed_vector
  1038. template<class AE>
  1039. BOOST_UBLAS_INLINE
  1040. fixed_vector &minus_assign (const vector_expression<AE> &ae) {
  1041. vector_assign<scalar_minus_assign> (*this, ae);
  1042. return *this;
  1043. }
  1044. /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector
  1045. /// Assign the product of the fixed_vector and a scalar to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  1046. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1047. /// \tparam AE is the type of the vector_expression
  1048. /// \param at is a const reference to the scalar
  1049. /// \return a reference to the resulting fixed_vector
  1050. template<class AT>
  1051. BOOST_UBLAS_INLINE
  1052. fixed_vector &operator *= (const AT &at) {
  1053. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  1054. return *this;
  1055. }
  1056. /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector
  1057. /// Assign the division of the fixed_vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
  1058. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  1059. /// \tparam AE is the type of the vector_expression
  1060. /// \param at is a const reference to the scalar
  1061. /// \return a reference to the resulting fixed_vector
  1062. template<class AT>
  1063. BOOST_UBLAS_INLINE
  1064. fixed_vector &operator /= (const AT &at) {
  1065. vector_assign_scalar<scalar_divides_assign> (*this, at);
  1066. return *this;
  1067. }
  1068. // --------
  1069. // Swapping
  1070. // --------
  1071. /// \brief Swap the content of the fixed_vector with another vector
  1072. /// \param v is the fixed_vector to be swapped with
  1073. BOOST_UBLAS_INLINE
  1074. void swap (fixed_vector &v) {
  1075. if (this != &v) {
  1076. data ().swap (v.data ());
  1077. }
  1078. }
  1079. /// \brief Swap the content of two fixed_vectors
  1080. /// \param v1 is the first fixed_vector. It takes values from v2
  1081. /// \param v2 is the second fixed_vector It takes values from v1
  1082. BOOST_UBLAS_INLINE
  1083. friend void swap (fixed_vector &v1, fixed_vector &v2) {
  1084. v1.swap (v2);
  1085. }
  1086. // Iterator types
  1087. private:
  1088. // Use the storage array iterator
  1089. typedef typename A::const_iterator const_subiterator_type;
  1090. typedef typename A::iterator subiterator_type;
  1091. public:
  1092. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1093. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1094. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1095. #else
  1096. class const_iterator;
  1097. class iterator;
  1098. #endif
  1099. // --------------
  1100. // Element lookup
  1101. // --------------
  1102. /// \brief Return a const iterator to the element \e i
  1103. /// \param i index of the element
  1104. BOOST_UBLAS_INLINE
  1105. const_iterator find (size_type i) const {
  1106. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1107. return const_iterator (*this, data ().begin () + i);
  1108. #else
  1109. return const_iterator (*this, i);
  1110. #endif
  1111. }
  1112. /// \brief Return an iterator to the element \e i
  1113. /// \param i index of the element
  1114. BOOST_UBLAS_INLINE
  1115. iterator find (size_type i) {
  1116. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1117. return iterator (*this, data ().begin () + i);
  1118. #else
  1119. return iterator (*this, i);
  1120. #endif
  1121. }
  1122. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1123. class const_iterator:
  1124. public container_const_reference<fixed_vector>,
  1125. public random_access_iterator_base<dense_random_access_iterator_tag,
  1126. const_iterator, value_type, difference_type> {
  1127. public:
  1128. typedef typename fixed_vector::difference_type difference_type;
  1129. typedef typename fixed_vector::value_type value_type;
  1130. typedef typename fixed_vector::const_reference reference;
  1131. typedef const typename fixed_vector::pointer pointer;
  1132. // ----------------------------
  1133. // Construction and destruction
  1134. // ----------------------------
  1135. BOOST_UBLAS_INLINE
  1136. const_iterator ():
  1137. container_const_reference<self_type> (), it_ () {}
  1138. BOOST_UBLAS_INLINE
  1139. const_iterator (const self_type &v, const const_subiterator_type &it):
  1140. container_const_reference<self_type> (v), it_ (it) {}
  1141. BOOST_UBLAS_INLINE
  1142. const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
  1143. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  1144. // ----------
  1145. // Arithmetic
  1146. // ----------
  1147. /// \brief Increment by 1 the position of the iterator
  1148. /// \return a reference to the const iterator
  1149. BOOST_UBLAS_INLINE
  1150. const_iterator &operator ++ () {
  1151. ++ it_;
  1152. return *this;
  1153. }
  1154. /// \brief Decrement by 1 the position of the iterator
  1155. /// \return a reference to the const iterator
  1156. BOOST_UBLAS_INLINE
  1157. const_iterator &operator -- () {
  1158. -- it_;
  1159. return *this;
  1160. }
  1161. /// \brief Increment by \e n the position of the iterator
  1162. /// \return a reference to the const iterator
  1163. BOOST_UBLAS_INLINE
  1164. const_iterator &operator += (difference_type n) {
  1165. it_ += n;
  1166. return *this;
  1167. }
  1168. /// \brief Decrement by \e n the position of the iterator
  1169. /// \return a reference to the const iterator
  1170. BOOST_UBLAS_INLINE
  1171. const_iterator &operator -= (difference_type n) {
  1172. it_ -= n;
  1173. return *this;
  1174. }
  1175. /// \brief Return the different in number of positions between 2 iterators
  1176. BOOST_UBLAS_INLINE
  1177. difference_type operator - (const const_iterator &it) const {
  1178. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1179. return it_ - it.it_;
  1180. }
  1181. /// \brief Dereference an iterator
  1182. /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  1183. /// \return a const reference to the value pointed by the iterator
  1184. BOOST_UBLAS_INLINE
  1185. const_reference operator * () const {
  1186. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1187. return *it_;
  1188. }
  1189. /// \brief Dereference an iterator at the n-th forward value
  1190. /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
  1191. /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  1192. /// \return a const reference
  1193. BOOST_UBLAS_INLINE
  1194. const_reference operator [] (difference_type n) const {
  1195. return *(it_ + n);
  1196. }
  1197. // Index
  1198. /// \brief return the index of the element referenced by the iterator
  1199. BOOST_UBLAS_INLINE
  1200. size_type index () const {
  1201. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1202. return it_ - (*this) ().begin ().it_;
  1203. }
  1204. // Assignment
  1205. BOOST_UBLAS_INLINE
  1206. /// \brief assign the value of an iterator to the iterator
  1207. const_iterator &operator = (const const_iterator &it) {
  1208. container_const_reference<self_type>::assign (&it ());
  1209. it_ = it.it_;
  1210. return *this;
  1211. }
  1212. // Comparison
  1213. /// \brief compare the value of two itetarors
  1214. /// \return true if they reference the same element
  1215. BOOST_UBLAS_INLINE
  1216. bool operator == (const const_iterator &it) const {
  1217. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1218. return it_ == it.it_;
  1219. }
  1220. /// \brief compare the value of two iterators
  1221. /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
  1222. BOOST_UBLAS_INLINE
  1223. bool operator < (const const_iterator &it) const {
  1224. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1225. return it_ < it.it_;
  1226. }
  1227. private:
  1228. const_subiterator_type it_;
  1229. friend class iterator;
  1230. };
  1231. #endif
  1232. /// \brief return an iterator on the first element of the fixed_vector
  1233. BOOST_UBLAS_INLINE
  1234. const_iterator begin () const {
  1235. return find (0);
  1236. }
  1237. /// \brief return an iterator on the first element of the fixed_vector
  1238. BOOST_UBLAS_INLINE
  1239. const_iterator cbegin () const {
  1240. return begin ();
  1241. }
  1242. /// \brief return an iterator after the last element of the fixed_vector
  1243. BOOST_UBLAS_INLINE
  1244. const_iterator end () const {
  1245. return find (data_.size ());
  1246. }
  1247. /// \brief return an iterator after the last element of the fixed_vector
  1248. BOOST_UBLAS_INLINE
  1249. const_iterator cend () const {
  1250. return end ();
  1251. }
  1252. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1253. class iterator:
  1254. public container_reference<fixed_vector>,
  1255. public random_access_iterator_base<dense_random_access_iterator_tag,
  1256. iterator, value_type, difference_type> {
  1257. public:
  1258. typedef typename fixed_vector::difference_type difference_type;
  1259. typedef typename fixed_vector::value_type value_type;
  1260. typedef typename fixed_vector::reference reference;
  1261. typedef typename fixed_vector::pointer pointer;
  1262. // Construction and destruction
  1263. BOOST_UBLAS_INLINE
  1264. iterator ():
  1265. container_reference<self_type> (), it_ () {}
  1266. BOOST_UBLAS_INLINE
  1267. iterator (self_type &v, const subiterator_type &it):
  1268. container_reference<self_type> (v), it_ (it) {}
  1269. // Arithmetic
  1270. BOOST_UBLAS_INLINE
  1271. iterator &operator ++ () {
  1272. ++ it_;
  1273. return *this;
  1274. }
  1275. BOOST_UBLAS_INLINE
  1276. iterator &operator -- () {
  1277. -- it_;
  1278. return *this;
  1279. }
  1280. BOOST_UBLAS_INLINE
  1281. iterator &operator += (difference_type n) {
  1282. it_ += n;
  1283. return *this;
  1284. }
  1285. BOOST_UBLAS_INLINE
  1286. iterator &operator -= (difference_type n) {
  1287. it_ -= n;
  1288. return *this;
  1289. }
  1290. BOOST_UBLAS_INLINE
  1291. difference_type operator - (const iterator &it) const {
  1292. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1293. return it_ - it.it_;
  1294. }
  1295. // Dereference
  1296. BOOST_UBLAS_INLINE
  1297. reference operator * () const {
  1298. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  1299. return *it_;
  1300. }
  1301. BOOST_UBLAS_INLINE
  1302. reference operator [] (difference_type n) const {
  1303. return *(it_ + n);
  1304. }
  1305. // Index
  1306. BOOST_UBLAS_INLINE
  1307. size_type index () const {
  1308. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  1309. return it_ - (*this) ().begin ().it_;
  1310. }
  1311. // Assignment
  1312. BOOST_UBLAS_INLINE
  1313. iterator &operator = (const iterator &it) {
  1314. container_reference<self_type>::assign (&it ());
  1315. it_ = it.it_;
  1316. return *this;
  1317. }
  1318. // Comparison
  1319. BOOST_UBLAS_INLINE
  1320. bool operator == (const iterator &it) const {
  1321. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1322. return it_ == it.it_;
  1323. }
  1324. BOOST_UBLAS_INLINE
  1325. bool operator < (const iterator &it) const {
  1326. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1327. return it_ < it.it_;
  1328. }
  1329. private:
  1330. subiterator_type it_;
  1331. friend class const_iterator;
  1332. };
  1333. #endif
  1334. /// \brief Return an iterator on the first element of the fixed_vector
  1335. BOOST_UBLAS_INLINE
  1336. iterator begin () {
  1337. return find (0);
  1338. }
  1339. /// \brief Return an iterator at the end of the fixed_vector
  1340. BOOST_UBLAS_INLINE
  1341. iterator end () {
  1342. return find (data_.size ());
  1343. }
  1344. // Reverse iterator
  1345. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1346. typedef reverse_iterator_base<iterator> reverse_iterator;
  1347. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1348. BOOST_UBLAS_INLINE
  1349. const_reverse_iterator rbegin () const {
  1350. return const_reverse_iterator (end ());
  1351. }
  1352. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1353. BOOST_UBLAS_INLINE
  1354. const_reverse_iterator crbegin () const {
  1355. return rbegin ();
  1356. }
  1357. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1358. BOOST_UBLAS_INLINE
  1359. const_reverse_iterator rend () const {
  1360. return const_reverse_iterator (begin ());
  1361. }
  1362. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1363. BOOST_UBLAS_INLINE
  1364. const_reverse_iterator crend () const {
  1365. return rend ();
  1366. }
  1367. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1368. BOOST_UBLAS_INLINE
  1369. reverse_iterator rbegin () {
  1370. return reverse_iterator (end ());
  1371. }
  1372. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1373. BOOST_UBLAS_INLINE
  1374. reverse_iterator rend () {
  1375. return reverse_iterator (begin ());
  1376. }
  1377. // -------------
  1378. // Serialization
  1379. // -------------
  1380. /// Serialize a fixed_vector into and archive as defined in Boost
  1381. /// \param ar Archive object. Can be a flat file, an XML file or any other stream
  1382. /// \param file_version Optional file version (not yet used)
  1383. template<class Archive>
  1384. void serialize(Archive & ar, const unsigned int /* file_version */){
  1385. ar & serialization::make_nvp("data",data_);
  1386. }
  1387. private:
  1388. array_type data_;
  1389. };
  1390. #endif // BOOST_UBLAS_CPP_GE_2011
  1391. // --------------------
  1392. // Bounded vector class
  1393. // --------------------
  1394. /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
  1395. /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor
  1396. /// 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.
  1397. template<class T, std::size_t N>
  1398. class bounded_vector:
  1399. public vector<T, bounded_array<T, N> > {
  1400. typedef vector<T, bounded_array<T, N> > vector_type;
  1401. public:
  1402. typedef typename vector_type::size_type size_type;
  1403. static const size_type max_size = N;
  1404. // Construction and destruction
  1405. BOOST_UBLAS_INLINE
  1406. bounded_vector ():
  1407. vector_type (N) {}
  1408. BOOST_UBLAS_INLINE
  1409. bounded_vector (size_type size):
  1410. vector_type (size) {}
  1411. BOOST_UBLAS_INLINE
  1412. bounded_vector (const bounded_vector &v):
  1413. vector_type (v) {}
  1414. template<class A2> // Allow vector<T,bounded_array<N> construction
  1415. BOOST_UBLAS_INLINE
  1416. bounded_vector (const vector<T, A2> &v):
  1417. vector_type (v) {}
  1418. template<class AE>
  1419. BOOST_UBLAS_INLINE
  1420. bounded_vector (const vector_expression<AE> &ae):
  1421. vector_type (ae) {}
  1422. BOOST_UBLAS_INLINE
  1423. ~bounded_vector () {}
  1424. // Assignment
  1425. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  1426. /*! @note "pass by value" the key idea to enable move semantics */
  1427. BOOST_UBLAS_INLINE
  1428. bounded_vector &operator = (bounded_vector v) {
  1429. vector_type::operator = (v);
  1430. return *this;
  1431. }
  1432. #else
  1433. BOOST_UBLAS_INLINE
  1434. bounded_vector &operator = (const bounded_vector &v) {
  1435. vector_type::operator = (v);
  1436. return *this;
  1437. }
  1438. #endif
  1439. template<class A2> // Generic vector assignment
  1440. BOOST_UBLAS_INLINE
  1441. bounded_vector &operator = (const vector<T, A2> &v) {
  1442. vector_type::operator = (v);
  1443. return *this;
  1444. }
  1445. template<class C> // Container assignment without temporary
  1446. BOOST_UBLAS_INLINE
  1447. bounded_vector &operator = (const vector_container<C> &v) {
  1448. vector_type::operator = (v);
  1449. return *this;
  1450. }
  1451. template<class AE>
  1452. BOOST_UBLAS_INLINE
  1453. bounded_vector &operator = (const vector_expression<AE> &ae) {
  1454. vector_type::operator = (ae);
  1455. return *this;
  1456. }
  1457. };
  1458. // -----------------
  1459. // Zero vector class
  1460. // -----------------
  1461. /// \brief A zero vector of type \c T and a given \c size
  1462. /// 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
  1463. /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
  1464. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  1465. template<class T, class ALLOC>
  1466. class zero_vector:
  1467. public vector_container<zero_vector<T, ALLOC> > {
  1468. typedef const T *const_pointer;
  1469. typedef zero_vector<T, ALLOC> self_type;
  1470. public:
  1471. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1472. using vector_container<self_type>::operator ();
  1473. #endif
  1474. typedef typename boost::allocator_size_type<ALLOC>::type size_type;
  1475. typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
  1476. typedef T value_type;
  1477. typedef const T &const_reference;
  1478. typedef T &reference;
  1479. typedef const vector_reference<const self_type> const_closure_type;
  1480. typedef vector_reference<self_type> closure_type;
  1481. typedef sparse_tag storage_category;
  1482. // Construction and destruction
  1483. BOOST_UBLAS_INLINE
  1484. zero_vector ():
  1485. vector_container<self_type> (),
  1486. size_ (0) {}
  1487. explicit BOOST_UBLAS_INLINE
  1488. zero_vector (size_type size):
  1489. vector_container<self_type> (),
  1490. size_ (size) {}
  1491. BOOST_UBLAS_INLINE
  1492. zero_vector (const zero_vector &v):
  1493. vector_container<self_type> (),
  1494. size_ (v.size_) {}
  1495. // Accessors
  1496. BOOST_UBLAS_INLINE
  1497. size_type size () const {
  1498. return size_;
  1499. }
  1500. // Resizing
  1501. BOOST_UBLAS_INLINE
  1502. void resize (size_type size, bool /*preserve*/ = true) {
  1503. size_ = size;
  1504. }
  1505. // Element support
  1506. BOOST_UBLAS_INLINE
  1507. const_pointer find_element (size_type /*i*/) const {
  1508. return & zero_;
  1509. }
  1510. // Element access
  1511. BOOST_UBLAS_INLINE
  1512. const_reference operator () (size_type /* i */) const {
  1513. return zero_;
  1514. }
  1515. BOOST_UBLAS_INLINE
  1516. const_reference operator [] (size_type i) const {
  1517. return (*this) (i);
  1518. }
  1519. // Assignment
  1520. BOOST_UBLAS_INLINE
  1521. zero_vector &operator = (const zero_vector &v) {
  1522. size_ = v.size_;
  1523. return *this;
  1524. }
  1525. BOOST_UBLAS_INLINE
  1526. zero_vector &assign_temporary (zero_vector &v) {
  1527. swap (v);
  1528. return *this;
  1529. }
  1530. // Swapping
  1531. BOOST_UBLAS_INLINE
  1532. void swap (zero_vector &v) {
  1533. if (this != &v) {
  1534. std::swap (size_, v.size_);
  1535. }
  1536. }
  1537. BOOST_UBLAS_INLINE
  1538. friend void swap (zero_vector &v1, zero_vector &v2) {
  1539. v1.swap (v2);
  1540. }
  1541. // Iterator types
  1542. public:
  1543. class const_iterator;
  1544. // Element lookup
  1545. BOOST_UBLAS_INLINE
  1546. const_iterator find (size_type /*i*/) const {
  1547. return const_iterator (*this);
  1548. }
  1549. class const_iterator:
  1550. public container_const_reference<zero_vector>,
  1551. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1552. const_iterator, value_type> {
  1553. public:
  1554. typedef typename zero_vector::difference_type difference_type;
  1555. typedef typename zero_vector::value_type value_type;
  1556. typedef typename zero_vector::const_reference reference;
  1557. typedef typename zero_vector::const_pointer pointer;
  1558. // Construction and destruction
  1559. BOOST_UBLAS_INLINE
  1560. const_iterator ():
  1561. container_const_reference<self_type> () {}
  1562. BOOST_UBLAS_INLINE
  1563. const_iterator (const self_type &v):
  1564. container_const_reference<self_type> (v) {}
  1565. // Arithmetic
  1566. BOOST_UBLAS_INLINE
  1567. const_iterator &operator ++ () {
  1568. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1569. return *this;
  1570. }
  1571. BOOST_UBLAS_INLINE
  1572. const_iterator &operator -- () {
  1573. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1574. return *this;
  1575. }
  1576. // Dereference
  1577. BOOST_UBLAS_INLINE
  1578. const_reference operator * () const {
  1579. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1580. return zero_; // arbitary return value
  1581. }
  1582. // Index
  1583. BOOST_UBLAS_INLINE
  1584. size_type index () const {
  1585. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1586. return 0; // arbitary return value
  1587. }
  1588. // Assignment
  1589. BOOST_UBLAS_INLINE
  1590. const_iterator &operator = (const const_iterator &it) {
  1591. container_const_reference<self_type>::assign (&it ());
  1592. return *this;
  1593. }
  1594. // Comparison
  1595. BOOST_UBLAS_INLINE
  1596. bool operator == (const const_iterator &it) const {
  1597. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1598. detail::ignore_unused_variable_warning(it);
  1599. return true;
  1600. }
  1601. };
  1602. typedef const_iterator iterator;
  1603. BOOST_UBLAS_INLINE
  1604. const_iterator begin () const {
  1605. return const_iterator (*this);
  1606. }
  1607. BOOST_UBLAS_INLINE
  1608. const_iterator cbegin () const {
  1609. return begin ();
  1610. }
  1611. BOOST_UBLAS_INLINE
  1612. const_iterator end () const {
  1613. return const_iterator (*this);
  1614. }
  1615. BOOST_UBLAS_INLINE
  1616. const_iterator cend () const {
  1617. return end ();
  1618. }
  1619. // Reverse iterator
  1620. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1621. BOOST_UBLAS_INLINE
  1622. const_reverse_iterator rbegin () const {
  1623. return const_reverse_iterator (end ());
  1624. }
  1625. BOOST_UBLAS_INLINE
  1626. const_reverse_iterator crbegin () const {
  1627. return rbegin ();
  1628. }
  1629. BOOST_UBLAS_INLINE
  1630. const_reverse_iterator rend () const {
  1631. return const_reverse_iterator (begin ());
  1632. }
  1633. BOOST_UBLAS_INLINE
  1634. const_reverse_iterator crend () const {
  1635. return rend ();
  1636. }
  1637. // Serialization
  1638. template<class Archive>
  1639. void serialize(Archive & ar, const unsigned int /* file_version */){
  1640. serialization::collection_size_type s (size_);
  1641. ar & serialization::make_nvp("size",s);
  1642. if (Archive::is_loading::value) {
  1643. size_ = s;
  1644. }
  1645. }
  1646. private:
  1647. size_type size_;
  1648. typedef const value_type const_value_type;
  1649. static const_value_type zero_;
  1650. };
  1651. template<class T, class ALLOC>
  1652. typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
  1653. // Unit vector class
  1654. /// \brief unit_vector represents a canonical unit vector
  1655. /// 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$.
  1656. /// At construction, the value \e k is given after the dimension of the vector.
  1657. /// \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.
  1658. /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
  1659. template<class T, class ALLOC>
  1660. class unit_vector:
  1661. public vector_container<unit_vector<T, ALLOC> > {
  1662. typedef const T *const_pointer;
  1663. typedef unit_vector<T, ALLOC> self_type;
  1664. public:
  1665. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1666. using vector_container<self_type>::operator ();
  1667. #endif
  1668. typedef typename boost::allocator_size_type<ALLOC>::type size_type;
  1669. typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
  1670. typedef T value_type;
  1671. typedef const T &const_reference;
  1672. typedef T &reference;
  1673. typedef const vector_reference<const self_type> const_closure_type;
  1674. typedef vector_reference<self_type> closure_type;
  1675. typedef sparse_tag storage_category;
  1676. // Construction and destruction
  1677. /// \brief Simple constructor with dimension and index 0
  1678. BOOST_UBLAS_INLINE
  1679. unit_vector ():
  1680. vector_container<self_type> (),
  1681. size_ (0), index_ (0) {}
  1682. /// \brief Constructor of unit_vector
  1683. /// \param size is the dimension of the vector
  1684. /// \param index is the order of the vector
  1685. BOOST_UBLAS_INLINE
  1686. explicit unit_vector (size_type size, size_type index = 0):
  1687. vector_container<self_type> (),
  1688. size_ (size), index_ (index) {}
  1689. /// \brief Copy-constructor
  1690. BOOST_UBLAS_INLINE
  1691. unit_vector (const unit_vector &v):
  1692. vector_container<self_type> (),
  1693. size_ (v.size_), index_ (v.index_) {}
  1694. // Accessors
  1695. //----------
  1696. /// \brief Return the size (dimension) of the vector
  1697. BOOST_UBLAS_INLINE
  1698. size_type size () const {
  1699. return size_;
  1700. }
  1701. /// \brief Return the order of the unit vector
  1702. BOOST_UBLAS_INLINE
  1703. size_type index () const {
  1704. return index_;
  1705. }
  1706. // Resizing
  1707. // --------
  1708. /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
  1709. /// \param size is the new size of the vector
  1710. BOOST_UBLAS_INLINE
  1711. void resize (size_type size, bool /*preserve*/ = true) {
  1712. size_ = size;
  1713. }
  1714. // Element support
  1715. // ---------------
  1716. /// \brief Return a const pointer to the element of index i
  1717. BOOST_UBLAS_INLINE
  1718. const_pointer find_element (size_type i) const {
  1719. if (i == index_)
  1720. return & one_;
  1721. else
  1722. return & zero_;
  1723. }
  1724. // Element access
  1725. BOOST_UBLAS_INLINE
  1726. const_reference operator () (size_type i) const {
  1727. if (i == index_)
  1728. return one_;
  1729. else
  1730. return zero_;
  1731. }
  1732. BOOST_UBLAS_INLINE
  1733. const_reference operator [] (size_type i) const {
  1734. return (*this) (i);
  1735. }
  1736. // Assignment
  1737. BOOST_UBLAS_INLINE
  1738. unit_vector &operator = (const unit_vector &v) {
  1739. size_ = v.size_;
  1740. index_ = v.index_;
  1741. return *this;
  1742. }
  1743. BOOST_UBLAS_INLINE
  1744. unit_vector &assign_temporary (unit_vector &v) {
  1745. swap (v);
  1746. return *this;
  1747. }
  1748. // Swapping
  1749. BOOST_UBLAS_INLINE
  1750. void swap (unit_vector &v) {
  1751. if (this != &v) {
  1752. std::swap (size_, v.size_);
  1753. std::swap (index_, v.index_);
  1754. }
  1755. }
  1756. BOOST_UBLAS_INLINE
  1757. friend void swap (unit_vector &v1, unit_vector &v2) {
  1758. v1.swap (v2);
  1759. }
  1760. // Iterator types
  1761. private:
  1762. // Use bool to indicate begin (one_ as value)
  1763. typedef bool const_subiterator_type;
  1764. public:
  1765. class const_iterator;
  1766. // Element lookup
  1767. BOOST_UBLAS_INLINE
  1768. const_iterator find (size_type i) const {
  1769. return const_iterator (*this, i <= index_);
  1770. }
  1771. class const_iterator:
  1772. public container_const_reference<unit_vector>,
  1773. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1774. const_iterator, value_type> {
  1775. public:
  1776. typedef typename unit_vector::difference_type difference_type;
  1777. typedef typename unit_vector::value_type value_type;
  1778. typedef typename unit_vector::const_reference reference;
  1779. typedef typename unit_vector::const_pointer pointer;
  1780. // Construction and destruction
  1781. BOOST_UBLAS_INLINE
  1782. const_iterator ():
  1783. container_const_reference<unit_vector> (), it_ () {}
  1784. BOOST_UBLAS_INLINE
  1785. const_iterator (const unit_vector &v, const const_subiterator_type &it):
  1786. container_const_reference<unit_vector> (v), it_ (it) {}
  1787. // Arithmetic
  1788. BOOST_UBLAS_INLINE
  1789. const_iterator &operator ++ () {
  1790. BOOST_UBLAS_CHECK (it_, bad_index ());
  1791. it_ = !it_;
  1792. return *this;
  1793. }
  1794. BOOST_UBLAS_INLINE
  1795. const_iterator &operator -- () {
  1796. BOOST_UBLAS_CHECK (!it_, bad_index ());
  1797. it_ = !it_;
  1798. return *this;
  1799. }
  1800. // Dereference
  1801. BOOST_UBLAS_INLINE
  1802. const_reference operator * () const {
  1803. BOOST_UBLAS_CHECK (it_, bad_index ());
  1804. return one_;
  1805. }
  1806. // Index
  1807. BOOST_UBLAS_INLINE
  1808. size_type index () const {
  1809. BOOST_UBLAS_CHECK (it_, bad_index ());
  1810. return (*this) ().index_;
  1811. }
  1812. // Assignment
  1813. BOOST_UBLAS_INLINE
  1814. const_iterator &operator = (const const_iterator &it) {
  1815. container_const_reference<unit_vector>::assign (&it ());
  1816. it_ = it.it_;
  1817. return *this;
  1818. }
  1819. // Comparison
  1820. BOOST_UBLAS_INLINE
  1821. bool operator == (const const_iterator &it) const {
  1822. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1823. return it_ == it.it_;
  1824. }
  1825. private:
  1826. const_subiterator_type it_;
  1827. };
  1828. typedef const_iterator iterator;
  1829. BOOST_UBLAS_INLINE
  1830. const_iterator begin () const {
  1831. return const_iterator (*this, true);
  1832. }
  1833. BOOST_UBLAS_INLINE
  1834. const_iterator cbegin () const {
  1835. return begin ();
  1836. }
  1837. BOOST_UBLAS_INLINE
  1838. const_iterator end () const {
  1839. return const_iterator (*this, false);
  1840. }
  1841. BOOST_UBLAS_INLINE
  1842. const_iterator cend () const {
  1843. return end ();
  1844. }
  1845. // Reverse iterator
  1846. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1847. BOOST_UBLAS_INLINE
  1848. const_reverse_iterator rbegin () const {
  1849. return const_reverse_iterator (end ());
  1850. }
  1851. BOOST_UBLAS_INLINE
  1852. const_reverse_iterator crbegin () const {
  1853. return rbegin ();
  1854. }
  1855. BOOST_UBLAS_INLINE
  1856. const_reverse_iterator rend () const {
  1857. return const_reverse_iterator (begin ());
  1858. }
  1859. BOOST_UBLAS_INLINE
  1860. const_reverse_iterator crend () const {
  1861. return rend ();
  1862. }
  1863. // Serialization
  1864. template<class Archive>
  1865. void serialize(Archive & ar, const unsigned int /* file_version */){
  1866. serialization::collection_size_type s (size_);
  1867. ar & serialization::make_nvp("size",s);
  1868. if (Archive::is_loading::value) {
  1869. size_ = s;
  1870. }
  1871. ar & serialization::make_nvp("index", index_);
  1872. }
  1873. private:
  1874. size_type size_;
  1875. size_type index_;
  1876. typedef const value_type const_value_type;
  1877. static const_value_type zero_;
  1878. static const_value_type one_;
  1879. };
  1880. template<class T, class ALLOC>
  1881. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
  1882. template<class T, class ALLOC>
  1883. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
  1884. /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
  1885. /// 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
  1886. /// 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.
  1887. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  1888. /// \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.
  1889. template<class T, class ALLOC>
  1890. class scalar_vector:
  1891. public vector_container<scalar_vector<T, ALLOC> > {
  1892. typedef const T *const_pointer;
  1893. typedef scalar_vector<T, ALLOC> self_type;
  1894. public:
  1895. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1896. using vector_container<self_type>::operator ();
  1897. #endif
  1898. typedef typename boost::allocator_size_type<ALLOC>::type size_type;
  1899. typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
  1900. typedef T value_type;
  1901. typedef const T &const_reference;
  1902. typedef T &reference;
  1903. typedef const vector_reference<const self_type> const_closure_type;
  1904. typedef vector_reference<self_type> closure_type;
  1905. typedef dense_tag storage_category;
  1906. // Construction and destruction
  1907. BOOST_UBLAS_INLINE
  1908. scalar_vector ():
  1909. vector_container<self_type> (),
  1910. size_ (0), value_ () {}
  1911. BOOST_UBLAS_INLINE
  1912. explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
  1913. vector_container<self_type> (),
  1914. size_ (size), value_ (value) {}
  1915. BOOST_UBLAS_INLINE
  1916. scalar_vector (const scalar_vector &v):
  1917. vector_container<self_type> (),
  1918. size_ (v.size_), value_ (v.value_) {}
  1919. // Accessors
  1920. BOOST_UBLAS_INLINE
  1921. size_type size () const {
  1922. return size_;
  1923. }
  1924. // Resizing
  1925. BOOST_UBLAS_INLINE
  1926. void resize (size_type size, bool /*preserve*/ = true) {
  1927. size_ = size;
  1928. }
  1929. // Element support
  1930. BOOST_UBLAS_INLINE
  1931. const_pointer find_element (size_type /*i*/) const {
  1932. return & value_;
  1933. }
  1934. // Element access
  1935. BOOST_UBLAS_INLINE
  1936. const_reference operator () (size_type /*i*/) const {
  1937. return value_;
  1938. }
  1939. BOOST_UBLAS_INLINE
  1940. const_reference operator [] (size_type /*i*/) const {
  1941. return value_;
  1942. }
  1943. // Assignment
  1944. BOOST_UBLAS_INLINE
  1945. scalar_vector &operator = (const scalar_vector &v) {
  1946. size_ = v.size_;
  1947. value_ = v.value_;
  1948. return *this;
  1949. }
  1950. BOOST_UBLAS_INLINE
  1951. scalar_vector &assign_temporary (scalar_vector &v) {
  1952. swap (v);
  1953. return *this;
  1954. }
  1955. // Swapping
  1956. BOOST_UBLAS_INLINE
  1957. void swap (scalar_vector &v) {
  1958. if (this != &v) {
  1959. std::swap (size_, v.size_);
  1960. std::swap (value_, v.value_);
  1961. }
  1962. }
  1963. BOOST_UBLAS_INLINE
  1964. friend void swap (scalar_vector &v1, scalar_vector &v2) {
  1965. v1.swap (v2);
  1966. }
  1967. // Iterator types
  1968. private:
  1969. // Use an index
  1970. typedef size_type const_subiterator_type;
  1971. public:
  1972. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1973. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1974. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1975. #else
  1976. class const_iterator;
  1977. #endif
  1978. // Element lookup
  1979. BOOST_UBLAS_INLINE
  1980. const_iterator find (size_type i) const {
  1981. return const_iterator (*this, i);
  1982. }
  1983. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1984. class const_iterator:
  1985. public container_const_reference<scalar_vector>,
  1986. public random_access_iterator_base<dense_random_access_iterator_tag,
  1987. const_iterator, value_type> {
  1988. public:
  1989. typedef typename scalar_vector::difference_type difference_type;
  1990. typedef typename scalar_vector::value_type value_type;
  1991. typedef typename scalar_vector::const_reference reference;
  1992. typedef typename scalar_vector::const_pointer pointer;
  1993. // Construction and destruction
  1994. BOOST_UBLAS_INLINE
  1995. const_iterator ():
  1996. container_const_reference<scalar_vector> (), it_ () {}
  1997. BOOST_UBLAS_INLINE
  1998. const_iterator (const scalar_vector &v, const const_subiterator_type &it):
  1999. container_const_reference<scalar_vector> (v), it_ (it) {}
  2000. // Arithmetic
  2001. BOOST_UBLAS_INLINE
  2002. const_iterator &operator ++ () {
  2003. ++ it_;
  2004. return *this;
  2005. }
  2006. BOOST_UBLAS_INLINE
  2007. const_iterator &operator -- () {
  2008. -- it_;
  2009. return *this;
  2010. }
  2011. BOOST_UBLAS_INLINE
  2012. const_iterator &operator += (difference_type n) {
  2013. it_ += n;
  2014. return *this;
  2015. }
  2016. BOOST_UBLAS_INLINE
  2017. const_iterator &operator -= (difference_type n) {
  2018. it_ -= n;
  2019. return *this;
  2020. }
  2021. BOOST_UBLAS_INLINE
  2022. difference_type operator - (const const_iterator &it) const {
  2023. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2024. return it_ - it.it_;
  2025. }
  2026. // Dereference
  2027. BOOST_UBLAS_INLINE
  2028. const_reference operator * () const {
  2029. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  2030. return (*this) () (index ());
  2031. }
  2032. BOOST_UBLAS_INLINE
  2033. const_reference operator [] (difference_type n) const {
  2034. return *(*this + n);
  2035. }
  2036. // Index
  2037. BOOST_UBLAS_INLINE
  2038. size_type index () const {
  2039. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  2040. return it_;
  2041. }
  2042. // Assignment
  2043. BOOST_UBLAS_INLINE
  2044. const_iterator &operator = (const const_iterator &it) {
  2045. container_const_reference<scalar_vector>::assign (&it ());
  2046. it_ = it.it_;
  2047. return *this;
  2048. }
  2049. // Comparison
  2050. BOOST_UBLAS_INLINE
  2051. bool operator == (const const_iterator &it) const {
  2052. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2053. return it_ == it.it_;
  2054. }
  2055. BOOST_UBLAS_INLINE
  2056. bool operator < (const const_iterator &it) const {
  2057. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2058. return it_ < it.it_;
  2059. }
  2060. private:
  2061. const_subiterator_type it_;
  2062. };
  2063. typedef const_iterator iterator;
  2064. #endif
  2065. BOOST_UBLAS_INLINE
  2066. const_iterator begin () const {
  2067. return find (0);
  2068. }
  2069. BOOST_UBLAS_INLINE
  2070. const_iterator cbegin () const {
  2071. return begin ();
  2072. }
  2073. BOOST_UBLAS_INLINE
  2074. const_iterator end () const {
  2075. return find (size_);
  2076. }
  2077. BOOST_UBLAS_INLINE
  2078. const_iterator cend () const {
  2079. return end ();
  2080. }
  2081. // Reverse iterator
  2082. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  2083. BOOST_UBLAS_INLINE
  2084. const_reverse_iterator rbegin () const {
  2085. return const_reverse_iterator (end ());
  2086. }
  2087. BOOST_UBLAS_INLINE
  2088. const_reverse_iterator crbegin () const {
  2089. return rbegin ();
  2090. }
  2091. BOOST_UBLAS_INLINE
  2092. const_reverse_iterator rend () const {
  2093. return const_reverse_iterator (begin ());
  2094. }
  2095. BOOST_UBLAS_INLINE
  2096. const_reverse_iterator crend () const {
  2097. return rend ();
  2098. }
  2099. // Serialization
  2100. template<class Archive>
  2101. void serialize(Archive & ar, const unsigned int /* file_version */){
  2102. serialization::collection_size_type s (size_);
  2103. ar & serialization::make_nvp("size",s);
  2104. if (Archive::is_loading::value) {
  2105. size_ = s;
  2106. }
  2107. ar & serialization::make_nvp("value", value_);
  2108. }
  2109. private:
  2110. size_type size_;
  2111. value_type value_;
  2112. };
  2113. // ------------------------
  2114. // Array based vector class
  2115. // ------------------------
  2116. /// \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]
  2117. template<class T, std::size_t N>
  2118. class c_vector:
  2119. public vector_container<c_vector<T, N> > {
  2120. typedef c_vector<T, N> self_type;
  2121. public:
  2122. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  2123. using vector_container<self_type>::operator ();
  2124. #endif
  2125. typedef std::size_t size_type;
  2126. typedef std::ptrdiff_t difference_type;
  2127. typedef T value_type;
  2128. typedef const T &const_reference;
  2129. typedef T &reference;
  2130. typedef value_type array_type[N];
  2131. typedef T *pointer;
  2132. typedef const T *const_pointer;
  2133. typedef const vector_reference<const self_type> const_closure_type;
  2134. typedef vector_reference<self_type> closure_type;
  2135. typedef self_type vector_temporary_type;
  2136. typedef dense_tag storage_category;
  2137. // Construction and destruction
  2138. BOOST_UBLAS_INLINE
  2139. c_vector ():
  2140. size_ (N) /* , data_ () */ {}
  2141. explicit BOOST_UBLAS_INLINE
  2142. c_vector (size_type size):
  2143. size_ (size) /* , data_ () */ {
  2144. if (size_ > N)
  2145. bad_size ().raise ();
  2146. }
  2147. BOOST_UBLAS_INLINE
  2148. c_vector (const c_vector &v):
  2149. size_ (v.size_) /* , data_ () */ {
  2150. if (size_ > N)
  2151. bad_size ().raise ();
  2152. assign(v);
  2153. }
  2154. template<class AE>
  2155. BOOST_UBLAS_INLINE
  2156. c_vector (const vector_expression<AE> &ae):
  2157. size_ (ae ().size ()) /* , data_ () */ {
  2158. if (size_ > N)
  2159. bad_size ().raise ();
  2160. vector_assign<scalar_assign> (*this, ae);
  2161. }
  2162. // Accessors
  2163. BOOST_UBLAS_INLINE
  2164. size_type size () const {
  2165. return size_;
  2166. }
  2167. BOOST_UBLAS_INLINE
  2168. const_pointer data () const {
  2169. return data_;
  2170. }
  2171. BOOST_UBLAS_INLINE
  2172. pointer data () {
  2173. return data_;
  2174. }
  2175. // Resizing
  2176. BOOST_UBLAS_INLINE
  2177. void resize (size_type size, bool /*preserve*/ = true) {
  2178. if (size > N)
  2179. bad_size ().raise ();
  2180. size_ = size;
  2181. }
  2182. // Element support
  2183. BOOST_UBLAS_INLINE
  2184. pointer find_element (size_type i) {
  2185. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  2186. }
  2187. BOOST_UBLAS_INLINE
  2188. const_pointer find_element (size_type i) const {
  2189. return & data_ [i];
  2190. }
  2191. // Element access
  2192. BOOST_UBLAS_INLINE
  2193. const_reference operator () (size_type i) const {
  2194. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2195. return data_ [i];
  2196. }
  2197. BOOST_UBLAS_INLINE
  2198. reference operator () (size_type i) {
  2199. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2200. return data_ [i];
  2201. }
  2202. BOOST_UBLAS_INLINE
  2203. const_reference operator [] (size_type i) const {
  2204. return (*this) (i);
  2205. }
  2206. BOOST_UBLAS_INLINE
  2207. reference operator [] (size_type i) {
  2208. return (*this) (i);
  2209. }
  2210. // Element assignment
  2211. BOOST_UBLAS_INLINE
  2212. reference insert_element (size_type i, const_reference t) {
  2213. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2214. return (data_ [i] = t);
  2215. }
  2216. BOOST_UBLAS_INLINE
  2217. void erase_element (size_type i) {
  2218. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2219. data_ [i] = value_type/*zero*/();
  2220. }
  2221. // Zeroing
  2222. BOOST_UBLAS_INLINE
  2223. void clear () {
  2224. std::fill (data_, data_ + size_, value_type/*zero*/());
  2225. }
  2226. // Assignment
  2227. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  2228. /*! @note "pass by value" the key idea to enable move semantics */
  2229. BOOST_UBLAS_INLINE
  2230. c_vector &operator = (c_vector v) {
  2231. assign_temporary(v);
  2232. return *this;
  2233. }
  2234. #else
  2235. BOOST_UBLAS_INLINE
  2236. c_vector &operator = (const c_vector &v) {
  2237. size_ = v.size_;
  2238. std::copy (v.data_, v.data_ + v.size_, data_);
  2239. return *this;
  2240. }
  2241. #endif
  2242. template<class C> // Container assignment without temporary
  2243. BOOST_UBLAS_INLINE
  2244. c_vector &operator = (const vector_container<C> &v) {
  2245. resize (v ().size (), false);
  2246. assign (v);
  2247. return *this;
  2248. }
  2249. BOOST_UBLAS_INLINE
  2250. c_vector &assign_temporary (c_vector &v) {
  2251. swap (v);
  2252. return *this;
  2253. }
  2254. template<class AE>
  2255. BOOST_UBLAS_INLINE
  2256. c_vector &operator = (const vector_expression<AE> &ae) {
  2257. self_type temporary (ae);
  2258. return assign_temporary (temporary);
  2259. }
  2260. template<class AE>
  2261. BOOST_UBLAS_INLINE
  2262. c_vector &assign (const vector_expression<AE> &ae) {
  2263. vector_assign<scalar_assign> (*this, ae);
  2264. return *this;
  2265. }
  2266. // Computed assignment
  2267. template<class AE>
  2268. BOOST_UBLAS_INLINE
  2269. c_vector &operator += (const vector_expression<AE> &ae) {
  2270. self_type temporary (*this + ae);
  2271. return assign_temporary (temporary);
  2272. }
  2273. template<class C> // Container assignment without temporary
  2274. BOOST_UBLAS_INLINE
  2275. c_vector &operator += (const vector_container<C> &v) {
  2276. plus_assign (v);
  2277. return *this;
  2278. }
  2279. template<class AE>
  2280. BOOST_UBLAS_INLINE
  2281. c_vector &plus_assign (const vector_expression<AE> &ae) {
  2282. vector_assign<scalar_plus_assign> ( *this, ae);
  2283. return *this;
  2284. }
  2285. template<class AE>
  2286. BOOST_UBLAS_INLINE
  2287. c_vector &operator -= (const vector_expression<AE> &ae) {
  2288. self_type temporary (*this - ae);
  2289. return assign_temporary (temporary);
  2290. }
  2291. template<class C> // Container assignment without temporary
  2292. BOOST_UBLAS_INLINE
  2293. c_vector &operator -= (const vector_container<C> &v) {
  2294. minus_assign (v);
  2295. return *this;
  2296. }
  2297. template<class AE>
  2298. BOOST_UBLAS_INLINE
  2299. c_vector &minus_assign (const vector_expression<AE> &ae) {
  2300. vector_assign<scalar_minus_assign> (*this, ae);
  2301. return *this;
  2302. }
  2303. template<class AT>
  2304. BOOST_UBLAS_INLINE
  2305. c_vector &operator *= (const AT &at) {
  2306. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  2307. return *this;
  2308. }
  2309. template<class AT>
  2310. BOOST_UBLAS_INLINE
  2311. c_vector &operator /= (const AT &at) {
  2312. vector_assign_scalar<scalar_divides_assign> (*this, at);
  2313. return *this;
  2314. }
  2315. // Swapping
  2316. BOOST_UBLAS_INLINE
  2317. void swap (c_vector &v) {
  2318. if (this != &v) {
  2319. BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
  2320. std::swap (size_, v.size_);
  2321. std::swap_ranges (data_, data_ + size_, v.data_);
  2322. }
  2323. }
  2324. BOOST_UBLAS_INLINE
  2325. friend void swap (c_vector &v1, c_vector &v2) {
  2326. v1.swap (v2);
  2327. }
  2328. // Iterator types
  2329. private:
  2330. // Use pointers for iterator
  2331. typedef const_pointer const_subiterator_type;
  2332. typedef pointer subiterator_type;
  2333. public:
  2334. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2335. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  2336. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  2337. #else
  2338. class const_iterator;
  2339. class iterator;
  2340. #endif
  2341. // Element lookup
  2342. BOOST_UBLAS_INLINE
  2343. const_iterator find (size_type i) const {
  2344. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2345. return const_iterator (*this, &data_ [i]);
  2346. #else
  2347. return const_iterator (*this, i);
  2348. #endif
  2349. }
  2350. BOOST_UBLAS_INLINE
  2351. iterator find (size_type i) {
  2352. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2353. return iterator (*this, &data_ [i]);
  2354. #else
  2355. return iterator (*this, i);
  2356. #endif
  2357. }
  2358. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2359. class const_iterator:
  2360. public container_const_reference<c_vector>,
  2361. public random_access_iterator_base<dense_random_access_iterator_tag,
  2362. const_iterator, value_type> {
  2363. public:
  2364. typedef typename c_vector::difference_type difference_type;
  2365. typedef typename c_vector::value_type value_type;
  2366. typedef typename c_vector::const_reference reference;
  2367. typedef typename c_vector::const_pointer pointer;
  2368. // Construction and destruction
  2369. BOOST_UBLAS_INLINE
  2370. const_iterator ():
  2371. container_const_reference<self_type> (), it_ () {}
  2372. BOOST_UBLAS_INLINE
  2373. const_iterator (const self_type &v, const const_subiterator_type &it):
  2374. container_const_reference<self_type> (v), it_ (it) {}
  2375. BOOST_UBLAS_INLINE
  2376. const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
  2377. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  2378. // Arithmetic
  2379. BOOST_UBLAS_INLINE
  2380. const_iterator &operator ++ () {
  2381. ++ it_;
  2382. return *this;
  2383. }
  2384. BOOST_UBLAS_INLINE
  2385. const_iterator &operator -- () {
  2386. -- it_;
  2387. return *this;
  2388. }
  2389. BOOST_UBLAS_INLINE
  2390. const_iterator &operator += (difference_type n) {
  2391. it_ += n;
  2392. return *this;
  2393. }
  2394. BOOST_UBLAS_INLINE
  2395. const_iterator &operator -= (difference_type n) {
  2396. it_ -= n;
  2397. return *this;
  2398. }
  2399. BOOST_UBLAS_INLINE
  2400. difference_type operator - (const const_iterator &it) const {
  2401. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2402. return it_ - it.it_;
  2403. }
  2404. // Dereference
  2405. BOOST_UBLAS_INLINE
  2406. const_reference operator * () const {
  2407. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2408. return *it_;
  2409. }
  2410. BOOST_UBLAS_INLINE
  2411. const_reference operator [] (difference_type n) const {
  2412. return *(it_ + n);
  2413. }
  2414. // Index
  2415. BOOST_UBLAS_INLINE
  2416. size_type index () const {
  2417. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2418. const self_type &v = (*this) ();
  2419. return it_ - v.begin ().it_;
  2420. }
  2421. // Assignment
  2422. BOOST_UBLAS_INLINE
  2423. const_iterator &operator = (const const_iterator &it) {
  2424. container_const_reference<self_type>::assign (&it ());
  2425. it_ = it.it_;
  2426. return *this;
  2427. }
  2428. // Comparison
  2429. BOOST_UBLAS_INLINE
  2430. bool operator == (const const_iterator &it) const {
  2431. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2432. return it_ == it.it_;
  2433. }
  2434. BOOST_UBLAS_INLINE
  2435. bool operator < (const const_iterator &it) const {
  2436. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2437. return it_ < it.it_;
  2438. }
  2439. private:
  2440. const_subiterator_type it_;
  2441. friend class iterator;
  2442. };
  2443. #endif
  2444. BOOST_UBLAS_INLINE
  2445. const_iterator begin () const {
  2446. return find (0);
  2447. }
  2448. BOOST_UBLAS_INLINE
  2449. const_iterator cbegin () const {
  2450. return begin ();
  2451. }
  2452. BOOST_UBLAS_INLINE
  2453. const_iterator end () const {
  2454. return find (size_);
  2455. }
  2456. BOOST_UBLAS_INLINE
  2457. const_iterator cend () const {
  2458. return end ();
  2459. }
  2460. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2461. class iterator:
  2462. public container_reference<c_vector>,
  2463. public random_access_iterator_base<dense_random_access_iterator_tag,
  2464. iterator, value_type> {
  2465. public:
  2466. typedef typename c_vector::difference_type difference_type;
  2467. typedef typename c_vector::value_type value_type;
  2468. typedef typename c_vector::reference reference;
  2469. typedef typename c_vector::pointer pointer;
  2470. // Construction and destruction
  2471. BOOST_UBLAS_INLINE
  2472. iterator ():
  2473. container_reference<self_type> (), it_ () {}
  2474. BOOST_UBLAS_INLINE
  2475. iterator (self_type &v, const subiterator_type &it):
  2476. container_reference<self_type> (v), it_ (it) {}
  2477. // Arithmetic
  2478. BOOST_UBLAS_INLINE
  2479. iterator &operator ++ () {
  2480. ++ it_;
  2481. return *this;
  2482. }
  2483. BOOST_UBLAS_INLINE
  2484. iterator &operator -- () {
  2485. -- it_;
  2486. return *this;
  2487. }
  2488. BOOST_UBLAS_INLINE
  2489. iterator &operator += (difference_type n) {
  2490. it_ += n;
  2491. return *this;
  2492. }
  2493. BOOST_UBLAS_INLINE
  2494. iterator &operator -= (difference_type n) {
  2495. it_ -= n;
  2496. return *this;
  2497. }
  2498. BOOST_UBLAS_INLINE
  2499. difference_type operator - (const iterator &it) const {
  2500. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2501. return it_ - it.it_;
  2502. }
  2503. // Dereference
  2504. BOOST_UBLAS_INLINE
  2505. reference operator * () const {
  2506. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2507. return *it_;
  2508. }
  2509. BOOST_UBLAS_INLINE
  2510. reference operator [] (difference_type n) const {
  2511. return *(it_ + n);
  2512. }
  2513. // Index
  2514. BOOST_UBLAS_INLINE
  2515. size_type index () const {
  2516. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2517. // EDG won't allow const self_type it doesn't allow friend access to it_
  2518. self_type &v = (*this) ();
  2519. return it_ - v.begin ().it_;
  2520. }
  2521. // Assignment
  2522. BOOST_UBLAS_INLINE
  2523. iterator &operator = (const iterator &it) {
  2524. container_reference<self_type>::assign (&it ());
  2525. it_ = it.it_;
  2526. return *this;
  2527. }
  2528. // Comparison
  2529. BOOST_UBLAS_INLINE
  2530. bool operator == (const iterator &it) const {
  2531. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2532. return it_ == it.it_;
  2533. }
  2534. BOOST_UBLAS_INLINE
  2535. bool operator < (const iterator &it) const {
  2536. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2537. return it_ < it.it_;
  2538. }
  2539. private:
  2540. subiterator_type it_;
  2541. friend class const_iterator;
  2542. };
  2543. #endif
  2544. BOOST_UBLAS_INLINE
  2545. iterator begin () {
  2546. return find (0);
  2547. }
  2548. BOOST_UBLAS_INLINE
  2549. iterator end () {
  2550. return find (size_);
  2551. }
  2552. // Reverse iterator
  2553. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  2554. typedef reverse_iterator_base<iterator> reverse_iterator;
  2555. BOOST_UBLAS_INLINE
  2556. const_reverse_iterator rbegin () const {
  2557. return const_reverse_iterator (end ());
  2558. }
  2559. BOOST_UBLAS_INLINE
  2560. const_reverse_iterator crbegin () const {
  2561. return rbegin ();
  2562. }
  2563. BOOST_UBLAS_INLINE
  2564. const_reverse_iterator rend () const {
  2565. return const_reverse_iterator (begin ());
  2566. }
  2567. BOOST_UBLAS_INLINE
  2568. const_reverse_iterator crend () const {
  2569. return rend ();
  2570. }
  2571. BOOST_UBLAS_INLINE
  2572. reverse_iterator rbegin () {
  2573. return reverse_iterator (end ());
  2574. }
  2575. BOOST_UBLAS_INLINE
  2576. reverse_iterator rend () {
  2577. return reverse_iterator (begin ());
  2578. }
  2579. // Serialization
  2580. template<class Archive>
  2581. void serialize(Archive & ar, const unsigned int /* file_version */){
  2582. serialization::collection_size_type s (size_);
  2583. ar & serialization::make_nvp("size",s);
  2584. // copy the value back if loading
  2585. if (Archive::is_loading::value) {
  2586. if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
  2587. size_ = s;
  2588. }
  2589. // ISSUE: this writes the full array
  2590. ar & serialization::make_nvp("data",data_);
  2591. }
  2592. private:
  2593. size_type size_;
  2594. array_type data_;
  2595. };
  2596. }}}
  2597. #endif