vector_of_vector.hpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347
  1. //
  2. // Copyright (c) 2003
  3. // Gunter Winkler, Joerg Walter
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // The authors gratefully acknowledge the support of
  10. // GeNeSys mbH & Co. KG in producing this work.
  11. //
  12. #ifndef _BOOST_UBLAS_VECTOR_OF_VECTOR_
  13. #define _BOOST_UBLAS_VECTOR_OF_VECTOR_
  14. #include <boost/type_traits.hpp>
  15. #include <boost/numeric/ublas/storage_sparse.hpp>
  16. #include <boost/numeric/ublas/matrix_sparse.hpp>
  17. // Iterators based on ideas of Jeremy Siek
  18. namespace boost { namespace numeric { namespace ublas {
  19. // uBLAS sparse vector based sparse matrix class
  20. // FIXME outer vector can be sparse type but it is completely filled
  21. template<class T, class L, class A>
  22. class generalized_vector_of_vector:
  23. public matrix_container<generalized_vector_of_vector<T, L, A> > {
  24. typedef T &true_reference;
  25. typedef T *pointer;
  26. typedef const T *const_pointer;
  27. typedef L layout_type;
  28. typedef generalized_vector_of_vector<T, L, A> self_type;
  29. public:
  30. #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
  31. using matrix_container<self_type>::operator ();
  32. #endif
  33. typedef typename A::size_type size_type;
  34. typedef typename A::difference_type difference_type;
  35. typedef T value_type;
  36. typedef const T &const_reference;
  37. #ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
  38. typedef T &reference;
  39. #else
  40. typedef sparse_matrix_element<self_type> reference;
  41. #endif
  42. typedef A array_type;
  43. typedef const matrix_reference<const self_type> const_closure_type;
  44. typedef matrix_reference<self_type> closure_type;
  45. typedef typename A::value_type vector_data_value_type;
  46. typedef vector_data_value_type vector_temporary_type;
  47. typedef self_type matrix_temporary_type;
  48. typedef sparse_tag storage_category;
  49. typedef typename L::orientation_category orientation_category;
  50. // Construction and destruction
  51. BOOST_UBLAS_INLINE
  52. generalized_vector_of_vector ():
  53. matrix_container<self_type> (),
  54. size1_ (0), size2_ (0), data_ (1) {
  55. const size_type sizeM = layout_type::size_M (size1_, size2_);
  56. // create size1+1 empty vector elements
  57. data_.insert_element (sizeM, vector_data_value_type ());
  58. storage_invariants ();
  59. }
  60. BOOST_UBLAS_INLINE
  61. generalized_vector_of_vector (size_type size1, size_type size2, size_type /*non_zeros = 0*/):
  62. matrix_container<self_type> (),
  63. size1_ (size1), size2_ (size2), data_ (layout_type::size_M (size1_, size2_) + 1) {
  64. const size_type sizeM = layout_type::size_M (size1_, size2_);
  65. const size_type sizem = layout_type::size_m (size1_, size2_);
  66. for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements
  67. data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
  68. data_.insert_element (sizeM, vector_data_value_type ());
  69. storage_invariants ();
  70. }
  71. BOOST_UBLAS_INLINE
  72. generalized_vector_of_vector (const generalized_vector_of_vector &m):
  73. matrix_container<self_type> (),
  74. size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {
  75. storage_invariants ();
  76. }
  77. template<class AE>
  78. BOOST_UBLAS_INLINE
  79. generalized_vector_of_vector (const matrix_expression<AE> &ae, size_type /*non_zeros = 0*/):
  80. matrix_container<self_type> (),
  81. size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
  82. const size_type sizeM = layout_type::size_M (size1_, size2_);
  83. const size_type sizem = layout_type::size_m (size1_, size2_);
  84. for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements
  85. data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
  86. data_.insert_element (sizeM, vector_data_value_type ());
  87. storage_invariants ();
  88. matrix_assign<scalar_assign> (*this, ae);
  89. }
  90. // Accessors
  91. BOOST_UBLAS_INLINE
  92. size_type size1 () const {
  93. return size1_;
  94. }
  95. BOOST_UBLAS_INLINE
  96. size_type size2 () const {
  97. return size2_;
  98. }
  99. BOOST_UBLAS_INLINE
  100. size_type nnz_capacity () const {
  101. size_type non_zeros = 0;
  102. for (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)
  103. non_zeros += (*itv).nnz_capacity ();
  104. return non_zeros;
  105. }
  106. BOOST_UBLAS_INLINE
  107. size_type nnz () const {
  108. size_type non_zeros = 0;
  109. for (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)
  110. non_zeros += (*itv).nnz ();
  111. return non_zeros;
  112. }
  113. // Storage accessors
  114. BOOST_UBLAS_INLINE
  115. const array_type &data () const {
  116. return data_;
  117. }
  118. BOOST_UBLAS_INLINE
  119. array_type &data () {
  120. return data_;
  121. }
  122. // Resizing
  123. BOOST_UBLAS_INLINE
  124. void resize (size_type size1, size_type size2, bool preserve = true) {
  125. const size_type oldM = layout_type::size_M (size1_, size2_);
  126. size1_ = size1;
  127. size2_ = size2;
  128. const size_type sizeM = layout_type::size_M (size1_, size2_);
  129. const size_type sizem = layout_type::size_m (size1_, size2_);
  130. data ().resize (sizeM + 1, preserve);
  131. if (preserve) {
  132. for (size_type i = 0; (i <= oldM) && (i < sizeM); ++ i)
  133. ref (data () [i]).resize (sizem, preserve);
  134. for (size_type i = oldM+1; i < sizeM; ++ i) // create new vector elements
  135. data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
  136. if (sizeM > oldM) {
  137. data_.insert_element (sizeM, vector_data_value_type ());
  138. } else {
  139. ref (data () [sizeM]).resize (0, false);
  140. }
  141. } else {
  142. for (size_type i = 0; i < sizeM; ++ i)
  143. data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
  144. data_.insert_element (sizeM, vector_data_value_type ());
  145. }
  146. storage_invariants ();
  147. }
  148. // Element support
  149. BOOST_UBLAS_INLINE
  150. pointer find_element (size_type i, size_type j) {
  151. return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
  152. }
  153. BOOST_UBLAS_INLINE
  154. const_pointer find_element (size_type i, size_type j) const {
  155. const size_type elementM = layout_type::index_M (i, j);
  156. const size_type elementm = layout_type::index_m (i, j);
  157. // optimise: check the storage_type and index directly if element always exists
  158. if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {
  159. return & (data () [elementM] [elementm]);
  160. }
  161. else {
  162. const typename array_type::value_type *pv = data ().find_element (elementM);
  163. if (!pv)
  164. return 0;
  165. return pv->find_element (elementm);
  166. }
  167. }
  168. // Element access
  169. BOOST_UBLAS_INLINE
  170. const_reference operator () (size_type i, size_type j) const {
  171. const_pointer p = find_element (i, j);
  172. // optimise: check the storage_type and index directly if element always exists
  173. if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {
  174. BOOST_UBLAS_CHECK (p, internal_logic () );
  175. return *p;
  176. }
  177. else {
  178. if (p)
  179. return *p;
  180. else
  181. return zero_;
  182. }
  183. }
  184. BOOST_UBLAS_INLINE
  185. reference operator () (size_type i, size_type j) {
  186. #ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
  187. return at_element (i, j);
  188. #else
  189. return reference (*this, i, j);
  190. #endif
  191. }
  192. // Assignment
  193. BOOST_UBLAS_INLINE
  194. generalized_vector_of_vector &operator = (const generalized_vector_of_vector &m) {
  195. if (this != &m) {
  196. size1_ = m.size1_;
  197. size2_ = m.size2_;
  198. data () = m.data ();
  199. }
  200. storage_invariants ();
  201. return *this;
  202. }
  203. BOOST_UBLAS_INLINE
  204. generalized_vector_of_vector &assign_temporary (generalized_vector_of_vector &m) {
  205. swap (m);
  206. return *this;
  207. }
  208. template<class AE>
  209. BOOST_UBLAS_INLINE
  210. generalized_vector_of_vector &operator = (const matrix_expression<AE> &ae) {
  211. self_type temporary (ae);
  212. return assign_temporary (temporary);
  213. }
  214. template<class AE>
  215. BOOST_UBLAS_INLINE
  216. generalized_vector_of_vector &assign (const matrix_expression<AE> &ae) {
  217. matrix_assign<scalar_assign> (*this, ae);
  218. return *this;
  219. }
  220. template<class AE>
  221. BOOST_UBLAS_INLINE
  222. generalized_vector_of_vector& operator += (const matrix_expression<AE> &ae) {
  223. self_type temporary (*this + ae);
  224. return assign_temporary (temporary);
  225. }
  226. template<class AE>
  227. BOOST_UBLAS_INLINE
  228. generalized_vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {
  229. matrix_assign<scalar_plus_assign> (*this, ae);
  230. return *this;
  231. }
  232. template<class AE>
  233. BOOST_UBLAS_INLINE
  234. generalized_vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
  235. self_type temporary (*this - ae);
  236. return assign_temporary (temporary);
  237. }
  238. template<class AE>
  239. BOOST_UBLAS_INLINE
  240. generalized_vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
  241. matrix_assign<scalar_minus_assign> (*this, ae);
  242. return *this;
  243. }
  244. template<class AT>
  245. BOOST_UBLAS_INLINE
  246. generalized_vector_of_vector& operator *= (const AT &at) {
  247. matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
  248. return *this;
  249. }
  250. template<class AT>
  251. BOOST_UBLAS_INLINE
  252. generalized_vector_of_vector& operator /= (const AT &at) {
  253. matrix_assign_scalar<scalar_divides_assign> (*this, at);
  254. return *this;
  255. }
  256. // Swapping
  257. BOOST_UBLAS_INLINE
  258. void swap (generalized_vector_of_vector &m) {
  259. if (this != &m) {
  260. std::swap (size1_, m.size1_);
  261. std::swap (size2_, m.size2_);
  262. data ().swap (m.data ());
  263. }
  264. storage_invariants ();
  265. }
  266. BOOST_UBLAS_INLINE
  267. friend void swap (generalized_vector_of_vector &m1, generalized_vector_of_vector &m2) {
  268. m1.swap (m2);
  269. }
  270. // Sorting
  271. void sort () {
  272. vectoriterator_type itv (data ().begin ());
  273. vectoriterator_type itv_end (data ().end ());
  274. while (itv != itv_end) {
  275. (*itv).sort ();
  276. ++ itv;
  277. }
  278. }
  279. // Element insertion and erasure
  280. BOOST_UBLAS_INLINE
  281. true_reference insert_element (size_type i, size_type j, const_reference t) {
  282. const size_type elementM = layout_type::index_M (i, j);
  283. const size_type elementm = layout_type::index_m (i, j);
  284. vector_data_value_type& vd (ref (data () [elementM]));
  285. storage_invariants ();
  286. return vd.insert_element (elementm, t);
  287. }
  288. BOOST_UBLAS_INLINE
  289. void append_element (size_type i, size_type j, const_reference t) {
  290. const size_type elementM = layout_type::index_M (i, j);
  291. const size_type elementm = layout_type::index_m (i, j);
  292. vector_data_value_type& vd (ref (data () [elementM]));
  293. storage_invariants ();
  294. return vd.append_element (elementm, t);
  295. }
  296. BOOST_UBLAS_INLINE
  297. void erase_element (size_type i, size_type j) {
  298. vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
  299. if (itv == data ().end ())
  300. return;
  301. (*itv).erase_element (layout_type::index_m (i, j));
  302. storage_invariants ();
  303. }
  304. BOOST_UBLAS_INLINE
  305. void clear () {
  306. const size_type sizeM = layout_type::size_M (size1_, size2_);
  307. // FIXME should clear data () if this is done via value_type/*zero*/() then it is not size preserving
  308. for (size_type i = 0; i < sizeM; ++ i)
  309. ref (data () [i]).clear ();
  310. storage_invariants ();
  311. }
  312. // Iterator types
  313. private:
  314. // Use vector iterator
  315. typedef typename A::const_iterator const_vectoriterator_type;
  316. typedef typename A::iterator vectoriterator_type;
  317. typedef typename A::value_type::const_iterator const_subiterator_type;
  318. typedef typename A::value_type::iterator subiterator_type;
  319. BOOST_UBLAS_INLINE
  320. true_reference at_element (size_type i, size_type j) {
  321. return ref (ref (data () [layout_type::index_M (i, j)]) [layout_type::index_m (i, j)]);
  322. }
  323. public:
  324. class const_iterator1;
  325. class iterator1;
  326. class const_iterator2;
  327. class iterator2;
  328. typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
  329. typedef reverse_iterator_base1<iterator1> reverse_iterator1;
  330. typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
  331. typedef reverse_iterator_base2<iterator2> reverse_iterator2;
  332. // Element lookup
  333. // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
  334. const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
  335. for (;;) {
  336. const_vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
  337. const_vectoriterator_type itv_end (data ().end ());
  338. if (itv == itv_end)
  339. return const_iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
  340. const_subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
  341. const_subiterator_type it_end ((*itv).end ());
  342. if (rank == 0)
  343. return const_iterator1 (*this, rank, i, j, itv, it);
  344. if (it != it_end && it.index () == layout_type::index_m (i, j))
  345. return const_iterator1 (*this, rank, i, j, itv, it);
  346. if (direction > 0) {
  347. if (layout_type::fast_i ()) {
  348. if (it == it_end)
  349. return const_iterator1 (*this, rank, i, j, itv, it);
  350. i = it.index ();
  351. } else {
  352. if (i >= size1_)
  353. return const_iterator1 (*this, rank, i, j, itv, it);
  354. ++ i;
  355. }
  356. } else /* if (direction < 0) */ {
  357. if (layout_type::fast_i ()) {
  358. if (it == (*itv).begin ())
  359. return const_iterator1 (*this, rank, i, j, itv, it);
  360. --it;
  361. i = it.index ();
  362. } else {
  363. if (i == 0)
  364. return const_iterator1 (*this, rank, i, j, itv, it);
  365. -- i;
  366. }
  367. }
  368. }
  369. }
  370. // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
  371. iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
  372. for (;;) {
  373. vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
  374. vectoriterator_type itv_end (data ().end ());
  375. if (itv == itv_end)
  376. return iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
  377. subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
  378. subiterator_type it_end ((*itv).end ());
  379. if (rank == 0)
  380. return iterator1 (*this, rank, i, j, itv, it);
  381. if (it != it_end && it.index () == layout_type::index_m (i, j))
  382. return iterator1 (*this, rank, i, j, itv, it);
  383. if (direction > 0) {
  384. if (layout_type::fast_i ()) {
  385. if (it == it_end)
  386. return iterator1 (*this, rank, i, j, itv, it);
  387. i = it.index ();
  388. } else {
  389. if (i >= size1_)
  390. return iterator1 (*this, rank, i, j, itv, it);
  391. ++ i;
  392. }
  393. } else /* if (direction < 0) */ {
  394. if (layout_type::fast_i ()) {
  395. if (it == (*itv).begin ())
  396. return iterator1 (*this, rank, i, j, itv, it);
  397. --it;
  398. i = it.index ();
  399. } else {
  400. if (i == 0)
  401. return iterator1 (*this, rank, i, j, itv, it);
  402. -- i;
  403. }
  404. }
  405. }
  406. }
  407. // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
  408. const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
  409. for (;;) {
  410. const_vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
  411. const_vectoriterator_type itv_end (data ().end ());
  412. if (itv == itv_end)
  413. return const_iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
  414. const_subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
  415. const_subiterator_type it_end ((*itv).end ());
  416. if (rank == 0)
  417. return const_iterator2 (*this, rank, i, j, itv, it);
  418. if (it != it_end && it.index () == layout_type::index_m (i, j))
  419. return const_iterator2 (*this, rank, i, j, itv, it);
  420. if (direction > 0) {
  421. if (layout_type::fast_j ()) {
  422. if (it == it_end)
  423. return const_iterator2 (*this, rank, i, j, itv, it);
  424. j = it.index ();
  425. } else {
  426. if (j >= size2_)
  427. return const_iterator2 (*this, rank, i, j, itv, it);
  428. ++ j;
  429. }
  430. } else /* if (direction < 0) */ {
  431. if (layout_type::fast_j ()) {
  432. if (it == (*itv).begin ())
  433. return const_iterator2 (*this, rank, i, j, itv, it);
  434. --it;
  435. j = it.index ();
  436. } else {
  437. if (j == 0)
  438. return const_iterator2 (*this, rank, i, j, itv, it);
  439. -- j;
  440. }
  441. }
  442. }
  443. }
  444. // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
  445. iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
  446. for (;;) {
  447. vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
  448. vectoriterator_type itv_end (data ().end ());
  449. if (itv == itv_end)
  450. return iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
  451. subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
  452. subiterator_type it_end ((*itv).end ());
  453. if (rank == 0)
  454. return iterator2 (*this, rank, i, j, itv, it);
  455. if (it != it_end && it.index () == layout_type::index_m (i, j))
  456. return iterator2 (*this, rank, i, j, itv, it);
  457. if (direction > 0) {
  458. if (layout_type::fast_j ()) {
  459. if (it == it_end)
  460. return iterator2 (*this, rank, i, j, itv, it);
  461. j = it.index ();
  462. } else {
  463. if (j >= size2_)
  464. return iterator2 (*this, rank, i, j, itv, it);
  465. ++ j;
  466. }
  467. } else /* if (direction < 0) */ {
  468. if (layout_type::fast_j ()) {
  469. if (it == (*itv).begin ())
  470. return iterator2 (*this, rank, i, j, itv, it);
  471. --it;
  472. j = it.index ();
  473. } else {
  474. if (j == 0)
  475. return iterator2 (*this, rank, i, j, itv, it);
  476. -- j;
  477. }
  478. }
  479. }
  480. }
  481. class const_iterator1:
  482. public container_const_reference<generalized_vector_of_vector>,
  483. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  484. const_iterator1, value_type> {
  485. public:
  486. typedef typename generalized_vector_of_vector::difference_type difference_type;
  487. typedef typename generalized_vector_of_vector::value_type value_type;
  488. typedef typename generalized_vector_of_vector::const_reference reference;
  489. typedef const typename generalized_vector_of_vector::pointer pointer;
  490. typedef const_iterator2 dual_iterator_type;
  491. typedef const_reverse_iterator2 dual_reverse_iterator_type;
  492. // Construction and destruction
  493. BOOST_UBLAS_INLINE
  494. const_iterator1 ():
  495. container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
  496. BOOST_UBLAS_INLINE
  497. const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const const_vectoriterator_type &itv, const const_subiterator_type &it):
  498. container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
  499. BOOST_UBLAS_INLINE
  500. const_iterator1 (const iterator1 &it):
  501. container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
  502. // Arithmetic
  503. BOOST_UBLAS_INLINE
  504. const_iterator1 &operator ++ () {
  505. if (rank_ == 1 && layout_type::fast_i ())
  506. ++ it_;
  507. else {
  508. const self_type &m = (*this) ();
  509. i_ = index1 () + 1;
  510. if (rank_ == 1 && ++ itv_ == m.end1 ().itv_)
  511. *this = m.find1 (rank_, i_, j_, 1);
  512. else if (rank_ == 1) {
  513. it_ = (*itv_).begin ();
  514. if (it_ == (*itv_).end () || index2 () != j_)
  515. *this = m.find1 (rank_, i_, j_, 1);
  516. }
  517. }
  518. return *this;
  519. }
  520. BOOST_UBLAS_INLINE
  521. const_iterator1 &operator -- () {
  522. if (rank_ == 1 && layout_type::fast_i ())
  523. -- it_;
  524. else {
  525. const self_type &m = (*this) ();
  526. i_ = index1 () - 1;
  527. if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
  528. *this = m.find1 (rank_, i_, j_, -1);
  529. else if (rank_ == 1) {
  530. it_ = (*itv_).begin ();
  531. if (it_ == (*itv_).end () || index2 () != j_)
  532. *this = m.find1 (rank_, i_, j_, -1);
  533. }
  534. }
  535. return *this;
  536. }
  537. // Dereference
  538. BOOST_UBLAS_INLINE
  539. const_reference operator * () const {
  540. BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
  541. BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
  542. if (rank_ == 1) {
  543. return *it_;
  544. } else {
  545. return (*this) () (i_, j_);
  546. }
  547. }
  548. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  549. BOOST_UBLAS_INLINE
  550. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  551. typename self_type::
  552. #endif
  553. const_iterator2 begin () const {
  554. const self_type &m = (*this) ();
  555. return m.find2 (1, index1 (), 0);
  556. }
  557. BOOST_UBLAS_INLINE
  558. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  559. typename self_type::
  560. #endif
  561. const_iterator2 cbegin () const {
  562. return begin ();
  563. }
  564. BOOST_UBLAS_INLINE
  565. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  566. typename self_type::
  567. #endif
  568. const_iterator2 end () const {
  569. const self_type &m = (*this) ();
  570. return m.find2 (1, index1 (), m.size2 ());
  571. }
  572. BOOST_UBLAS_INLINE
  573. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  574. typename self_type::
  575. #endif
  576. const_iterator2 cend () const {
  577. return end ();
  578. }
  579. BOOST_UBLAS_INLINE
  580. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  581. typename self_type::
  582. #endif
  583. const_reverse_iterator2 rbegin () const {
  584. return const_reverse_iterator2 (end ());
  585. }
  586. BOOST_UBLAS_INLINE
  587. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  588. typename self_type::
  589. #endif
  590. const_reverse_iterator2 crbegin () const {
  591. return rbegin ();
  592. }
  593. BOOST_UBLAS_INLINE
  594. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  595. typename self_type::
  596. #endif
  597. const_reverse_iterator2 rend () const {
  598. return const_reverse_iterator2 (begin ());
  599. }
  600. BOOST_UBLAS_INLINE
  601. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  602. typename self_type::
  603. #endif
  604. const_reverse_iterator2 crend () const {
  605. return rend ();
  606. }
  607. #endif
  608. // Indices
  609. BOOST_UBLAS_INLINE
  610. size_type index1 () const {
  611. BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
  612. if (rank_ == 1) {
  613. BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
  614. return layout_type::index_M (itv_.index (), it_.index ());
  615. } else {
  616. return i_;
  617. }
  618. }
  619. BOOST_UBLAS_INLINE
  620. size_type index2 () const {
  621. BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
  622. if (rank_ == 1) {
  623. BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
  624. return layout_type::index_m (itv_.index (), it_.index ());
  625. } else {
  626. return j_;
  627. }
  628. }
  629. // Assignment
  630. BOOST_UBLAS_INLINE
  631. const_iterator1 &operator = (const const_iterator1 &it) {
  632. container_const_reference<self_type>::assign (&it ());
  633. rank_ = it.rank_;
  634. i_ = it.i_;
  635. j_ = it.j_;
  636. itv_ = it.itv_;
  637. it_ = it.it_;
  638. return *this;
  639. }
  640. // Comparison
  641. BOOST_UBLAS_INLINE
  642. bool operator == (const const_iterator1 &it) const {
  643. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  644. // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
  645. if (rank_ == 1 || it.rank_ == 1) {
  646. return it_ == it.it_;
  647. } else {
  648. return i_ == it.i_ && j_ == it.j_;
  649. }
  650. }
  651. private:
  652. int rank_;
  653. size_type i_;
  654. size_type j_;
  655. const_vectoriterator_type itv_;
  656. const_subiterator_type it_;
  657. };
  658. BOOST_UBLAS_INLINE
  659. const_iterator1 begin1 () const {
  660. return find1 (0, 0, 0);
  661. }
  662. BOOST_UBLAS_INLINE
  663. const_iterator1 cbegin1 () const {
  664. return begin1 ();
  665. }
  666. BOOST_UBLAS_INLINE
  667. const_iterator1 end1 () const {
  668. return find1 (0, size1_, 0);
  669. }
  670. BOOST_UBLAS_INLINE
  671. const_iterator1 cend1 () const {
  672. return end1 ();
  673. }
  674. class iterator1:
  675. public container_reference<generalized_vector_of_vector>,
  676. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  677. iterator1, value_type> {
  678. public:
  679. typedef typename generalized_vector_of_vector::difference_type difference_type;
  680. typedef typename generalized_vector_of_vector::value_type value_type;
  681. typedef typename generalized_vector_of_vector::true_reference reference;
  682. typedef typename generalized_vector_of_vector::pointer pointer;
  683. typedef iterator2 dual_iterator_type;
  684. typedef reverse_iterator2 dual_reverse_iterator_type;
  685. // Construction and destruction
  686. BOOST_UBLAS_INLINE
  687. iterator1 ():
  688. container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
  689. BOOST_UBLAS_INLINE
  690. iterator1 (self_type &m, int rank, size_type i, size_type j, const vectoriterator_type &itv, const subiterator_type &it):
  691. container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
  692. // Arithmetic
  693. BOOST_UBLAS_INLINE
  694. iterator1 &operator ++ () {
  695. if (rank_ == 1 && layout_type::fast_i ())
  696. ++ it_;
  697. else {
  698. self_type &m = (*this) ();
  699. i_ = index1 () + 1;
  700. if (rank_ == 1 && ++ itv_ == m.end1 ().itv_)
  701. *this = m.find1 (rank_, i_, j_, 1);
  702. else if (rank_ == 1) {
  703. it_ = (*itv_).begin ();
  704. if (it_ == (*itv_).end () || index2 () != j_)
  705. *this = m.find1 (rank_, i_, j_, 1);
  706. }
  707. }
  708. return *this;
  709. }
  710. BOOST_UBLAS_INLINE
  711. iterator1 &operator -- () {
  712. if (rank_ == 1 && layout_type::fast_i ())
  713. -- it_;
  714. else {
  715. self_type &m = (*this) ();
  716. i_ = index1 () - 1;
  717. if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
  718. *this = m.find1 (rank_, i_, j_, -1);
  719. else if (rank_ == 1) {
  720. it_ = (*itv_).begin ();
  721. if (it_ == (*itv_).end () || index2 () != j_)
  722. *this = m.find1 (rank_, i_, j_, -1);
  723. }
  724. }
  725. return *this;
  726. }
  727. // Dereference
  728. BOOST_UBLAS_INLINE
  729. true_reference operator * () const {
  730. BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
  731. BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
  732. if (rank_ == 1) {
  733. return *it_;
  734. } else {
  735. return (*this) ().at_element (i_, j_);
  736. }
  737. }
  738. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  739. BOOST_UBLAS_INLINE
  740. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  741. typename self_type::
  742. #endif
  743. iterator2 begin () const {
  744. self_type &m = (*this) ();
  745. return m.find2 (1, index1 (), 0);
  746. }
  747. BOOST_UBLAS_INLINE
  748. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  749. typename self_type::
  750. #endif
  751. iterator2 end () const {
  752. self_type &m = (*this) ();
  753. return m.find2 (1, index1 (), m.size2 ());
  754. }
  755. BOOST_UBLAS_INLINE
  756. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  757. typename self_type::
  758. #endif
  759. reverse_iterator2 rbegin () const {
  760. return reverse_iterator2 (end ());
  761. }
  762. BOOST_UBLAS_INLINE
  763. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  764. typename self_type::
  765. #endif
  766. reverse_iterator2 rend () const {
  767. return reverse_iterator2 (begin ());
  768. }
  769. #endif
  770. // Indices
  771. BOOST_UBLAS_INLINE
  772. size_type index1 () const {
  773. BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
  774. if (rank_ == 1) {
  775. BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
  776. return layout_type::index_M (itv_.index (), it_.index ());
  777. } else {
  778. return i_;
  779. }
  780. }
  781. BOOST_UBLAS_INLINE
  782. size_type index2 () const {
  783. BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
  784. if (rank_ == 1) {
  785. BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
  786. return layout_type::index_m (itv_.index (), it_.index ());
  787. } else {
  788. return j_;
  789. }
  790. }
  791. // Assignment
  792. BOOST_UBLAS_INLINE
  793. iterator1 &operator = (const iterator1 &it) {
  794. container_reference<self_type>::assign (&it ());
  795. rank_ = it.rank_;
  796. i_ = it.i_;
  797. j_ = it.j_;
  798. itv_ = it.itv_;
  799. it_ = it.it_;
  800. return *this;
  801. }
  802. // Comparison
  803. BOOST_UBLAS_INLINE
  804. bool operator == (const iterator1 &it) const {
  805. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  806. // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
  807. if (rank_ == 1 || it.rank_ == 1) {
  808. return it_ == it.it_;
  809. } else {
  810. return i_ == it.i_ && j_ == it.j_;
  811. }
  812. }
  813. private:
  814. int rank_;
  815. size_type i_;
  816. size_type j_;
  817. vectoriterator_type itv_;
  818. subiterator_type it_;
  819. friend class const_iterator1;
  820. };
  821. BOOST_UBLAS_INLINE
  822. iterator1 begin1 () {
  823. return find1 (0, 0, 0);
  824. }
  825. BOOST_UBLAS_INLINE
  826. iterator1 end1 () {
  827. return find1 (0, size1_, 0);
  828. }
  829. class const_iterator2:
  830. public container_const_reference<generalized_vector_of_vector>,
  831. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  832. const_iterator2, value_type> {
  833. public:
  834. typedef typename generalized_vector_of_vector::difference_type difference_type;
  835. typedef typename generalized_vector_of_vector::value_type value_type;
  836. typedef typename generalized_vector_of_vector::const_reference reference;
  837. typedef const typename generalized_vector_of_vector::pointer pointer;
  838. typedef const_iterator1 dual_iterator_type;
  839. typedef const_reverse_iterator1 dual_reverse_iterator_type;
  840. // Construction and destruction
  841. BOOST_UBLAS_INLINE
  842. const_iterator2 ():
  843. container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
  844. BOOST_UBLAS_INLINE
  845. const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const const_vectoriterator_type &itv, const const_subiterator_type &it):
  846. container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
  847. BOOST_UBLAS_INLINE
  848. const_iterator2 (const iterator2 &it):
  849. container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
  850. // Arithmetic
  851. BOOST_UBLAS_INLINE
  852. const_iterator2 &operator ++ () {
  853. if (rank_ == 1 && layout_type::fast_j ())
  854. ++ it_;
  855. else {
  856. const self_type &m = (*this) ();
  857. j_ = index2 () + 1;
  858. if (rank_ == 1 && ++ itv_ == m.end2 ().itv_)
  859. *this = m.find2 (rank_, i_, j_, 1);
  860. else if (rank_ == 1) {
  861. it_ = (*itv_).begin ();
  862. if (it_ == (*itv_).end () || index1 () != i_)
  863. *this = m.find2 (rank_, i_, j_, 1);
  864. }
  865. }
  866. return *this;
  867. }
  868. BOOST_UBLAS_INLINE
  869. const_iterator2 &operator -- () {
  870. if (rank_ == 1 && layout_type::fast_j ())
  871. -- it_;
  872. else {
  873. const self_type &m = (*this) ();
  874. j_ = index2 () - 1;
  875. if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
  876. *this = m.find2 (rank_, i_, j_, -1);
  877. else if (rank_ == 1) {
  878. it_ = (*itv_).begin ();
  879. if (it_ == (*itv_).end () || index1 () != i_)
  880. *this = m.find2 (rank_, i_, j_, -1);
  881. }
  882. }
  883. return *this;
  884. }
  885. // Dereference
  886. BOOST_UBLAS_INLINE
  887. const_reference operator * () const {
  888. BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
  889. BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
  890. if (rank_ == 1) {
  891. return *it_;
  892. } else {
  893. return (*this) () (i_, j_);
  894. }
  895. }
  896. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  897. BOOST_UBLAS_INLINE
  898. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  899. typename self_type::
  900. #endif
  901. const_iterator1 begin () const {
  902. const self_type &m = (*this) ();
  903. return m.find1 (1, 0, index2 ());
  904. }
  905. BOOST_UBLAS_INLINE
  906. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  907. typename self_type::
  908. #endif
  909. const_iterator1 cbegin () const {
  910. return begin ();
  911. }
  912. BOOST_UBLAS_INLINE
  913. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  914. typename self_type::
  915. #endif
  916. const_iterator1 end () const {
  917. const self_type &m = (*this) ();
  918. return m.find1 (1, m.size1 (), index2 ());
  919. }
  920. BOOST_UBLAS_INLINE
  921. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  922. typename self_type::
  923. #endif
  924. const_iterator1 cend () const {
  925. return end ();
  926. }
  927. BOOST_UBLAS_INLINE
  928. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  929. typename self_type::
  930. #endif
  931. const_reverse_iterator1 rbegin () const {
  932. return const_reverse_iterator1 (end ());
  933. }
  934. BOOST_UBLAS_INLINE
  935. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  936. typename self_type::
  937. #endif
  938. const_reverse_iterator1 crbegin () const {
  939. return rbegin ();
  940. }
  941. BOOST_UBLAS_INLINE
  942. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  943. typename self_type::
  944. #endif
  945. const_reverse_iterator1 rend () const {
  946. return const_reverse_iterator1 (begin ());
  947. }
  948. BOOST_UBLAS_INLINE
  949. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  950. typename self_type::
  951. #endif
  952. const_reverse_iterator1 crend () const {
  953. return rend ();
  954. }
  955. #endif
  956. // Indices
  957. BOOST_UBLAS_INLINE
  958. size_type index1 () const {
  959. BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
  960. if (rank_ == 1) {
  961. BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
  962. return layout_type::index_M (itv_.index (), it_.index ());
  963. } else {
  964. return i_;
  965. }
  966. }
  967. BOOST_UBLAS_INLINE
  968. size_type index2 () const {
  969. BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
  970. if (rank_ == 1) {
  971. BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
  972. return layout_type::index_m (itv_.index (), it_.index ());
  973. } else {
  974. return j_;
  975. }
  976. }
  977. // Assignment
  978. BOOST_UBLAS_INLINE
  979. const_iterator2 &operator = (const const_iterator2 &it) {
  980. container_const_reference<self_type>::assign (&it ());
  981. rank_ = it.rank_;
  982. i_ = it.i_;
  983. j_ = it.j_;
  984. itv_ = it.itv_;
  985. it_ = it.it_;
  986. return *this;
  987. }
  988. // Comparison
  989. BOOST_UBLAS_INLINE
  990. bool operator == (const const_iterator2 &it) const {
  991. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  992. // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
  993. if (rank_ == 1 || it.rank_ == 1) {
  994. return it_ == it.it_;
  995. } else {
  996. return i_ == it.i_ && j_ == it.j_;
  997. }
  998. }
  999. private:
  1000. int rank_;
  1001. size_type i_;
  1002. size_type j_;
  1003. const_vectoriterator_type itv_;
  1004. const_subiterator_type it_;
  1005. };
  1006. BOOST_UBLAS_INLINE
  1007. const_iterator2 begin2 () const {
  1008. return find2 (0, 0, 0);
  1009. }
  1010. BOOST_UBLAS_INLINE
  1011. const_iterator2 cbegin2 () const {
  1012. return begin2 ();
  1013. }
  1014. BOOST_UBLAS_INLINE
  1015. const_iterator2 end2 () const {
  1016. return find2 (0, 0, size2_);
  1017. }
  1018. BOOST_UBLAS_INLINE
  1019. const_iterator2 cend2 () const {
  1020. return end2 ();
  1021. }
  1022. class iterator2:
  1023. public container_reference<generalized_vector_of_vector>,
  1024. public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
  1025. iterator2, value_type> {
  1026. public:
  1027. typedef typename generalized_vector_of_vector::difference_type difference_type;
  1028. typedef typename generalized_vector_of_vector::value_type value_type;
  1029. typedef typename generalized_vector_of_vector::true_reference reference;
  1030. typedef typename generalized_vector_of_vector::pointer pointer;
  1031. typedef iterator1 dual_iterator_type;
  1032. typedef reverse_iterator1 dual_reverse_iterator_type;
  1033. // Construction and destruction
  1034. BOOST_UBLAS_INLINE
  1035. iterator2 ():
  1036. container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
  1037. BOOST_UBLAS_INLINE
  1038. iterator2 (self_type &m, int rank, size_type i, size_type j, const vectoriterator_type &itv, const subiterator_type &it):
  1039. container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
  1040. // Arithmetic
  1041. BOOST_UBLAS_INLINE
  1042. iterator2 &operator ++ () {
  1043. if (rank_ == 1 && layout_type::fast_j ())
  1044. ++ it_;
  1045. else {
  1046. self_type &m = (*this) ();
  1047. j_ = index2 () + 1;
  1048. if (rank_ == 1 && ++ itv_ == m.end2 ().itv_)
  1049. *this = m.find2 (rank_, i_, j_, 1);
  1050. else if (rank_ == 1) {
  1051. it_ = (*itv_).begin ();
  1052. if (it_ == (*itv_).end () || index1 () != i_)
  1053. *this = m.find2 (rank_, i_, j_, 1);
  1054. }
  1055. }
  1056. return *this;
  1057. }
  1058. BOOST_UBLAS_INLINE
  1059. iterator2 &operator -- () {
  1060. if (rank_ == 1 && layout_type::fast_j ())
  1061. -- it_;
  1062. else {
  1063. self_type &m = (*this) ();
  1064. j_ = index2 () - 1;
  1065. if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
  1066. *this = m.find2 (rank_, i_, j_, -1);
  1067. else if (rank_ == 1) {
  1068. it_ = (*itv_).begin ();
  1069. if (it_ == (*itv_).end () || index1 () != i_)
  1070. *this = m.find2 (rank_, i_, j_, -1);
  1071. }
  1072. }
  1073. return *this;
  1074. }
  1075. // Dereference
  1076. BOOST_UBLAS_INLINE
  1077. true_reference operator * () const {
  1078. BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
  1079. BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
  1080. if (rank_ == 1) {
  1081. return *it_;
  1082. } else {
  1083. return (*this) ().at_element (i_, j_);
  1084. }
  1085. }
  1086. #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
  1087. BOOST_UBLAS_INLINE
  1088. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1089. typename self_type::
  1090. #endif
  1091. iterator1 begin () const {
  1092. self_type &m = (*this) ();
  1093. return m.find1 (1, 0, index2 ());
  1094. }
  1095. BOOST_UBLAS_INLINE
  1096. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1097. typename self_type::
  1098. #endif
  1099. iterator1 end () const {
  1100. self_type &m = (*this) ();
  1101. return m.find1 (1, m.size1 (), index2 ());
  1102. }
  1103. BOOST_UBLAS_INLINE
  1104. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1105. typename self_type::
  1106. #endif
  1107. reverse_iterator1 rbegin () const {
  1108. return reverse_iterator1 (end ());
  1109. }
  1110. BOOST_UBLAS_INLINE
  1111. #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
  1112. typename self_type::
  1113. #endif
  1114. reverse_iterator1 rend () const {
  1115. return reverse_iterator1 (begin ());
  1116. }
  1117. #endif
  1118. // Indices
  1119. BOOST_UBLAS_INLINE
  1120. size_type index1 () const {
  1121. BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
  1122. if (rank_ == 1) {
  1123. BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
  1124. return layout_type::index_M (itv_.index (), it_.index ());
  1125. } else {
  1126. return i_;
  1127. }
  1128. }
  1129. BOOST_UBLAS_INLINE
  1130. size_type index2 () const {
  1131. BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
  1132. if (rank_ == 1) {
  1133. BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
  1134. return layout_type::index_m (itv_.index (), it_.index ());
  1135. } else {
  1136. return j_;
  1137. }
  1138. }
  1139. // Assignment
  1140. BOOST_UBLAS_INLINE
  1141. iterator2 &operator = (const iterator2 &it) {
  1142. container_reference<self_type>::assign (&it ());
  1143. rank_ = it.rank_;
  1144. i_ = it.i_;
  1145. j_ = it.j_;
  1146. itv_ = it.itv_;
  1147. it_ = it.it_;
  1148. return *this;
  1149. }
  1150. // Comparison
  1151. BOOST_UBLAS_INLINE
  1152. bool operator == (const iterator2 &it) const {
  1153. BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
  1154. // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
  1155. if (rank_ == 1 || it.rank_ == 1) {
  1156. return it_ == it.it_;
  1157. } else {
  1158. return i_ == it.i_ && j_ == it.j_;
  1159. }
  1160. }
  1161. private:
  1162. int rank_;
  1163. size_type i_;
  1164. size_type j_;
  1165. vectoriterator_type itv_;
  1166. subiterator_type it_;
  1167. friend class const_iterator2;
  1168. };
  1169. BOOST_UBLAS_INLINE
  1170. iterator2 begin2 () {
  1171. return find2 (0, 0, 0);
  1172. }
  1173. BOOST_UBLAS_INLINE
  1174. iterator2 end2 () {
  1175. return find2 (0, 0, size2_);
  1176. }
  1177. // Reverse iterators
  1178. BOOST_UBLAS_INLINE
  1179. const_reverse_iterator1 rbegin1 () const {
  1180. return const_reverse_iterator1 (end1 ());
  1181. }
  1182. BOOST_UBLAS_INLINE
  1183. const_reverse_iterator1 crbegin1 () const {
  1184. return rbegin1 ();
  1185. }
  1186. BOOST_UBLAS_INLINE
  1187. const_reverse_iterator1 rend1 () const {
  1188. return const_reverse_iterator1 (begin1 ());
  1189. }
  1190. BOOST_UBLAS_INLINE
  1191. const_reverse_iterator1 crend1 () const {
  1192. return rend1 ();
  1193. }
  1194. BOOST_UBLAS_INLINE
  1195. reverse_iterator1 rbegin1 () {
  1196. return reverse_iterator1 (end1 ());
  1197. }
  1198. BOOST_UBLAS_INLINE
  1199. reverse_iterator1 rend1 () {
  1200. return reverse_iterator1 (begin1 ());
  1201. }
  1202. BOOST_UBLAS_INLINE
  1203. const_reverse_iterator2 rbegin2 () const {
  1204. return const_reverse_iterator2 (end2 ());
  1205. }
  1206. BOOST_UBLAS_INLINE
  1207. const_reverse_iterator2 crbegin2 () const {
  1208. return rbegin2 ();
  1209. }
  1210. BOOST_UBLAS_INLINE
  1211. const_reverse_iterator2 rend2 () const {
  1212. return const_reverse_iterator2 (begin2 ());
  1213. }
  1214. BOOST_UBLAS_INLINE
  1215. const_reverse_iterator2 crend2 () const {
  1216. return rend2 ();
  1217. }
  1218. BOOST_UBLAS_INLINE
  1219. reverse_iterator2 rbegin2 () {
  1220. return reverse_iterator2 (end2 ());
  1221. }
  1222. BOOST_UBLAS_INLINE
  1223. reverse_iterator2 rend2 () {
  1224. return reverse_iterator2 (begin2 ());
  1225. }
  1226. // Serialization
  1227. template<class Archive>
  1228. void serialize(Archive & ar, const unsigned int /* file_version */){
  1229. // we need to copy to a collection_size_type to get a portable
  1230. // and efficient serialization
  1231. serialization::collection_size_type s1 (size1_);
  1232. serialization::collection_size_type s2 (size2_);
  1233. // serialize the sizes
  1234. ar & serialization::make_nvp("size1",s1)
  1235. & serialization::make_nvp("size2",s2);
  1236. // copy the values back if loading
  1237. if (Archive::is_loading::value) {
  1238. size1_ = s1;
  1239. size2_ = s2;
  1240. }
  1241. ar & serialization::make_nvp("data", data_);
  1242. storage_invariants();
  1243. }
  1244. private:
  1245. void storage_invariants () const
  1246. {
  1247. BOOST_UBLAS_CHECK (layout_type::size_M (size1_, size2_) + 1 == data_.size (), internal_logic ());
  1248. BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
  1249. }
  1250. size_type size1_;
  1251. size_type size2_;
  1252. array_type data_;
  1253. static const value_type zero_;
  1254. };
  1255. template<class T, class L, class A>
  1256. const typename generalized_vector_of_vector<T, L, A>::value_type generalized_vector_of_vector<T, L, A>::zero_ = value_type/*zero*/();
  1257. }}}
  1258. #endif