vector.hpp 104 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954
  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. #if defined(BOOST_MSVC)
  791. // This may or may not work. Maybe use this for all instead only for MSVC
  792. template <typename... U>
  793. fixed_vector(U&&... values) :
  794. vector_container<self_type> (),
  795. data_{{ std::forward<U>(values)... }} {}
  796. #else
  797. template <typename... Types>
  798. fixed_vector(value_type v0, Types... vrest) :
  799. vector_container<self_type> (),
  800. data_{ { v0, vrest... } } {}
  801. #endif
  802. // -----------------------
  803. // Random Access Container
  804. // -----------------------
  805. /// \brief Return the maximum size of the data container.
  806. /// 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.
  807. BOOST_UBLAS_INLINE
  808. size_type max_size () const {
  809. return data_.max_size ();
  810. }
  811. /// \brief Return true if the vector is empty (\c size==0)
  812. /// \return \c true if empty, \c false otherwise
  813. BOOST_UBLAS_INLINE
  814. const bool &empty () const {
  815. return data_.empty();
  816. }
  817. // ---------
  818. // Accessors
  819. // ---------
  820. /// \brief Return the size of the vector
  821. BOOST_UBLAS_INLINE
  822. BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14
  823. return data_.size ();
  824. }
  825. // -----------------
  826. // Storage accessors
  827. // -----------------
  828. /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
  829. BOOST_UBLAS_INLINE
  830. const array_type &data () const {
  831. return data_;
  832. }
  833. /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
  834. BOOST_UBLAS_INLINE
  835. array_type &data () {
  836. return data_;
  837. }
  838. // ---------------
  839. // Element support
  840. // ---------------
  841. /// \brief Return a 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. pointer find_element (size_type i) {
  846. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  847. }
  848. /// \brief Return a const pointer to the element \f$i\f$
  849. /// \param i index of the element
  850. // XXX this semantic is not the one expected by the name of this method
  851. BOOST_UBLAS_INLINE
  852. const_pointer find_element (size_type i) const {
  853. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds
  854. return & (data () [i]);
  855. }
  856. // --------------
  857. // Element access
  858. // --------------
  859. /// \brief Return a const reference to the element \f$i\f$
  860. /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  861. /// \param i index of the element
  862. BOOST_UBLAS_INLINE
  863. const_reference operator () (size_type i) const {
  864. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  865. return data () [i];
  866. }
  867. /// \brief Return a reference to the element \f$i\f$
  868. /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
  869. /// \param i index of the element
  870. BOOST_UBLAS_INLINE
  871. reference operator () (size_type i) {
  872. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  873. return data () [i];
  874. }
  875. /// \brief Return a const reference to the element \f$i\f$
  876. /// \param i index of the element
  877. BOOST_UBLAS_INLINE
  878. const_reference operator [] (size_type i) const {
  879. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  880. return (*this) (i);
  881. }
  882. /// \brief Return a reference to the element \f$i\f$
  883. /// \param i index of the element
  884. BOOST_UBLAS_INLINE
  885. reference operator [] (size_type i) {
  886. BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
  887. return (*this) (i);
  888. }
  889. // ------------------
  890. // Element assignment
  891. // ------------------
  892. /// \brief Set element \f$i\f$ to the value \c t
  893. /// \param i index of the element
  894. /// \param t reference to the value to be set
  895. // XXX semantic of this is to insert a new element and therefore size=size+1 ?
  896. BOOST_UBLAS_INLINE
  897. reference insert_element (size_type i, const_reference t) {
  898. BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
  899. return (data () [i] = t);
  900. }
  901. /// \brief Set element \f$i\f$ to the \e zero value
  902. /// \param i index of the element
  903. BOOST_UBLAS_INLINE
  904. void erase_element (size_type i) {
  905. BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
  906. data () [i] = value_type/*zero*/();
  907. }
  908. // -------
  909. // Zeroing
  910. // -------
  911. /// \brief Clear the vector, i.e. set all values to the \c zero value.
  912. BOOST_UBLAS_INLINE
  913. void clear () {
  914. std::fill (data ().begin (), data ().end (), value_type/*zero*/());
  915. }
  916. // Assignment
  917. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  918. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  919. /// \param v is the source vector
  920. /// \return a reference to a fixed_vector (i.e. the destination vector)
  921. /*! @note "pass by value" the key idea to enable move semantics */
  922. BOOST_UBLAS_INLINE
  923. fixed_vector &operator = (fixed_vector v) {
  924. assign_temporary(v);
  925. return *this;
  926. }
  927. #else
  928. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  929. /// \param v is the source fixed_vector
  930. /// \return a reference to a fixed_vector (i.e. the destination vector)
  931. BOOST_UBLAS_INLINE
  932. fixed_vector &operator = (const fixed_vector &v) {
  933. data () = v.data ();
  934. return *this;
  935. }
  936. #endif
  937. /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  938. /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary.
  939. /// \param v is the source vector container
  940. /// \return a reference to a vector (i.e. the destination vector)
  941. template<class C> // Container assignment without temporary
  942. BOOST_UBLAS_INLINE
  943. fixed_vector &operator = (const vector_container<C> &v) {
  944. assign (v);
  945. return *this;
  946. }
  947. /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
  948. /// \param v is the source fixed_vector
  949. /// \return a reference to a fixed_vector (i.e. the destination fixed_vector)
  950. BOOST_UBLAS_INLINE
  951. fixed_vector &assign_temporary (fixed_vector &v) {
  952. swap ( v );
  953. return *this;
  954. }
  955. /// \brief Assign the result of a vector_expression to the fixed_vector
  956. /// 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.
  957. /// \tparam AE is the type of the vector_expression
  958. /// \param ae is a const reference to the vector_expression
  959. /// \return a reference to the resulting fixed_vector
  960. template<class AE>
  961. BOOST_UBLAS_INLINE
  962. fixed_vector &operator = (const vector_expression<AE> &ae) {
  963. self_type temporary (ae);
  964. return assign_temporary (temporary);
  965. }
  966. /// \brief Assign the result of a vector_expression to the fixed_vector
  967. /// 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.
  968. /// \tparam AE is the type of the vector_expression
  969. /// \param ae is a const reference to the vector_expression
  970. /// \return a reference to the resulting fixed_vector
  971. template<class AE>
  972. BOOST_UBLAS_INLINE
  973. fixed_vector &assign (const vector_expression<AE> &ae) {
  974. vector_assign<scalar_assign> (*this, ae);
  975. return *this;
  976. }
  977. // -------------------
  978. // Computed assignment
  979. // -------------------
  980. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  981. /// 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.
  982. /// A temporary is created for the computations.
  983. /// \tparam AE is the type of the vector_expression
  984. /// \param ae is a const reference to the vector_expression
  985. /// \return a reference to the resulting fixed_vector
  986. template<class AE>
  987. BOOST_UBLAS_INLINE
  988. fixed_vector &operator += (const vector_expression<AE> &ae) {
  989. self_type temporary (*this + ae);
  990. return assign_temporary (temporary);
  991. }
  992. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  993. /// 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.
  994. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  995. /// \tparam AE is the type of the vector_expression
  996. /// \param ae is a const reference to the vector_expression
  997. /// \return a reference to the resulting vector
  998. template<class C> // Container assignment without temporary
  999. BOOST_UBLAS_INLINE
  1000. fixed_vector &operator += (const vector_container<C> &v) {
  1001. plus_assign (v);
  1002. return *this;
  1003. }
  1004. /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
  1005. /// 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.
  1006. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1007. /// \tparam AE is the type of the vector_expression
  1008. /// \param ae is a const reference to the vector_expression
  1009. /// \return a reference to the resulting vector
  1010. template<class AE>
  1011. BOOST_UBLAS_INLINE
  1012. fixed_vector &plus_assign (const vector_expression<AE> &ae) {
  1013. vector_assign<scalar_plus_assign> (*this, ae);
  1014. return *this;
  1015. }
  1016. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1017. /// 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.
  1018. /// A temporary is created for the computations.
  1019. /// \tparam AE is the type of the vector_expression
  1020. /// \param ae is a const reference to the vector_expression
  1021. template<class AE>
  1022. BOOST_UBLAS_INLINE
  1023. fixed_vector &operator -= (const vector_expression<AE> &ae) {
  1024. self_type temporary (*this - ae);
  1025. return assign_temporary (temporary);
  1026. }
  1027. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1028. /// 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.
  1029. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1030. /// \tparam AE is the type of the vector_expression
  1031. /// \param ae is a const reference to the vector_expression
  1032. /// \return a reference to the resulting vector
  1033. template<class C> // Container assignment without temporary
  1034. BOOST_UBLAS_INLINE
  1035. fixed_vector &operator -= (const vector_container<C> &v) {
  1036. minus_assign (v);
  1037. return *this;
  1038. }
  1039. /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
  1040. /// 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.
  1041. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1042. /// \tparam AE is the type of the vector_expression
  1043. /// \param ae is a const reference to the vector_expression
  1044. /// \return a reference to the resulting fixed_vector
  1045. template<class AE>
  1046. BOOST_UBLAS_INLINE
  1047. fixed_vector &minus_assign (const vector_expression<AE> &ae) {
  1048. vector_assign<scalar_minus_assign> (*this, ae);
  1049. return *this;
  1050. }
  1051. /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector
  1052. /// 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.
  1053. /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
  1054. /// \tparam AE is the type of the vector_expression
  1055. /// \param at is a const reference to the scalar
  1056. /// \return a reference to the resulting fixed_vector
  1057. template<class AT>
  1058. BOOST_UBLAS_INLINE
  1059. fixed_vector &operator *= (const AT &at) {
  1060. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  1061. return *this;
  1062. }
  1063. /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector
  1064. /// 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.
  1065. /// No temporary is created. Computations are done and stored directly into the resulting vector.
  1066. /// \tparam AE is the type of the vector_expression
  1067. /// \param at is a const reference to the scalar
  1068. /// \return a reference to the resulting fixed_vector
  1069. template<class AT>
  1070. BOOST_UBLAS_INLINE
  1071. fixed_vector &operator /= (const AT &at) {
  1072. vector_assign_scalar<scalar_divides_assign> (*this, at);
  1073. return *this;
  1074. }
  1075. // --------
  1076. // Swapping
  1077. // --------
  1078. /// \brief Swap the content of the fixed_vector with another vector
  1079. /// \param v is the fixed_vector to be swapped with
  1080. BOOST_UBLAS_INLINE
  1081. void swap (fixed_vector &v) {
  1082. if (this != &v) {
  1083. data ().swap (v.data ());
  1084. }
  1085. }
  1086. /// \brief Swap the content of two fixed_vectors
  1087. /// \param v1 is the first fixed_vector. It takes values from v2
  1088. /// \param v2 is the second fixed_vector It takes values from v1
  1089. BOOST_UBLAS_INLINE
  1090. friend void swap (fixed_vector &v1, fixed_vector &v2) {
  1091. v1.swap (v2);
  1092. }
  1093. // Iterator types
  1094. private:
  1095. // Use the storage array iterator
  1096. typedef typename A::const_iterator const_subiterator_type;
  1097. typedef typename A::iterator subiterator_type;
  1098. public:
  1099. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1100. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1101. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1102. #else
  1103. class const_iterator;
  1104. class iterator;
  1105. #endif
  1106. // --------------
  1107. // Element lookup
  1108. // --------------
  1109. /// \brief Return a const iterator to the element \e i
  1110. /// \param i index of the element
  1111. BOOST_UBLAS_INLINE
  1112. const_iterator find (size_type i) const {
  1113. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1114. return const_iterator (*this, data ().begin () + i);
  1115. #else
  1116. return const_iterator (*this, i);
  1117. #endif
  1118. }
  1119. /// \brief Return an iterator to the element \e i
  1120. /// \param i index of the element
  1121. BOOST_UBLAS_INLINE
  1122. iterator find (size_type i) {
  1123. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1124. return iterator (*this, data ().begin () + i);
  1125. #else
  1126. return iterator (*this, i);
  1127. #endif
  1128. }
  1129. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1130. class const_iterator:
  1131. public container_const_reference<fixed_vector>,
  1132. public random_access_iterator_base<dense_random_access_iterator_tag,
  1133. const_iterator, value_type, difference_type> {
  1134. public:
  1135. typedef typename fixed_vector::difference_type difference_type;
  1136. typedef typename fixed_vector::value_type value_type;
  1137. typedef typename fixed_vector::const_reference reference;
  1138. typedef const typename fixed_vector::pointer pointer;
  1139. // ----------------------------
  1140. // Construction and destruction
  1141. // ----------------------------
  1142. BOOST_UBLAS_INLINE
  1143. const_iterator ():
  1144. container_const_reference<self_type> (), it_ () {}
  1145. BOOST_UBLAS_INLINE
  1146. const_iterator (const self_type &v, const const_subiterator_type &it):
  1147. container_const_reference<self_type> (v), it_ (it) {}
  1148. BOOST_UBLAS_INLINE
  1149. const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
  1150. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  1151. // ----------
  1152. // Arithmetic
  1153. // ----------
  1154. /// \brief Increment 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 Decrement by 1 the position of the iterator
  1162. /// \return a reference to the const iterator
  1163. BOOST_UBLAS_INLINE
  1164. const_iterator &operator -- () {
  1165. -- it_;
  1166. return *this;
  1167. }
  1168. /// \brief Increment 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 Decrement by \e n the position of the iterator
  1176. /// \return a reference to the const iterator
  1177. BOOST_UBLAS_INLINE
  1178. const_iterator &operator -= (difference_type n) {
  1179. it_ -= n;
  1180. return *this;
  1181. }
  1182. /// \brief Return the different in number of positions between 2 iterators
  1183. BOOST_UBLAS_INLINE
  1184. difference_type operator - (const const_iterator &it) const {
  1185. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1186. return it_ - it.it_;
  1187. }
  1188. /// \brief Dereference an iterator
  1189. /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  1190. /// \return a const reference to the value pointed by the iterator
  1191. BOOST_UBLAS_INLINE
  1192. const_reference operator * () const {
  1193. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1194. return *it_;
  1195. }
  1196. /// \brief Dereference an iterator at the n-th forward value
  1197. /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
  1198. /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
  1199. /// \return a const reference
  1200. BOOST_UBLAS_INLINE
  1201. const_reference operator [] (difference_type n) const {
  1202. return *(it_ + n);
  1203. }
  1204. // Index
  1205. /// \brief return the index of the element referenced by the iterator
  1206. BOOST_UBLAS_INLINE
  1207. size_type index () const {
  1208. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  1209. return it_ - (*this) ().begin ().it_;
  1210. }
  1211. // Assignment
  1212. BOOST_UBLAS_INLINE
  1213. /// \brief assign the value of an iterator to the iterator
  1214. const_iterator &operator = (const const_iterator &it) {
  1215. container_const_reference<self_type>::assign (&it ());
  1216. it_ = it.it_;
  1217. return *this;
  1218. }
  1219. // Comparison
  1220. /// \brief compare the value of two itetarors
  1221. /// \return true if they reference the same element
  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. /// \brief compare the value of two iterators
  1228. /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
  1229. BOOST_UBLAS_INLINE
  1230. bool operator < (const const_iterator &it) const {
  1231. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1232. return it_ < it.it_;
  1233. }
  1234. private:
  1235. const_subiterator_type it_;
  1236. friend class iterator;
  1237. };
  1238. #endif
  1239. /// \brief return an iterator on the first element of the fixed_vector
  1240. BOOST_UBLAS_INLINE
  1241. const_iterator begin () const {
  1242. return find (0);
  1243. }
  1244. /// \brief return an iterator on the first element of the fixed_vector
  1245. BOOST_UBLAS_INLINE
  1246. const_iterator cbegin () const {
  1247. return begin ();
  1248. }
  1249. /// \brief return an iterator after the last element of the fixed_vector
  1250. BOOST_UBLAS_INLINE
  1251. const_iterator end () const {
  1252. return find (data_.size ());
  1253. }
  1254. /// \brief return an iterator after the last element of the fixed_vector
  1255. BOOST_UBLAS_INLINE
  1256. const_iterator cend () const {
  1257. return end ();
  1258. }
  1259. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1260. class iterator:
  1261. public container_reference<fixed_vector>,
  1262. public random_access_iterator_base<dense_random_access_iterator_tag,
  1263. iterator, value_type, difference_type> {
  1264. public:
  1265. typedef typename fixed_vector::difference_type difference_type;
  1266. typedef typename fixed_vector::value_type value_type;
  1267. typedef typename fixed_vector::reference reference;
  1268. typedef typename fixed_vector::pointer pointer;
  1269. // Construction and destruction
  1270. BOOST_UBLAS_INLINE
  1271. iterator ():
  1272. container_reference<self_type> (), it_ () {}
  1273. BOOST_UBLAS_INLINE
  1274. iterator (self_type &v, const subiterator_type &it):
  1275. container_reference<self_type> (v), it_ (it) {}
  1276. // Arithmetic
  1277. BOOST_UBLAS_INLINE
  1278. iterator &operator ++ () {
  1279. ++ it_;
  1280. return *this;
  1281. }
  1282. BOOST_UBLAS_INLINE
  1283. iterator &operator -- () {
  1284. -- it_;
  1285. return *this;
  1286. }
  1287. BOOST_UBLAS_INLINE
  1288. iterator &operator += (difference_type n) {
  1289. it_ += n;
  1290. return *this;
  1291. }
  1292. BOOST_UBLAS_INLINE
  1293. iterator &operator -= (difference_type n) {
  1294. it_ -= n;
  1295. return *this;
  1296. }
  1297. BOOST_UBLAS_INLINE
  1298. difference_type operator - (const iterator &it) const {
  1299. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1300. return it_ - it.it_;
  1301. }
  1302. // Dereference
  1303. BOOST_UBLAS_INLINE
  1304. reference operator * () const {
  1305. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  1306. return *it_;
  1307. }
  1308. BOOST_UBLAS_INLINE
  1309. reference operator [] (difference_type n) const {
  1310. return *(it_ + n);
  1311. }
  1312. // Index
  1313. BOOST_UBLAS_INLINE
  1314. size_type index () const {
  1315. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
  1316. return it_ - (*this) ().begin ().it_;
  1317. }
  1318. // Assignment
  1319. BOOST_UBLAS_INLINE
  1320. iterator &operator = (const iterator &it) {
  1321. container_reference<self_type>::assign (&it ());
  1322. it_ = it.it_;
  1323. return *this;
  1324. }
  1325. // Comparison
  1326. BOOST_UBLAS_INLINE
  1327. bool operator == (const iterator &it) const {
  1328. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1329. return it_ == it.it_;
  1330. }
  1331. BOOST_UBLAS_INLINE
  1332. bool operator < (const iterator &it) const {
  1333. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1334. return it_ < it.it_;
  1335. }
  1336. private:
  1337. subiterator_type it_;
  1338. friend class const_iterator;
  1339. };
  1340. #endif
  1341. /// \brief Return an iterator on the first element of the fixed_vector
  1342. BOOST_UBLAS_INLINE
  1343. iterator begin () {
  1344. return find (0);
  1345. }
  1346. /// \brief Return an iterator at the end of the fixed_vector
  1347. BOOST_UBLAS_INLINE
  1348. iterator end () {
  1349. return find (data_.size ());
  1350. }
  1351. // Reverse iterator
  1352. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1353. typedef reverse_iterator_base<iterator> reverse_iterator;
  1354. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1355. BOOST_UBLAS_INLINE
  1356. const_reverse_iterator rbegin () const {
  1357. return const_reverse_iterator (end ());
  1358. }
  1359. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1360. BOOST_UBLAS_INLINE
  1361. const_reverse_iterator crbegin () const {
  1362. return rbegin ();
  1363. }
  1364. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1365. BOOST_UBLAS_INLINE
  1366. const_reverse_iterator rend () const {
  1367. return const_reverse_iterator (begin ());
  1368. }
  1369. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1370. BOOST_UBLAS_INLINE
  1371. const_reverse_iterator crend () const {
  1372. return rend ();
  1373. }
  1374. /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
  1375. BOOST_UBLAS_INLINE
  1376. reverse_iterator rbegin () {
  1377. return reverse_iterator (end ());
  1378. }
  1379. /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
  1380. BOOST_UBLAS_INLINE
  1381. reverse_iterator rend () {
  1382. return reverse_iterator (begin ());
  1383. }
  1384. // -------------
  1385. // Serialization
  1386. // -------------
  1387. /// Serialize a fixed_vector into and archive as defined in Boost
  1388. /// \param ar Archive object. Can be a flat file, an XML file or any other stream
  1389. /// \param file_version Optional file version (not yet used)
  1390. template<class Archive>
  1391. void serialize(Archive & ar, const unsigned int /* file_version */){
  1392. ar & serialization::make_nvp("data",data_);
  1393. }
  1394. private:
  1395. array_type data_;
  1396. };
  1397. #endif // BOOST_UBLAS_CPP_GE_2011
  1398. // --------------------
  1399. // Bounded vector class
  1400. // --------------------
  1401. /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
  1402. /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor
  1403. /// 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.
  1404. template<class T, std::size_t N>
  1405. class bounded_vector:
  1406. public vector<T, bounded_array<T, N> > {
  1407. typedef vector<T, bounded_array<T, N> > vector_type;
  1408. public:
  1409. typedef typename vector_type::size_type size_type;
  1410. static const size_type max_size = N;
  1411. // Construction and destruction
  1412. BOOST_UBLAS_INLINE
  1413. bounded_vector ():
  1414. vector_type (N) {}
  1415. BOOST_UBLAS_INLINE
  1416. bounded_vector (size_type size):
  1417. vector_type (size) {}
  1418. BOOST_UBLAS_INLINE
  1419. bounded_vector (const bounded_vector &v):
  1420. vector_type (v) {}
  1421. template<class A2> // Allow vector<T,bounded_array<N> construction
  1422. BOOST_UBLAS_INLINE
  1423. bounded_vector (const vector<T, A2> &v):
  1424. vector_type (v) {}
  1425. template<class AE>
  1426. BOOST_UBLAS_INLINE
  1427. bounded_vector (const vector_expression<AE> &ae):
  1428. vector_type (ae) {}
  1429. BOOST_UBLAS_INLINE
  1430. ~bounded_vector () {}
  1431. // Assignment
  1432. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  1433. /*! @note "pass by value" the key idea to enable move semantics */
  1434. BOOST_UBLAS_INLINE
  1435. bounded_vector &operator = (bounded_vector v) {
  1436. vector_type::operator = (v);
  1437. return *this;
  1438. }
  1439. #else
  1440. BOOST_UBLAS_INLINE
  1441. bounded_vector &operator = (const bounded_vector &v) {
  1442. vector_type::operator = (v);
  1443. return *this;
  1444. }
  1445. #endif
  1446. template<class A2> // Generic vector assignment
  1447. BOOST_UBLAS_INLINE
  1448. bounded_vector &operator = (const vector<T, A2> &v) {
  1449. vector_type::operator = (v);
  1450. return *this;
  1451. }
  1452. template<class C> // Container assignment without temporary
  1453. BOOST_UBLAS_INLINE
  1454. bounded_vector &operator = (const vector_container<C> &v) {
  1455. vector_type::operator = (v);
  1456. return *this;
  1457. }
  1458. template<class AE>
  1459. BOOST_UBLAS_INLINE
  1460. bounded_vector &operator = (const vector_expression<AE> &ae) {
  1461. vector_type::operator = (ae);
  1462. return *this;
  1463. }
  1464. };
  1465. // -----------------
  1466. // Zero vector class
  1467. // -----------------
  1468. /// \brief A zero vector of type \c T and a given \c size
  1469. /// 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
  1470. /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
  1471. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  1472. template<class T, class ALLOC>
  1473. class zero_vector:
  1474. public vector_container<zero_vector<T, ALLOC> > {
  1475. typedef const T *const_pointer;
  1476. typedef zero_vector<T, ALLOC> self_type;
  1477. public:
  1478. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1479. using vector_container<self_type>::operator ();
  1480. #endif
  1481. typedef typename ALLOC::size_type size_type;
  1482. typedef typename ALLOC::difference_type difference_type;
  1483. typedef T value_type;
  1484. typedef const T &const_reference;
  1485. typedef T &reference;
  1486. typedef const vector_reference<const self_type> const_closure_type;
  1487. typedef vector_reference<self_type> closure_type;
  1488. typedef sparse_tag storage_category;
  1489. // Construction and destruction
  1490. BOOST_UBLAS_INLINE
  1491. zero_vector ():
  1492. vector_container<self_type> (),
  1493. size_ (0) {}
  1494. explicit BOOST_UBLAS_INLINE
  1495. zero_vector (size_type size):
  1496. vector_container<self_type> (),
  1497. size_ (size) {}
  1498. BOOST_UBLAS_INLINE
  1499. zero_vector (const zero_vector &v):
  1500. vector_container<self_type> (),
  1501. size_ (v.size_) {}
  1502. // Accessors
  1503. BOOST_UBLAS_INLINE
  1504. size_type size () const {
  1505. return size_;
  1506. }
  1507. // Resizing
  1508. BOOST_UBLAS_INLINE
  1509. void resize (size_type size, bool /*preserve*/ = true) {
  1510. size_ = size;
  1511. }
  1512. // Element support
  1513. BOOST_UBLAS_INLINE
  1514. const_pointer find_element (size_type /*i*/) const {
  1515. return & zero_;
  1516. }
  1517. // Element access
  1518. BOOST_UBLAS_INLINE
  1519. const_reference operator () (size_type /* i */) const {
  1520. return zero_;
  1521. }
  1522. BOOST_UBLAS_INLINE
  1523. const_reference operator [] (size_type i) const {
  1524. return (*this) (i);
  1525. }
  1526. // Assignment
  1527. BOOST_UBLAS_INLINE
  1528. zero_vector &operator = (const zero_vector &v) {
  1529. size_ = v.size_;
  1530. return *this;
  1531. }
  1532. BOOST_UBLAS_INLINE
  1533. zero_vector &assign_temporary (zero_vector &v) {
  1534. swap (v);
  1535. return *this;
  1536. }
  1537. // Swapping
  1538. BOOST_UBLAS_INLINE
  1539. void swap (zero_vector &v) {
  1540. if (this != &v) {
  1541. std::swap (size_, v.size_);
  1542. }
  1543. }
  1544. BOOST_UBLAS_INLINE
  1545. friend void swap (zero_vector &v1, zero_vector &v2) {
  1546. v1.swap (v2);
  1547. }
  1548. // Iterator types
  1549. public:
  1550. class const_iterator;
  1551. // Element lookup
  1552. BOOST_UBLAS_INLINE
  1553. const_iterator find (size_type /*i*/) const {
  1554. return const_iterator (*this);
  1555. }
  1556. class const_iterator:
  1557. public container_const_reference<zero_vector>,
  1558. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1559. const_iterator, value_type> {
  1560. public:
  1561. typedef typename zero_vector::difference_type difference_type;
  1562. typedef typename zero_vector::value_type value_type;
  1563. typedef typename zero_vector::const_reference reference;
  1564. typedef typename zero_vector::const_pointer pointer;
  1565. // Construction and destruction
  1566. BOOST_UBLAS_INLINE
  1567. const_iterator ():
  1568. container_const_reference<self_type> () {}
  1569. BOOST_UBLAS_INLINE
  1570. const_iterator (const self_type &v):
  1571. container_const_reference<self_type> (v) {}
  1572. // Arithmetic
  1573. BOOST_UBLAS_INLINE
  1574. const_iterator &operator ++ () {
  1575. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1576. return *this;
  1577. }
  1578. BOOST_UBLAS_INLINE
  1579. const_iterator &operator -- () {
  1580. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1581. return *this;
  1582. }
  1583. // Dereference
  1584. BOOST_UBLAS_INLINE
  1585. const_reference operator * () const {
  1586. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1587. return zero_; // arbitary return value
  1588. }
  1589. // Index
  1590. BOOST_UBLAS_INLINE
  1591. size_type index () const {
  1592. BOOST_UBLAS_CHECK_FALSE (bad_index ());
  1593. return 0; // arbitary return value
  1594. }
  1595. // Assignment
  1596. BOOST_UBLAS_INLINE
  1597. const_iterator &operator = (const const_iterator &it) {
  1598. container_const_reference<self_type>::assign (&it ());
  1599. return *this;
  1600. }
  1601. // Comparison
  1602. BOOST_UBLAS_INLINE
  1603. bool operator == (const const_iterator &it) const {
  1604. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1605. detail::ignore_unused_variable_warning(it);
  1606. return true;
  1607. }
  1608. };
  1609. typedef const_iterator iterator;
  1610. BOOST_UBLAS_INLINE
  1611. const_iterator begin () const {
  1612. return const_iterator (*this);
  1613. }
  1614. BOOST_UBLAS_INLINE
  1615. const_iterator cbegin () const {
  1616. return begin ();
  1617. }
  1618. BOOST_UBLAS_INLINE
  1619. const_iterator end () const {
  1620. return const_iterator (*this);
  1621. }
  1622. BOOST_UBLAS_INLINE
  1623. const_iterator cend () const {
  1624. return end ();
  1625. }
  1626. // Reverse iterator
  1627. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1628. BOOST_UBLAS_INLINE
  1629. const_reverse_iterator rbegin () const {
  1630. return const_reverse_iterator (end ());
  1631. }
  1632. BOOST_UBLAS_INLINE
  1633. const_reverse_iterator crbegin () const {
  1634. return rbegin ();
  1635. }
  1636. BOOST_UBLAS_INLINE
  1637. const_reverse_iterator rend () const {
  1638. return const_reverse_iterator (begin ());
  1639. }
  1640. BOOST_UBLAS_INLINE
  1641. const_reverse_iterator crend () const {
  1642. return rend ();
  1643. }
  1644. // Serialization
  1645. template<class Archive>
  1646. void serialize(Archive & ar, const unsigned int /* file_version */){
  1647. serialization::collection_size_type s (size_);
  1648. ar & serialization::make_nvp("size",s);
  1649. if (Archive::is_loading::value) {
  1650. size_ = s;
  1651. }
  1652. }
  1653. private:
  1654. size_type size_;
  1655. typedef const value_type const_value_type;
  1656. static const_value_type zero_;
  1657. };
  1658. template<class T, class ALLOC>
  1659. typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
  1660. // Unit vector class
  1661. /// \brief unit_vector represents a canonical unit vector
  1662. /// 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$.
  1663. /// At construction, the value \e k is given after the dimension of the vector.
  1664. /// \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.
  1665. /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
  1666. template<class T, class ALLOC>
  1667. class unit_vector:
  1668. public vector_container<unit_vector<T, ALLOC> > {
  1669. typedef const T *const_pointer;
  1670. typedef unit_vector<T, ALLOC> self_type;
  1671. public:
  1672. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1673. using vector_container<self_type>::operator ();
  1674. #endif
  1675. typedef typename ALLOC::size_type size_type;
  1676. typedef typename ALLOC::difference_type difference_type;
  1677. typedef T value_type;
  1678. typedef const T &const_reference;
  1679. typedef T &reference;
  1680. typedef const vector_reference<const self_type> const_closure_type;
  1681. typedef vector_reference<self_type> closure_type;
  1682. typedef sparse_tag storage_category;
  1683. // Construction and destruction
  1684. /// \brief Simple constructor with dimension and index 0
  1685. BOOST_UBLAS_INLINE
  1686. unit_vector ():
  1687. vector_container<self_type> (),
  1688. size_ (0), index_ (0) {}
  1689. /// \brief Constructor of unit_vector
  1690. /// \param size is the dimension of the vector
  1691. /// \param index is the order of the vector
  1692. BOOST_UBLAS_INLINE
  1693. explicit unit_vector (size_type size, size_type index = 0):
  1694. vector_container<self_type> (),
  1695. size_ (size), index_ (index) {}
  1696. /// \brief Copy-constructor
  1697. BOOST_UBLAS_INLINE
  1698. unit_vector (const unit_vector &v):
  1699. vector_container<self_type> (),
  1700. size_ (v.size_), index_ (v.index_) {}
  1701. // Accessors
  1702. //----------
  1703. /// \brief Return the size (dimension) of the vector
  1704. BOOST_UBLAS_INLINE
  1705. size_type size () const {
  1706. return size_;
  1707. }
  1708. /// \brief Return the order of the unit vector
  1709. BOOST_UBLAS_INLINE
  1710. size_type index () const {
  1711. return index_;
  1712. }
  1713. // Resizing
  1714. // --------
  1715. /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
  1716. /// \param size is the new size of the vector
  1717. BOOST_UBLAS_INLINE
  1718. void resize (size_type size, bool /*preserve*/ = true) {
  1719. size_ = size;
  1720. }
  1721. // Element support
  1722. // ---------------
  1723. /// \brief Return a const pointer to the element of index i
  1724. BOOST_UBLAS_INLINE
  1725. const_pointer find_element (size_type i) const {
  1726. if (i == index_)
  1727. return & one_;
  1728. else
  1729. return & zero_;
  1730. }
  1731. // Element access
  1732. BOOST_UBLAS_INLINE
  1733. const_reference operator () (size_type i) const {
  1734. if (i == index_)
  1735. return one_;
  1736. else
  1737. return zero_;
  1738. }
  1739. BOOST_UBLAS_INLINE
  1740. const_reference operator [] (size_type i) const {
  1741. return (*this) (i);
  1742. }
  1743. // Assignment
  1744. BOOST_UBLAS_INLINE
  1745. unit_vector &operator = (const unit_vector &v) {
  1746. size_ = v.size_;
  1747. index_ = v.index_;
  1748. return *this;
  1749. }
  1750. BOOST_UBLAS_INLINE
  1751. unit_vector &assign_temporary (unit_vector &v) {
  1752. swap (v);
  1753. return *this;
  1754. }
  1755. // Swapping
  1756. BOOST_UBLAS_INLINE
  1757. void swap (unit_vector &v) {
  1758. if (this != &v) {
  1759. std::swap (size_, v.size_);
  1760. std::swap (index_, v.index_);
  1761. }
  1762. }
  1763. BOOST_UBLAS_INLINE
  1764. friend void swap (unit_vector &v1, unit_vector &v2) {
  1765. v1.swap (v2);
  1766. }
  1767. // Iterator types
  1768. private:
  1769. // Use bool to indicate begin (one_ as value)
  1770. typedef bool const_subiterator_type;
  1771. public:
  1772. class const_iterator;
  1773. // Element lookup
  1774. BOOST_UBLAS_INLINE
  1775. const_iterator find (size_type i) const {
  1776. return const_iterator (*this, i <= index_);
  1777. }
  1778. class const_iterator:
  1779. public container_const_reference<unit_vector>,
  1780. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1781. const_iterator, value_type> {
  1782. public:
  1783. typedef typename unit_vector::difference_type difference_type;
  1784. typedef typename unit_vector::value_type value_type;
  1785. typedef typename unit_vector::const_reference reference;
  1786. typedef typename unit_vector::const_pointer pointer;
  1787. // Construction and destruction
  1788. BOOST_UBLAS_INLINE
  1789. const_iterator ():
  1790. container_const_reference<unit_vector> (), it_ () {}
  1791. BOOST_UBLAS_INLINE
  1792. const_iterator (const unit_vector &v, const const_subiterator_type &it):
  1793. container_const_reference<unit_vector> (v), it_ (it) {}
  1794. // Arithmetic
  1795. BOOST_UBLAS_INLINE
  1796. const_iterator &operator ++ () {
  1797. BOOST_UBLAS_CHECK (it_, bad_index ());
  1798. it_ = !it_;
  1799. return *this;
  1800. }
  1801. BOOST_UBLAS_INLINE
  1802. const_iterator &operator -- () {
  1803. BOOST_UBLAS_CHECK (!it_, bad_index ());
  1804. it_ = !it_;
  1805. return *this;
  1806. }
  1807. // Dereference
  1808. BOOST_UBLAS_INLINE
  1809. const_reference operator * () const {
  1810. BOOST_UBLAS_CHECK (it_, bad_index ());
  1811. return one_;
  1812. }
  1813. // Index
  1814. BOOST_UBLAS_INLINE
  1815. size_type index () const {
  1816. BOOST_UBLAS_CHECK (it_, bad_index ());
  1817. return (*this) ().index_;
  1818. }
  1819. // Assignment
  1820. BOOST_UBLAS_INLINE
  1821. const_iterator &operator = (const const_iterator &it) {
  1822. container_const_reference<unit_vector>::assign (&it ());
  1823. it_ = it.it_;
  1824. return *this;
  1825. }
  1826. // Comparison
  1827. BOOST_UBLAS_INLINE
  1828. bool operator == (const const_iterator &it) const {
  1829. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1830. return it_ == it.it_;
  1831. }
  1832. private:
  1833. const_subiterator_type it_;
  1834. };
  1835. typedef const_iterator iterator;
  1836. BOOST_UBLAS_INLINE
  1837. const_iterator begin () const {
  1838. return const_iterator (*this, true);
  1839. }
  1840. BOOST_UBLAS_INLINE
  1841. const_iterator cbegin () const {
  1842. return begin ();
  1843. }
  1844. BOOST_UBLAS_INLINE
  1845. const_iterator end () const {
  1846. return const_iterator (*this, false);
  1847. }
  1848. BOOST_UBLAS_INLINE
  1849. const_iterator cend () const {
  1850. return end ();
  1851. }
  1852. // Reverse iterator
  1853. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  1854. BOOST_UBLAS_INLINE
  1855. const_reverse_iterator rbegin () const {
  1856. return const_reverse_iterator (end ());
  1857. }
  1858. BOOST_UBLAS_INLINE
  1859. const_reverse_iterator crbegin () const {
  1860. return rbegin ();
  1861. }
  1862. BOOST_UBLAS_INLINE
  1863. const_reverse_iterator rend () const {
  1864. return const_reverse_iterator (begin ());
  1865. }
  1866. BOOST_UBLAS_INLINE
  1867. const_reverse_iterator crend () const {
  1868. return rend ();
  1869. }
  1870. // Serialization
  1871. template<class Archive>
  1872. void serialize(Archive & ar, const unsigned int /* file_version */){
  1873. serialization::collection_size_type s (size_);
  1874. ar & serialization::make_nvp("size",s);
  1875. if (Archive::is_loading::value) {
  1876. size_ = s;
  1877. }
  1878. ar & serialization::make_nvp("index", index_);
  1879. }
  1880. private:
  1881. size_type size_;
  1882. size_type index_;
  1883. typedef const value_type const_value_type;
  1884. static const_value_type zero_;
  1885. static const_value_type one_;
  1886. };
  1887. template<class T, class ALLOC>
  1888. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
  1889. template<class T, class ALLOC>
  1890. typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
  1891. /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
  1892. /// 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
  1893. /// 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.
  1894. /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
  1895. /// \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.
  1896. template<class T, class ALLOC>
  1897. class scalar_vector:
  1898. public vector_container<scalar_vector<T, ALLOC> > {
  1899. typedef const T *const_pointer;
  1900. typedef scalar_vector<T, ALLOC> self_type;
  1901. public:
  1902. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  1903. using vector_container<self_type>::operator ();
  1904. #endif
  1905. typedef typename ALLOC::size_type size_type;
  1906. typedef typename ALLOC::difference_type difference_type;
  1907. typedef T value_type;
  1908. typedef const T &const_reference;
  1909. typedef T &reference;
  1910. typedef const vector_reference<const self_type> const_closure_type;
  1911. typedef vector_reference<self_type> closure_type;
  1912. typedef dense_tag storage_category;
  1913. // Construction and destruction
  1914. BOOST_UBLAS_INLINE
  1915. scalar_vector ():
  1916. vector_container<self_type> (),
  1917. size_ (0), value_ () {}
  1918. BOOST_UBLAS_INLINE
  1919. explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
  1920. vector_container<self_type> (),
  1921. size_ (size), value_ (value) {}
  1922. BOOST_UBLAS_INLINE
  1923. scalar_vector (const scalar_vector &v):
  1924. vector_container<self_type> (),
  1925. size_ (v.size_), value_ (v.value_) {}
  1926. // Accessors
  1927. BOOST_UBLAS_INLINE
  1928. size_type size () const {
  1929. return size_;
  1930. }
  1931. // Resizing
  1932. BOOST_UBLAS_INLINE
  1933. void resize (size_type size, bool /*preserve*/ = true) {
  1934. size_ = size;
  1935. }
  1936. // Element support
  1937. BOOST_UBLAS_INLINE
  1938. const_pointer find_element (size_type /*i*/) const {
  1939. return & value_;
  1940. }
  1941. // Element access
  1942. BOOST_UBLAS_INLINE
  1943. const_reference operator () (size_type /*i*/) const {
  1944. return value_;
  1945. }
  1946. BOOST_UBLAS_INLINE
  1947. const_reference operator [] (size_type /*i*/) const {
  1948. return value_;
  1949. }
  1950. // Assignment
  1951. BOOST_UBLAS_INLINE
  1952. scalar_vector &operator = (const scalar_vector &v) {
  1953. size_ = v.size_;
  1954. value_ = v.value_;
  1955. return *this;
  1956. }
  1957. BOOST_UBLAS_INLINE
  1958. scalar_vector &assign_temporary (scalar_vector &v) {
  1959. swap (v);
  1960. return *this;
  1961. }
  1962. // Swapping
  1963. BOOST_UBLAS_INLINE
  1964. void swap (scalar_vector &v) {
  1965. if (this != &v) {
  1966. std::swap (size_, v.size_);
  1967. std::swap (value_, v.value_);
  1968. }
  1969. }
  1970. BOOST_UBLAS_INLINE
  1971. friend void swap (scalar_vector &v1, scalar_vector &v2) {
  1972. v1.swap (v2);
  1973. }
  1974. // Iterator types
  1975. private:
  1976. // Use an index
  1977. typedef size_type const_subiterator_type;
  1978. public:
  1979. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1980. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
  1981. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  1982. #else
  1983. class const_iterator;
  1984. #endif
  1985. // Element lookup
  1986. BOOST_UBLAS_INLINE
  1987. const_iterator find (size_type i) const {
  1988. return const_iterator (*this, i);
  1989. }
  1990. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  1991. class const_iterator:
  1992. public container_const_reference<scalar_vector>,
  1993. public random_access_iterator_base<dense_random_access_iterator_tag,
  1994. const_iterator, value_type> {
  1995. public:
  1996. typedef typename scalar_vector::difference_type difference_type;
  1997. typedef typename scalar_vector::value_type value_type;
  1998. typedef typename scalar_vector::const_reference reference;
  1999. typedef typename scalar_vector::const_pointer pointer;
  2000. // Construction and destruction
  2001. BOOST_UBLAS_INLINE
  2002. const_iterator ():
  2003. container_const_reference<scalar_vector> (), it_ () {}
  2004. BOOST_UBLAS_INLINE
  2005. const_iterator (const scalar_vector &v, const const_subiterator_type &it):
  2006. container_const_reference<scalar_vector> (v), it_ (it) {}
  2007. // Arithmetic
  2008. BOOST_UBLAS_INLINE
  2009. const_iterator &operator ++ () {
  2010. ++ it_;
  2011. return *this;
  2012. }
  2013. BOOST_UBLAS_INLINE
  2014. const_iterator &operator -- () {
  2015. -- it_;
  2016. return *this;
  2017. }
  2018. BOOST_UBLAS_INLINE
  2019. const_iterator &operator += (difference_type n) {
  2020. it_ += n;
  2021. return *this;
  2022. }
  2023. BOOST_UBLAS_INLINE
  2024. const_iterator &operator -= (difference_type n) {
  2025. it_ -= n;
  2026. return *this;
  2027. }
  2028. BOOST_UBLAS_INLINE
  2029. difference_type operator - (const const_iterator &it) const {
  2030. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2031. return it_ - it.it_;
  2032. }
  2033. // Dereference
  2034. BOOST_UBLAS_INLINE
  2035. const_reference operator * () const {
  2036. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  2037. return (*this) () (index ());
  2038. }
  2039. BOOST_UBLAS_INLINE
  2040. const_reference operator [] (difference_type n) const {
  2041. return *(*this + n);
  2042. }
  2043. // Index
  2044. BOOST_UBLAS_INLINE
  2045. size_type index () const {
  2046. BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
  2047. return it_;
  2048. }
  2049. // Assignment
  2050. BOOST_UBLAS_INLINE
  2051. const_iterator &operator = (const const_iterator &it) {
  2052. container_const_reference<scalar_vector>::assign (&it ());
  2053. it_ = it.it_;
  2054. return *this;
  2055. }
  2056. // Comparison
  2057. BOOST_UBLAS_INLINE
  2058. bool operator == (const const_iterator &it) const {
  2059. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2060. return it_ == it.it_;
  2061. }
  2062. BOOST_UBLAS_INLINE
  2063. bool operator < (const const_iterator &it) const {
  2064. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2065. return it_ < it.it_;
  2066. }
  2067. private:
  2068. const_subiterator_type it_;
  2069. };
  2070. typedef const_iterator iterator;
  2071. #endif
  2072. BOOST_UBLAS_INLINE
  2073. const_iterator begin () const {
  2074. return find (0);
  2075. }
  2076. BOOST_UBLAS_INLINE
  2077. const_iterator cbegin () const {
  2078. return begin ();
  2079. }
  2080. BOOST_UBLAS_INLINE
  2081. const_iterator end () const {
  2082. return find (size_);
  2083. }
  2084. BOOST_UBLAS_INLINE
  2085. const_iterator cend () const {
  2086. return end ();
  2087. }
  2088. // Reverse iterator
  2089. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  2090. BOOST_UBLAS_INLINE
  2091. const_reverse_iterator rbegin () const {
  2092. return const_reverse_iterator (end ());
  2093. }
  2094. BOOST_UBLAS_INLINE
  2095. const_reverse_iterator crbegin () const {
  2096. return rbegin ();
  2097. }
  2098. BOOST_UBLAS_INLINE
  2099. const_reverse_iterator rend () const {
  2100. return const_reverse_iterator (begin ());
  2101. }
  2102. BOOST_UBLAS_INLINE
  2103. const_reverse_iterator crend () const {
  2104. return rend ();
  2105. }
  2106. // Serialization
  2107. template<class Archive>
  2108. void serialize(Archive & ar, const unsigned int /* file_version */){
  2109. serialization::collection_size_type s (size_);
  2110. ar & serialization::make_nvp("size",s);
  2111. if (Archive::is_loading::value) {
  2112. size_ = s;
  2113. }
  2114. ar & serialization::make_nvp("value", value_);
  2115. }
  2116. private:
  2117. size_type size_;
  2118. value_type value_;
  2119. };
  2120. // ------------------------
  2121. // Array based vector class
  2122. // ------------------------
  2123. /// \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]
  2124. template<class T, std::size_t N>
  2125. class c_vector:
  2126. public vector_container<c_vector<T, N> > {
  2127. typedef c_vector<T, N> self_type;
  2128. public:
  2129. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  2130. using vector_container<self_type>::operator ();
  2131. #endif
  2132. typedef std::size_t size_type;
  2133. typedef std::ptrdiff_t difference_type;
  2134. typedef T value_type;
  2135. typedef const T &const_reference;
  2136. typedef T &reference;
  2137. typedef value_type array_type[N];
  2138. typedef T *pointer;
  2139. typedef const T *const_pointer;
  2140. typedef const vector_reference<const self_type> const_closure_type;
  2141. typedef vector_reference<self_type> closure_type;
  2142. typedef self_type vector_temporary_type;
  2143. typedef dense_tag storage_category;
  2144. // Construction and destruction
  2145. BOOST_UBLAS_INLINE
  2146. c_vector ():
  2147. size_ (N) /* , data_ () */ {}
  2148. explicit BOOST_UBLAS_INLINE
  2149. c_vector (size_type size):
  2150. size_ (size) /* , data_ () */ {
  2151. if (size_ > N)
  2152. bad_size ().raise ();
  2153. }
  2154. BOOST_UBLAS_INLINE
  2155. c_vector (const c_vector &v):
  2156. size_ (v.size_) /* , data_ () */ {
  2157. if (size_ > N)
  2158. bad_size ().raise ();
  2159. assign(v);
  2160. }
  2161. template<class AE>
  2162. BOOST_UBLAS_INLINE
  2163. c_vector (const vector_expression<AE> &ae):
  2164. size_ (ae ().size ()) /* , data_ () */ {
  2165. if (size_ > N)
  2166. bad_size ().raise ();
  2167. vector_assign<scalar_assign> (*this, ae);
  2168. }
  2169. // Accessors
  2170. BOOST_UBLAS_INLINE
  2171. size_type size () const {
  2172. return size_;
  2173. }
  2174. BOOST_UBLAS_INLINE
  2175. const_pointer data () const {
  2176. return data_;
  2177. }
  2178. BOOST_UBLAS_INLINE
  2179. pointer data () {
  2180. return data_;
  2181. }
  2182. // Resizing
  2183. BOOST_UBLAS_INLINE
  2184. void resize (size_type size, bool /*preserve*/ = true) {
  2185. if (size > N)
  2186. bad_size ().raise ();
  2187. size_ = size;
  2188. }
  2189. // Element support
  2190. BOOST_UBLAS_INLINE
  2191. pointer find_element (size_type i) {
  2192. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
  2193. }
  2194. BOOST_UBLAS_INLINE
  2195. const_pointer find_element (size_type i) const {
  2196. return & data_ [i];
  2197. }
  2198. // Element access
  2199. BOOST_UBLAS_INLINE
  2200. const_reference operator () (size_type i) const {
  2201. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2202. return data_ [i];
  2203. }
  2204. BOOST_UBLAS_INLINE
  2205. reference operator () (size_type i) {
  2206. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2207. return data_ [i];
  2208. }
  2209. BOOST_UBLAS_INLINE
  2210. const_reference operator [] (size_type i) const {
  2211. return (*this) (i);
  2212. }
  2213. BOOST_UBLAS_INLINE
  2214. reference operator [] (size_type i) {
  2215. return (*this) (i);
  2216. }
  2217. // Element assignment
  2218. BOOST_UBLAS_INLINE
  2219. reference insert_element (size_type i, const_reference t) {
  2220. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2221. return (data_ [i] = t);
  2222. }
  2223. BOOST_UBLAS_INLINE
  2224. void erase_element (size_type i) {
  2225. BOOST_UBLAS_CHECK (i < size_, bad_index ());
  2226. data_ [i] = value_type/*zero*/();
  2227. }
  2228. // Zeroing
  2229. BOOST_UBLAS_INLINE
  2230. void clear () {
  2231. std::fill (data_, data_ + size_, value_type/*zero*/());
  2232. }
  2233. // Assignment
  2234. #ifdef BOOST_UBLAS_MOVE_SEMANTICS
  2235. /*! @note "pass by value" the key idea to enable move semantics */
  2236. BOOST_UBLAS_INLINE
  2237. c_vector &operator = (c_vector v) {
  2238. assign_temporary(v);
  2239. return *this;
  2240. }
  2241. #else
  2242. BOOST_UBLAS_INLINE
  2243. c_vector &operator = (const c_vector &v) {
  2244. size_ = v.size_;
  2245. std::copy (v.data_, v.data_ + v.size_, data_);
  2246. return *this;
  2247. }
  2248. #endif
  2249. template<class C> // Container assignment without temporary
  2250. BOOST_UBLAS_INLINE
  2251. c_vector &operator = (const vector_container<C> &v) {
  2252. resize (v ().size (), false);
  2253. assign (v);
  2254. return *this;
  2255. }
  2256. BOOST_UBLAS_INLINE
  2257. c_vector &assign_temporary (c_vector &v) {
  2258. swap (v);
  2259. return *this;
  2260. }
  2261. template<class AE>
  2262. BOOST_UBLAS_INLINE
  2263. c_vector &operator = (const vector_expression<AE> &ae) {
  2264. self_type temporary (ae);
  2265. return assign_temporary (temporary);
  2266. }
  2267. template<class AE>
  2268. BOOST_UBLAS_INLINE
  2269. c_vector &assign (const vector_expression<AE> &ae) {
  2270. vector_assign<scalar_assign> (*this, ae);
  2271. return *this;
  2272. }
  2273. // Computed assignment
  2274. template<class AE>
  2275. BOOST_UBLAS_INLINE
  2276. c_vector &operator += (const vector_expression<AE> &ae) {
  2277. self_type temporary (*this + ae);
  2278. return assign_temporary (temporary);
  2279. }
  2280. template<class C> // Container assignment without temporary
  2281. BOOST_UBLAS_INLINE
  2282. c_vector &operator += (const vector_container<C> &v) {
  2283. plus_assign (v);
  2284. return *this;
  2285. }
  2286. template<class AE>
  2287. BOOST_UBLAS_INLINE
  2288. c_vector &plus_assign (const vector_expression<AE> &ae) {
  2289. vector_assign<scalar_plus_assign> ( *this, ae);
  2290. return *this;
  2291. }
  2292. template<class AE>
  2293. BOOST_UBLAS_INLINE
  2294. c_vector &operator -= (const vector_expression<AE> &ae) {
  2295. self_type temporary (*this - ae);
  2296. return assign_temporary (temporary);
  2297. }
  2298. template<class C> // Container assignment without temporary
  2299. BOOST_UBLAS_INLINE
  2300. c_vector &operator -= (const vector_container<C> &v) {
  2301. minus_assign (v);
  2302. return *this;
  2303. }
  2304. template<class AE>
  2305. BOOST_UBLAS_INLINE
  2306. c_vector &minus_assign (const vector_expression<AE> &ae) {
  2307. vector_assign<scalar_minus_assign> (*this, ae);
  2308. return *this;
  2309. }
  2310. template<class AT>
  2311. BOOST_UBLAS_INLINE
  2312. c_vector &operator *= (const AT &at) {
  2313. vector_assign_scalar<scalar_multiplies_assign> (*this, at);
  2314. return *this;
  2315. }
  2316. template<class AT>
  2317. BOOST_UBLAS_INLINE
  2318. c_vector &operator /= (const AT &at) {
  2319. vector_assign_scalar<scalar_divides_assign> (*this, at);
  2320. return *this;
  2321. }
  2322. // Swapping
  2323. BOOST_UBLAS_INLINE
  2324. void swap (c_vector &v) {
  2325. if (this != &v) {
  2326. BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
  2327. std::swap (size_, v.size_);
  2328. std::swap_ranges (data_, data_ + size_, v.data_);
  2329. }
  2330. }
  2331. BOOST_UBLAS_INLINE
  2332. friend void swap (c_vector &v1, c_vector &v2) {
  2333. v1.swap (v2);
  2334. }
  2335. // Iterator types
  2336. private:
  2337. // Use pointers for iterator
  2338. typedef const_pointer const_subiterator_type;
  2339. typedef pointer subiterator_type;
  2340. public:
  2341. #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2342. typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
  2343. typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
  2344. #else
  2345. class const_iterator;
  2346. class iterator;
  2347. #endif
  2348. // Element lookup
  2349. BOOST_UBLAS_INLINE
  2350. const_iterator find (size_type i) const {
  2351. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2352. return const_iterator (*this, &data_ [i]);
  2353. #else
  2354. return const_iterator (*this, i);
  2355. #endif
  2356. }
  2357. BOOST_UBLAS_INLINE
  2358. iterator find (size_type i) {
  2359. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2360. return iterator (*this, &data_ [i]);
  2361. #else
  2362. return iterator (*this, i);
  2363. #endif
  2364. }
  2365. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2366. class const_iterator:
  2367. public container_const_reference<c_vector>,
  2368. public random_access_iterator_base<dense_random_access_iterator_tag,
  2369. const_iterator, value_type> {
  2370. public:
  2371. typedef typename c_vector::difference_type difference_type;
  2372. typedef typename c_vector::value_type value_type;
  2373. typedef typename c_vector::const_reference reference;
  2374. typedef typename c_vector::const_pointer pointer;
  2375. // Construction and destruction
  2376. BOOST_UBLAS_INLINE
  2377. const_iterator ():
  2378. container_const_reference<self_type> (), it_ () {}
  2379. BOOST_UBLAS_INLINE
  2380. const_iterator (const self_type &v, const const_subiterator_type &it):
  2381. container_const_reference<self_type> (v), it_ (it) {}
  2382. BOOST_UBLAS_INLINE
  2383. const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
  2384. container_const_reference<self_type> (it ()), it_ (it.it_) {}
  2385. // Arithmetic
  2386. BOOST_UBLAS_INLINE
  2387. const_iterator &operator ++ () {
  2388. ++ it_;
  2389. return *this;
  2390. }
  2391. BOOST_UBLAS_INLINE
  2392. const_iterator &operator -- () {
  2393. -- it_;
  2394. return *this;
  2395. }
  2396. BOOST_UBLAS_INLINE
  2397. const_iterator &operator += (difference_type n) {
  2398. it_ += n;
  2399. return *this;
  2400. }
  2401. BOOST_UBLAS_INLINE
  2402. const_iterator &operator -= (difference_type n) {
  2403. it_ -= n;
  2404. return *this;
  2405. }
  2406. BOOST_UBLAS_INLINE
  2407. difference_type operator - (const const_iterator &it) const {
  2408. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2409. return it_ - it.it_;
  2410. }
  2411. // Dereference
  2412. BOOST_UBLAS_INLINE
  2413. const_reference operator * () const {
  2414. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2415. return *it_;
  2416. }
  2417. BOOST_UBLAS_INLINE
  2418. const_reference operator [] (difference_type n) const {
  2419. return *(it_ + n);
  2420. }
  2421. // Index
  2422. BOOST_UBLAS_INLINE
  2423. size_type index () const {
  2424. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2425. const self_type &v = (*this) ();
  2426. return it_ - v.begin ().it_;
  2427. }
  2428. // Assignment
  2429. BOOST_UBLAS_INLINE
  2430. const_iterator &operator = (const const_iterator &it) {
  2431. container_const_reference<self_type>::assign (&it ());
  2432. it_ = it.it_;
  2433. return *this;
  2434. }
  2435. // Comparison
  2436. BOOST_UBLAS_INLINE
  2437. bool operator == (const const_iterator &it) const {
  2438. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2439. return it_ == it.it_;
  2440. }
  2441. BOOST_UBLAS_INLINE
  2442. bool operator < (const const_iterator &it) const {
  2443. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2444. return it_ < it.it_;
  2445. }
  2446. private:
  2447. const_subiterator_type it_;
  2448. friend class iterator;
  2449. };
  2450. #endif
  2451. BOOST_UBLAS_INLINE
  2452. const_iterator begin () const {
  2453. return find (0);
  2454. }
  2455. BOOST_UBLAS_INLINE
  2456. const_iterator cbegin () const {
  2457. return begin ();
  2458. }
  2459. BOOST_UBLAS_INLINE
  2460. const_iterator end () const {
  2461. return find (size_);
  2462. }
  2463. BOOST_UBLAS_INLINE
  2464. const_iterator cend () const {
  2465. return end ();
  2466. }
  2467. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
  2468. class iterator:
  2469. public container_reference<c_vector>,
  2470. public random_access_iterator_base<dense_random_access_iterator_tag,
  2471. iterator, value_type> {
  2472. public:
  2473. typedef typename c_vector::difference_type difference_type;
  2474. typedef typename c_vector::value_type value_type;
  2475. typedef typename c_vector::reference reference;
  2476. typedef typename c_vector::pointer pointer;
  2477. // Construction and destruction
  2478. BOOST_UBLAS_INLINE
  2479. iterator ():
  2480. container_reference<self_type> (), it_ () {}
  2481. BOOST_UBLAS_INLINE
  2482. iterator (self_type &v, const subiterator_type &it):
  2483. container_reference<self_type> (v), it_ (it) {}
  2484. // Arithmetic
  2485. BOOST_UBLAS_INLINE
  2486. iterator &operator ++ () {
  2487. ++ it_;
  2488. return *this;
  2489. }
  2490. BOOST_UBLAS_INLINE
  2491. iterator &operator -- () {
  2492. -- it_;
  2493. return *this;
  2494. }
  2495. BOOST_UBLAS_INLINE
  2496. iterator &operator += (difference_type n) {
  2497. it_ += n;
  2498. return *this;
  2499. }
  2500. BOOST_UBLAS_INLINE
  2501. iterator &operator -= (difference_type n) {
  2502. it_ -= n;
  2503. return *this;
  2504. }
  2505. BOOST_UBLAS_INLINE
  2506. difference_type operator - (const iterator &it) const {
  2507. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2508. return it_ - it.it_;
  2509. }
  2510. // Dereference
  2511. BOOST_UBLAS_INLINE
  2512. reference operator * () const {
  2513. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2514. return *it_;
  2515. }
  2516. BOOST_UBLAS_INLINE
  2517. reference operator [] (difference_type n) const {
  2518. return *(it_ + n);
  2519. }
  2520. // Index
  2521. BOOST_UBLAS_INLINE
  2522. size_type index () const {
  2523. BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
  2524. // EDG won't allow const self_type it doesn't allow friend access to it_
  2525. self_type &v = (*this) ();
  2526. return it_ - v.begin ().it_;
  2527. }
  2528. // Assignment
  2529. BOOST_UBLAS_INLINE
  2530. iterator &operator = (const iterator &it) {
  2531. container_reference<self_type>::assign (&it ());
  2532. it_ = it.it_;
  2533. return *this;
  2534. }
  2535. // Comparison
  2536. BOOST_UBLAS_INLINE
  2537. bool operator == (const iterator &it) const {
  2538. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2539. return it_ == it.it_;
  2540. }
  2541. BOOST_UBLAS_INLINE
  2542. bool operator < (const iterator &it) const {
  2543. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  2544. return it_ < it.it_;
  2545. }
  2546. private:
  2547. subiterator_type it_;
  2548. friend class const_iterator;
  2549. };
  2550. #endif
  2551. BOOST_UBLAS_INLINE
  2552. iterator begin () {
  2553. return find (0);
  2554. }
  2555. BOOST_UBLAS_INLINE
  2556. iterator end () {
  2557. return find (size_);
  2558. }
  2559. // Reverse iterator
  2560. typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
  2561. typedef reverse_iterator_base<iterator> reverse_iterator;
  2562. BOOST_UBLAS_INLINE
  2563. const_reverse_iterator rbegin () const {
  2564. return const_reverse_iterator (end ());
  2565. }
  2566. BOOST_UBLAS_INLINE
  2567. const_reverse_iterator crbegin () const {
  2568. return rbegin ();
  2569. }
  2570. BOOST_UBLAS_INLINE
  2571. const_reverse_iterator rend () const {
  2572. return const_reverse_iterator (begin ());
  2573. }
  2574. BOOST_UBLAS_INLINE
  2575. const_reverse_iterator crend () const {
  2576. return rend ();
  2577. }
  2578. BOOST_UBLAS_INLINE
  2579. reverse_iterator rbegin () {
  2580. return reverse_iterator (end ());
  2581. }
  2582. BOOST_UBLAS_INLINE
  2583. reverse_iterator rend () {
  2584. return reverse_iterator (begin ());
  2585. }
  2586. // Serialization
  2587. template<class Archive>
  2588. void serialize(Archive & ar, const unsigned int /* file_version */){
  2589. serialization::collection_size_type s (size_);
  2590. ar & serialization::make_nvp("size",s);
  2591. // copy the value back if loading
  2592. if (Archive::is_loading::value) {
  2593. if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
  2594. size_ = s;
  2595. }
  2596. // ISSUE: this writes the full array
  2597. ar & serialization::make_nvp("data",data_);
  2598. }
  2599. private:
  2600. size_type size_;
  2601. array_type data_;
  2602. };
  2603. }}}
  2604. #endif