Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2000-2010
|
Chris@16
|
3 // Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // The authors gratefully acknowledge the support of
|
Chris@16
|
10 // GeNeSys mbH & Co. KG in producing this work.
|
Chris@16
|
11 //
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef _BOOST_UBLAS_MATRIX_
|
Chris@16
|
14 #define _BOOST_UBLAS_MATRIX_
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/numeric/ublas/vector.hpp>
|
Chris@16
|
17 #include <boost/numeric/ublas/matrix_expression.hpp>
|
Chris@16
|
18 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
|
Chris@16
|
19 #include <boost/serialization/collection_size_type.hpp>
|
Chris@16
|
20 #include <boost/serialization/array.hpp>
|
Chris@16
|
21 #include <boost/serialization/nvp.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 // Iterators based on ideas of Jeremy Siek
|
Chris@16
|
24
|
Chris@16
|
25 namespace boost { namespace numeric {
|
Chris@16
|
26
|
Chris@16
|
27 /** \brief main namespace of uBLAS.
|
Chris@16
|
28 *
|
Chris@16
|
29 * Use this namespace for all operations with uBLAS. It can also be abbreviated with
|
Chris@16
|
30 * \code namespace ublas = boost::numeric::ublas; \endcode
|
Chris@16
|
31 *
|
Chris@16
|
32 * A common practice is to bring this namespace into the current scope with
|
Chris@16
|
33 * \code using namespace boost::numeric::ublas; \endcode.
|
Chris@16
|
34 *
|
Chris@16
|
35 * However, be warned that using the ublas namespace and the std::vector at the same time can lead to the compiler to confusion.
|
Chris@16
|
36 * The solution is simply to prefix each ublas vector like \c boost::numeric::ublas::vector<T>. If you think it's too long to
|
Chris@16
|
37 * write, you can define a new namespace like \c namespace ublas = boost::numeric::ublas and then just declare your vectors
|
Chris@16
|
38 * with \c ublas::vector<T>. STL vectors will be declared as vector<T>. No need to prefix with \c std::
|
Chris@16
|
39 */
|
Chris@16
|
40 namespace ublas {
|
Chris@16
|
41
|
Chris@16
|
42 namespace detail {
|
Chris@16
|
43 using namespace boost::numeric::ublas;
|
Chris@16
|
44
|
Chris@16
|
45 // Matrix resizing algorithm
|
Chris@16
|
46 template <class L, class M>
|
Chris@16
|
47 BOOST_UBLAS_INLINE
|
Chris@16
|
48 void matrix_resize_preserve (M& m, M& temporary) {
|
Chris@16
|
49 typedef L layout_type;
|
Chris@16
|
50 typedef typename M::size_type size_type;
|
Chris@16
|
51 const size_type msize1 (m.size1 ()); // original size
|
Chris@16
|
52 const size_type msize2 (m.size2 ());
|
Chris@16
|
53 const size_type size1 (temporary.size1 ()); // new size is specified by temporary
|
Chris@16
|
54 const size_type size2 (temporary.size2 ());
|
Chris@16
|
55 // Common elements to preserve
|
Chris@16
|
56 const size_type size1_min = (std::min) (size1, msize1);
|
Chris@16
|
57 const size_type size2_min = (std::min) (size2, msize2);
|
Chris@16
|
58 // Order for major and minor sizes
|
Chris@16
|
59 const size_type major_size = layout_type::size_M (size1_min, size2_min);
|
Chris@16
|
60 const size_type minor_size = layout_type::size_m (size1_min, size2_min);
|
Chris@16
|
61 // Indexing copy over major
|
Chris@16
|
62 for (size_type major = 0; major != major_size; ++major) {
|
Chris@16
|
63 for (size_type minor = 0; minor != minor_size; ++minor) {
|
Chris@16
|
64 // find indexes - use invertability of element_ functions
|
Chris@16
|
65 const size_type i1 = layout_type::index_M(major, minor);
|
Chris@16
|
66 const size_type i2 = layout_type::index_m(major, minor);
|
Chris@16
|
67 temporary.data () [layout_type::element (i1, size1, i2, size2)] =
|
Chris@16
|
68 m.data() [layout_type::element (i1, msize1, i2, msize2)];
|
Chris@16
|
69 }
|
Chris@16
|
70 }
|
Chris@16
|
71 m.assign_temporary (temporary);
|
Chris@16
|
72 }
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 /** \brief A dense matrix of values of type \c T.
|
Chris@16
|
76 *
|
Chris@16
|
77 * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to
|
Chris@16
|
78 * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of
|
Chris@16
|
79 * the container for column major orientation. In a dense matrix all elements are represented in memory in a
|
Chris@16
|
80 * contiguous chunk of memory by definition.
|
Chris@16
|
81 *
|
Chris@16
|
82 * Orientation and storage can also be specified, otherwise a \c row_major and \c unbounded_array are used. It is \b not
|
Chris@16
|
83 * required by the storage to initialize elements of the matrix.
|
Chris@16
|
84 *
|
Chris@16
|
85 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
86 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
|
Chris@16
|
87 * \tparam A the type of Storage array. Default is \c unbounded_array
|
Chris@16
|
88 */
|
Chris@16
|
89 template<class T, class L, class A>
|
Chris@16
|
90 class matrix:
|
Chris@16
|
91 public matrix_container<matrix<T, L, A> > {
|
Chris@16
|
92
|
Chris@16
|
93 typedef T *pointer;
|
Chris@16
|
94 typedef L layout_type;
|
Chris@16
|
95 typedef matrix<T, L, A> self_type;
|
Chris@16
|
96 public:
|
Chris@16
|
97 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
98 using matrix_container<self_type>::operator ();
|
Chris@16
|
99 #endif
|
Chris@16
|
100 typedef typename A::size_type size_type;
|
Chris@16
|
101 typedef typename A::difference_type difference_type;
|
Chris@16
|
102 typedef T value_type;
|
Chris@16
|
103 typedef const T &const_reference;
|
Chris@16
|
104 typedef T &reference;
|
Chris@16
|
105 typedef A array_type;
|
Chris@16
|
106 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
107 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
108 typedef vector<T, A> vector_temporary_type;
|
Chris@16
|
109 typedef self_type matrix_temporary_type;
|
Chris@16
|
110 typedef dense_tag storage_category;
|
Chris@16
|
111 // This could be better for performance,
|
Chris@16
|
112 // typedef typename unknown_orientation_tag orientation_category;
|
Chris@16
|
113 // but others depend on the orientation information...
|
Chris@16
|
114 typedef typename L::orientation_category orientation_category;
|
Chris@16
|
115
|
Chris@16
|
116 // Construction and destruction
|
Chris@16
|
117
|
Chris@16
|
118 /// Default dense matrix constructor. Make a dense matrix of size (0,0)
|
Chris@16
|
119 BOOST_UBLAS_INLINE
|
Chris@16
|
120 matrix ():
|
Chris@16
|
121 matrix_container<self_type> (),
|
Chris@16
|
122 size1_ (0), size2_ (0), data_ () {}
|
Chris@16
|
123
|
Chris@16
|
124 /** Dense matrix constructor with defined size
|
Chris@16
|
125 * \param size1 number of rows
|
Chris@16
|
126 * \param size2 number of columns
|
Chris@16
|
127 */
|
Chris@16
|
128 BOOST_UBLAS_INLINE
|
Chris@16
|
129 matrix (size_type size1, size_type size2):
|
Chris@16
|
130 matrix_container<self_type> (),
|
Chris@16
|
131 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
|
Chris@16
|
132 }
|
Chris@16
|
133
|
Chris@16
|
134 /** Dense matrix constructor with defined size a initial value for all the matrix elements
|
Chris@16
|
135 * \param size1 number of rows
|
Chris@16
|
136 * \param size2 number of columns
|
Chris@16
|
137 * \param init initial value assigned to all elements
|
Chris@16
|
138 */
|
Chris@16
|
139 matrix (size_type size1, size_type size2, const value_type &init):
|
Chris@16
|
140 matrix_container<self_type> (),
|
Chris@16
|
141 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 /** Dense matrix constructor with defined size and an initial data array
|
Chris@16
|
145 * \param size1 number of rows
|
Chris@16
|
146 * \param size2 number of columns
|
Chris@16
|
147 * \param data array to copy into the matrix. Must have the same dimension as the matrix
|
Chris@16
|
148 */
|
Chris@16
|
149 BOOST_UBLAS_INLINE
|
Chris@16
|
150 matrix (size_type size1, size_type size2, const array_type &data):
|
Chris@16
|
151 matrix_container<self_type> (),
|
Chris@16
|
152 size1_ (size1), size2_ (size2), data_ (data) {}
|
Chris@16
|
153
|
Chris@16
|
154 /** Copy-constructor of a dense matrix
|
Chris@16
|
155 * \param m is a dense matrix
|
Chris@16
|
156 */
|
Chris@16
|
157 BOOST_UBLAS_INLINE
|
Chris@16
|
158 matrix (const matrix &m):
|
Chris@16
|
159 matrix_container<self_type> (),
|
Chris@16
|
160 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
|
Chris@16
|
161
|
Chris@16
|
162 /** Copy-constructor of a dense matrix from a matrix expression
|
Chris@16
|
163 * \param ae is a matrix expression
|
Chris@16
|
164 */
|
Chris@16
|
165 template<class AE>
|
Chris@16
|
166 BOOST_UBLAS_INLINE
|
Chris@16
|
167 matrix (const matrix_expression<AE> &ae):
|
Chris@16
|
168 matrix_container<self_type> (),
|
Chris@16
|
169 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
|
Chris@16
|
170 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 // Accessors
|
Chris@16
|
174 /** Return the number of rows of the matrix
|
Chris@16
|
175 * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a matrix
|
Chris@16
|
176 */
|
Chris@16
|
177 BOOST_UBLAS_INLINE
|
Chris@16
|
178 size_type size1 () const {
|
Chris@16
|
179 return size1_;
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 /** Return the number of colums of the matrix
|
Chris@16
|
183 * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a matrix
|
Chris@16
|
184 */
|
Chris@16
|
185 BOOST_UBLAS_INLINE
|
Chris@16
|
186 size_type size2 () const {
|
Chris@16
|
187 return size2_;
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 // Storage accessors
|
Chris@16
|
191 /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
|
Chris@16
|
192 * It's type depends on the type used by the matrix to store its data
|
Chris@16
|
193 */
|
Chris@16
|
194 BOOST_UBLAS_INLINE
|
Chris@16
|
195 const array_type &data () const {
|
Chris@16
|
196 return data_;
|
Chris@16
|
197 }
|
Chris@16
|
198 /** Return a reference to the internal storage of a dense matrix, i.e. the raw data
|
Chris@16
|
199 * It's type depends on the type used by the matrix to store its data
|
Chris@16
|
200 */
|
Chris@16
|
201 BOOST_UBLAS_INLINE
|
Chris@16
|
202 array_type &data () {
|
Chris@16
|
203 return data_;
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 // Resizing
|
Chris@16
|
207 /** Resize a matrix to new dimensions
|
Chris@16
|
208 * If data are preserved, then if the size if bigger at least on one dimension, extra values are filled with zeros.
|
Chris@16
|
209 * If data are not preserved, then nothing has to be assumed regarding the content of the matrix after resizing.
|
Chris@16
|
210 * \param size1 the new number of rows
|
Chris@16
|
211 * \param size2 the new number of colums
|
Chris@16
|
212 * \param preserve a boolean to say if one wants the data to be preserved during the resizing. Default is true.
|
Chris@16
|
213 */
|
Chris@16
|
214 BOOST_UBLAS_INLINE
|
Chris@16
|
215 void resize (size_type size1, size_type size2, bool preserve = true) {
|
Chris@16
|
216 if (preserve) {
|
Chris@16
|
217 self_type temporary (size1, size2);
|
Chris@16
|
218 detail::matrix_resize_preserve<layout_type> (*this, temporary);
|
Chris@16
|
219 }
|
Chris@16
|
220 else {
|
Chris@16
|
221 data ().resize (layout_type::storage_size (size1, size2));
|
Chris@16
|
222 size1_ = size1;
|
Chris@16
|
223 size2_ = size2;
|
Chris@16
|
224 }
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 // Element access
|
Chris@16
|
228
|
Chris@16
|
229 /** Access a matrix element. Here we return a const reference
|
Chris@16
|
230 * \param i the first coordinate of the element. By default it's the row
|
Chris@16
|
231 * \param j the second coordinate of the element. By default it's the column
|
Chris@16
|
232 * \return a const reference to the element
|
Chris@16
|
233 */
|
Chris@16
|
234 BOOST_UBLAS_INLINE
|
Chris@16
|
235 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
236 return data () [layout_type::element (i, size1_, j, size2_)];
|
Chris@16
|
237 }
|
Chris@16
|
238
|
Chris@16
|
239 /** Access a matrix element. Here we return a reference
|
Chris@16
|
240 * \param i the first coordinate of the element. By default it's the row
|
Chris@16
|
241 * \param j the second coordinate of the element. By default it's the column
|
Chris@16
|
242 * \return a reference to the element
|
Chris@16
|
243 */
|
Chris@16
|
244 BOOST_UBLAS_INLINE
|
Chris@16
|
245 reference at_element (size_type i, size_type j) {
|
Chris@16
|
246 return data () [layout_type::element (i, size1_, j, size2_)];
|
Chris@16
|
247 }
|
Chris@16
|
248
|
Chris@16
|
249 /** Access a matrix element. Here we return a reference
|
Chris@16
|
250 * \param i the first coordinate of the element. By default it's the row
|
Chris@16
|
251 * \param j the second coordinate of the element. By default it's the column
|
Chris@16
|
252 * \return a reference to the element
|
Chris@16
|
253 */
|
Chris@16
|
254 BOOST_UBLAS_INLINE
|
Chris@16
|
255 reference operator () (size_type i, size_type j) {
|
Chris@16
|
256 return at_element (i, j);
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 // Element assignment
|
Chris@16
|
260
|
Chris@16
|
261 /** Change the value of a matrix element. Return back a reference to it
|
Chris@16
|
262 * \param i the first coordinate of the element. By default it's the row
|
Chris@16
|
263 * \param j the second coordinate of the element. By default it's the column
|
Chris@16
|
264 * \param t the new value of the element
|
Chris@16
|
265 * \return a reference to the newly changed element
|
Chris@16
|
266 */
|
Chris@16
|
267 BOOST_UBLAS_INLINE
|
Chris@16
|
268 reference insert_element (size_type i, size_type j, const_reference t) {
|
Chris@16
|
269 return (at_element (i, j) = t);
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 /** Erase the element
|
Chris@16
|
273 * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
|
Chris@16
|
274 * For user-defined types, it could be another value if you decided it. Your type in that case must
|
Chris@16
|
275 * contain a default null value.
|
Chris@16
|
276 * \param i the first coordinate of the element. By default it's the row
|
Chris@16
|
277 * \param j the second coordinate of the element. By default it's the column
|
Chris@16
|
278 */
|
Chris@16
|
279 void erase_element (size_type i, size_type j) {
|
Chris@16
|
280 at_element (i, j) = value_type/*zero*/();
|
Chris@16
|
281 }
|
Chris@16
|
282
|
Chris@16
|
283 // Zeroing
|
Chris@16
|
284 /** Erase all elements in the matrix
|
Chris@16
|
285 * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
|
Chris@16
|
286 * For user-defined types, it could be another value if you decided it. Your type in that case must
|
Chris@16
|
287 * contain a default null value.
|
Chris@16
|
288 */
|
Chris@16
|
289 BOOST_UBLAS_INLINE
|
Chris@16
|
290 void clear () {
|
Chris@16
|
291 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
|
Chris@16
|
292 }
|
Chris@16
|
293
|
Chris@16
|
294 // Assignment
|
Chris@16
|
295 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
|
Chris@16
|
296
|
Chris@16
|
297 /*! @note "pass by value" the key idea to enable move semantics */
|
Chris@16
|
298 BOOST_UBLAS_INLINE
|
Chris@16
|
299 matrix &operator = (matrix m) {
|
Chris@16
|
300 assign_temporary(m);
|
Chris@16
|
301 return *this;
|
Chris@16
|
302 }
|
Chris@16
|
303 #else
|
Chris@16
|
304 BOOST_UBLAS_INLINE
|
Chris@16
|
305 matrix &operator = (const matrix &m) {
|
Chris@16
|
306 size1_ = m.size1_;
|
Chris@16
|
307 size2_ = m.size2_;
|
Chris@16
|
308 data () = m.data ();
|
Chris@16
|
309 return *this;
|
Chris@16
|
310 }
|
Chris@16
|
311 #endif
|
Chris@16
|
312 template<class C> // Container assignment without temporary
|
Chris@16
|
313 BOOST_UBLAS_INLINE
|
Chris@16
|
314 matrix &operator = (const matrix_container<C> &m) {
|
Chris@16
|
315 resize (m ().size1 (), m ().size2 (), false);
|
Chris@16
|
316 assign (m);
|
Chris@16
|
317 return *this;
|
Chris@16
|
318 }
|
Chris@16
|
319 BOOST_UBLAS_INLINE
|
Chris@16
|
320 matrix &assign_temporary (matrix &m) {
|
Chris@16
|
321 swap (m);
|
Chris@16
|
322 return *this;
|
Chris@16
|
323 }
|
Chris@16
|
324 template<class AE>
|
Chris@16
|
325 BOOST_UBLAS_INLINE
|
Chris@16
|
326 matrix &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
327 self_type temporary (ae);
|
Chris@16
|
328 return assign_temporary (temporary);
|
Chris@16
|
329 }
|
Chris@16
|
330 template<class AE>
|
Chris@16
|
331 BOOST_UBLAS_INLINE
|
Chris@16
|
332 matrix &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
333 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
334 return *this;
|
Chris@16
|
335 }
|
Chris@16
|
336 template<class AE>
|
Chris@16
|
337 BOOST_UBLAS_INLINE
|
Chris@16
|
338 matrix& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
339 self_type temporary (*this + ae);
|
Chris@16
|
340 return assign_temporary (temporary);
|
Chris@16
|
341 }
|
Chris@16
|
342 template<class C> // Container assignment without temporary
|
Chris@16
|
343 BOOST_UBLAS_INLINE
|
Chris@16
|
344 matrix &operator += (const matrix_container<C> &m) {
|
Chris@16
|
345 plus_assign (m);
|
Chris@16
|
346 return *this;
|
Chris@16
|
347 }
|
Chris@16
|
348 template<class AE>
|
Chris@16
|
349 BOOST_UBLAS_INLINE
|
Chris@16
|
350 matrix &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
351 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
352 return *this;
|
Chris@16
|
353 }
|
Chris@16
|
354 template<class AE>
|
Chris@16
|
355 BOOST_UBLAS_INLINE
|
Chris@16
|
356 matrix& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
357 self_type temporary (*this - ae);
|
Chris@16
|
358 return assign_temporary (temporary);
|
Chris@16
|
359 }
|
Chris@16
|
360 template<class C> // Container assignment without temporary
|
Chris@16
|
361 BOOST_UBLAS_INLINE
|
Chris@16
|
362 matrix &operator -= (const matrix_container<C> &m) {
|
Chris@16
|
363 minus_assign (m);
|
Chris@16
|
364 return *this;
|
Chris@16
|
365 }
|
Chris@16
|
366 template<class AE>
|
Chris@16
|
367 BOOST_UBLAS_INLINE
|
Chris@16
|
368 matrix &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
369 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
370 return *this;
|
Chris@16
|
371 }
|
Chris@16
|
372 template<class AT>
|
Chris@16
|
373 BOOST_UBLAS_INLINE
|
Chris@16
|
374 matrix& operator *= (const AT &at) {
|
Chris@16
|
375 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
376 return *this;
|
Chris@16
|
377 }
|
Chris@16
|
378 template<class AT>
|
Chris@16
|
379 BOOST_UBLAS_INLINE
|
Chris@16
|
380 matrix& operator /= (const AT &at) {
|
Chris@16
|
381 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
382 return *this;
|
Chris@16
|
383 }
|
Chris@16
|
384
|
Chris@16
|
385 // Swapping
|
Chris@16
|
386 BOOST_UBLAS_INLINE
|
Chris@16
|
387 void swap (matrix &m) {
|
Chris@16
|
388 if (this != &m) {
|
Chris@16
|
389 std::swap (size1_, m.size1_);
|
Chris@16
|
390 std::swap (size2_, m.size2_);
|
Chris@16
|
391 data ().swap (m.data ());
|
Chris@16
|
392 }
|
Chris@16
|
393 }
|
Chris@16
|
394 BOOST_UBLAS_INLINE
|
Chris@16
|
395 friend void swap (matrix &m1, matrix &m2) {
|
Chris@16
|
396 m1.swap (m2);
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399 // Iterator types
|
Chris@16
|
400 private:
|
Chris@16
|
401 // Use the storage array iterator
|
Chris@16
|
402 typedef typename A::const_iterator const_subiterator_type;
|
Chris@16
|
403 typedef typename A::iterator subiterator_type;
|
Chris@16
|
404
|
Chris@16
|
405 public:
|
Chris@16
|
406 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
407 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
|
Chris@16
|
408 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
|
Chris@16
|
409 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
|
Chris@16
|
410 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
|
Chris@16
|
411 #else
|
Chris@16
|
412 class const_iterator1;
|
Chris@16
|
413 class iterator1;
|
Chris@16
|
414 class const_iterator2;
|
Chris@16
|
415 class iterator2;
|
Chris@16
|
416 #endif
|
Chris@16
|
417 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
418 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
419 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
420 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
421
|
Chris@16
|
422 // Element lookup
|
Chris@16
|
423 BOOST_UBLAS_INLINE
|
Chris@16
|
424 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
425 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
426 return const_iterator1 (*this, i, j);
|
Chris@16
|
427 #else
|
Chris@16
|
428 return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
|
Chris@16
|
429 #endif
|
Chris@16
|
430 }
|
Chris@16
|
431 BOOST_UBLAS_INLINE
|
Chris@16
|
432 iterator1 find1 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
433 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
434 return iterator1 (*this, i, j);
|
Chris@16
|
435 #else
|
Chris@16
|
436 return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
|
Chris@16
|
437 #endif
|
Chris@16
|
438 }
|
Chris@16
|
439 BOOST_UBLAS_INLINE
|
Chris@16
|
440 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
441 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
442 return const_iterator2 (*this, i, j);
|
Chris@16
|
443 #else
|
Chris@16
|
444 return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
|
Chris@16
|
445 #endif
|
Chris@16
|
446 }
|
Chris@16
|
447 BOOST_UBLAS_INLINE
|
Chris@16
|
448 iterator2 find2 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
449 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
450 return iterator2 (*this, i, j);
|
Chris@16
|
451 #else
|
Chris@16
|
452 return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
|
Chris@16
|
453 #endif
|
Chris@16
|
454 }
|
Chris@16
|
455
|
Chris@16
|
456
|
Chris@16
|
457 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
458 class const_iterator1:
|
Chris@16
|
459 public container_const_reference<matrix>,
|
Chris@16
|
460 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
461 const_iterator1, value_type> {
|
Chris@16
|
462 public:
|
Chris@16
|
463 typedef typename matrix::value_type value_type;
|
Chris@16
|
464 typedef typename matrix::difference_type difference_type;
|
Chris@16
|
465 typedef typename matrix::const_reference reference;
|
Chris@16
|
466 typedef const typename matrix::pointer pointer;
|
Chris@16
|
467
|
Chris@16
|
468 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
469 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
470
|
Chris@16
|
471 // Construction and destruction
|
Chris@16
|
472 BOOST_UBLAS_INLINE
|
Chris@16
|
473 const_iterator1 ():
|
Chris@16
|
474 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
475 BOOST_UBLAS_INLINE
|
Chris@16
|
476 const_iterator1 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
477 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
478 BOOST_UBLAS_INLINE
|
Chris@16
|
479 const_iterator1 (const iterator1 &it):
|
Chris@16
|
480 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
481
|
Chris@16
|
482 // Arithmetic
|
Chris@16
|
483 BOOST_UBLAS_INLINE
|
Chris@16
|
484 const_iterator1 &operator ++ () {
|
Chris@16
|
485 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
486 return *this;
|
Chris@16
|
487 }
|
Chris@16
|
488 BOOST_UBLAS_INLINE
|
Chris@16
|
489 const_iterator1 &operator -- () {
|
Chris@16
|
490 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
491 return *this;
|
Chris@16
|
492 }
|
Chris@16
|
493 BOOST_UBLAS_INLINE
|
Chris@16
|
494 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
495 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
496 return *this;
|
Chris@16
|
497 }
|
Chris@16
|
498 BOOST_UBLAS_INLINE
|
Chris@16
|
499 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
500 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
501 return *this;
|
Chris@16
|
502 }
|
Chris@16
|
503 BOOST_UBLAS_INLINE
|
Chris@16
|
504 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
505 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
506 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
507 }
|
Chris@16
|
508
|
Chris@16
|
509 // Dereference
|
Chris@16
|
510 BOOST_UBLAS_INLINE
|
Chris@16
|
511 const_reference operator * () const {
|
Chris@16
|
512 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
513 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
514 return *it_;
|
Chris@16
|
515 }
|
Chris@16
|
516 BOOST_UBLAS_INLINE
|
Chris@16
|
517 const_reference operator [] (difference_type n) const {
|
Chris@16
|
518 return *(*this + n);
|
Chris@16
|
519 }
|
Chris@16
|
520
|
Chris@16
|
521 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
522 BOOST_UBLAS_INLINE
|
Chris@16
|
523 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
524 typename self_type::
|
Chris@16
|
525 #endif
|
Chris@16
|
526 const_iterator2 begin () const {
|
Chris@16
|
527 const self_type &m = (*this) ();
|
Chris@16
|
528 return m.find2 (1, index1 (), 0);
|
Chris@16
|
529 }
|
Chris@16
|
530 BOOST_UBLAS_INLINE
|
Chris@16
|
531 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
532 typename self_type::
|
Chris@16
|
533 #endif
|
Chris@16
|
534 const_iterator2 end () const {
|
Chris@16
|
535 const self_type &m = (*this) ();
|
Chris@16
|
536 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
537 }
|
Chris@16
|
538 BOOST_UBLAS_INLINE
|
Chris@16
|
539 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
540 typename self_type::
|
Chris@16
|
541 #endif
|
Chris@16
|
542 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
543 return const_reverse_iterator2 (end ());
|
Chris@16
|
544 }
|
Chris@16
|
545 BOOST_UBLAS_INLINE
|
Chris@16
|
546 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
547 typename self_type::
|
Chris@16
|
548 #endif
|
Chris@16
|
549 const_reverse_iterator2 rend () const {
|
Chris@16
|
550 return const_reverse_iterator2 (begin ());
|
Chris@16
|
551 }
|
Chris@16
|
552 #endif
|
Chris@16
|
553
|
Chris@16
|
554 // Indices
|
Chris@16
|
555 BOOST_UBLAS_INLINE
|
Chris@16
|
556 size_type index1 () const {
|
Chris@16
|
557 const self_type &m = (*this) ();
|
Chris@16
|
558 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
559 }
|
Chris@16
|
560 BOOST_UBLAS_INLINE
|
Chris@16
|
561 size_type index2 () const {
|
Chris@16
|
562 const self_type &m = (*this) ();
|
Chris@16
|
563 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
564 }
|
Chris@16
|
565
|
Chris@16
|
566 // Assignment
|
Chris@16
|
567 BOOST_UBLAS_INLINE
|
Chris@16
|
568 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
569 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
570 it_ = it.it_;
|
Chris@16
|
571 return *this;
|
Chris@16
|
572 }
|
Chris@16
|
573
|
Chris@16
|
574 // Comparison
|
Chris@16
|
575 BOOST_UBLAS_INLINE
|
Chris@16
|
576 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
577 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
578 return it_ == it.it_;
|
Chris@16
|
579 }
|
Chris@16
|
580 BOOST_UBLAS_INLINE
|
Chris@16
|
581 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
582 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
583 return it_ < it.it_;
|
Chris@16
|
584 }
|
Chris@16
|
585
|
Chris@16
|
586 private:
|
Chris@16
|
587 const_subiterator_type it_;
|
Chris@16
|
588
|
Chris@16
|
589 friend class iterator1;
|
Chris@16
|
590 };
|
Chris@16
|
591 #endif
|
Chris@16
|
592
|
Chris@16
|
593 BOOST_UBLAS_INLINE
|
Chris@16
|
594 const_iterator1 begin1 () const {
|
Chris@16
|
595 return find1 (0, 0, 0);
|
Chris@16
|
596 }
|
Chris@16
|
597 BOOST_UBLAS_INLINE
|
Chris@16
|
598 const_iterator1 end1 () const {
|
Chris@16
|
599 return find1 (0, size1_, 0);
|
Chris@16
|
600 }
|
Chris@16
|
601
|
Chris@16
|
602 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
603 class iterator1:
|
Chris@16
|
604 public container_reference<matrix>,
|
Chris@16
|
605 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
606 iterator1, value_type> {
|
Chris@16
|
607 public:
|
Chris@16
|
608 typedef typename matrix::value_type value_type;
|
Chris@16
|
609 typedef typename matrix::difference_type difference_type;
|
Chris@16
|
610 typedef typename matrix::reference reference;
|
Chris@16
|
611 typedef typename matrix::pointer pointer;
|
Chris@16
|
612
|
Chris@16
|
613 typedef iterator2 dual_iterator_type;
|
Chris@16
|
614 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
615
|
Chris@16
|
616 // Construction and destruction
|
Chris@16
|
617 BOOST_UBLAS_INLINE
|
Chris@16
|
618 iterator1 ():
|
Chris@16
|
619 container_reference<self_type> (), it_ () {}
|
Chris@16
|
620 BOOST_UBLAS_INLINE
|
Chris@16
|
621 iterator1 (self_type &m, const subiterator_type &it):
|
Chris@16
|
622 container_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
623
|
Chris@16
|
624 // Arithmetic
|
Chris@16
|
625 BOOST_UBLAS_INLINE
|
Chris@16
|
626 iterator1 &operator ++ () {
|
Chris@16
|
627 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
628 return *this;
|
Chris@16
|
629 }
|
Chris@16
|
630 BOOST_UBLAS_INLINE
|
Chris@16
|
631 iterator1 &operator -- () {
|
Chris@16
|
632 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
633 return *this;
|
Chris@16
|
634 }
|
Chris@16
|
635 BOOST_UBLAS_INLINE
|
Chris@16
|
636 iterator1 &operator += (difference_type n) {
|
Chris@16
|
637 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
638 return *this;
|
Chris@16
|
639 }
|
Chris@16
|
640 BOOST_UBLAS_INLINE
|
Chris@16
|
641 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
642 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
643 return *this;
|
Chris@16
|
644 }
|
Chris@16
|
645 BOOST_UBLAS_INLINE
|
Chris@16
|
646 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
647 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
648 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
649 }
|
Chris@16
|
650
|
Chris@16
|
651 // Dereference
|
Chris@16
|
652 BOOST_UBLAS_INLINE
|
Chris@16
|
653 reference operator * () const {
|
Chris@16
|
654 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
655 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
656 return *it_;
|
Chris@16
|
657 }
|
Chris@16
|
658 BOOST_UBLAS_INLINE
|
Chris@16
|
659 reference operator [] (difference_type n) const {
|
Chris@16
|
660 return *(*this + n);
|
Chris@16
|
661 }
|
Chris@16
|
662
|
Chris@16
|
663 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
664 BOOST_UBLAS_INLINE
|
Chris@16
|
665 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
666 typename self_type::
|
Chris@16
|
667 #endif
|
Chris@16
|
668 iterator2 begin () const {
|
Chris@16
|
669 self_type &m = (*this) ();
|
Chris@16
|
670 return m.find2 (1, index1 (), 0);
|
Chris@16
|
671 }
|
Chris@16
|
672 BOOST_UBLAS_INLINE
|
Chris@16
|
673 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
674 typename self_type::
|
Chris@16
|
675 #endif
|
Chris@16
|
676 iterator2 end () const {
|
Chris@16
|
677 self_type &m = (*this) ();
|
Chris@16
|
678 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
679 }
|
Chris@16
|
680 BOOST_UBLAS_INLINE
|
Chris@16
|
681 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
682 typename self_type::
|
Chris@16
|
683 #endif
|
Chris@16
|
684 reverse_iterator2 rbegin () const {
|
Chris@16
|
685 return reverse_iterator2 (end ());
|
Chris@16
|
686 }
|
Chris@16
|
687 BOOST_UBLAS_INLINE
|
Chris@16
|
688 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
689 typename self_type::
|
Chris@16
|
690 #endif
|
Chris@16
|
691 reverse_iterator2 rend () const {
|
Chris@16
|
692 return reverse_iterator2 (begin ());
|
Chris@16
|
693 }
|
Chris@16
|
694 #endif
|
Chris@16
|
695
|
Chris@16
|
696 // Indices
|
Chris@16
|
697 BOOST_UBLAS_INLINE
|
Chris@16
|
698 size_type index1 () const {
|
Chris@16
|
699 self_type &m = (*this) ();
|
Chris@16
|
700 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
701 }
|
Chris@16
|
702 BOOST_UBLAS_INLINE
|
Chris@16
|
703 size_type index2 () const {
|
Chris@16
|
704 self_type &m = (*this) ();
|
Chris@16
|
705 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
706 }
|
Chris@16
|
707
|
Chris@16
|
708 // Assignment
|
Chris@16
|
709 BOOST_UBLAS_INLINE
|
Chris@16
|
710 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
711 container_reference<self_type>::assign (&it ());
|
Chris@16
|
712 it_ = it.it_;
|
Chris@16
|
713 return *this;
|
Chris@16
|
714 }
|
Chris@16
|
715
|
Chris@16
|
716 // Comparison
|
Chris@16
|
717 BOOST_UBLAS_INLINE
|
Chris@16
|
718 bool operator == (const iterator1 &it) const {
|
Chris@16
|
719 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
720 return it_ == it.it_;
|
Chris@16
|
721 }
|
Chris@16
|
722 BOOST_UBLAS_INLINE
|
Chris@16
|
723 bool operator < (const iterator1 &it) const {
|
Chris@16
|
724 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
725 return it_ < it.it_;
|
Chris@16
|
726 }
|
Chris@16
|
727
|
Chris@16
|
728 private:
|
Chris@16
|
729 subiterator_type it_;
|
Chris@16
|
730
|
Chris@16
|
731 friend class const_iterator1;
|
Chris@16
|
732 };
|
Chris@16
|
733 #endif
|
Chris@16
|
734
|
Chris@16
|
735 BOOST_UBLAS_INLINE
|
Chris@16
|
736 iterator1 begin1 () {
|
Chris@16
|
737 return find1 (0, 0, 0);
|
Chris@16
|
738 }
|
Chris@16
|
739 BOOST_UBLAS_INLINE
|
Chris@16
|
740 iterator1 end1 () {
|
Chris@16
|
741 return find1 (0, size1_, 0);
|
Chris@16
|
742 }
|
Chris@16
|
743
|
Chris@16
|
744 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
745 class const_iterator2:
|
Chris@16
|
746 public container_const_reference<matrix>,
|
Chris@16
|
747 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
748 const_iterator2, value_type> {
|
Chris@16
|
749 public:
|
Chris@16
|
750 typedef typename matrix::value_type value_type;
|
Chris@16
|
751 typedef typename matrix::difference_type difference_type;
|
Chris@16
|
752 typedef typename matrix::const_reference reference;
|
Chris@16
|
753 typedef const typename matrix::pointer pointer;
|
Chris@16
|
754
|
Chris@16
|
755 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
756 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
757
|
Chris@16
|
758 // Construction and destruction
|
Chris@16
|
759 BOOST_UBLAS_INLINE
|
Chris@16
|
760 const_iterator2 ():
|
Chris@16
|
761 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
762 BOOST_UBLAS_INLINE
|
Chris@16
|
763 const_iterator2 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
764 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
765 BOOST_UBLAS_INLINE
|
Chris@16
|
766 const_iterator2 (const iterator2 &it):
|
Chris@16
|
767 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
768
|
Chris@16
|
769 // Arithmetic
|
Chris@16
|
770 BOOST_UBLAS_INLINE
|
Chris@16
|
771 const_iterator2 &operator ++ () {
|
Chris@16
|
772 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
773 return *this;
|
Chris@16
|
774 }
|
Chris@16
|
775 BOOST_UBLAS_INLINE
|
Chris@16
|
776 const_iterator2 &operator -- () {
|
Chris@16
|
777 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
778 return *this;
|
Chris@16
|
779 }
|
Chris@16
|
780 BOOST_UBLAS_INLINE
|
Chris@16
|
781 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
782 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
783 return *this;
|
Chris@16
|
784 }
|
Chris@16
|
785 BOOST_UBLAS_INLINE
|
Chris@16
|
786 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
787 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
788 return *this;
|
Chris@16
|
789 }
|
Chris@16
|
790 BOOST_UBLAS_INLINE
|
Chris@16
|
791 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
792 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
793 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
794 }
|
Chris@16
|
795
|
Chris@16
|
796 // Dereference
|
Chris@16
|
797 BOOST_UBLAS_INLINE
|
Chris@16
|
798 const_reference operator * () const {
|
Chris@16
|
799 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
800 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
801 return *it_;
|
Chris@16
|
802 }
|
Chris@16
|
803 BOOST_UBLAS_INLINE
|
Chris@16
|
804 const_reference operator [] (difference_type n) const {
|
Chris@16
|
805 return *(*this + n);
|
Chris@16
|
806 }
|
Chris@16
|
807
|
Chris@16
|
808 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
809 BOOST_UBLAS_INLINE
|
Chris@16
|
810 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
811 typename self_type::
|
Chris@16
|
812 #endif
|
Chris@16
|
813 const_iterator1 begin () const {
|
Chris@16
|
814 const self_type &m = (*this) ();
|
Chris@16
|
815 return m.find1 (1, 0, index2 ());
|
Chris@16
|
816 }
|
Chris@16
|
817 BOOST_UBLAS_INLINE
|
Chris@16
|
818 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
819 typename self_type::
|
Chris@16
|
820 #endif
|
Chris@16
|
821 const_iterator1 end () const {
|
Chris@16
|
822 const self_type &m = (*this) ();
|
Chris@16
|
823 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
824 }
|
Chris@16
|
825 BOOST_UBLAS_INLINE
|
Chris@16
|
826 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
827 typename self_type::
|
Chris@16
|
828 #endif
|
Chris@16
|
829 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
830 return const_reverse_iterator1 (end ());
|
Chris@16
|
831 }
|
Chris@16
|
832 BOOST_UBLAS_INLINE
|
Chris@16
|
833 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
834 typename self_type::
|
Chris@16
|
835 #endif
|
Chris@16
|
836 const_reverse_iterator1 rend () const {
|
Chris@16
|
837 return const_reverse_iterator1 (begin ());
|
Chris@16
|
838 }
|
Chris@16
|
839 #endif
|
Chris@16
|
840
|
Chris@16
|
841 // Indices
|
Chris@16
|
842 BOOST_UBLAS_INLINE
|
Chris@16
|
843 size_type index1 () const {
|
Chris@16
|
844 const self_type &m = (*this) ();
|
Chris@16
|
845 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
846 }
|
Chris@16
|
847 BOOST_UBLAS_INLINE
|
Chris@16
|
848 size_type index2 () const {
|
Chris@16
|
849 const self_type &m = (*this) ();
|
Chris@16
|
850 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
851 }
|
Chris@16
|
852
|
Chris@16
|
853 // Assignment
|
Chris@16
|
854 BOOST_UBLAS_INLINE
|
Chris@16
|
855 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
856 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
857 it_ = it.it_;
|
Chris@16
|
858 return *this;
|
Chris@16
|
859 }
|
Chris@16
|
860
|
Chris@16
|
861 // Comparison
|
Chris@16
|
862 BOOST_UBLAS_INLINE
|
Chris@16
|
863 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
864 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
865 return it_ == it.it_;
|
Chris@16
|
866 }
|
Chris@16
|
867 BOOST_UBLAS_INLINE
|
Chris@16
|
868 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
869 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
870 return it_ < it.it_;
|
Chris@16
|
871 }
|
Chris@16
|
872
|
Chris@16
|
873 private:
|
Chris@16
|
874 const_subiterator_type it_;
|
Chris@16
|
875
|
Chris@16
|
876 friend class iterator2;
|
Chris@16
|
877 };
|
Chris@16
|
878 #endif
|
Chris@16
|
879
|
Chris@16
|
880 BOOST_UBLAS_INLINE
|
Chris@16
|
881 const_iterator2 begin2 () const {
|
Chris@16
|
882 return find2 (0, 0, 0);
|
Chris@16
|
883 }
|
Chris@16
|
884 BOOST_UBLAS_INLINE
|
Chris@16
|
885 const_iterator2 end2 () const {
|
Chris@16
|
886 return find2 (0, 0, size2_);
|
Chris@16
|
887 }
|
Chris@16
|
888
|
Chris@16
|
889 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
890 class iterator2:
|
Chris@16
|
891 public container_reference<matrix>,
|
Chris@16
|
892 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
893 iterator2, value_type> {
|
Chris@16
|
894 public:
|
Chris@16
|
895 typedef typename matrix::value_type value_type;
|
Chris@16
|
896 typedef typename matrix::difference_type difference_type;
|
Chris@16
|
897 typedef typename matrix::reference reference;
|
Chris@16
|
898 typedef typename matrix::pointer pointer;
|
Chris@16
|
899
|
Chris@16
|
900 typedef iterator1 dual_iterator_type;
|
Chris@16
|
901 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
902
|
Chris@16
|
903 // Construction and destruction
|
Chris@16
|
904 BOOST_UBLAS_INLINE
|
Chris@16
|
905 iterator2 ():
|
Chris@16
|
906 container_reference<self_type> (), it_ () {}
|
Chris@16
|
907 BOOST_UBLAS_INLINE
|
Chris@16
|
908 iterator2 (self_type &m, const subiterator_type &it):
|
Chris@16
|
909 container_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
910
|
Chris@16
|
911 // Arithmetic
|
Chris@16
|
912 BOOST_UBLAS_INLINE
|
Chris@16
|
913 iterator2 &operator ++ () {
|
Chris@16
|
914 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
915 return *this;
|
Chris@16
|
916 }
|
Chris@16
|
917 BOOST_UBLAS_INLINE
|
Chris@16
|
918 iterator2 &operator -- () {
|
Chris@16
|
919 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
920 return *this;
|
Chris@16
|
921 }
|
Chris@16
|
922 BOOST_UBLAS_INLINE
|
Chris@16
|
923 iterator2 &operator += (difference_type n) {
|
Chris@16
|
924 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
925 return *this;
|
Chris@16
|
926 }
|
Chris@16
|
927 BOOST_UBLAS_INLINE
|
Chris@16
|
928 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
929 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
930 return *this;
|
Chris@16
|
931 }
|
Chris@16
|
932 BOOST_UBLAS_INLINE
|
Chris@16
|
933 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
934 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
935 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
|
Chris@16
|
936 }
|
Chris@16
|
937
|
Chris@16
|
938 // Dereference
|
Chris@16
|
939 BOOST_UBLAS_INLINE
|
Chris@16
|
940 reference operator * () const {
|
Chris@16
|
941 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
942 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
943 return *it_;
|
Chris@16
|
944 }
|
Chris@16
|
945 BOOST_UBLAS_INLINE
|
Chris@16
|
946 reference operator [] (difference_type n) const {
|
Chris@16
|
947 return *(*this + n);
|
Chris@16
|
948 }
|
Chris@16
|
949
|
Chris@16
|
950 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
951 BOOST_UBLAS_INLINE
|
Chris@16
|
952 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
953 typename self_type::
|
Chris@16
|
954 #endif
|
Chris@16
|
955 iterator1 begin () const {
|
Chris@16
|
956 self_type &m = (*this) ();
|
Chris@16
|
957 return m.find1 (1, 0, index2 ());
|
Chris@16
|
958 }
|
Chris@16
|
959 BOOST_UBLAS_INLINE
|
Chris@16
|
960 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
961 typename self_type::
|
Chris@16
|
962 #endif
|
Chris@16
|
963 iterator1 end () const {
|
Chris@16
|
964 self_type &m = (*this) ();
|
Chris@16
|
965 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
966 }
|
Chris@16
|
967 BOOST_UBLAS_INLINE
|
Chris@16
|
968 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
969 typename self_type::
|
Chris@16
|
970 #endif
|
Chris@16
|
971 reverse_iterator1 rbegin () const {
|
Chris@16
|
972 return reverse_iterator1 (end ());
|
Chris@16
|
973 }
|
Chris@16
|
974 BOOST_UBLAS_INLINE
|
Chris@16
|
975 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
976 typename self_type::
|
Chris@16
|
977 #endif
|
Chris@16
|
978 reverse_iterator1 rend () const {
|
Chris@16
|
979 return reverse_iterator1 (begin ());
|
Chris@16
|
980 }
|
Chris@16
|
981 #endif
|
Chris@16
|
982
|
Chris@16
|
983 // Indices
|
Chris@16
|
984 BOOST_UBLAS_INLINE
|
Chris@16
|
985 size_type index1 () const {
|
Chris@16
|
986 self_type &m = (*this) ();
|
Chris@16
|
987 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
988 }
|
Chris@16
|
989 BOOST_UBLAS_INLINE
|
Chris@16
|
990 size_type index2 () const {
|
Chris@16
|
991 self_type &m = (*this) ();
|
Chris@16
|
992 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
|
Chris@16
|
993 }
|
Chris@16
|
994
|
Chris@16
|
995 // Assignment
|
Chris@16
|
996 BOOST_UBLAS_INLINE
|
Chris@16
|
997 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
998 container_reference<self_type>::assign (&it ());
|
Chris@16
|
999 it_ = it.it_;
|
Chris@16
|
1000 return *this;
|
Chris@16
|
1001 }
|
Chris@16
|
1002
|
Chris@16
|
1003 // Comparison
|
Chris@16
|
1004 BOOST_UBLAS_INLINE
|
Chris@16
|
1005 bool operator == (const iterator2 &it) const {
|
Chris@16
|
1006 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1007 return it_ == it.it_;
|
Chris@16
|
1008 }
|
Chris@16
|
1009 BOOST_UBLAS_INLINE
|
Chris@16
|
1010 bool operator < (const iterator2 &it) const {
|
Chris@16
|
1011 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1012 return it_ < it.it_;
|
Chris@16
|
1013 }
|
Chris@16
|
1014
|
Chris@16
|
1015 private:
|
Chris@16
|
1016 subiterator_type it_;
|
Chris@16
|
1017
|
Chris@16
|
1018 friend class const_iterator2;
|
Chris@16
|
1019 };
|
Chris@16
|
1020 #endif
|
Chris@16
|
1021
|
Chris@16
|
1022 BOOST_UBLAS_INLINE
|
Chris@16
|
1023 iterator2 begin2 () {
|
Chris@16
|
1024 return find2 (0, 0, 0);
|
Chris@16
|
1025 }
|
Chris@16
|
1026 BOOST_UBLAS_INLINE
|
Chris@16
|
1027 iterator2 end2 () {
|
Chris@16
|
1028 return find2 (0, 0, size2_);
|
Chris@16
|
1029 }
|
Chris@16
|
1030
|
Chris@16
|
1031 // Reverse iterators
|
Chris@16
|
1032
|
Chris@16
|
1033 BOOST_UBLAS_INLINE
|
Chris@16
|
1034 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
1035 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
1036 }
|
Chris@16
|
1037 BOOST_UBLAS_INLINE
|
Chris@16
|
1038 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
1039 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
1040 }
|
Chris@16
|
1041
|
Chris@16
|
1042 BOOST_UBLAS_INLINE
|
Chris@16
|
1043 reverse_iterator1 rbegin1 () {
|
Chris@16
|
1044 return reverse_iterator1 (end1 ());
|
Chris@16
|
1045 }
|
Chris@16
|
1046 BOOST_UBLAS_INLINE
|
Chris@16
|
1047 reverse_iterator1 rend1 () {
|
Chris@16
|
1048 return reverse_iterator1 (begin1 ());
|
Chris@16
|
1049 }
|
Chris@16
|
1050
|
Chris@16
|
1051 BOOST_UBLAS_INLINE
|
Chris@16
|
1052 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
1053 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
1054 }
|
Chris@16
|
1055 BOOST_UBLAS_INLINE
|
Chris@16
|
1056 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
1057 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
1058 }
|
Chris@16
|
1059
|
Chris@16
|
1060 BOOST_UBLAS_INLINE
|
Chris@16
|
1061 reverse_iterator2 rbegin2 () {
|
Chris@16
|
1062 return reverse_iterator2 (end2 ());
|
Chris@16
|
1063 }
|
Chris@16
|
1064 BOOST_UBLAS_INLINE
|
Chris@16
|
1065 reverse_iterator2 rend2 () {
|
Chris@16
|
1066 return reverse_iterator2 (begin2 ());
|
Chris@16
|
1067 }
|
Chris@16
|
1068
|
Chris@16
|
1069 // Serialization
|
Chris@16
|
1070 template<class Archive>
|
Chris@16
|
1071 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
1072
|
Chris@16
|
1073 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
1074 // and efficient serialization
|
Chris@16
|
1075 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
1076 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
1077
|
Chris@16
|
1078 // serialize the sizes
|
Chris@16
|
1079 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
1080 & serialization::make_nvp("size2",s2);
|
Chris@16
|
1081
|
Chris@16
|
1082 // copy the values back if loading
|
Chris@16
|
1083 if (Archive::is_loading::value) {
|
Chris@16
|
1084 size1_ = s1;
|
Chris@16
|
1085 size2_ = s2;
|
Chris@16
|
1086 }
|
Chris@16
|
1087 ar & serialization::make_nvp("data",data_);
|
Chris@16
|
1088 }
|
Chris@16
|
1089
|
Chris@16
|
1090 private:
|
Chris@16
|
1091 size_type size1_;
|
Chris@16
|
1092 size_type size2_;
|
Chris@16
|
1093 array_type data_;
|
Chris@16
|
1094 };
|
Chris@16
|
1095
|
Chris@16
|
1096 /** \brief A dense matrix of values of type \c T with a variable size bounded to a maximum of \f$M\f$ by \f$N\f$.
|
Chris@16
|
1097 *
|
Chris@16
|
1098 * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped
|
Chris@16
|
1099 * to the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$(i + j.m)\f$-th element
|
Chris@16
|
1100 * of the container for column major orientation. Finally in a dense matrix all elements are represented in memory
|
Chris@16
|
1101 * in a contiguous chunk of memory.
|
Chris@16
|
1102 *
|
Chris@16
|
1103 * Orientation can be specified. Default is \c row_major
|
Chris@16
|
1104 * The default constructor creates the matrix with size \f$M\f$ by \f$N\f$. Elements are constructed by the storage
|
Chris@16
|
1105 * type \c bounded_array, which need not initialise their value.
|
Chris@16
|
1106 *
|
Chris@16
|
1107 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
1108 * \tparam M maximum and default number of rows (if not specified at construction)
|
Chris@16
|
1109 * \tparam N maximum and default number of columns (if not specified at construction)
|
Chris@16
|
1110 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
|
Chris@16
|
1111 */
|
Chris@16
|
1112 template<class T, std::size_t M, std::size_t N, class L>
|
Chris@16
|
1113 class bounded_matrix:
|
Chris@16
|
1114 public matrix<T, L, bounded_array<T, M * N> > {
|
Chris@16
|
1115
|
Chris@16
|
1116 typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
|
Chris@16
|
1117 public:
|
Chris@16
|
1118 typedef typename matrix_type::size_type size_type;
|
Chris@16
|
1119 static const size_type max_size1 = M;
|
Chris@16
|
1120 static const size_type max_size2 = N;
|
Chris@16
|
1121
|
Chris@16
|
1122 // Construction and destruction
|
Chris@16
|
1123 BOOST_UBLAS_INLINE
|
Chris@16
|
1124 bounded_matrix ():
|
Chris@16
|
1125 matrix_type (M, N) {}
|
Chris@16
|
1126 BOOST_UBLAS_INLINE
|
Chris@16
|
1127 bounded_matrix (size_type size1, size_type size2):
|
Chris@16
|
1128 matrix_type (size1, size2) {}
|
Chris@16
|
1129 BOOST_UBLAS_INLINE
|
Chris@16
|
1130 bounded_matrix (const bounded_matrix &m):
|
Chris@16
|
1131 matrix_type (m) {}
|
Chris@16
|
1132 template<class A2> // Allow matrix<T, L, bounded_array<M,N> > construction
|
Chris@16
|
1133 BOOST_UBLAS_INLINE
|
Chris@16
|
1134 bounded_matrix (const matrix<T, L, A2> &m):
|
Chris@16
|
1135 matrix_type (m) {}
|
Chris@16
|
1136 template<class AE>
|
Chris@16
|
1137 BOOST_UBLAS_INLINE
|
Chris@16
|
1138 bounded_matrix (const matrix_expression<AE> &ae):
|
Chris@16
|
1139 matrix_type (ae) {}
|
Chris@16
|
1140 BOOST_UBLAS_INLINE
|
Chris@16
|
1141 ~bounded_matrix () {}
|
Chris@16
|
1142
|
Chris@16
|
1143 // Assignment
|
Chris@16
|
1144 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
|
Chris@16
|
1145
|
Chris@16
|
1146 /*! @note "pass by value" the key idea to enable move semantics */
|
Chris@16
|
1147 BOOST_UBLAS_INLINE
|
Chris@16
|
1148 bounded_matrix &operator = (bounded_matrix m) {
|
Chris@16
|
1149 matrix_type::operator = (m);
|
Chris@16
|
1150 return *this;
|
Chris@16
|
1151 }
|
Chris@16
|
1152 #else
|
Chris@16
|
1153 BOOST_UBLAS_INLINE
|
Chris@16
|
1154 bounded_matrix &operator = (const bounded_matrix &m) {
|
Chris@16
|
1155 matrix_type::operator = (m);
|
Chris@16
|
1156 return *this;
|
Chris@16
|
1157 }
|
Chris@16
|
1158 #endif
|
Chris@16
|
1159 template<class L2, class A2> // Generic matrix assignment
|
Chris@16
|
1160 BOOST_UBLAS_INLINE
|
Chris@16
|
1161 bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
|
Chris@16
|
1162 matrix_type::operator = (m);
|
Chris@16
|
1163 return *this;
|
Chris@16
|
1164 }
|
Chris@16
|
1165 template<class C> // Container assignment without temporary
|
Chris@16
|
1166 BOOST_UBLAS_INLINE
|
Chris@16
|
1167 bounded_matrix &operator = (const matrix_container<C> &m) {
|
Chris@16
|
1168 matrix_type::operator = (m);
|
Chris@16
|
1169 return *this;
|
Chris@16
|
1170 }
|
Chris@16
|
1171 template<class AE>
|
Chris@16
|
1172 BOOST_UBLAS_INLINE
|
Chris@16
|
1173 bounded_matrix &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
1174 matrix_type::operator = (ae);
|
Chris@16
|
1175 return *this;
|
Chris@16
|
1176 }
|
Chris@16
|
1177 };
|
Chris@16
|
1178
|
Chris@16
|
1179 /** \brief A dense matrix of values of type \c T stored as a vector of vectors.
|
Chris@16
|
1180 *
|
Chris@16
|
1181 * Rows or columns are not stored into contiguous chunks of memory but data inside rows (or columns) are.
|
Chris@16
|
1182 * Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
|
Chris@16
|
1183 * The data is stored as a vector of vectors, meaning that rows or columns might not be stored into contiguous chunks
|
Chris@16
|
1184 * of memory. Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
|
Chris@16
|
1185 * The storage type defaults to \c unbounded_array<unbounded_array<T>> and orientation is \c row_major. It is \b not
|
Chris@16
|
1186 * required by the storage to initialize elements of the matrix. For a \f$(m \times n)\f$-dimensional matrix and
|
Chris@16
|
1187 * \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the
|
Chris@16
|
1188 * container for row major orientation or the \f$(i + j.m)\f$-th element of the container for column major orientation.
|
Chris@16
|
1189 *
|
Chris@16
|
1190 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
1191 * \tparam L the storage organization. It can be either \c row_major or \c column_major. By default it is \c row_major
|
Chris@16
|
1192 * \tparam A the type of Storage array. By default, it is an \unbounded_array<unbounder_array<T>>
|
Chris@16
|
1193 */
|
Chris@16
|
1194 template<class T, class L, class A>
|
Chris@16
|
1195 class vector_of_vector:
|
Chris@16
|
1196 public matrix_container<vector_of_vector<T, L, A> > {
|
Chris@16
|
1197
|
Chris@16
|
1198 typedef T *pointer;
|
Chris@16
|
1199 typedef L layout_type;
|
Chris@16
|
1200 typedef vector_of_vector<T, L, A> self_type;
|
Chris@16
|
1201 public:
|
Chris@16
|
1202 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
1203 using matrix_container<self_type>::operator ();
|
Chris@16
|
1204 #endif
|
Chris@16
|
1205 typedef typename A::size_type size_type;
|
Chris@16
|
1206 typedef typename A::difference_type difference_type;
|
Chris@16
|
1207 typedef T value_type;
|
Chris@16
|
1208 typedef const T &const_reference;
|
Chris@16
|
1209 typedef T &reference;
|
Chris@16
|
1210 typedef A array_type;
|
Chris@16
|
1211 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
1212 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
1213 typedef vector<T, typename A::value_type> vector_temporary_type;
|
Chris@16
|
1214 typedef self_type matrix_temporary_type;
|
Chris@16
|
1215 typedef dense_tag storage_category;
|
Chris@16
|
1216 // This could be better for performance,
|
Chris@16
|
1217 // typedef typename unknown_orientation_tag orientation_category;
|
Chris@16
|
1218 // but others depend on the orientation information...
|
Chris@16
|
1219 typedef typename L::orientation_category orientation_category;
|
Chris@16
|
1220
|
Chris@16
|
1221 // Construction and destruction
|
Chris@16
|
1222 BOOST_UBLAS_INLINE
|
Chris@16
|
1223 vector_of_vector ():
|
Chris@16
|
1224 matrix_container<self_type> (),
|
Chris@16
|
1225 size1_ (0), size2_ (0), data_ (1) {}
|
Chris@16
|
1226 BOOST_UBLAS_INLINE
|
Chris@16
|
1227 vector_of_vector (size_type size1, size_type size2):
|
Chris@16
|
1228 matrix_container<self_type> (),
|
Chris@16
|
1229 size1_ (size1), size2_ (size2), data_ (1) {
|
Chris@16
|
1230 resize (size1, size2, true);
|
Chris@16
|
1231 }
|
Chris@16
|
1232 BOOST_UBLAS_INLINE
|
Chris@16
|
1233 vector_of_vector (const vector_of_vector &m):
|
Chris@16
|
1234 matrix_container<self_type> (),
|
Chris@16
|
1235 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
|
Chris@16
|
1236 template<class AE>
|
Chris@16
|
1237 BOOST_UBLAS_INLINE
|
Chris@16
|
1238 vector_of_vector (const matrix_expression<AE> &ae):
|
Chris@16
|
1239 matrix_container<self_type> (),
|
Chris@16
|
1240 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
|
Chris@16
|
1241 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
|
Chris@16
|
1242 data ()[k].resize (layout_type::size_m (size1_, size2_));
|
Chris@16
|
1243 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
1244 }
|
Chris@16
|
1245
|
Chris@16
|
1246 // Accessors
|
Chris@16
|
1247 BOOST_UBLAS_INLINE
|
Chris@16
|
1248 size_type size1 () const {
|
Chris@16
|
1249 return size1_;
|
Chris@16
|
1250 }
|
Chris@16
|
1251 BOOST_UBLAS_INLINE
|
Chris@16
|
1252 size_type size2 () const {
|
Chris@16
|
1253 return size2_;
|
Chris@16
|
1254 }
|
Chris@16
|
1255
|
Chris@16
|
1256 // Storage accessors
|
Chris@16
|
1257 BOOST_UBLAS_INLINE
|
Chris@16
|
1258 const array_type &data () const {
|
Chris@16
|
1259 return data_;
|
Chris@16
|
1260 }
|
Chris@16
|
1261 BOOST_UBLAS_INLINE
|
Chris@16
|
1262 array_type &data () {
|
Chris@16
|
1263 return data_;
|
Chris@16
|
1264 }
|
Chris@16
|
1265
|
Chris@16
|
1266 // Resizing
|
Chris@16
|
1267 BOOST_UBLAS_INLINE
|
Chris@16
|
1268 void resize (size_type size1, size_type size2, bool preserve = true) {
|
Chris@16
|
1269 size1_ = size1;
|
Chris@16
|
1270 size2_ = size2;
|
Chris@16
|
1271 if (preserve)
|
Chris@16
|
1272 data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ());
|
Chris@16
|
1273 else
|
Chris@16
|
1274 data ().resize (layout_type::size_M (size1, size2) + 1);
|
Chris@16
|
1275 for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) {
|
Chris@16
|
1276 if (preserve)
|
Chris@16
|
1277 data () [k].resize (layout_type::size_m (size1, size2), value_type ());
|
Chris@16
|
1278 else
|
Chris@16
|
1279 data () [k].resize (layout_type::size_m (size1, size2));
|
Chris@16
|
1280 }
|
Chris@16
|
1281 }
|
Chris@16
|
1282
|
Chris@16
|
1283 // Element access
|
Chris@16
|
1284 BOOST_UBLAS_INLINE
|
Chris@16
|
1285 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
1286 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
|
Chris@16
|
1287 }
|
Chris@16
|
1288 BOOST_UBLAS_INLINE
|
Chris@16
|
1289 reference at_element (size_type i, size_type j) {
|
Chris@16
|
1290 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
|
Chris@16
|
1291 }
|
Chris@16
|
1292 BOOST_UBLAS_INLINE
|
Chris@16
|
1293 reference operator () (size_type i, size_type j) {
|
Chris@16
|
1294 return at_element (i, j);
|
Chris@16
|
1295 }
|
Chris@16
|
1296
|
Chris@16
|
1297 // Element assignment
|
Chris@16
|
1298 BOOST_UBLAS_INLINE
|
Chris@16
|
1299 reference insert_element (size_type i, size_type j, const_reference t) {
|
Chris@16
|
1300 return (at_element (i, j) = t);
|
Chris@16
|
1301 }
|
Chris@16
|
1302 BOOST_UBLAS_INLINE
|
Chris@16
|
1303 void erase_element (size_type i, size_type j) {
|
Chris@16
|
1304 at_element (i, j) = value_type/*zero*/();
|
Chris@16
|
1305 }
|
Chris@16
|
1306
|
Chris@16
|
1307 // Zeroing
|
Chris@16
|
1308 BOOST_UBLAS_INLINE
|
Chris@16
|
1309 void clear () {
|
Chris@16
|
1310 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
|
Chris@16
|
1311 std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
|
Chris@16
|
1312 }
|
Chris@16
|
1313
|
Chris@16
|
1314 // Assignment
|
Chris@16
|
1315 BOOST_UBLAS_INLINE
|
Chris@16
|
1316 vector_of_vector &operator = (const vector_of_vector &m) {
|
Chris@16
|
1317 size1_ = m.size1_;
|
Chris@16
|
1318 size2_ = m.size2_;
|
Chris@16
|
1319 data () = m.data ();
|
Chris@16
|
1320 return *this;
|
Chris@16
|
1321 }
|
Chris@16
|
1322 BOOST_UBLAS_INLINE
|
Chris@16
|
1323 vector_of_vector &assign_temporary (vector_of_vector &m) {
|
Chris@16
|
1324 swap (m);
|
Chris@16
|
1325 return *this;
|
Chris@16
|
1326 }
|
Chris@16
|
1327 template<class AE>
|
Chris@16
|
1328 BOOST_UBLAS_INLINE
|
Chris@16
|
1329 vector_of_vector &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
1330 self_type temporary (ae);
|
Chris@16
|
1331 return assign_temporary (temporary);
|
Chris@16
|
1332 }
|
Chris@16
|
1333 template<class C> // Container assignment without temporary
|
Chris@16
|
1334 BOOST_UBLAS_INLINE
|
Chris@16
|
1335 vector_of_vector &operator = (const matrix_container<C> &m) {
|
Chris@16
|
1336 resize (m ().size1 (), m ().size2 (), false);
|
Chris@16
|
1337 assign (m);
|
Chris@16
|
1338 return *this;
|
Chris@16
|
1339 }
|
Chris@16
|
1340 template<class AE>
|
Chris@16
|
1341 BOOST_UBLAS_INLINE
|
Chris@16
|
1342 vector_of_vector &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
1343 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
1344 return *this;
|
Chris@16
|
1345 }
|
Chris@16
|
1346 template<class AE>
|
Chris@16
|
1347 BOOST_UBLAS_INLINE
|
Chris@16
|
1348 vector_of_vector& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
1349 self_type temporary (*this + ae);
|
Chris@16
|
1350 return assign_temporary (temporary);
|
Chris@16
|
1351 }
|
Chris@16
|
1352 template<class C> // Container assignment without temporary
|
Chris@16
|
1353 BOOST_UBLAS_INLINE
|
Chris@16
|
1354 vector_of_vector &operator += (const matrix_container<C> &m) {
|
Chris@16
|
1355 plus_assign (m);
|
Chris@16
|
1356 return *this;
|
Chris@16
|
1357 }
|
Chris@16
|
1358 template<class AE>
|
Chris@16
|
1359 BOOST_UBLAS_INLINE
|
Chris@16
|
1360 vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
1361 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
1362 return *this;
|
Chris@16
|
1363 }
|
Chris@16
|
1364 template<class AE>
|
Chris@16
|
1365 BOOST_UBLAS_INLINE
|
Chris@16
|
1366 vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
1367 self_type temporary (*this - ae);
|
Chris@16
|
1368 return assign_temporary (temporary);
|
Chris@16
|
1369 }
|
Chris@16
|
1370 template<class C> // Container assignment without temporary
|
Chris@16
|
1371 BOOST_UBLAS_INLINE
|
Chris@16
|
1372 vector_of_vector &operator -= (const matrix_container<C> &m) {
|
Chris@16
|
1373 minus_assign (m);
|
Chris@16
|
1374 return *this;
|
Chris@16
|
1375 }
|
Chris@16
|
1376 template<class AE>
|
Chris@16
|
1377 BOOST_UBLAS_INLINE
|
Chris@16
|
1378 vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
1379 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
1380 return *this;
|
Chris@16
|
1381 }
|
Chris@16
|
1382 template<class AT>
|
Chris@16
|
1383 BOOST_UBLAS_INLINE
|
Chris@16
|
1384 vector_of_vector& operator *= (const AT &at) {
|
Chris@16
|
1385 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
1386 return *this;
|
Chris@16
|
1387 }
|
Chris@16
|
1388 template<class AT>
|
Chris@16
|
1389 BOOST_UBLAS_INLINE
|
Chris@16
|
1390 vector_of_vector& operator /= (const AT &at) {
|
Chris@16
|
1391 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
1392 return *this;
|
Chris@16
|
1393 }
|
Chris@16
|
1394
|
Chris@16
|
1395 // Swapping
|
Chris@16
|
1396 BOOST_UBLAS_INLINE
|
Chris@16
|
1397 void swap (vector_of_vector &m) {
|
Chris@16
|
1398 if (this != &m) {
|
Chris@16
|
1399 std::swap (size1_, m.size1_);
|
Chris@16
|
1400 std::swap (size2_, m.size2_);
|
Chris@16
|
1401 data ().swap (m.data ());
|
Chris@16
|
1402 }
|
Chris@16
|
1403 }
|
Chris@16
|
1404 BOOST_UBLAS_INLINE
|
Chris@16
|
1405 friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
|
Chris@16
|
1406 m1.swap (m2);
|
Chris@16
|
1407 }
|
Chris@16
|
1408
|
Chris@16
|
1409 // Iterator types
|
Chris@16
|
1410 private:
|
Chris@16
|
1411 // Use the vector iterator
|
Chris@16
|
1412 typedef typename A::value_type::const_iterator const_subiterator_type;
|
Chris@16
|
1413 typedef typename A::value_type::iterator subiterator_type;
|
Chris@16
|
1414 public:
|
Chris@16
|
1415 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1416 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
|
Chris@16
|
1417 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
|
Chris@16
|
1418 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
|
Chris@16
|
1419 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
|
Chris@16
|
1420 #else
|
Chris@16
|
1421 class const_iterator1;
|
Chris@16
|
1422 class iterator1;
|
Chris@16
|
1423 class const_iterator2;
|
Chris@16
|
1424 class iterator2;
|
Chris@16
|
1425 #endif
|
Chris@16
|
1426 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
1427 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
1428 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
1429 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
1430
|
Chris@16
|
1431 // Element lookup
|
Chris@16
|
1432 BOOST_UBLAS_INLINE
|
Chris@16
|
1433 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
|
Chris@16
|
1434 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1435 return const_iterator1 (*this, i, j);
|
Chris@16
|
1436 #else
|
Chris@16
|
1437 return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
|
Chris@16
|
1438 #endif
|
Chris@16
|
1439 }
|
Chris@16
|
1440 BOOST_UBLAS_INLINE
|
Chris@16
|
1441 iterator1 find1 (int /*rank*/, size_type i, size_type j) {
|
Chris@16
|
1442 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1443 return iterator1 (*this, i, j);
|
Chris@16
|
1444 #else
|
Chris@16
|
1445 return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
|
Chris@16
|
1446 #endif
|
Chris@16
|
1447 }
|
Chris@16
|
1448 BOOST_UBLAS_INLINE
|
Chris@16
|
1449 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
|
Chris@16
|
1450 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1451 return const_iterator2 (*this, i, j);
|
Chris@16
|
1452 #else
|
Chris@16
|
1453 return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
|
Chris@16
|
1454 #endif
|
Chris@16
|
1455 }
|
Chris@16
|
1456 BOOST_UBLAS_INLINE
|
Chris@16
|
1457 iterator2 find2 (int /*rank*/, size_type i, size_type j) {
|
Chris@16
|
1458 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1459 return iterator2 (*this, i, j);
|
Chris@16
|
1460 #else
|
Chris@16
|
1461 return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
|
Chris@16
|
1462 #endif
|
Chris@16
|
1463 }
|
Chris@16
|
1464
|
Chris@16
|
1465
|
Chris@16
|
1466 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1467 class const_iterator1:
|
Chris@16
|
1468 public container_const_reference<vector_of_vector>,
|
Chris@16
|
1469 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
1470 const_iterator1, value_type> {
|
Chris@16
|
1471 public:
|
Chris@16
|
1472 typedef typename vector_of_vector::value_type value_type;
|
Chris@16
|
1473 typedef typename vector_of_vector::difference_type difference_type;
|
Chris@16
|
1474 typedef typename vector_of_vector::const_reference reference;
|
Chris@16
|
1475 typedef const typename vector_of_vector::pointer pointer;
|
Chris@16
|
1476
|
Chris@16
|
1477 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
1478 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
1479
|
Chris@16
|
1480 // Construction and destruction
|
Chris@16
|
1481 BOOST_UBLAS_INLINE
|
Chris@16
|
1482 const_iterator1 ():
|
Chris@16
|
1483 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
|
Chris@16
|
1484 BOOST_UBLAS_INLINE
|
Chris@16
|
1485 const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
|
Chris@16
|
1486 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
|
Chris@16
|
1487 BOOST_UBLAS_INLINE
|
Chris@16
|
1488 const_iterator1 (const iterator1 &it):
|
Chris@16
|
1489 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
|
Chris@16
|
1490
|
Chris@16
|
1491 // Arithmetic
|
Chris@16
|
1492 BOOST_UBLAS_INLINE
|
Chris@16
|
1493 const_iterator1 &operator ++ () {
|
Chris@16
|
1494 ++ i_;
|
Chris@16
|
1495 const self_type &m = (*this) ();
|
Chris@16
|
1496 if (layout_type::fast_i ())
|
Chris@16
|
1497 ++ it_;
|
Chris@16
|
1498 else
|
Chris@16
|
1499 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1500 return *this;
|
Chris@16
|
1501 }
|
Chris@16
|
1502 BOOST_UBLAS_INLINE
|
Chris@16
|
1503 const_iterator1 &operator -- () {
|
Chris@16
|
1504 -- i_;
|
Chris@16
|
1505 const self_type &m = (*this) ();
|
Chris@16
|
1506 if (layout_type::fast_i ())
|
Chris@16
|
1507 -- it_;
|
Chris@16
|
1508 else
|
Chris@16
|
1509 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1510 return *this;
|
Chris@16
|
1511 }
|
Chris@16
|
1512 BOOST_UBLAS_INLINE
|
Chris@16
|
1513 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
1514 i_ += n;
|
Chris@16
|
1515 const self_type &m = (*this) ();
|
Chris@16
|
1516 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1517 return *this;
|
Chris@16
|
1518 }
|
Chris@16
|
1519 BOOST_UBLAS_INLINE
|
Chris@16
|
1520 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
1521 i_ -= n;
|
Chris@16
|
1522 const self_type &m = (*this) ();
|
Chris@16
|
1523 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1524 return *this;
|
Chris@16
|
1525 }
|
Chris@16
|
1526 BOOST_UBLAS_INLINE
|
Chris@16
|
1527 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
1528 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1529 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1530 return index1 () - it.index1 ();
|
Chris@16
|
1531 }
|
Chris@16
|
1532
|
Chris@16
|
1533 // Dereference
|
Chris@16
|
1534 BOOST_UBLAS_INLINE
|
Chris@16
|
1535 const_reference operator * () const {
|
Chris@16
|
1536 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1537 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1538 return *it_;
|
Chris@16
|
1539 }
|
Chris@16
|
1540 BOOST_UBLAS_INLINE
|
Chris@16
|
1541 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1542 return *(*this + n);
|
Chris@16
|
1543 }
|
Chris@16
|
1544
|
Chris@16
|
1545 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1546 BOOST_UBLAS_INLINE
|
Chris@16
|
1547 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1548 typename self_type::
|
Chris@16
|
1549 #endif
|
Chris@16
|
1550 const_iterator2 begin () const {
|
Chris@16
|
1551 const self_type &m = (*this) ();
|
Chris@16
|
1552 return m.find2 (1, index1 (), 0);
|
Chris@16
|
1553 }
|
Chris@16
|
1554 BOOST_UBLAS_INLINE
|
Chris@16
|
1555 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1556 typename self_type::
|
Chris@16
|
1557 #endif
|
Chris@16
|
1558 const_iterator2 end () const {
|
Chris@16
|
1559 const self_type &m = (*this) ();
|
Chris@16
|
1560 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
1561 }
|
Chris@16
|
1562 BOOST_UBLAS_INLINE
|
Chris@16
|
1563 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1564 typename self_type::
|
Chris@16
|
1565 #endif
|
Chris@16
|
1566 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
1567 return const_reverse_iterator2 (end ());
|
Chris@16
|
1568 }
|
Chris@16
|
1569 BOOST_UBLAS_INLINE
|
Chris@16
|
1570 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1571 typename self_type::
|
Chris@16
|
1572 #endif
|
Chris@16
|
1573 const_reverse_iterator2 rend () const {
|
Chris@16
|
1574 return const_reverse_iterator2 (begin ());
|
Chris@16
|
1575 }
|
Chris@16
|
1576 #endif
|
Chris@16
|
1577
|
Chris@16
|
1578 // Indices
|
Chris@16
|
1579 BOOST_UBLAS_INLINE
|
Chris@16
|
1580 size_type index1 () const {
|
Chris@16
|
1581 return i_;
|
Chris@16
|
1582 }
|
Chris@16
|
1583 BOOST_UBLAS_INLINE
|
Chris@16
|
1584 size_type index2 () const {
|
Chris@16
|
1585 return j_;
|
Chris@16
|
1586 }
|
Chris@16
|
1587
|
Chris@16
|
1588 // Assignment
|
Chris@16
|
1589 BOOST_UBLAS_INLINE
|
Chris@16
|
1590 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
1591 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
1592 it_ = it.it_;
|
Chris@16
|
1593 return *this;
|
Chris@16
|
1594 }
|
Chris@16
|
1595
|
Chris@16
|
1596 // Comparison
|
Chris@16
|
1597 BOOST_UBLAS_INLINE
|
Chris@16
|
1598 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
1599 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1600 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1601 return it_ == it.it_;
|
Chris@16
|
1602 }
|
Chris@16
|
1603 BOOST_UBLAS_INLINE
|
Chris@16
|
1604 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
1605 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1606 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1607 return it_ < it.it_;
|
Chris@16
|
1608 }
|
Chris@16
|
1609
|
Chris@16
|
1610 private:
|
Chris@16
|
1611 size_type i_;
|
Chris@16
|
1612 size_type j_;
|
Chris@16
|
1613 const_subiterator_type it_;
|
Chris@16
|
1614
|
Chris@16
|
1615 friend class iterator1;
|
Chris@16
|
1616 };
|
Chris@16
|
1617 #endif
|
Chris@16
|
1618
|
Chris@16
|
1619 BOOST_UBLAS_INLINE
|
Chris@16
|
1620 const_iterator1 begin1 () const {
|
Chris@16
|
1621 return find1 (0, 0, 0);
|
Chris@16
|
1622 }
|
Chris@16
|
1623 BOOST_UBLAS_INLINE
|
Chris@16
|
1624 const_iterator1 end1 () const {
|
Chris@16
|
1625 return find1 (0, size1_, 0);
|
Chris@16
|
1626 }
|
Chris@16
|
1627
|
Chris@16
|
1628 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1629 class iterator1:
|
Chris@16
|
1630 public container_reference<vector_of_vector>,
|
Chris@16
|
1631 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
1632 iterator1, value_type> {
|
Chris@16
|
1633 public:
|
Chris@16
|
1634 typedef typename vector_of_vector::value_type value_type;
|
Chris@16
|
1635 typedef typename vector_of_vector::difference_type difference_type;
|
Chris@16
|
1636 typedef typename vector_of_vector::reference reference;
|
Chris@16
|
1637 typedef typename vector_of_vector::pointer pointer;
|
Chris@16
|
1638
|
Chris@16
|
1639 typedef iterator2 dual_iterator_type;
|
Chris@16
|
1640 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
1641
|
Chris@16
|
1642 // Construction and destruction
|
Chris@16
|
1643 BOOST_UBLAS_INLINE
|
Chris@16
|
1644 iterator1 ():
|
Chris@16
|
1645 container_reference<self_type> (), i_ (), j_ (), it_ () {}
|
Chris@16
|
1646 BOOST_UBLAS_INLINE
|
Chris@16
|
1647 iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
|
Chris@16
|
1648 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
|
Chris@16
|
1649
|
Chris@16
|
1650 // Arithmetic
|
Chris@16
|
1651 BOOST_UBLAS_INLINE
|
Chris@16
|
1652 iterator1 &operator ++ () {
|
Chris@16
|
1653 ++ i_;
|
Chris@16
|
1654 self_type &m = (*this) ();
|
Chris@16
|
1655 if (layout_type::fast_i ())
|
Chris@16
|
1656 ++ it_;
|
Chris@16
|
1657 else
|
Chris@16
|
1658 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1659 return *this;
|
Chris@16
|
1660 }
|
Chris@16
|
1661 BOOST_UBLAS_INLINE
|
Chris@16
|
1662 iterator1 &operator -- () {
|
Chris@16
|
1663 -- i_;
|
Chris@16
|
1664 self_type &m = (*this) ();
|
Chris@16
|
1665 if (layout_type::fast_i ())
|
Chris@16
|
1666 -- it_;
|
Chris@16
|
1667 else
|
Chris@16
|
1668 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1669 return *this;
|
Chris@16
|
1670 }
|
Chris@16
|
1671 BOOST_UBLAS_INLINE
|
Chris@16
|
1672 iterator1 &operator += (difference_type n) {
|
Chris@16
|
1673 i_ += n;
|
Chris@16
|
1674 self_type &m = (*this) ();
|
Chris@16
|
1675 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1676 return *this;
|
Chris@16
|
1677 }
|
Chris@16
|
1678 BOOST_UBLAS_INLINE
|
Chris@16
|
1679 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
1680 i_ -= n;
|
Chris@16
|
1681 self_type &m = (*this) ();
|
Chris@16
|
1682 it_ = m.find1 (1, i_, j_).it_;
|
Chris@16
|
1683 return *this;
|
Chris@16
|
1684 }
|
Chris@16
|
1685 BOOST_UBLAS_INLINE
|
Chris@16
|
1686 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
1687 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1688 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1689 return index1 () - it.index1 ();
|
Chris@16
|
1690 }
|
Chris@16
|
1691
|
Chris@16
|
1692 // Dereference
|
Chris@16
|
1693 BOOST_UBLAS_INLINE
|
Chris@16
|
1694 reference operator * () const {
|
Chris@16
|
1695 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1696 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1697 return *it_;
|
Chris@16
|
1698 }
|
Chris@16
|
1699 BOOST_UBLAS_INLINE
|
Chris@16
|
1700 reference operator [] (difference_type n) const {
|
Chris@16
|
1701 return *(*this + n);
|
Chris@16
|
1702 }
|
Chris@16
|
1703
|
Chris@16
|
1704 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1705 BOOST_UBLAS_INLINE
|
Chris@16
|
1706 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1707 typename self_type::
|
Chris@16
|
1708 #endif
|
Chris@16
|
1709 iterator2 begin () const {
|
Chris@16
|
1710 self_type &m = (*this) ();
|
Chris@16
|
1711 return m.find2 (1, index1 (), 0);
|
Chris@16
|
1712 }
|
Chris@16
|
1713 BOOST_UBLAS_INLINE
|
Chris@16
|
1714 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1715 typename self_type::
|
Chris@16
|
1716 #endif
|
Chris@16
|
1717 iterator2 end () const {
|
Chris@16
|
1718 self_type &m = (*this) ();
|
Chris@16
|
1719 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
1720 }
|
Chris@16
|
1721 BOOST_UBLAS_INLINE
|
Chris@16
|
1722 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1723 typename self_type::
|
Chris@16
|
1724 #endif
|
Chris@16
|
1725 reverse_iterator2 rbegin () const {
|
Chris@16
|
1726 return reverse_iterator2 (end ());
|
Chris@16
|
1727 }
|
Chris@16
|
1728 BOOST_UBLAS_INLINE
|
Chris@16
|
1729 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1730 typename self_type::
|
Chris@16
|
1731 #endif
|
Chris@16
|
1732 reverse_iterator2 rend () const {
|
Chris@16
|
1733 return reverse_iterator2 (begin ());
|
Chris@16
|
1734 }
|
Chris@16
|
1735 #endif
|
Chris@16
|
1736
|
Chris@16
|
1737 // Indices
|
Chris@16
|
1738 BOOST_UBLAS_INLINE
|
Chris@16
|
1739 size_type index1 () const {
|
Chris@16
|
1740 return i_;
|
Chris@16
|
1741 }
|
Chris@16
|
1742 BOOST_UBLAS_INLINE
|
Chris@16
|
1743 size_type index2 () const {
|
Chris@16
|
1744 return j_;
|
Chris@16
|
1745 }
|
Chris@16
|
1746
|
Chris@16
|
1747 // Assignment
|
Chris@16
|
1748 BOOST_UBLAS_INLINE
|
Chris@16
|
1749 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
1750 container_reference<self_type>::assign (&it ());
|
Chris@16
|
1751 it_ = it.it_;
|
Chris@16
|
1752 return *this;
|
Chris@16
|
1753 }
|
Chris@16
|
1754
|
Chris@16
|
1755 // Comparison
|
Chris@16
|
1756 BOOST_UBLAS_INLINE
|
Chris@16
|
1757 bool operator == (const iterator1 &it) const {
|
Chris@16
|
1758 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1759 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1760 return it_ == it.it_;
|
Chris@16
|
1761 }
|
Chris@16
|
1762 BOOST_UBLAS_INLINE
|
Chris@16
|
1763 bool operator < (const iterator1 &it) const {
|
Chris@16
|
1764 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1765 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
|
Chris@16
|
1766 return it_ < it.it_;
|
Chris@16
|
1767 }
|
Chris@16
|
1768
|
Chris@16
|
1769 private:
|
Chris@16
|
1770 size_type i_;
|
Chris@16
|
1771 size_type j_;
|
Chris@16
|
1772 subiterator_type it_;
|
Chris@16
|
1773
|
Chris@16
|
1774 friend class const_iterator1;
|
Chris@16
|
1775 };
|
Chris@16
|
1776 #endif
|
Chris@16
|
1777
|
Chris@16
|
1778 BOOST_UBLAS_INLINE
|
Chris@16
|
1779 iterator1 begin1 () {
|
Chris@16
|
1780 return find1 (0, 0, 0);
|
Chris@16
|
1781 }
|
Chris@16
|
1782 BOOST_UBLAS_INLINE
|
Chris@16
|
1783 iterator1 end1 () {
|
Chris@16
|
1784 return find1 (0, size1_, 0);
|
Chris@16
|
1785 }
|
Chris@16
|
1786
|
Chris@16
|
1787 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1788 class const_iterator2:
|
Chris@16
|
1789 public container_const_reference<vector_of_vector>,
|
Chris@16
|
1790 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
1791 const_iterator2, value_type> {
|
Chris@16
|
1792 public:
|
Chris@16
|
1793 typedef typename vector_of_vector::value_type value_type;
|
Chris@16
|
1794 typedef typename vector_of_vector::difference_type difference_type;
|
Chris@16
|
1795 typedef typename vector_of_vector::const_reference reference;
|
Chris@16
|
1796 typedef const typename vector_of_vector::pointer pointer;
|
Chris@16
|
1797
|
Chris@16
|
1798 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
1799 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
1800
|
Chris@16
|
1801 // Construction and destruction
|
Chris@16
|
1802 BOOST_UBLAS_INLINE
|
Chris@16
|
1803 const_iterator2 ():
|
Chris@16
|
1804 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
|
Chris@16
|
1805 BOOST_UBLAS_INLINE
|
Chris@16
|
1806 const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
|
Chris@16
|
1807 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
|
Chris@16
|
1808 BOOST_UBLAS_INLINE
|
Chris@16
|
1809 const_iterator2 (const iterator2 &it):
|
Chris@16
|
1810 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
|
Chris@16
|
1811
|
Chris@16
|
1812 // Arithmetic
|
Chris@16
|
1813 BOOST_UBLAS_INLINE
|
Chris@16
|
1814 const_iterator2 &operator ++ () {
|
Chris@16
|
1815 ++ j_;
|
Chris@16
|
1816 const self_type &m = (*this) ();
|
Chris@16
|
1817 if (layout_type::fast_j ())
|
Chris@16
|
1818 ++ it_;
|
Chris@16
|
1819 else
|
Chris@16
|
1820 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1821 return *this;
|
Chris@16
|
1822 }
|
Chris@16
|
1823 BOOST_UBLAS_INLINE
|
Chris@16
|
1824 const_iterator2 &operator -- () {
|
Chris@16
|
1825 -- j_;
|
Chris@16
|
1826 const self_type &m = (*this) ();
|
Chris@16
|
1827 if (layout_type::fast_j ())
|
Chris@16
|
1828 -- it_;
|
Chris@16
|
1829 else
|
Chris@16
|
1830 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1831 return *this;
|
Chris@16
|
1832 }
|
Chris@16
|
1833 BOOST_UBLAS_INLINE
|
Chris@16
|
1834 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
1835 j_ += n;
|
Chris@16
|
1836 const self_type &m = (*this) ();
|
Chris@16
|
1837 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1838 return *this;
|
Chris@16
|
1839 }
|
Chris@16
|
1840 BOOST_UBLAS_INLINE
|
Chris@16
|
1841 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
1842 j_ -= n;
|
Chris@16
|
1843 const self_type &m = (*this) ();
|
Chris@16
|
1844 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1845 return *this;
|
Chris@16
|
1846 }
|
Chris@16
|
1847 BOOST_UBLAS_INLINE
|
Chris@16
|
1848 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
1849 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1850 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
1851 return index2 () - it.index2 ();
|
Chris@16
|
1852 }
|
Chris@16
|
1853
|
Chris@16
|
1854 // Dereference
|
Chris@16
|
1855 BOOST_UBLAS_INLINE
|
Chris@16
|
1856 const_reference operator * () const {
|
Chris@16
|
1857 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1858 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1859 return *it_;
|
Chris@16
|
1860 }
|
Chris@16
|
1861 BOOST_UBLAS_INLINE
|
Chris@16
|
1862 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1863 return *(*this + n);
|
Chris@16
|
1864 }
|
Chris@16
|
1865
|
Chris@16
|
1866 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1867 BOOST_UBLAS_INLINE
|
Chris@16
|
1868 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1869 typename self_type::
|
Chris@16
|
1870 #endif
|
Chris@16
|
1871 const_iterator1 begin () const {
|
Chris@16
|
1872 const self_type &m = (*this) ();
|
Chris@16
|
1873 return m.find1 (1, 0, index2 ());
|
Chris@16
|
1874 }
|
Chris@16
|
1875 BOOST_UBLAS_INLINE
|
Chris@16
|
1876 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1877 typename self_type::
|
Chris@16
|
1878 #endif
|
Chris@16
|
1879 const_iterator1 end () const {
|
Chris@16
|
1880 const self_type &m = (*this) ();
|
Chris@16
|
1881 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
1882 }
|
Chris@16
|
1883 BOOST_UBLAS_INLINE
|
Chris@16
|
1884 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1885 typename self_type::
|
Chris@16
|
1886 #endif
|
Chris@16
|
1887 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
1888 return const_reverse_iterator1 (end ());
|
Chris@16
|
1889 }
|
Chris@16
|
1890 BOOST_UBLAS_INLINE
|
Chris@16
|
1891 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
1892 typename self_type::
|
Chris@16
|
1893 #endif
|
Chris@16
|
1894 const_reverse_iterator1 rend () const {
|
Chris@16
|
1895 return const_reverse_iterator1 (begin ());
|
Chris@16
|
1896 }
|
Chris@16
|
1897 #endif
|
Chris@16
|
1898
|
Chris@16
|
1899 // Indices
|
Chris@16
|
1900 BOOST_UBLAS_INLINE
|
Chris@16
|
1901 size_type index1 () const {
|
Chris@16
|
1902 return i_;
|
Chris@16
|
1903 }
|
Chris@16
|
1904 BOOST_UBLAS_INLINE
|
Chris@16
|
1905 size_type index2 () const {
|
Chris@16
|
1906 return j_;
|
Chris@16
|
1907 }
|
Chris@16
|
1908
|
Chris@16
|
1909 // Assignment
|
Chris@16
|
1910 BOOST_UBLAS_INLINE
|
Chris@16
|
1911 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
1912 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
1913 it_ = it.it_;
|
Chris@16
|
1914 return *this;
|
Chris@16
|
1915 }
|
Chris@16
|
1916
|
Chris@16
|
1917 // Comparison
|
Chris@16
|
1918 BOOST_UBLAS_INLINE
|
Chris@16
|
1919 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
1920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1921 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
1922 return it_ == it.it_;
|
Chris@16
|
1923 }
|
Chris@16
|
1924 BOOST_UBLAS_INLINE
|
Chris@16
|
1925 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
1926 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1927 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
1928 return it_ < it.it_;
|
Chris@16
|
1929 }
|
Chris@16
|
1930
|
Chris@16
|
1931 private:
|
Chris@16
|
1932 size_type i_;
|
Chris@16
|
1933 size_type j_;
|
Chris@16
|
1934 const_subiterator_type it_;
|
Chris@16
|
1935
|
Chris@16
|
1936 friend class iterator2;
|
Chris@16
|
1937 };
|
Chris@16
|
1938 #endif
|
Chris@16
|
1939
|
Chris@16
|
1940 BOOST_UBLAS_INLINE
|
Chris@16
|
1941 const_iterator2 begin2 () const {
|
Chris@16
|
1942 return find2 (0, 0, 0);
|
Chris@16
|
1943 }
|
Chris@16
|
1944 BOOST_UBLAS_INLINE
|
Chris@16
|
1945 const_iterator2 end2 () const {
|
Chris@16
|
1946 return find2 (0, 0, size2_);
|
Chris@16
|
1947 }
|
Chris@16
|
1948
|
Chris@16
|
1949 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1950 class iterator2:
|
Chris@16
|
1951 public container_reference<vector_of_vector>,
|
Chris@16
|
1952 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
1953 iterator2, value_type> {
|
Chris@16
|
1954 public:
|
Chris@16
|
1955 typedef typename vector_of_vector::value_type value_type;
|
Chris@16
|
1956 typedef typename vector_of_vector::difference_type difference_type;
|
Chris@16
|
1957 typedef typename vector_of_vector::reference reference;
|
Chris@16
|
1958 typedef typename vector_of_vector::pointer pointer;
|
Chris@16
|
1959
|
Chris@16
|
1960 typedef iterator1 dual_iterator_type;
|
Chris@16
|
1961 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
1962
|
Chris@16
|
1963 // Construction and destruction
|
Chris@16
|
1964 BOOST_UBLAS_INLINE
|
Chris@16
|
1965 iterator2 ():
|
Chris@16
|
1966 container_reference<self_type> (), i_ (), j_ (), it_ () {}
|
Chris@16
|
1967 BOOST_UBLAS_INLINE
|
Chris@16
|
1968 iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
|
Chris@16
|
1969 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
|
Chris@16
|
1970
|
Chris@16
|
1971 // Arithmetic
|
Chris@16
|
1972 BOOST_UBLAS_INLINE
|
Chris@16
|
1973 iterator2 &operator ++ () {
|
Chris@16
|
1974 ++ j_;
|
Chris@16
|
1975 self_type &m = (*this) ();
|
Chris@16
|
1976 if (layout_type::fast_j ())
|
Chris@16
|
1977 ++ it_;
|
Chris@16
|
1978 else
|
Chris@16
|
1979 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1980 return *this;
|
Chris@16
|
1981 }
|
Chris@16
|
1982 BOOST_UBLAS_INLINE
|
Chris@16
|
1983 iterator2 &operator -- () {
|
Chris@16
|
1984 -- j_;
|
Chris@16
|
1985 self_type &m = (*this) ();
|
Chris@16
|
1986 if (layout_type::fast_j ())
|
Chris@16
|
1987 -- it_;
|
Chris@16
|
1988 else
|
Chris@16
|
1989 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1990 return *this;
|
Chris@16
|
1991 }
|
Chris@16
|
1992 BOOST_UBLAS_INLINE
|
Chris@16
|
1993 iterator2 &operator += (difference_type n) {
|
Chris@16
|
1994 j_ += n;
|
Chris@16
|
1995 self_type &m = (*this) ();
|
Chris@16
|
1996 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
1997 return *this;
|
Chris@16
|
1998 }
|
Chris@16
|
1999 BOOST_UBLAS_INLINE
|
Chris@16
|
2000 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
2001 j_ -= n;
|
Chris@16
|
2002 self_type &m = (*this) ();
|
Chris@16
|
2003 it_ = m.find2 (1, i_, j_).it_;
|
Chris@16
|
2004 return *this;
|
Chris@16
|
2005 }
|
Chris@16
|
2006 BOOST_UBLAS_INLINE
|
Chris@16
|
2007 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
2008 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2009 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
2010 return index2 () - it.index2 ();
|
Chris@16
|
2011 }
|
Chris@16
|
2012
|
Chris@16
|
2013 // Dereference
|
Chris@16
|
2014 BOOST_UBLAS_INLINE
|
Chris@16
|
2015 reference operator * () const {
|
Chris@16
|
2016 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
2017 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
2018 return *it_;
|
Chris@16
|
2019 }
|
Chris@16
|
2020 BOOST_UBLAS_INLINE
|
Chris@16
|
2021 reference operator [] (difference_type n) const {
|
Chris@16
|
2022 return *(*this + n);
|
Chris@16
|
2023 }
|
Chris@16
|
2024
|
Chris@16
|
2025 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2026 BOOST_UBLAS_INLINE
|
Chris@16
|
2027 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2028 typename self_type::
|
Chris@16
|
2029 #endif
|
Chris@16
|
2030 iterator1 begin () const {
|
Chris@16
|
2031 self_type &m = (*this) ();
|
Chris@16
|
2032 return m.find1 (1, 0, index2 ());
|
Chris@16
|
2033 }
|
Chris@16
|
2034 BOOST_UBLAS_INLINE
|
Chris@16
|
2035 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2036 typename self_type::
|
Chris@16
|
2037 #endif
|
Chris@16
|
2038 iterator1 end () const {
|
Chris@16
|
2039 self_type &m = (*this) ();
|
Chris@16
|
2040 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
2041 }
|
Chris@16
|
2042 BOOST_UBLAS_INLINE
|
Chris@16
|
2043 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2044 typename self_type::
|
Chris@16
|
2045 #endif
|
Chris@16
|
2046 reverse_iterator1 rbegin () const {
|
Chris@16
|
2047 return reverse_iterator1 (end ());
|
Chris@16
|
2048 }
|
Chris@16
|
2049 BOOST_UBLAS_INLINE
|
Chris@16
|
2050 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2051 typename self_type::
|
Chris@16
|
2052 #endif
|
Chris@16
|
2053 reverse_iterator1 rend () const {
|
Chris@16
|
2054 return reverse_iterator1 (begin ());
|
Chris@16
|
2055 }
|
Chris@16
|
2056 #endif
|
Chris@16
|
2057
|
Chris@16
|
2058 // Indices
|
Chris@16
|
2059 BOOST_UBLAS_INLINE
|
Chris@16
|
2060 size_type index1 () const {
|
Chris@16
|
2061 return i_;
|
Chris@16
|
2062 }
|
Chris@16
|
2063 BOOST_UBLAS_INLINE
|
Chris@16
|
2064 size_type index2 () const {
|
Chris@16
|
2065 return j_;
|
Chris@16
|
2066 }
|
Chris@16
|
2067
|
Chris@16
|
2068 // Assignment
|
Chris@16
|
2069 BOOST_UBLAS_INLINE
|
Chris@16
|
2070 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
2071 container_reference<self_type>::assign (&it ());
|
Chris@16
|
2072 it_ = it.it_;
|
Chris@16
|
2073 return *this;
|
Chris@16
|
2074 }
|
Chris@16
|
2075
|
Chris@16
|
2076 // Comparison
|
Chris@16
|
2077 BOOST_UBLAS_INLINE
|
Chris@16
|
2078 bool operator == (const iterator2 &it) const {
|
Chris@16
|
2079 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2080 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
2081 return it_ == it.it_;
|
Chris@16
|
2082 }
|
Chris@16
|
2083 BOOST_UBLAS_INLINE
|
Chris@16
|
2084 bool operator < (const iterator2 &it) const {
|
Chris@16
|
2085 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2086 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
|
Chris@16
|
2087 return it_ < it.it_;
|
Chris@16
|
2088 }
|
Chris@16
|
2089
|
Chris@16
|
2090 private:
|
Chris@16
|
2091 size_type i_;
|
Chris@16
|
2092 size_type j_;
|
Chris@16
|
2093 subiterator_type it_;
|
Chris@16
|
2094
|
Chris@16
|
2095 friend class const_iterator2;
|
Chris@16
|
2096 };
|
Chris@16
|
2097 #endif
|
Chris@16
|
2098
|
Chris@16
|
2099 BOOST_UBLAS_INLINE
|
Chris@16
|
2100 iterator2 begin2 () {
|
Chris@16
|
2101 return find2 (0, 0, 0);
|
Chris@16
|
2102 }
|
Chris@16
|
2103 BOOST_UBLAS_INLINE
|
Chris@16
|
2104 iterator2 end2 () {
|
Chris@16
|
2105 return find2 (0, 0, size2_);
|
Chris@16
|
2106 }
|
Chris@16
|
2107
|
Chris@16
|
2108 // Reverse iterators
|
Chris@16
|
2109
|
Chris@16
|
2110 BOOST_UBLAS_INLINE
|
Chris@16
|
2111 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
2112 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
2113 }
|
Chris@16
|
2114 BOOST_UBLAS_INLINE
|
Chris@16
|
2115 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
2116 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
2117 }
|
Chris@16
|
2118
|
Chris@16
|
2119 BOOST_UBLAS_INLINE
|
Chris@16
|
2120 reverse_iterator1 rbegin1 () {
|
Chris@16
|
2121 return reverse_iterator1 (end1 ());
|
Chris@16
|
2122 }
|
Chris@16
|
2123 BOOST_UBLAS_INLINE
|
Chris@16
|
2124 reverse_iterator1 rend1 () {
|
Chris@16
|
2125 return reverse_iterator1 (begin1 ());
|
Chris@16
|
2126 }
|
Chris@16
|
2127
|
Chris@16
|
2128 BOOST_UBLAS_INLINE
|
Chris@16
|
2129 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
2130 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
2131 }
|
Chris@16
|
2132 BOOST_UBLAS_INLINE
|
Chris@16
|
2133 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
2134 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
2135 }
|
Chris@16
|
2136
|
Chris@16
|
2137 BOOST_UBLAS_INLINE
|
Chris@16
|
2138 reverse_iterator2 rbegin2 () {
|
Chris@16
|
2139 return reverse_iterator2 (end2 ());
|
Chris@16
|
2140 }
|
Chris@16
|
2141 BOOST_UBLAS_INLINE
|
Chris@16
|
2142 reverse_iterator2 rend2 () {
|
Chris@16
|
2143 return reverse_iterator2 (begin2 ());
|
Chris@16
|
2144 }
|
Chris@16
|
2145
|
Chris@16
|
2146 // Serialization
|
Chris@16
|
2147 template<class Archive>
|
Chris@16
|
2148 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
2149
|
Chris@16
|
2150 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
2151 // and efficient serialization
|
Chris@16
|
2152 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
2153 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
2154
|
Chris@16
|
2155 // serialize the sizes
|
Chris@16
|
2156 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
2157 & serialization::make_nvp("size2",s2);
|
Chris@16
|
2158
|
Chris@16
|
2159 // copy the values back if loading
|
Chris@16
|
2160 if (Archive::is_loading::value) {
|
Chris@16
|
2161 size1_ = s1;
|
Chris@16
|
2162 size2_ = s2;
|
Chris@16
|
2163 }
|
Chris@16
|
2164 ar & serialization::make_nvp("data",data_);
|
Chris@16
|
2165 }
|
Chris@16
|
2166
|
Chris@16
|
2167 private:
|
Chris@16
|
2168 size_type size1_;
|
Chris@16
|
2169 size_type size2_;
|
Chris@16
|
2170 array_type data_;
|
Chris@16
|
2171 };
|
Chris@16
|
2172
|
Chris@16
|
2173
|
Chris@16
|
2174 /** \brief A matrix with all values of type \c T equal to zero
|
Chris@16
|
2175 *
|
Chris@16
|
2176 * Changing values does not affect the matrix, however assigning it to a normal matrix will put zero
|
Chris@16
|
2177 * everywhere in the target matrix. All accesses are constant time, due to the trivial value.
|
Chris@16
|
2178 *
|
Chris@16
|
2179 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
2180 * \tparam ALLOC an allocator for storing the zero element. By default, a standar allocator is used.
|
Chris@16
|
2181 */
|
Chris@16
|
2182 template<class T, class ALLOC>
|
Chris@16
|
2183 class zero_matrix:
|
Chris@16
|
2184 public matrix_container<zero_matrix<T, ALLOC> > {
|
Chris@16
|
2185
|
Chris@16
|
2186 typedef const T *const_pointer;
|
Chris@16
|
2187 typedef zero_matrix<T, ALLOC> self_type;
|
Chris@16
|
2188 public:
|
Chris@16
|
2189 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
2190 using matrix_container<self_type>::operator ();
|
Chris@16
|
2191 #endif
|
Chris@16
|
2192 typedef typename ALLOC::size_type size_type;
|
Chris@16
|
2193 typedef typename ALLOC::difference_type difference_type;
|
Chris@16
|
2194 typedef T value_type;
|
Chris@16
|
2195 typedef const T &const_reference;
|
Chris@16
|
2196 typedef T &reference;
|
Chris@16
|
2197 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
2198 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
2199 typedef sparse_tag storage_category;
|
Chris@16
|
2200 typedef unknown_orientation_tag orientation_category;
|
Chris@16
|
2201
|
Chris@16
|
2202 // Construction and destruction
|
Chris@16
|
2203 BOOST_UBLAS_INLINE
|
Chris@16
|
2204 zero_matrix ():
|
Chris@16
|
2205 matrix_container<self_type> (),
|
Chris@16
|
2206 size1_ (0), size2_ (0) {}
|
Chris@16
|
2207 BOOST_UBLAS_INLINE
|
Chris@16
|
2208 zero_matrix (size_type size):
|
Chris@16
|
2209 matrix_container<self_type> (),
|
Chris@16
|
2210 size1_ (size), size2_ (size) {}
|
Chris@16
|
2211 BOOST_UBLAS_INLINE
|
Chris@16
|
2212 zero_matrix (size_type size1, size_type size2):
|
Chris@16
|
2213 matrix_container<self_type> (),
|
Chris@16
|
2214 size1_ (size1), size2_ (size2) {}
|
Chris@16
|
2215 BOOST_UBLAS_INLINE
|
Chris@16
|
2216 zero_matrix (const zero_matrix &m):
|
Chris@16
|
2217 matrix_container<self_type> (),
|
Chris@16
|
2218 size1_ (m.size1_), size2_ (m.size2_) {}
|
Chris@16
|
2219
|
Chris@16
|
2220 // Accessors
|
Chris@16
|
2221 BOOST_UBLAS_INLINE
|
Chris@16
|
2222 size_type size1 () const {
|
Chris@16
|
2223 return size1_;
|
Chris@16
|
2224 }
|
Chris@16
|
2225 BOOST_UBLAS_INLINE
|
Chris@16
|
2226 size_type size2 () const {
|
Chris@16
|
2227 return size2_;
|
Chris@16
|
2228 }
|
Chris@16
|
2229
|
Chris@16
|
2230 // Resizing
|
Chris@16
|
2231 BOOST_UBLAS_INLINE
|
Chris@16
|
2232 void resize (size_type size, bool preserve = true) {
|
Chris@16
|
2233 size1_ = size;
|
Chris@16
|
2234 size2_ = size;
|
Chris@16
|
2235 }
|
Chris@16
|
2236 BOOST_UBLAS_INLINE
|
Chris@16
|
2237 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
|
Chris@16
|
2238 size1_ = size1;
|
Chris@16
|
2239 size2_ = size2;
|
Chris@16
|
2240 }
|
Chris@16
|
2241
|
Chris@16
|
2242 // Element access
|
Chris@16
|
2243 BOOST_UBLAS_INLINE
|
Chris@16
|
2244 const_reference operator () (size_type /* i */, size_type /* j */) const {
|
Chris@16
|
2245 return zero_;
|
Chris@16
|
2246 }
|
Chris@16
|
2247
|
Chris@16
|
2248 // Assignment
|
Chris@16
|
2249 BOOST_UBLAS_INLINE
|
Chris@16
|
2250 zero_matrix &operator = (const zero_matrix &m) {
|
Chris@16
|
2251 size1_ = m.size1_;
|
Chris@16
|
2252 size2_ = m.size2_;
|
Chris@16
|
2253 return *this;
|
Chris@16
|
2254 }
|
Chris@16
|
2255 BOOST_UBLAS_INLINE
|
Chris@16
|
2256 zero_matrix &assign_temporary (zero_matrix &m) {
|
Chris@16
|
2257 swap (m);
|
Chris@16
|
2258 return *this;
|
Chris@16
|
2259 }
|
Chris@16
|
2260
|
Chris@16
|
2261 // Swapping
|
Chris@16
|
2262 BOOST_UBLAS_INLINE
|
Chris@16
|
2263 void swap (zero_matrix &m) {
|
Chris@16
|
2264 if (this != &m) {
|
Chris@16
|
2265 std::swap (size1_, m.size1_);
|
Chris@16
|
2266 std::swap (size2_, m.size2_);
|
Chris@16
|
2267 }
|
Chris@16
|
2268 }
|
Chris@16
|
2269 BOOST_UBLAS_INLINE
|
Chris@16
|
2270 friend void swap (zero_matrix &m1, zero_matrix &m2) {
|
Chris@16
|
2271 m1.swap (m2);
|
Chris@16
|
2272 }
|
Chris@16
|
2273
|
Chris@16
|
2274 // Iterator types
|
Chris@16
|
2275 public:
|
Chris@16
|
2276 class const_iterator1;
|
Chris@16
|
2277 class const_iterator2;
|
Chris@16
|
2278 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
2279 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
2280
|
Chris@16
|
2281 // Element lookup
|
Chris@16
|
2282 BOOST_UBLAS_INLINE
|
Chris@16
|
2283 const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
|
Chris@16
|
2284 return const_iterator1 (*this);
|
Chris@16
|
2285 }
|
Chris@16
|
2286 BOOST_UBLAS_INLINE
|
Chris@16
|
2287 const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
|
Chris@16
|
2288 return const_iterator2 (*this);
|
Chris@16
|
2289 }
|
Chris@16
|
2290
|
Chris@16
|
2291 class const_iterator1:
|
Chris@16
|
2292 public container_const_reference<zero_matrix>,
|
Chris@16
|
2293 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
|
Chris@16
|
2294 const_iterator1, value_type> {
|
Chris@16
|
2295 public:
|
Chris@16
|
2296 typedef typename zero_matrix::value_type value_type;
|
Chris@16
|
2297 typedef typename zero_matrix::difference_type difference_type;
|
Chris@16
|
2298 typedef typename zero_matrix::const_reference reference;
|
Chris@16
|
2299 typedef typename zero_matrix::const_pointer pointer;
|
Chris@16
|
2300
|
Chris@16
|
2301 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
2302 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
2303
|
Chris@16
|
2304 // Construction and destruction
|
Chris@16
|
2305 BOOST_UBLAS_INLINE
|
Chris@16
|
2306 const_iterator1 ():
|
Chris@16
|
2307 container_const_reference<self_type> () {}
|
Chris@16
|
2308 BOOST_UBLAS_INLINE
|
Chris@16
|
2309 const_iterator1 (const self_type &m):
|
Chris@16
|
2310 container_const_reference<self_type> (m) {}
|
Chris@16
|
2311
|
Chris@16
|
2312 // Arithmetic
|
Chris@16
|
2313 BOOST_UBLAS_INLINE
|
Chris@16
|
2314 const_iterator1 &operator ++ () {
|
Chris@16
|
2315 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2316 return *this;
|
Chris@16
|
2317 }
|
Chris@16
|
2318 BOOST_UBLAS_INLINE
|
Chris@16
|
2319 const_iterator1 &operator -- () {
|
Chris@16
|
2320 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2321 return *this;
|
Chris@16
|
2322 }
|
Chris@16
|
2323
|
Chris@16
|
2324 // Dereference
|
Chris@16
|
2325 BOOST_UBLAS_INLINE
|
Chris@16
|
2326 const_reference operator * () const {
|
Chris@16
|
2327 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2328 return zero_; // arbitary return value
|
Chris@16
|
2329 }
|
Chris@16
|
2330
|
Chris@16
|
2331 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2332 BOOST_UBLAS_INLINE
|
Chris@16
|
2333 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2334 typename self_type::
|
Chris@16
|
2335 #endif
|
Chris@16
|
2336 const_iterator2 begin () const {
|
Chris@16
|
2337 return const_iterator2 ((*this) ());
|
Chris@16
|
2338 }
|
Chris@16
|
2339 BOOST_UBLAS_INLINE
|
Chris@16
|
2340 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2341 typename self_type::
|
Chris@16
|
2342 #endif
|
Chris@16
|
2343 const_iterator2 end () const {
|
Chris@16
|
2344 return const_iterator2 ((*this) ());
|
Chris@16
|
2345 }
|
Chris@16
|
2346 BOOST_UBLAS_INLINE
|
Chris@16
|
2347 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2348 typename self_type::
|
Chris@16
|
2349 #endif
|
Chris@16
|
2350 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
2351 return const_reverse_iterator2 (end ());
|
Chris@16
|
2352 }
|
Chris@16
|
2353 BOOST_UBLAS_INLINE
|
Chris@16
|
2354 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2355 typename self_type::
|
Chris@16
|
2356 #endif
|
Chris@16
|
2357 const_reverse_iterator2 rend () const {
|
Chris@16
|
2358 return const_reverse_iterator2 (begin ());
|
Chris@16
|
2359 }
|
Chris@16
|
2360 #endif
|
Chris@16
|
2361
|
Chris@16
|
2362 // Indices
|
Chris@16
|
2363 BOOST_UBLAS_INLINE
|
Chris@16
|
2364 size_type index1 () const {
|
Chris@16
|
2365 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2366 return 0; // arbitary return value
|
Chris@16
|
2367 }
|
Chris@16
|
2368 BOOST_UBLAS_INLINE
|
Chris@16
|
2369 size_type index2 () const {
|
Chris@16
|
2370 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2371 return 0; // arbitary return value
|
Chris@16
|
2372 }
|
Chris@16
|
2373
|
Chris@16
|
2374 // Assignment
|
Chris@16
|
2375 BOOST_UBLAS_INLINE
|
Chris@16
|
2376 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
2377 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2378 return *this;
|
Chris@16
|
2379 }
|
Chris@16
|
2380
|
Chris@16
|
2381 // Comparison
|
Chris@16
|
2382 BOOST_UBLAS_INLINE
|
Chris@16
|
2383 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
2384 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2385 detail::ignore_unused_variable_warning(it);
|
Chris@16
|
2386 return true;
|
Chris@16
|
2387 }
|
Chris@16
|
2388 };
|
Chris@16
|
2389
|
Chris@16
|
2390 typedef const_iterator1 iterator1;
|
Chris@16
|
2391
|
Chris@16
|
2392 BOOST_UBLAS_INLINE
|
Chris@16
|
2393 const_iterator1 begin1 () const {
|
Chris@16
|
2394 return const_iterator1 (*this);
|
Chris@16
|
2395 }
|
Chris@16
|
2396 BOOST_UBLAS_INLINE
|
Chris@16
|
2397 const_iterator1 end1 () const {
|
Chris@16
|
2398 return const_iterator1 (*this);
|
Chris@16
|
2399 }
|
Chris@16
|
2400
|
Chris@16
|
2401 class const_iterator2:
|
Chris@16
|
2402 public container_const_reference<zero_matrix>,
|
Chris@16
|
2403 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
|
Chris@16
|
2404 const_iterator2, value_type> {
|
Chris@16
|
2405 public:
|
Chris@16
|
2406 typedef typename zero_matrix::value_type value_type;
|
Chris@16
|
2407 typedef typename zero_matrix::difference_type difference_type;
|
Chris@16
|
2408 typedef typename zero_matrix::const_reference reference;
|
Chris@16
|
2409 typedef typename zero_matrix::const_pointer pointer;
|
Chris@16
|
2410
|
Chris@16
|
2411 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
2412 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
2413
|
Chris@16
|
2414 // Construction and destruction
|
Chris@16
|
2415 BOOST_UBLAS_INLINE
|
Chris@16
|
2416 const_iterator2 ():
|
Chris@16
|
2417 container_const_reference<self_type> () {}
|
Chris@16
|
2418 BOOST_UBLAS_INLINE
|
Chris@16
|
2419 const_iterator2 (const self_type &m):
|
Chris@16
|
2420 container_const_reference<self_type> (m) {}
|
Chris@16
|
2421
|
Chris@16
|
2422 // Arithmetic
|
Chris@16
|
2423 BOOST_UBLAS_INLINE
|
Chris@16
|
2424 const_iterator2 &operator ++ () {
|
Chris@16
|
2425 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2426 return *this;
|
Chris@16
|
2427 }
|
Chris@16
|
2428 BOOST_UBLAS_INLINE
|
Chris@16
|
2429 const_iterator2 &operator -- () {
|
Chris@16
|
2430 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2431 return *this;
|
Chris@16
|
2432 }
|
Chris@16
|
2433
|
Chris@16
|
2434 // Dereference
|
Chris@16
|
2435 BOOST_UBLAS_INLINE
|
Chris@16
|
2436 const_reference operator * () const {
|
Chris@16
|
2437 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2438 return zero_; // arbitary return value
|
Chris@16
|
2439 }
|
Chris@16
|
2440
|
Chris@16
|
2441 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2442 BOOST_UBLAS_INLINE
|
Chris@16
|
2443 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2444 typename self_type::
|
Chris@16
|
2445 #endif
|
Chris@16
|
2446 const_iterator1 begin () const {
|
Chris@16
|
2447 return const_iterator1 ((*this) ());
|
Chris@16
|
2448 }
|
Chris@16
|
2449 BOOST_UBLAS_INLINE
|
Chris@16
|
2450 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2451 typename self_type::
|
Chris@16
|
2452 #endif
|
Chris@16
|
2453 const_iterator1 end () const {
|
Chris@16
|
2454 return const_iterator1 ((*this) ());
|
Chris@16
|
2455 }
|
Chris@16
|
2456 BOOST_UBLAS_INLINE
|
Chris@16
|
2457 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2458 typename self_type::
|
Chris@16
|
2459 #endif
|
Chris@16
|
2460 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
2461 return const_reverse_iterator1 (end ());
|
Chris@16
|
2462 }
|
Chris@16
|
2463 BOOST_UBLAS_INLINE
|
Chris@16
|
2464 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2465 typename self_type::
|
Chris@16
|
2466 #endif
|
Chris@16
|
2467 const_reverse_iterator1 rend () const {
|
Chris@16
|
2468 return const_reverse_iterator1 (begin ());
|
Chris@16
|
2469 }
|
Chris@16
|
2470 #endif
|
Chris@16
|
2471
|
Chris@16
|
2472 // Indices
|
Chris@16
|
2473 BOOST_UBLAS_INLINE
|
Chris@16
|
2474 size_type index1 () const {
|
Chris@16
|
2475 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2476 return 0; // arbitary return value
|
Chris@16
|
2477 }
|
Chris@16
|
2478 BOOST_UBLAS_INLINE
|
Chris@16
|
2479 size_type index2 () const {
|
Chris@16
|
2480 BOOST_UBLAS_CHECK_FALSE (bad_index ());
|
Chris@16
|
2481 return 0; // arbitary return value
|
Chris@16
|
2482 }
|
Chris@16
|
2483
|
Chris@16
|
2484 // Assignment
|
Chris@16
|
2485 BOOST_UBLAS_INLINE
|
Chris@16
|
2486 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
2487 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2488 return *this;
|
Chris@16
|
2489 }
|
Chris@16
|
2490
|
Chris@16
|
2491 // Comparison
|
Chris@16
|
2492 BOOST_UBLAS_INLINE
|
Chris@16
|
2493 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
2494 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2495 detail::ignore_unused_variable_warning(it);
|
Chris@16
|
2496 return true;
|
Chris@16
|
2497 }
|
Chris@16
|
2498 };
|
Chris@16
|
2499
|
Chris@16
|
2500 typedef const_iterator2 iterator2;
|
Chris@16
|
2501
|
Chris@16
|
2502 BOOST_UBLAS_INLINE
|
Chris@16
|
2503 const_iterator2 begin2 () const {
|
Chris@16
|
2504 return find2 (0, 0, 0);
|
Chris@16
|
2505 }
|
Chris@16
|
2506 BOOST_UBLAS_INLINE
|
Chris@16
|
2507 const_iterator2 end2 () const {
|
Chris@16
|
2508 return find2 (0, 0, size2_);
|
Chris@16
|
2509 }
|
Chris@16
|
2510
|
Chris@16
|
2511 // Reverse iterators
|
Chris@16
|
2512
|
Chris@16
|
2513 BOOST_UBLAS_INLINE
|
Chris@16
|
2514 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
2515 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
2516 }
|
Chris@16
|
2517 BOOST_UBLAS_INLINE
|
Chris@16
|
2518 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
2519 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
2520 }
|
Chris@16
|
2521
|
Chris@16
|
2522 BOOST_UBLAS_INLINE
|
Chris@16
|
2523 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
2524 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
2525 }
|
Chris@16
|
2526 BOOST_UBLAS_INLINE
|
Chris@16
|
2527 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
2528 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
2529 }
|
Chris@16
|
2530
|
Chris@16
|
2531 // Serialization
|
Chris@16
|
2532 template<class Archive>
|
Chris@16
|
2533 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
2534
|
Chris@16
|
2535 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
2536 // and efficient serialization
|
Chris@16
|
2537 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
2538 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
2539
|
Chris@16
|
2540 // serialize the sizes
|
Chris@16
|
2541 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
2542 & serialization::make_nvp("size2",s2);
|
Chris@16
|
2543
|
Chris@16
|
2544 // copy the values back if loading
|
Chris@16
|
2545 if (Archive::is_loading::value) {
|
Chris@16
|
2546 size1_ = s1;
|
Chris@16
|
2547 size2_ = s2;
|
Chris@16
|
2548 }
|
Chris@16
|
2549 }
|
Chris@16
|
2550
|
Chris@16
|
2551 private:
|
Chris@16
|
2552 size_type size1_;
|
Chris@16
|
2553 size_type size2_;
|
Chris@16
|
2554 static const value_type zero_;
|
Chris@16
|
2555 };
|
Chris@16
|
2556
|
Chris@16
|
2557 template<class T, class ALLOC>
|
Chris@16
|
2558 const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T(/*zero*/);
|
Chris@16
|
2559
|
Chris@16
|
2560 /** \brief An identity matrix with values of type \c T
|
Chris@16
|
2561 *
|
Chris@16
|
2562 * Elements or cordinates \f$(i,i)\f$ are equal to 1 (one) and all others to 0 (zero).
|
Chris@16
|
2563 * Changing values does not affect the matrix, however assigning it to a normal matrix will
|
Chris@16
|
2564 * make the matrix equal to an identity matrix. All accesses are constant du to the trivial values.
|
Chris@16
|
2565 *
|
Chris@16
|
2566 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
2567 * \tparam ALLOC an allocator for storing the zeros and one elements. By default, a standar allocator is used.
|
Chris@16
|
2568 */
|
Chris@16
|
2569 template<class T, class ALLOC>
|
Chris@16
|
2570 class identity_matrix:
|
Chris@16
|
2571 public matrix_container<identity_matrix<T, ALLOC> > {
|
Chris@16
|
2572
|
Chris@16
|
2573 typedef const T *const_pointer;
|
Chris@16
|
2574 typedef identity_matrix<T, ALLOC> self_type;
|
Chris@16
|
2575 public:
|
Chris@16
|
2576 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
2577 using matrix_container<self_type>::operator ();
|
Chris@16
|
2578 #endif
|
Chris@16
|
2579 typedef typename ALLOC::size_type size_type;
|
Chris@16
|
2580 typedef typename ALLOC::difference_type difference_type;
|
Chris@16
|
2581 typedef T value_type;
|
Chris@16
|
2582 typedef const T &const_reference;
|
Chris@16
|
2583 typedef T &reference;
|
Chris@16
|
2584 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
2585 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
2586 typedef sparse_tag storage_category;
|
Chris@16
|
2587 typedef unknown_orientation_tag orientation_category;
|
Chris@16
|
2588
|
Chris@16
|
2589 // Construction and destruction
|
Chris@16
|
2590 BOOST_UBLAS_INLINE
|
Chris@16
|
2591 identity_matrix ():
|
Chris@16
|
2592 matrix_container<self_type> (),
|
Chris@16
|
2593 size1_ (0), size2_ (0), size_common_ (0) {}
|
Chris@16
|
2594 BOOST_UBLAS_INLINE
|
Chris@16
|
2595 identity_matrix (size_type size):
|
Chris@16
|
2596 matrix_container<self_type> (),
|
Chris@16
|
2597 size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
|
Chris@16
|
2598 BOOST_UBLAS_INLINE
|
Chris@16
|
2599 identity_matrix (size_type size1, size_type size2):
|
Chris@16
|
2600 matrix_container<self_type> (),
|
Chris@16
|
2601 size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
|
Chris@16
|
2602 BOOST_UBLAS_INLINE
|
Chris@16
|
2603 identity_matrix (const identity_matrix &m):
|
Chris@16
|
2604 matrix_container<self_type> (),
|
Chris@16
|
2605 size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
|
Chris@16
|
2606
|
Chris@16
|
2607 // Accessors
|
Chris@16
|
2608 BOOST_UBLAS_INLINE
|
Chris@16
|
2609 size_type size1 () const {
|
Chris@16
|
2610 return size1_;
|
Chris@16
|
2611 }
|
Chris@16
|
2612 BOOST_UBLAS_INLINE
|
Chris@16
|
2613 size_type size2 () const {
|
Chris@16
|
2614 return size2_;
|
Chris@16
|
2615 }
|
Chris@16
|
2616
|
Chris@16
|
2617 // Resizing
|
Chris@16
|
2618 BOOST_UBLAS_INLINE
|
Chris@16
|
2619 void resize (size_type size, bool preserve = true) {
|
Chris@16
|
2620 size1_ = size;
|
Chris@16
|
2621 size2_ = size;
|
Chris@16
|
2622 size_common_ = ((std::min)(size1_, size2_));
|
Chris@16
|
2623 }
|
Chris@16
|
2624 BOOST_UBLAS_INLINE
|
Chris@16
|
2625 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
|
Chris@16
|
2626 size1_ = size1;
|
Chris@16
|
2627 size2_ = size2;
|
Chris@16
|
2628 size_common_ = ((std::min)(size1_, size2_));
|
Chris@16
|
2629 }
|
Chris@16
|
2630
|
Chris@16
|
2631 // Element access
|
Chris@16
|
2632 BOOST_UBLAS_INLINE
|
Chris@16
|
2633 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
2634 if (i == j)
|
Chris@16
|
2635 return one_;
|
Chris@16
|
2636 else
|
Chris@16
|
2637 return zero_;
|
Chris@16
|
2638 }
|
Chris@16
|
2639
|
Chris@16
|
2640 // Assignment
|
Chris@16
|
2641 BOOST_UBLAS_INLINE
|
Chris@16
|
2642 identity_matrix &operator = (const identity_matrix &m) {
|
Chris@16
|
2643 size1_ = m.size1_;
|
Chris@16
|
2644 size2_ = m.size2_;
|
Chris@16
|
2645 size_common_ = m.size_common_;
|
Chris@16
|
2646 return *this;
|
Chris@16
|
2647 }
|
Chris@16
|
2648 BOOST_UBLAS_INLINE
|
Chris@16
|
2649 identity_matrix &assign_temporary (identity_matrix &m) {
|
Chris@16
|
2650 swap (m);
|
Chris@16
|
2651 return *this;
|
Chris@16
|
2652 }
|
Chris@16
|
2653
|
Chris@16
|
2654 // Swapping
|
Chris@16
|
2655 BOOST_UBLAS_INLINE
|
Chris@16
|
2656 void swap (identity_matrix &m) {
|
Chris@16
|
2657 if (this != &m) {
|
Chris@16
|
2658 std::swap (size1_, m.size1_);
|
Chris@16
|
2659 std::swap (size2_, m.size2_);
|
Chris@16
|
2660 std::swap (size_common_, m.size_common_);
|
Chris@16
|
2661 }
|
Chris@16
|
2662 }
|
Chris@16
|
2663 BOOST_UBLAS_INLINE
|
Chris@16
|
2664 friend void swap (identity_matrix &m1, identity_matrix &m2) {
|
Chris@16
|
2665 m1.swap (m2);
|
Chris@16
|
2666 }
|
Chris@16
|
2667
|
Chris@16
|
2668 // Iterator types
|
Chris@16
|
2669 private:
|
Chris@16
|
2670 // Use an index
|
Chris@16
|
2671 typedef size_type const_subiterator_type;
|
Chris@16
|
2672
|
Chris@16
|
2673 public:
|
Chris@16
|
2674 class const_iterator1;
|
Chris@16
|
2675 class const_iterator2;
|
Chris@16
|
2676 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
2677 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
2678
|
Chris@16
|
2679 // Element lookup
|
Chris@16
|
2680 BOOST_UBLAS_INLINE
|
Chris@16
|
2681 const_iterator1 find1 (int rank, size_type i, size_type j) const {
|
Chris@16
|
2682 if (rank == 1) {
|
Chris@16
|
2683 i = (std::max) (i, j);
|
Chris@16
|
2684 i = (std::min) (i, j + 1);
|
Chris@16
|
2685 }
|
Chris@16
|
2686 return const_iterator1 (*this, i);
|
Chris@16
|
2687 }
|
Chris@16
|
2688 BOOST_UBLAS_INLINE
|
Chris@16
|
2689 const_iterator2 find2 (int rank, size_type i, size_type j) const {
|
Chris@16
|
2690 if (rank == 1) {
|
Chris@16
|
2691 j = (std::max) (j, i);
|
Chris@16
|
2692 j = (std::min) (j, i + 1);
|
Chris@16
|
2693 }
|
Chris@16
|
2694 return const_iterator2 (*this, j);
|
Chris@16
|
2695 }
|
Chris@16
|
2696
|
Chris@16
|
2697
|
Chris@16
|
2698 class const_iterator1:
|
Chris@16
|
2699 public container_const_reference<identity_matrix>,
|
Chris@16
|
2700 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
|
Chris@16
|
2701 const_iterator1, value_type> {
|
Chris@16
|
2702 public:
|
Chris@16
|
2703 typedef typename identity_matrix::value_type value_type;
|
Chris@16
|
2704 typedef typename identity_matrix::difference_type difference_type;
|
Chris@16
|
2705 typedef typename identity_matrix::const_reference reference;
|
Chris@16
|
2706 typedef typename identity_matrix::const_pointer pointer;
|
Chris@16
|
2707
|
Chris@16
|
2708 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
2709 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
2710
|
Chris@16
|
2711 // Construction and destruction
|
Chris@16
|
2712 BOOST_UBLAS_INLINE
|
Chris@16
|
2713 const_iterator1 ():
|
Chris@16
|
2714 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
2715 BOOST_UBLAS_INLINE
|
Chris@16
|
2716 const_iterator1 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
2717 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
2718
|
Chris@16
|
2719 // Arithmetic
|
Chris@16
|
2720 BOOST_UBLAS_INLINE
|
Chris@16
|
2721 const_iterator1 &operator ++ () {
|
Chris@16
|
2722 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
|
Chris@16
|
2723 ++it_;
|
Chris@16
|
2724 return *this;
|
Chris@16
|
2725 }
|
Chris@16
|
2726 BOOST_UBLAS_INLINE
|
Chris@16
|
2727 const_iterator1 &operator -- () {
|
Chris@16
|
2728 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
|
Chris@16
|
2729 --it_;
|
Chris@16
|
2730 return *this;
|
Chris@16
|
2731 }
|
Chris@16
|
2732
|
Chris@16
|
2733 // Dereference
|
Chris@16
|
2734 BOOST_UBLAS_INLINE
|
Chris@16
|
2735 const_reference operator * () const {
|
Chris@16
|
2736 return one_;
|
Chris@16
|
2737 }
|
Chris@16
|
2738
|
Chris@16
|
2739 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2740 BOOST_UBLAS_INLINE
|
Chris@16
|
2741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2742 typename self_type::
|
Chris@16
|
2743 #endif
|
Chris@16
|
2744 const_iterator2 begin () const {
|
Chris@16
|
2745 return const_iterator2 ((*this) (), it_);
|
Chris@16
|
2746 }
|
Chris@16
|
2747 BOOST_UBLAS_INLINE
|
Chris@16
|
2748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2749 typename self_type::
|
Chris@16
|
2750 #endif
|
Chris@16
|
2751 const_iterator2 end () const {
|
Chris@16
|
2752 return const_iterator2 ((*this) (), it_ + 1);
|
Chris@16
|
2753 }
|
Chris@16
|
2754 BOOST_UBLAS_INLINE
|
Chris@16
|
2755 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2756 typename self_type::
|
Chris@16
|
2757 #endif
|
Chris@16
|
2758 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
2759 return const_reverse_iterator2 (end ());
|
Chris@16
|
2760 }
|
Chris@16
|
2761 BOOST_UBLAS_INLINE
|
Chris@16
|
2762 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2763 typename self_type::
|
Chris@16
|
2764 #endif
|
Chris@16
|
2765 const_reverse_iterator2 rend () const {
|
Chris@16
|
2766 return const_reverse_iterator2 (begin ());
|
Chris@16
|
2767 }
|
Chris@16
|
2768 #endif
|
Chris@16
|
2769
|
Chris@16
|
2770 // Indices
|
Chris@16
|
2771 BOOST_UBLAS_INLINE
|
Chris@16
|
2772 size_type index1 () const {
|
Chris@16
|
2773 return it_;
|
Chris@16
|
2774 }
|
Chris@16
|
2775 BOOST_UBLAS_INLINE
|
Chris@16
|
2776 size_type index2 () const {
|
Chris@16
|
2777 return it_;
|
Chris@16
|
2778 }
|
Chris@16
|
2779
|
Chris@16
|
2780 // Assignment
|
Chris@16
|
2781 BOOST_UBLAS_INLINE
|
Chris@16
|
2782 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
2783 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2784 it_ = it.it_;
|
Chris@16
|
2785 return *this;
|
Chris@16
|
2786 }
|
Chris@16
|
2787
|
Chris@16
|
2788 // Comparison
|
Chris@16
|
2789 BOOST_UBLAS_INLINE
|
Chris@16
|
2790 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
2791 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2792 return it_ == it.it_;
|
Chris@16
|
2793 }
|
Chris@16
|
2794
|
Chris@16
|
2795 private:
|
Chris@16
|
2796 const_subiterator_type it_;
|
Chris@16
|
2797 };
|
Chris@16
|
2798
|
Chris@16
|
2799 typedef const_iterator1 iterator1;
|
Chris@16
|
2800
|
Chris@16
|
2801 BOOST_UBLAS_INLINE
|
Chris@16
|
2802 const_iterator1 begin1 () const {
|
Chris@16
|
2803 return const_iterator1 (*this, 0);
|
Chris@16
|
2804 }
|
Chris@16
|
2805 BOOST_UBLAS_INLINE
|
Chris@16
|
2806 const_iterator1 end1 () const {
|
Chris@16
|
2807 return const_iterator1 (*this, size_common_);
|
Chris@16
|
2808 }
|
Chris@16
|
2809
|
Chris@16
|
2810 class const_iterator2:
|
Chris@16
|
2811 public container_const_reference<identity_matrix>,
|
Chris@16
|
2812 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
|
Chris@16
|
2813 const_iterator2, value_type> {
|
Chris@16
|
2814 public:
|
Chris@16
|
2815 typedef typename identity_matrix::value_type value_type;
|
Chris@16
|
2816 typedef typename identity_matrix::difference_type difference_type;
|
Chris@16
|
2817 typedef typename identity_matrix::const_reference reference;
|
Chris@16
|
2818 typedef typename identity_matrix::const_pointer pointer;
|
Chris@16
|
2819
|
Chris@16
|
2820 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
2821 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
2822
|
Chris@16
|
2823 // Construction and destruction
|
Chris@16
|
2824 BOOST_UBLAS_INLINE
|
Chris@16
|
2825 const_iterator2 ():
|
Chris@16
|
2826 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
2827 BOOST_UBLAS_INLINE
|
Chris@16
|
2828 const_iterator2 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
2829 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
2830
|
Chris@16
|
2831 // Arithmetic
|
Chris@16
|
2832 BOOST_UBLAS_INLINE
|
Chris@16
|
2833 const_iterator2 &operator ++ () {
|
Chris@16
|
2834 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
|
Chris@16
|
2835 ++it_;
|
Chris@16
|
2836 return *this;
|
Chris@16
|
2837 }
|
Chris@16
|
2838 BOOST_UBLAS_INLINE
|
Chris@16
|
2839 const_iterator2 &operator -- () {
|
Chris@16
|
2840 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
|
Chris@16
|
2841 --it_;
|
Chris@16
|
2842 return *this;
|
Chris@16
|
2843 }
|
Chris@16
|
2844
|
Chris@16
|
2845 // Dereference
|
Chris@16
|
2846 BOOST_UBLAS_INLINE
|
Chris@16
|
2847 const_reference operator * () const {
|
Chris@16
|
2848 return one_;
|
Chris@16
|
2849 }
|
Chris@16
|
2850
|
Chris@16
|
2851 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2852 BOOST_UBLAS_INLINE
|
Chris@16
|
2853 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2854 typename self_type::
|
Chris@16
|
2855 #endif
|
Chris@16
|
2856 const_iterator1 begin () const {
|
Chris@16
|
2857 return const_iterator1 ((*this) (), it_);
|
Chris@16
|
2858 }
|
Chris@16
|
2859 BOOST_UBLAS_INLINE
|
Chris@16
|
2860 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2861 typename self_type::
|
Chris@16
|
2862 #endif
|
Chris@16
|
2863 const_iterator1 end () const {
|
Chris@16
|
2864 return const_iterator1 ((*this) (), it_ + 1);
|
Chris@16
|
2865 }
|
Chris@16
|
2866 BOOST_UBLAS_INLINE
|
Chris@16
|
2867 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2868 typename self_type::
|
Chris@16
|
2869 #endif
|
Chris@16
|
2870 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
2871 return const_reverse_iterator1 (end ());
|
Chris@16
|
2872 }
|
Chris@16
|
2873 BOOST_UBLAS_INLINE
|
Chris@16
|
2874 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2875 typename self_type::
|
Chris@16
|
2876 #endif
|
Chris@16
|
2877 const_reverse_iterator1 rend () const {
|
Chris@16
|
2878 return const_reverse_iterator1 (begin ());
|
Chris@16
|
2879 }
|
Chris@16
|
2880 #endif
|
Chris@16
|
2881
|
Chris@16
|
2882 // Indices
|
Chris@16
|
2883 BOOST_UBLAS_INLINE
|
Chris@16
|
2884 size_type index1 () const {
|
Chris@16
|
2885 return it_;
|
Chris@16
|
2886 }
|
Chris@16
|
2887 BOOST_UBLAS_INLINE
|
Chris@16
|
2888 size_type index2 () const {
|
Chris@16
|
2889 return it_;
|
Chris@16
|
2890 }
|
Chris@16
|
2891
|
Chris@16
|
2892 // Assignment
|
Chris@16
|
2893 BOOST_UBLAS_INLINE
|
Chris@16
|
2894 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
2895 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2896 it_ = it.it_;
|
Chris@16
|
2897 return *this;
|
Chris@16
|
2898 }
|
Chris@16
|
2899
|
Chris@16
|
2900 // Comparison
|
Chris@16
|
2901 BOOST_UBLAS_INLINE
|
Chris@16
|
2902 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
2903 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
2904 return it_ == it.it_;
|
Chris@16
|
2905 }
|
Chris@16
|
2906
|
Chris@16
|
2907 private:
|
Chris@16
|
2908 const_subiterator_type it_;
|
Chris@16
|
2909 };
|
Chris@16
|
2910
|
Chris@16
|
2911 typedef const_iterator2 iterator2;
|
Chris@16
|
2912
|
Chris@16
|
2913 BOOST_UBLAS_INLINE
|
Chris@16
|
2914 const_iterator2 begin2 () const {
|
Chris@16
|
2915 return const_iterator2 (*this, 0);
|
Chris@16
|
2916 }
|
Chris@16
|
2917 BOOST_UBLAS_INLINE
|
Chris@16
|
2918 const_iterator2 end2 () const {
|
Chris@16
|
2919 return const_iterator2 (*this, size_common_);
|
Chris@16
|
2920 }
|
Chris@16
|
2921
|
Chris@16
|
2922 // Reverse iterators
|
Chris@16
|
2923
|
Chris@16
|
2924 BOOST_UBLAS_INLINE
|
Chris@16
|
2925 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
2926 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
2927 }
|
Chris@16
|
2928 BOOST_UBLAS_INLINE
|
Chris@16
|
2929 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
2930 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
2931 }
|
Chris@16
|
2932
|
Chris@16
|
2933 BOOST_UBLAS_INLINE
|
Chris@16
|
2934 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
2935 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
2936 }
|
Chris@16
|
2937 BOOST_UBLAS_INLINE
|
Chris@16
|
2938 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
2939 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
2940 }
|
Chris@16
|
2941
|
Chris@16
|
2942 // Serialization
|
Chris@16
|
2943 template<class Archive>
|
Chris@16
|
2944 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
2945
|
Chris@16
|
2946 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
2947 // and efficient serialization
|
Chris@16
|
2948 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
2949 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
2950
|
Chris@16
|
2951 // serialize the sizes
|
Chris@16
|
2952 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
2953 & serialization::make_nvp("size2",s2);
|
Chris@16
|
2954
|
Chris@16
|
2955 // copy the values back if loading
|
Chris@16
|
2956 if (Archive::is_loading::value) {
|
Chris@16
|
2957 size1_ = s1;
|
Chris@16
|
2958 size2_ = s2;
|
Chris@16
|
2959 size_common_ = ((std::min)(size1_, size2_));
|
Chris@16
|
2960 }
|
Chris@16
|
2961 }
|
Chris@16
|
2962
|
Chris@16
|
2963 private:
|
Chris@16
|
2964 size_type size1_;
|
Chris@16
|
2965 size_type size2_;
|
Chris@16
|
2966 size_type size_common_;
|
Chris@16
|
2967 static const value_type zero_;
|
Chris@16
|
2968 static const value_type one_;
|
Chris@16
|
2969 };
|
Chris@16
|
2970
|
Chris@16
|
2971 template<class T, class ALLOC>
|
Chris@16
|
2972 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T(/*zero*/);
|
Chris@16
|
2973 template<class T, class ALLOC>
|
Chris@16
|
2974 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
|
Chris@16
|
2975
|
Chris@16
|
2976
|
Chris@16
|
2977 /** \brief A matrix with all values of type \c T equal to the same value
|
Chris@16
|
2978 *
|
Chris@16
|
2979 * Changing one value has the effect of changing all the values. Assigning it to a normal matrix will copy
|
Chris@16
|
2980 * the same value everywhere in this matrix. All accesses are constant time, due to the trivial value.
|
Chris@16
|
2981 *
|
Chris@16
|
2982 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
2983 * \tparam ALLOC an allocator for storing the unique value. By default, a standar allocator is used.
|
Chris@16
|
2984 */
|
Chris@16
|
2985 template<class T, class ALLOC>
|
Chris@16
|
2986 class scalar_matrix:
|
Chris@16
|
2987 public matrix_container<scalar_matrix<T, ALLOC> > {
|
Chris@16
|
2988
|
Chris@16
|
2989 typedef const T *const_pointer;
|
Chris@16
|
2990 typedef scalar_matrix<T, ALLOC> self_type;
|
Chris@16
|
2991 public:
|
Chris@16
|
2992 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
2993 using matrix_container<self_type>::operator ();
|
Chris@16
|
2994 #endif
|
Chris@16
|
2995 typedef std::size_t size_type;
|
Chris@16
|
2996 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
2997 typedef T value_type;
|
Chris@16
|
2998 typedef const T &const_reference;
|
Chris@16
|
2999 typedef T &reference;
|
Chris@16
|
3000 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
3001 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
3002 typedef dense_tag storage_category;
|
Chris@16
|
3003 typedef unknown_orientation_tag orientation_category;
|
Chris@16
|
3004
|
Chris@16
|
3005 // Construction and destruction
|
Chris@16
|
3006 BOOST_UBLAS_INLINE
|
Chris@16
|
3007 scalar_matrix ():
|
Chris@16
|
3008 matrix_container<self_type> (),
|
Chris@16
|
3009 size1_ (0), size2_ (0), value_ () {}
|
Chris@16
|
3010 BOOST_UBLAS_INLINE
|
Chris@16
|
3011 scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
|
Chris@16
|
3012 matrix_container<self_type> (),
|
Chris@16
|
3013 size1_ (size1), size2_ (size2), value_ (value) {}
|
Chris@16
|
3014 BOOST_UBLAS_INLINE
|
Chris@16
|
3015 scalar_matrix (const scalar_matrix &m):
|
Chris@16
|
3016 matrix_container<self_type> (),
|
Chris@16
|
3017 size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
|
Chris@16
|
3018
|
Chris@16
|
3019 // Accessors
|
Chris@16
|
3020 BOOST_UBLAS_INLINE
|
Chris@16
|
3021 size_type size1 () const {
|
Chris@16
|
3022 return size1_;
|
Chris@16
|
3023 }
|
Chris@16
|
3024 BOOST_UBLAS_INLINE
|
Chris@16
|
3025 size_type size2 () const {
|
Chris@16
|
3026 return size2_;
|
Chris@16
|
3027 }
|
Chris@16
|
3028
|
Chris@16
|
3029 // Resizing
|
Chris@16
|
3030 BOOST_UBLAS_INLINE
|
Chris@16
|
3031 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
|
Chris@16
|
3032 size1_ = size1;
|
Chris@16
|
3033 size2_ = size2;
|
Chris@16
|
3034 }
|
Chris@16
|
3035
|
Chris@16
|
3036 // Element access
|
Chris@16
|
3037 BOOST_UBLAS_INLINE
|
Chris@16
|
3038 const_reference operator () (size_type /*i*/, size_type /*j*/) const {
|
Chris@16
|
3039 return value_;
|
Chris@16
|
3040 }
|
Chris@16
|
3041
|
Chris@16
|
3042 // Assignment
|
Chris@16
|
3043 BOOST_UBLAS_INLINE
|
Chris@16
|
3044 scalar_matrix &operator = (const scalar_matrix &m) {
|
Chris@16
|
3045 size1_ = m.size1_;
|
Chris@16
|
3046 size2_ = m.size2_;
|
Chris@16
|
3047 value_ = m.value_;
|
Chris@16
|
3048 return *this;
|
Chris@16
|
3049 }
|
Chris@16
|
3050 BOOST_UBLAS_INLINE
|
Chris@16
|
3051 scalar_matrix &assign_temporary (scalar_matrix &m) {
|
Chris@16
|
3052 swap (m);
|
Chris@16
|
3053 return *this;
|
Chris@16
|
3054 }
|
Chris@16
|
3055
|
Chris@16
|
3056 // Swapping
|
Chris@16
|
3057 BOOST_UBLAS_INLINE
|
Chris@16
|
3058 void swap (scalar_matrix &m) {
|
Chris@16
|
3059 if (this != &m) {
|
Chris@16
|
3060 std::swap (size1_, m.size1_);
|
Chris@16
|
3061 std::swap (size2_, m.size2_);
|
Chris@16
|
3062 std::swap (value_, m.value_);
|
Chris@16
|
3063 }
|
Chris@16
|
3064 }
|
Chris@16
|
3065 BOOST_UBLAS_INLINE
|
Chris@16
|
3066 friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
|
Chris@16
|
3067 m1.swap (m2);
|
Chris@16
|
3068 }
|
Chris@16
|
3069
|
Chris@16
|
3070 // Iterator types
|
Chris@16
|
3071 private:
|
Chris@16
|
3072 // Use an index
|
Chris@16
|
3073 typedef size_type const_subiterator_type;
|
Chris@16
|
3074
|
Chris@16
|
3075 public:
|
Chris@16
|
3076 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3077 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
|
Chris@16
|
3078 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
|
Chris@16
|
3079 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
|
Chris@16
|
3080 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
|
Chris@16
|
3081 #else
|
Chris@16
|
3082 class const_iterator1;
|
Chris@16
|
3083 class const_iterator2;
|
Chris@16
|
3084 #endif
|
Chris@16
|
3085 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
3086 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
3087
|
Chris@16
|
3088 // Element lookup
|
Chris@16
|
3089 BOOST_UBLAS_INLINE
|
Chris@16
|
3090 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
|
Chris@16
|
3091 return const_iterator1 (*this, i, j);
|
Chris@16
|
3092 }
|
Chris@16
|
3093 BOOST_UBLAS_INLINE
|
Chris@16
|
3094 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
|
Chris@16
|
3095 return const_iterator2 (*this, i, j);
|
Chris@16
|
3096 }
|
Chris@16
|
3097
|
Chris@16
|
3098
|
Chris@16
|
3099 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3100 class const_iterator1:
|
Chris@16
|
3101 public container_const_reference<scalar_matrix>,
|
Chris@16
|
3102 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
3103 const_iterator1, value_type> {
|
Chris@16
|
3104 public:
|
Chris@16
|
3105 typedef typename scalar_matrix::value_type value_type;
|
Chris@16
|
3106 typedef typename scalar_matrix::difference_type difference_type;
|
Chris@16
|
3107 typedef typename scalar_matrix::const_reference reference;
|
Chris@16
|
3108 typedef typename scalar_matrix::const_pointer pointer;
|
Chris@16
|
3109
|
Chris@16
|
3110 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
3111 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
3112
|
Chris@16
|
3113 // Construction and destruction
|
Chris@16
|
3114 BOOST_UBLAS_INLINE
|
Chris@16
|
3115 const_iterator1 ():
|
Chris@16
|
3116 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
|
Chris@16
|
3117 BOOST_UBLAS_INLINE
|
Chris@16
|
3118 const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
|
Chris@16
|
3119 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
3120
|
Chris@16
|
3121 // Arithmetic
|
Chris@16
|
3122 BOOST_UBLAS_INLINE
|
Chris@16
|
3123 const_iterator1 &operator ++ () {
|
Chris@16
|
3124 ++ it1_;
|
Chris@16
|
3125 return *this;
|
Chris@16
|
3126 }
|
Chris@16
|
3127 BOOST_UBLAS_INLINE
|
Chris@16
|
3128 const_iterator1 &operator -- () {
|
Chris@16
|
3129 -- it1_;
|
Chris@16
|
3130 return *this;
|
Chris@16
|
3131 }
|
Chris@16
|
3132 BOOST_UBLAS_INLINE
|
Chris@16
|
3133 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
3134 it1_ += n;
|
Chris@16
|
3135 return *this;
|
Chris@16
|
3136 }
|
Chris@16
|
3137 BOOST_UBLAS_INLINE
|
Chris@16
|
3138 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
3139 it1_ -= n;
|
Chris@16
|
3140 return *this;
|
Chris@16
|
3141 }
|
Chris@16
|
3142 BOOST_UBLAS_INLINE
|
Chris@16
|
3143 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
3144 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3145 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3146 return it1_ - it.it1_;
|
Chris@16
|
3147 }
|
Chris@16
|
3148
|
Chris@16
|
3149 // Dereference
|
Chris@16
|
3150 BOOST_UBLAS_INLINE
|
Chris@16
|
3151 const_reference operator * () const {
|
Chris@16
|
3152 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
3153 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
3154 return (*this) () (index1 (), index2 ());
|
Chris@16
|
3155 }
|
Chris@16
|
3156 BOOST_UBLAS_INLINE
|
Chris@16
|
3157 const_reference operator [] (difference_type n) const {
|
Chris@16
|
3158 return *(*this + n);
|
Chris@16
|
3159 }
|
Chris@16
|
3160
|
Chris@16
|
3161 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3162 BOOST_UBLAS_INLINE
|
Chris@16
|
3163 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3164 typename self_type::
|
Chris@16
|
3165 #endif
|
Chris@16
|
3166 const_iterator2 begin () const {
|
Chris@16
|
3167 const scalar_matrix &m = (*this) ();
|
Chris@16
|
3168 return m.find2 (1, index1 (), 0);
|
Chris@16
|
3169 }
|
Chris@16
|
3170 BOOST_UBLAS_INLINE
|
Chris@16
|
3171 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3172 typename self_type::
|
Chris@16
|
3173 #endif
|
Chris@16
|
3174 const_iterator2 end () const {
|
Chris@16
|
3175 const scalar_matrix &m = (*this) ();
|
Chris@16
|
3176 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
3177 }
|
Chris@16
|
3178 BOOST_UBLAS_INLINE
|
Chris@16
|
3179 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3180 typename self_type::
|
Chris@16
|
3181 #endif
|
Chris@16
|
3182 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
3183 return const_reverse_iterator2 (end ());
|
Chris@16
|
3184 }
|
Chris@16
|
3185 BOOST_UBLAS_INLINE
|
Chris@16
|
3186 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3187 typename self_type::
|
Chris@16
|
3188 #endif
|
Chris@16
|
3189 const_reverse_iterator2 rend () const {
|
Chris@16
|
3190 return const_reverse_iterator2 (begin ());
|
Chris@16
|
3191 }
|
Chris@16
|
3192 #endif
|
Chris@16
|
3193
|
Chris@16
|
3194 // Indices
|
Chris@16
|
3195 BOOST_UBLAS_INLINE
|
Chris@16
|
3196 size_type index1 () const {
|
Chris@16
|
3197 return it1_;
|
Chris@16
|
3198 }
|
Chris@16
|
3199 BOOST_UBLAS_INLINE
|
Chris@16
|
3200 size_type index2 () const {
|
Chris@16
|
3201 return it2_;
|
Chris@16
|
3202 }
|
Chris@16
|
3203
|
Chris@16
|
3204 // Assignment
|
Chris@16
|
3205 BOOST_UBLAS_INLINE
|
Chris@16
|
3206 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
3207 container_const_reference<scalar_matrix>::assign (&it ());
|
Chris@16
|
3208 it1_ = it.it1_;
|
Chris@16
|
3209 it2_ = it.it2_;
|
Chris@16
|
3210 return *this;
|
Chris@16
|
3211 }
|
Chris@16
|
3212
|
Chris@16
|
3213 // Comparison
|
Chris@16
|
3214 BOOST_UBLAS_INLINE
|
Chris@16
|
3215 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
3216 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3217 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3218 return it1_ == it.it1_;
|
Chris@16
|
3219 }
|
Chris@16
|
3220 BOOST_UBLAS_INLINE
|
Chris@16
|
3221 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
3222 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3223 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3224 return it1_ < it.it1_;
|
Chris@16
|
3225 }
|
Chris@16
|
3226
|
Chris@16
|
3227 private:
|
Chris@16
|
3228 const_subiterator_type it1_;
|
Chris@16
|
3229 const_subiterator_type it2_;
|
Chris@16
|
3230 };
|
Chris@16
|
3231
|
Chris@16
|
3232 typedef const_iterator1 iterator1;
|
Chris@16
|
3233 #endif
|
Chris@16
|
3234
|
Chris@16
|
3235 BOOST_UBLAS_INLINE
|
Chris@16
|
3236 const_iterator1 begin1 () const {
|
Chris@16
|
3237 return find1 (0, 0, 0);
|
Chris@16
|
3238 }
|
Chris@16
|
3239 BOOST_UBLAS_INLINE
|
Chris@16
|
3240 const_iterator1 end1 () const {
|
Chris@16
|
3241 return find1 (0, size1_, 0);
|
Chris@16
|
3242 }
|
Chris@16
|
3243
|
Chris@16
|
3244 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3245 class const_iterator2:
|
Chris@16
|
3246 public container_const_reference<scalar_matrix>,
|
Chris@16
|
3247 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
3248 const_iterator2, value_type> {
|
Chris@16
|
3249 public:
|
Chris@16
|
3250 typedef typename scalar_matrix::value_type value_type;
|
Chris@16
|
3251 typedef typename scalar_matrix::difference_type difference_type;
|
Chris@16
|
3252 typedef typename scalar_matrix::const_reference reference;
|
Chris@16
|
3253 typedef typename scalar_matrix::const_pointer pointer;
|
Chris@16
|
3254
|
Chris@16
|
3255 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
3256 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
3257
|
Chris@16
|
3258 // Construction and destruction
|
Chris@16
|
3259 BOOST_UBLAS_INLINE
|
Chris@16
|
3260 const_iterator2 ():
|
Chris@16
|
3261 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
|
Chris@16
|
3262 BOOST_UBLAS_INLINE
|
Chris@16
|
3263 const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
|
Chris@16
|
3264 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
3265
|
Chris@16
|
3266 // Arithmetic
|
Chris@16
|
3267 BOOST_UBLAS_INLINE
|
Chris@16
|
3268 const_iterator2 &operator ++ () {
|
Chris@16
|
3269 ++ it2_;
|
Chris@16
|
3270 return *this;
|
Chris@16
|
3271 }
|
Chris@16
|
3272 BOOST_UBLAS_INLINE
|
Chris@16
|
3273 const_iterator2 &operator -- () {
|
Chris@16
|
3274 -- it2_;
|
Chris@16
|
3275 return *this;
|
Chris@16
|
3276 }
|
Chris@16
|
3277 BOOST_UBLAS_INLINE
|
Chris@16
|
3278 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
3279 it2_ += n;
|
Chris@16
|
3280 return *this;
|
Chris@16
|
3281 }
|
Chris@16
|
3282 BOOST_UBLAS_INLINE
|
Chris@16
|
3283 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
3284 it2_ -= n;
|
Chris@16
|
3285 return *this;
|
Chris@16
|
3286 }
|
Chris@16
|
3287 BOOST_UBLAS_INLINE
|
Chris@16
|
3288 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
3289 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3290 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
3291 return it2_ - it.it2_;
|
Chris@16
|
3292 }
|
Chris@16
|
3293
|
Chris@16
|
3294 // Dereference
|
Chris@16
|
3295 BOOST_UBLAS_INLINE
|
Chris@16
|
3296 const_reference operator * () const {
|
Chris@16
|
3297 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
3298 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
3299 return (*this) () (index1 (), index2 ());
|
Chris@16
|
3300 }
|
Chris@16
|
3301 BOOST_UBLAS_INLINE
|
Chris@16
|
3302 const_reference operator [] (difference_type n) const {
|
Chris@16
|
3303 return *(*this + n);
|
Chris@16
|
3304 }
|
Chris@16
|
3305
|
Chris@16
|
3306 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3307 BOOST_UBLAS_INLINE
|
Chris@16
|
3308 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3309 typename self_type::
|
Chris@16
|
3310 #endif
|
Chris@16
|
3311 const_iterator1 begin () const {
|
Chris@16
|
3312 const scalar_matrix &m = (*this) ();
|
Chris@16
|
3313 return m.find1 (1, 0, index2 ());
|
Chris@16
|
3314 }
|
Chris@16
|
3315 BOOST_UBLAS_INLINE
|
Chris@16
|
3316 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3317 typename self_type::
|
Chris@16
|
3318 #endif
|
Chris@16
|
3319 const_iterator1 end () const {
|
Chris@16
|
3320 const scalar_matrix &m = (*this) ();
|
Chris@16
|
3321 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
3322 }
|
Chris@16
|
3323 BOOST_UBLAS_INLINE
|
Chris@16
|
3324 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3325 typename self_type::
|
Chris@16
|
3326 #endif
|
Chris@16
|
3327 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
3328 return const_reverse_iterator1 (end ());
|
Chris@16
|
3329 }
|
Chris@16
|
3330 BOOST_UBLAS_INLINE
|
Chris@16
|
3331 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3332 typename self_type::
|
Chris@16
|
3333 #endif
|
Chris@16
|
3334 const_reverse_iterator1 rend () const {
|
Chris@16
|
3335 return const_reverse_iterator1 (begin ());
|
Chris@16
|
3336 }
|
Chris@16
|
3337 #endif
|
Chris@16
|
3338
|
Chris@16
|
3339 // Indices
|
Chris@16
|
3340 BOOST_UBLAS_INLINE
|
Chris@16
|
3341 size_type index1 () const {
|
Chris@16
|
3342 return it1_;
|
Chris@16
|
3343 }
|
Chris@16
|
3344 BOOST_UBLAS_INLINE
|
Chris@16
|
3345 size_type index2 () const {
|
Chris@16
|
3346 return it2_;
|
Chris@16
|
3347 }
|
Chris@16
|
3348
|
Chris@16
|
3349 // Assignment
|
Chris@16
|
3350 BOOST_UBLAS_INLINE
|
Chris@16
|
3351 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
3352 container_const_reference<scalar_matrix>::assign (&it ());
|
Chris@16
|
3353 it1_ = it.it1_;
|
Chris@16
|
3354 it2_ = it.it2_;
|
Chris@16
|
3355 return *this;
|
Chris@16
|
3356 }
|
Chris@16
|
3357
|
Chris@16
|
3358 // Comparison
|
Chris@16
|
3359 BOOST_UBLAS_INLINE
|
Chris@16
|
3360 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
3361 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3362 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
3363 return it2_ == it.it2_;
|
Chris@16
|
3364 }
|
Chris@16
|
3365 BOOST_UBLAS_INLINE
|
Chris@16
|
3366 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
3367 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3368 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
3369 return it2_ < it.it2_;
|
Chris@16
|
3370 }
|
Chris@16
|
3371
|
Chris@16
|
3372 private:
|
Chris@16
|
3373 const_subiterator_type it1_;
|
Chris@16
|
3374 const_subiterator_type it2_;
|
Chris@16
|
3375 };
|
Chris@16
|
3376
|
Chris@16
|
3377 typedef const_iterator2 iterator2;
|
Chris@16
|
3378 #endif
|
Chris@16
|
3379
|
Chris@16
|
3380 BOOST_UBLAS_INLINE
|
Chris@16
|
3381 const_iterator2 begin2 () const {
|
Chris@16
|
3382 return find2 (0, 0, 0);
|
Chris@16
|
3383 }
|
Chris@16
|
3384 BOOST_UBLAS_INLINE
|
Chris@16
|
3385 const_iterator2 end2 () const {
|
Chris@16
|
3386 return find2 (0, 0, size2_);
|
Chris@16
|
3387 }
|
Chris@16
|
3388
|
Chris@16
|
3389 // Reverse iterators
|
Chris@16
|
3390
|
Chris@16
|
3391 BOOST_UBLAS_INLINE
|
Chris@16
|
3392 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
3393 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
3394 }
|
Chris@16
|
3395 BOOST_UBLAS_INLINE
|
Chris@16
|
3396 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
3397 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
3398 }
|
Chris@16
|
3399
|
Chris@16
|
3400 BOOST_UBLAS_INLINE
|
Chris@16
|
3401 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
3402 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
3403 }
|
Chris@16
|
3404 BOOST_UBLAS_INLINE
|
Chris@16
|
3405 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
3406 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
3407 }
|
Chris@16
|
3408
|
Chris@16
|
3409 // Serialization
|
Chris@16
|
3410 template<class Archive>
|
Chris@16
|
3411 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
3412
|
Chris@16
|
3413 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
3414 // and efficient serialization
|
Chris@16
|
3415 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
3416 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
3417
|
Chris@16
|
3418 // serialize the sizes
|
Chris@16
|
3419 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
3420 & serialization::make_nvp("size2",s2);
|
Chris@16
|
3421
|
Chris@16
|
3422 // copy the values back if loading
|
Chris@16
|
3423 if (Archive::is_loading::value) {
|
Chris@16
|
3424 size1_ = s1;
|
Chris@16
|
3425 size2_ = s2;
|
Chris@16
|
3426 }
|
Chris@16
|
3427
|
Chris@16
|
3428 ar & serialization::make_nvp("value", value_);
|
Chris@16
|
3429 }
|
Chris@16
|
3430
|
Chris@16
|
3431 private:
|
Chris@16
|
3432 size_type size1_;
|
Chris@16
|
3433 size_type size2_;
|
Chris@16
|
3434 value_type value_;
|
Chris@16
|
3435 };
|
Chris@16
|
3436
|
Chris@16
|
3437
|
Chris@16
|
3438 /** \brief An array based matrix class which size is defined at type specification or object instanciation
|
Chris@16
|
3439 *
|
Chris@16
|
3440 * This matrix is directly based on a predefined C-style arry of data, thus providing the fastest
|
Chris@16
|
3441 * implementation possible. The constraint is that dimensions of the matrix must be specified at
|
Chris@16
|
3442 * the instanciation or the type specification.
|
Chris@16
|
3443 *
|
Chris@16
|
3444 * For instance, \code typedef c_matrix<double,4,4> my_4by4_matrix \endcode
|
Chris@16
|
3445 * defines a 4 by 4 double-precision matrix. You can also instantiate it directly with
|
Chris@16
|
3446 * \code c_matrix<int,8,5> my_fast_matrix \endcode. This will make a 8 by 5 integer matrix. The
|
Chris@16
|
3447 * price to pay for this speed is that you cannot resize it to a size larger than the one defined
|
Chris@16
|
3448 * in the template parameters. In the previous example, a size of 4 by 5 or 3 by 2 is acceptable,
|
Chris@16
|
3449 * but a new size of 9 by 5 or even 10 by 10 will raise a bad_size() exception.
|
Chris@16
|
3450 *
|
Chris@16
|
3451 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
|
Chris@16
|
3452 * \tparam N the default maximum number of rows
|
Chris@16
|
3453 * \tparam M the default maximum number of columns
|
Chris@16
|
3454 */
|
Chris@16
|
3455 template<class T, std::size_t N, std::size_t M>
|
Chris@16
|
3456 class c_matrix:
|
Chris@16
|
3457 public matrix_container<c_matrix<T, N, M> > {
|
Chris@16
|
3458
|
Chris@16
|
3459 typedef c_matrix<T, N, M> self_type;
|
Chris@16
|
3460 public:
|
Chris@16
|
3461 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
3462 using matrix_container<self_type>::operator ();
|
Chris@16
|
3463 #endif
|
Chris@16
|
3464 typedef std::size_t size_type;
|
Chris@16
|
3465 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
3466 typedef T value_type;
|
Chris@16
|
3467 typedef const T &const_reference;
|
Chris@16
|
3468 typedef T &reference;
|
Chris@16
|
3469 typedef const T *const_pointer;
|
Chris@16
|
3470 typedef T *pointer;
|
Chris@16
|
3471 typedef const matrix_reference<const self_type> const_closure_type;
|
Chris@16
|
3472 typedef matrix_reference<self_type> closure_type;
|
Chris@16
|
3473 typedef c_vector<T, N * M> vector_temporary_type; // vector able to store all elements of c_matrix
|
Chris@16
|
3474 typedef self_type matrix_temporary_type;
|
Chris@16
|
3475 typedef dense_tag storage_category;
|
Chris@16
|
3476 // This could be better for performance,
|
Chris@16
|
3477 // typedef typename unknown_orientation_tag orientation_category;
|
Chris@16
|
3478 // but others depend on the orientation information...
|
Chris@16
|
3479 typedef row_major_tag orientation_category;
|
Chris@16
|
3480
|
Chris@16
|
3481 // Construction and destruction
|
Chris@16
|
3482 BOOST_UBLAS_INLINE
|
Chris@16
|
3483 c_matrix ():
|
Chris@16
|
3484 size1_ (N), size2_ (M) /* , data_ () */ {
|
Chris@16
|
3485 }
|
Chris@16
|
3486 BOOST_UBLAS_INLINE
|
Chris@16
|
3487 c_matrix (size_type size1, size_type size2):
|
Chris@16
|
3488 size1_ (size1), size2_ (size2) /* , data_ () */ {
|
Chris@16
|
3489 if (size1_ > N || size2_ > M)
|
Chris@16
|
3490 bad_size ().raise ();
|
Chris@16
|
3491 }
|
Chris@16
|
3492 BOOST_UBLAS_INLINE
|
Chris@16
|
3493 c_matrix (const c_matrix &m):
|
Chris@16
|
3494 size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
|
Chris@16
|
3495 if (size1_ > N || size2_ > M)
|
Chris@16
|
3496 bad_size ().raise ();
|
Chris@16
|
3497 assign(m);
|
Chris@16
|
3498 }
|
Chris@16
|
3499 template<class AE>
|
Chris@16
|
3500 BOOST_UBLAS_INLINE
|
Chris@16
|
3501 c_matrix (const matrix_expression<AE> &ae):
|
Chris@16
|
3502 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
|
Chris@16
|
3503 if (size1_ > N || size2_ > M)
|
Chris@16
|
3504 bad_size ().raise ();
|
Chris@16
|
3505 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
3506 }
|
Chris@16
|
3507
|
Chris@16
|
3508 // Accessors
|
Chris@16
|
3509 BOOST_UBLAS_INLINE
|
Chris@16
|
3510 size_type size1 () const {
|
Chris@16
|
3511 return size1_;
|
Chris@16
|
3512 }
|
Chris@16
|
3513 BOOST_UBLAS_INLINE
|
Chris@16
|
3514 size_type size2 () const {
|
Chris@16
|
3515 return size2_;
|
Chris@16
|
3516 }
|
Chris@16
|
3517 BOOST_UBLAS_INLINE
|
Chris@16
|
3518 const_pointer data () const {
|
Chris@16
|
3519 return reinterpret_cast<const_pointer> (data_);
|
Chris@16
|
3520 }
|
Chris@16
|
3521 BOOST_UBLAS_INLINE
|
Chris@16
|
3522 pointer data () {
|
Chris@16
|
3523 return reinterpret_cast<pointer> (data_);
|
Chris@16
|
3524 }
|
Chris@16
|
3525
|
Chris@16
|
3526 // Resizing
|
Chris@16
|
3527 BOOST_UBLAS_INLINE
|
Chris@16
|
3528 void resize (size_type size1, size_type size2, bool preserve = true) {
|
Chris@16
|
3529 if (size1 > N || size2 > M)
|
Chris@16
|
3530 bad_size ().raise ();
|
Chris@16
|
3531 if (preserve) {
|
Chris@16
|
3532 self_type temporary (size1, size2);
|
Chris@16
|
3533 // Common elements to preserve
|
Chris@16
|
3534 const size_type size1_min = (std::min) (size1, size1_);
|
Chris@16
|
3535 const size_type size2_min = (std::min) (size2, size2_);
|
Chris@16
|
3536 for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major
|
Chris@16
|
3537 for (size_type j = 0; j != size2_min; ++j) {
|
Chris@16
|
3538 temporary.data_[i][j] = data_[i][j];
|
Chris@16
|
3539 }
|
Chris@16
|
3540 }
|
Chris@16
|
3541 assign_temporary (temporary);
|
Chris@16
|
3542 }
|
Chris@16
|
3543 else {
|
Chris@16
|
3544 size1_ = size1;
|
Chris@16
|
3545 size2_ = size2;
|
Chris@16
|
3546 }
|
Chris@16
|
3547 }
|
Chris@16
|
3548
|
Chris@16
|
3549 // Element access
|
Chris@16
|
3550 BOOST_UBLAS_INLINE
|
Chris@16
|
3551 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
3552 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
|
Chris@16
|
3553 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
|
Chris@16
|
3554 return data_ [i] [j];
|
Chris@16
|
3555 }
|
Chris@16
|
3556 BOOST_UBLAS_INLINE
|
Chris@16
|
3557 reference at_element (size_type i, size_type j) {
|
Chris@16
|
3558 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
|
Chris@16
|
3559 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
|
Chris@16
|
3560 return data_ [i] [j];
|
Chris@16
|
3561 }
|
Chris@16
|
3562 BOOST_UBLAS_INLINE
|
Chris@16
|
3563 reference operator () (size_type i, size_type j) {
|
Chris@16
|
3564 return at_element (i, j);
|
Chris@16
|
3565 }
|
Chris@16
|
3566
|
Chris@16
|
3567 // Element assignment
|
Chris@16
|
3568 BOOST_UBLAS_INLINE
|
Chris@16
|
3569 reference insert_element (size_type i, size_type j, const_reference t) {
|
Chris@16
|
3570 return (at_element (i, j) = t);
|
Chris@16
|
3571 }
|
Chris@16
|
3572
|
Chris@16
|
3573 // Zeroing
|
Chris@16
|
3574 BOOST_UBLAS_INLINE
|
Chris@16
|
3575 void clear () {
|
Chris@16
|
3576 for (size_type i = 0; i < size1_; ++ i)
|
Chris@16
|
3577 std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
|
Chris@16
|
3578 }
|
Chris@16
|
3579
|
Chris@16
|
3580 // Assignment
|
Chris@16
|
3581 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
|
Chris@16
|
3582
|
Chris@16
|
3583 /*! @note "pass by value" the key idea to enable move semantics */
|
Chris@16
|
3584 BOOST_UBLAS_INLINE
|
Chris@16
|
3585 c_matrix &operator = (c_matrix m) {
|
Chris@16
|
3586 assign_temporary(m);
|
Chris@16
|
3587 return *this;
|
Chris@16
|
3588 }
|
Chris@16
|
3589 #else
|
Chris@16
|
3590 BOOST_UBLAS_INLINE
|
Chris@16
|
3591 c_matrix &operator = (const c_matrix &m) {
|
Chris@16
|
3592 size1_ = m.size1_;
|
Chris@16
|
3593 size2_ = m.size2_;
|
Chris@16
|
3594 for (size_type i = 0; i < m.size1_; ++ i)
|
Chris@16
|
3595 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
|
Chris@16
|
3596 return *this;
|
Chris@16
|
3597 }
|
Chris@16
|
3598 #endif
|
Chris@16
|
3599 template<class C> // Container assignment without temporary
|
Chris@16
|
3600 BOOST_UBLAS_INLINE
|
Chris@16
|
3601 c_matrix &operator = (const matrix_container<C> &m) {
|
Chris@16
|
3602 resize (m ().size1 (), m ().size2 (), false);
|
Chris@16
|
3603 assign (m);
|
Chris@16
|
3604 return *this;
|
Chris@16
|
3605 }
|
Chris@16
|
3606 BOOST_UBLAS_INLINE
|
Chris@16
|
3607 c_matrix &assign_temporary (c_matrix &m) {
|
Chris@16
|
3608 swap (m);
|
Chris@16
|
3609 return *this;
|
Chris@16
|
3610 }
|
Chris@16
|
3611 template<class AE>
|
Chris@16
|
3612 BOOST_UBLAS_INLINE
|
Chris@16
|
3613 c_matrix &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
3614 self_type temporary (ae);
|
Chris@16
|
3615 return assign_temporary (temporary);
|
Chris@16
|
3616 }
|
Chris@16
|
3617 template<class AE>
|
Chris@16
|
3618 BOOST_UBLAS_INLINE
|
Chris@16
|
3619 c_matrix &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3620 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
3621 return *this;
|
Chris@16
|
3622 }
|
Chris@16
|
3623 template<class AE>
|
Chris@16
|
3624 BOOST_UBLAS_INLINE
|
Chris@16
|
3625 c_matrix& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
3626 self_type temporary (*this + ae);
|
Chris@16
|
3627 return assign_temporary (temporary);
|
Chris@16
|
3628 }
|
Chris@16
|
3629 template<class C> // Container assignment without temporary
|
Chris@16
|
3630 BOOST_UBLAS_INLINE
|
Chris@16
|
3631 c_matrix &operator += (const matrix_container<C> &m) {
|
Chris@16
|
3632 plus_assign (m);
|
Chris@16
|
3633 return *this;
|
Chris@16
|
3634 }
|
Chris@16
|
3635 template<class AE>
|
Chris@16
|
3636 BOOST_UBLAS_INLINE
|
Chris@16
|
3637 c_matrix &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3638 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
3639 return *this;
|
Chris@16
|
3640 }
|
Chris@16
|
3641 template<class AE>
|
Chris@16
|
3642 BOOST_UBLAS_INLINE
|
Chris@16
|
3643 c_matrix& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
3644 self_type temporary (*this - ae);
|
Chris@16
|
3645 return assign_temporary (temporary);
|
Chris@16
|
3646 }
|
Chris@16
|
3647 template<class C> // Container assignment without temporary
|
Chris@16
|
3648 BOOST_UBLAS_INLINE
|
Chris@16
|
3649 c_matrix &operator -= (const matrix_container<C> &m) {
|
Chris@16
|
3650 minus_assign (m);
|
Chris@16
|
3651 return *this;
|
Chris@16
|
3652 }
|
Chris@16
|
3653 template<class AE>
|
Chris@16
|
3654 BOOST_UBLAS_INLINE
|
Chris@16
|
3655 c_matrix &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3656 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
3657 return *this;
|
Chris@16
|
3658 }
|
Chris@16
|
3659 template<class AT>
|
Chris@16
|
3660 BOOST_UBLAS_INLINE
|
Chris@16
|
3661 c_matrix& operator *= (const AT &at) {
|
Chris@16
|
3662 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
3663 return *this;
|
Chris@16
|
3664 }
|
Chris@16
|
3665 template<class AT>
|
Chris@16
|
3666 BOOST_UBLAS_INLINE
|
Chris@16
|
3667 c_matrix& operator /= (const AT &at) {
|
Chris@16
|
3668 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
3669 return *this;
|
Chris@16
|
3670 }
|
Chris@16
|
3671
|
Chris@16
|
3672 // Swapping
|
Chris@16
|
3673 BOOST_UBLAS_INLINE
|
Chris@16
|
3674 void swap (c_matrix &m) {
|
Chris@16
|
3675 if (this != &m) {
|
Chris@16
|
3676 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
|
Chris@16
|
3677 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
|
Chris@16
|
3678 std::swap (size1_, m.size1_);
|
Chris@16
|
3679 std::swap (size2_, m.size2_);
|
Chris@16
|
3680 for (size_type i = 0; i < size1_; ++ i)
|
Chris@16
|
3681 std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
|
Chris@16
|
3682 }
|
Chris@16
|
3683 }
|
Chris@16
|
3684 BOOST_UBLAS_INLINE
|
Chris@16
|
3685 friend void swap (c_matrix &m1, c_matrix &m2) {
|
Chris@16
|
3686 m1.swap (m2);
|
Chris@16
|
3687 }
|
Chris@16
|
3688
|
Chris@16
|
3689 // Iterator types
|
Chris@16
|
3690 private:
|
Chris@16
|
3691 // Use pointers for iterator
|
Chris@16
|
3692 typedef const_pointer const_subiterator_type;
|
Chris@16
|
3693 typedef pointer subiterator_type;
|
Chris@16
|
3694
|
Chris@16
|
3695 public:
|
Chris@16
|
3696 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3697 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
|
Chris@16
|
3698 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
|
Chris@16
|
3699 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
|
Chris@16
|
3700 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
|
Chris@16
|
3701 #else
|
Chris@16
|
3702 class const_iterator1;
|
Chris@16
|
3703 class iterator1;
|
Chris@16
|
3704 class const_iterator2;
|
Chris@16
|
3705 class iterator2;
|
Chris@16
|
3706 #endif
|
Chris@16
|
3707 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
3708 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
3709 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
3710 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
3711
|
Chris@16
|
3712 // Element lookup
|
Chris@16
|
3713 BOOST_UBLAS_INLINE
|
Chris@16
|
3714 const_iterator1 find1 (int rank, size_type i, size_type j) const {
|
Chris@16
|
3715 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3716 return const_iterator1 (*this, i, j);
|
Chris@16
|
3717 #else
|
Chris@16
|
3718 return const_iterator1 (*this, &data_ [i] [j]);
|
Chris@16
|
3719 #endif
|
Chris@16
|
3720 }
|
Chris@16
|
3721 BOOST_UBLAS_INLINE
|
Chris@16
|
3722 iterator1 find1 (int rank, size_type i, size_type j) {
|
Chris@16
|
3723 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3724 return iterator1 (*this, i, j);
|
Chris@16
|
3725 #else
|
Chris@16
|
3726 return iterator1 (*this, &data_ [i] [j]);
|
Chris@16
|
3727 #endif
|
Chris@16
|
3728 }
|
Chris@16
|
3729 BOOST_UBLAS_INLINE
|
Chris@16
|
3730 const_iterator2 find2 (int rank, size_type i, size_type j) const {
|
Chris@16
|
3731 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3732 return const_iterator2 (*this, i, j);
|
Chris@16
|
3733 #else
|
Chris@16
|
3734 return const_iterator2 (*this, &data_ [i] [j]);
|
Chris@16
|
3735 #endif
|
Chris@16
|
3736 }
|
Chris@16
|
3737 BOOST_UBLAS_INLINE
|
Chris@16
|
3738 iterator2 find2 (int rank, size_type i, size_type j) {
|
Chris@16
|
3739 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3740 return iterator2 (*this, i, j);
|
Chris@16
|
3741 #else
|
Chris@16
|
3742 return iterator2 (*this, &data_ [i] [j]);
|
Chris@16
|
3743 #endif
|
Chris@16
|
3744 }
|
Chris@16
|
3745
|
Chris@16
|
3746
|
Chris@16
|
3747 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3748 class const_iterator1:
|
Chris@16
|
3749 public container_const_reference<c_matrix>,
|
Chris@16
|
3750 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
3751 const_iterator1, value_type> {
|
Chris@16
|
3752 public:
|
Chris@16
|
3753 typedef typename c_matrix::difference_type difference_type;
|
Chris@16
|
3754 typedef typename c_matrix::value_type value_type;
|
Chris@16
|
3755 typedef typename c_matrix::const_reference reference;
|
Chris@16
|
3756 typedef typename c_matrix::const_pointer pointer;
|
Chris@16
|
3757
|
Chris@16
|
3758 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
3759 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
3760
|
Chris@16
|
3761 // Construction and destruction
|
Chris@16
|
3762 BOOST_UBLAS_INLINE
|
Chris@16
|
3763 const_iterator1 ():
|
Chris@16
|
3764 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
3765 BOOST_UBLAS_INLINE
|
Chris@16
|
3766 const_iterator1 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
3767 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
3768 BOOST_UBLAS_INLINE
|
Chris@16
|
3769 const_iterator1 (const iterator1 &it):
|
Chris@16
|
3770 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
3771
|
Chris@16
|
3772 // Arithmetic
|
Chris@16
|
3773 BOOST_UBLAS_INLINE
|
Chris@16
|
3774 const_iterator1 &operator ++ () {
|
Chris@16
|
3775 it_ += M;
|
Chris@16
|
3776 return *this;
|
Chris@16
|
3777 }
|
Chris@16
|
3778 BOOST_UBLAS_INLINE
|
Chris@16
|
3779 const_iterator1 &operator -- () {
|
Chris@16
|
3780 it_ -= M;
|
Chris@16
|
3781 return *this;
|
Chris@16
|
3782 }
|
Chris@16
|
3783 BOOST_UBLAS_INLINE
|
Chris@16
|
3784 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
3785 it_ += n * M;
|
Chris@16
|
3786 return *this;
|
Chris@16
|
3787 }
|
Chris@16
|
3788 BOOST_UBLAS_INLINE
|
Chris@16
|
3789 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
3790 it_ -= n * M;
|
Chris@16
|
3791 return *this;
|
Chris@16
|
3792 }
|
Chris@16
|
3793 BOOST_UBLAS_INLINE
|
Chris@16
|
3794 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
3795 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3796 return (it_ - it.it_) / M;
|
Chris@16
|
3797 }
|
Chris@16
|
3798
|
Chris@16
|
3799 // Dereference
|
Chris@16
|
3800 BOOST_UBLAS_INLINE
|
Chris@16
|
3801 const_reference operator * () const {
|
Chris@16
|
3802 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
3803 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
3804 return *it_;
|
Chris@16
|
3805 }
|
Chris@16
|
3806 BOOST_UBLAS_INLINE
|
Chris@16
|
3807 const_reference operator [] (difference_type n) const {
|
Chris@16
|
3808 return *(*this + n);
|
Chris@16
|
3809 }
|
Chris@16
|
3810
|
Chris@16
|
3811 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3812 BOOST_UBLAS_INLINE
|
Chris@16
|
3813 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3814 typename self_type::
|
Chris@16
|
3815 #endif
|
Chris@16
|
3816 const_iterator2 begin () const {
|
Chris@16
|
3817 const self_type &m = (*this) ();
|
Chris@16
|
3818 return m.find2 (1, index1 (), 0);
|
Chris@16
|
3819 }
|
Chris@16
|
3820 BOOST_UBLAS_INLINE
|
Chris@16
|
3821 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3822 typename self_type::
|
Chris@16
|
3823 #endif
|
Chris@16
|
3824 const_iterator2 end () const {
|
Chris@16
|
3825 const self_type &m = (*this) ();
|
Chris@16
|
3826 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
3827 }
|
Chris@16
|
3828 BOOST_UBLAS_INLINE
|
Chris@16
|
3829 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3830 typename self_type::
|
Chris@16
|
3831 #endif
|
Chris@16
|
3832 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
3833 return const_reverse_iterator2 (end ());
|
Chris@16
|
3834 }
|
Chris@16
|
3835 BOOST_UBLAS_INLINE
|
Chris@16
|
3836 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3837 typename self_type::
|
Chris@16
|
3838 #endif
|
Chris@16
|
3839 const_reverse_iterator2 rend () const {
|
Chris@16
|
3840 return const_reverse_iterator2 (begin ());
|
Chris@16
|
3841 }
|
Chris@16
|
3842 #endif
|
Chris@16
|
3843
|
Chris@16
|
3844 // Indices
|
Chris@16
|
3845 BOOST_UBLAS_INLINE
|
Chris@16
|
3846 size_type index1 () const {
|
Chris@16
|
3847 const self_type &m = (*this) ();
|
Chris@16
|
3848 return (it_ - m.begin1 ().it_) / M;
|
Chris@16
|
3849 }
|
Chris@16
|
3850 BOOST_UBLAS_INLINE
|
Chris@16
|
3851 size_type index2 () const {
|
Chris@16
|
3852 const self_type &m = (*this) ();
|
Chris@16
|
3853 return (it_ - m.begin1 ().it_) % M;
|
Chris@16
|
3854 }
|
Chris@16
|
3855
|
Chris@16
|
3856 // Assignment
|
Chris@16
|
3857 BOOST_UBLAS_INLINE
|
Chris@16
|
3858 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
3859 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
3860 it_ = it.it_;
|
Chris@16
|
3861 return *this;
|
Chris@16
|
3862 }
|
Chris@16
|
3863
|
Chris@16
|
3864 // Comparison
|
Chris@16
|
3865 BOOST_UBLAS_INLINE
|
Chris@16
|
3866 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
3867 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3868 return it_ == it.it_;
|
Chris@16
|
3869 }
|
Chris@16
|
3870 BOOST_UBLAS_INLINE
|
Chris@16
|
3871 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
3872 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3873 return it_ < it.it_;
|
Chris@16
|
3874 }
|
Chris@16
|
3875
|
Chris@16
|
3876 private:
|
Chris@16
|
3877 const_subiterator_type it_;
|
Chris@16
|
3878
|
Chris@16
|
3879 friend class iterator1;
|
Chris@16
|
3880 };
|
Chris@16
|
3881 #endif
|
Chris@16
|
3882
|
Chris@16
|
3883 BOOST_UBLAS_INLINE
|
Chris@16
|
3884 const_iterator1 begin1 () const {
|
Chris@16
|
3885 return find1 (0, 0, 0);
|
Chris@16
|
3886 }
|
Chris@16
|
3887 BOOST_UBLAS_INLINE
|
Chris@16
|
3888 const_iterator1 end1 () const {
|
Chris@16
|
3889 return find1 (0, size1_, 0);
|
Chris@16
|
3890 }
|
Chris@16
|
3891
|
Chris@16
|
3892 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3893 class iterator1:
|
Chris@16
|
3894 public container_reference<c_matrix>,
|
Chris@16
|
3895 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
3896 iterator1, value_type> {
|
Chris@16
|
3897 public:
|
Chris@16
|
3898
|
Chris@16
|
3899 typedef typename c_matrix::difference_type difference_type;
|
Chris@16
|
3900 typedef typename c_matrix::value_type value_type;
|
Chris@16
|
3901 typedef typename c_matrix::reference reference;
|
Chris@16
|
3902 typedef typename c_matrix::pointer pointer;
|
Chris@16
|
3903
|
Chris@16
|
3904 typedef iterator2 dual_iterator_type;
|
Chris@16
|
3905 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
3906
|
Chris@16
|
3907 // Construction and destruction
|
Chris@16
|
3908 BOOST_UBLAS_INLINE
|
Chris@16
|
3909 iterator1 ():
|
Chris@16
|
3910 container_reference<self_type> (), it_ () {}
|
Chris@16
|
3911 BOOST_UBLAS_INLINE
|
Chris@16
|
3912 iterator1 (self_type &m, const subiterator_type &it):
|
Chris@16
|
3913 container_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
3914
|
Chris@16
|
3915 // Arithmetic
|
Chris@16
|
3916 BOOST_UBLAS_INLINE
|
Chris@16
|
3917 iterator1 &operator ++ () {
|
Chris@16
|
3918 it_ += M;
|
Chris@16
|
3919 return *this;
|
Chris@16
|
3920 }
|
Chris@16
|
3921 BOOST_UBLAS_INLINE
|
Chris@16
|
3922 iterator1 &operator -- () {
|
Chris@16
|
3923 it_ -= M;
|
Chris@16
|
3924 return *this;
|
Chris@16
|
3925 }
|
Chris@16
|
3926 BOOST_UBLAS_INLINE
|
Chris@16
|
3927 iterator1 &operator += (difference_type n) {
|
Chris@16
|
3928 it_ += n * M;
|
Chris@16
|
3929 return *this;
|
Chris@16
|
3930 }
|
Chris@16
|
3931 BOOST_UBLAS_INLINE
|
Chris@16
|
3932 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
3933 it_ -= n * M;
|
Chris@16
|
3934 return *this;
|
Chris@16
|
3935 }
|
Chris@16
|
3936 BOOST_UBLAS_INLINE
|
Chris@16
|
3937 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
3938 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
3939 return (it_ - it.it_) / M;
|
Chris@16
|
3940 }
|
Chris@16
|
3941
|
Chris@16
|
3942 // Dereference
|
Chris@16
|
3943 BOOST_UBLAS_INLINE
|
Chris@16
|
3944 reference operator * () const {
|
Chris@16
|
3945 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
3946 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
3947 return *it_;
|
Chris@16
|
3948 }
|
Chris@16
|
3949 BOOST_UBLAS_INLINE
|
Chris@16
|
3950 reference operator [] (difference_type n) const {
|
Chris@16
|
3951 return *(*this + n);
|
Chris@16
|
3952 }
|
Chris@16
|
3953
|
Chris@16
|
3954 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3955 BOOST_UBLAS_INLINE
|
Chris@16
|
3956 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3957 typename self_type::
|
Chris@16
|
3958 #endif
|
Chris@16
|
3959 iterator2 begin () const {
|
Chris@16
|
3960 self_type &m = (*this) ();
|
Chris@16
|
3961 return m.find2 (1, index1 (), 0);
|
Chris@16
|
3962 }
|
Chris@16
|
3963 BOOST_UBLAS_INLINE
|
Chris@16
|
3964 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3965 typename self_type::
|
Chris@16
|
3966 #endif
|
Chris@16
|
3967 iterator2 end () const {
|
Chris@16
|
3968 self_type &m = (*this) ();
|
Chris@16
|
3969 return m.find2 (1, index1 (), m.size2 ());
|
Chris@16
|
3970 }
|
Chris@16
|
3971 BOOST_UBLAS_INLINE
|
Chris@16
|
3972 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3973 typename self_type::
|
Chris@16
|
3974 #endif
|
Chris@16
|
3975 reverse_iterator2 rbegin () const {
|
Chris@16
|
3976 return reverse_iterator2 (end ());
|
Chris@16
|
3977 }
|
Chris@16
|
3978 BOOST_UBLAS_INLINE
|
Chris@16
|
3979 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3980 typename self_type::
|
Chris@16
|
3981 #endif
|
Chris@16
|
3982 reverse_iterator2 rend () const {
|
Chris@16
|
3983 return reverse_iterator2 (begin ());
|
Chris@16
|
3984 }
|
Chris@16
|
3985 #endif
|
Chris@16
|
3986
|
Chris@16
|
3987 // Indices
|
Chris@16
|
3988 BOOST_UBLAS_INLINE
|
Chris@16
|
3989 size_type index1 () const {
|
Chris@16
|
3990 const self_type &m = (*this) ();
|
Chris@16
|
3991 return (it_ - m.begin1 ().it_) / M;
|
Chris@16
|
3992 }
|
Chris@16
|
3993 BOOST_UBLAS_INLINE
|
Chris@16
|
3994 size_type index2 () const {
|
Chris@16
|
3995 const self_type &m = (*this) ();
|
Chris@16
|
3996 return (it_ - m.begin1 ().it_) % M;
|
Chris@16
|
3997 }
|
Chris@16
|
3998
|
Chris@16
|
3999 // Assignment
|
Chris@16
|
4000 BOOST_UBLAS_INLINE
|
Chris@16
|
4001 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
4002 container_reference<self_type>::assign (&it ());
|
Chris@16
|
4003 it_ = it.it_;
|
Chris@16
|
4004 return *this;
|
Chris@16
|
4005 }
|
Chris@16
|
4006
|
Chris@16
|
4007 // Comparison
|
Chris@16
|
4008 BOOST_UBLAS_INLINE
|
Chris@16
|
4009 bool operator == (const iterator1 &it) const {
|
Chris@16
|
4010 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4011 return it_ == it.it_;
|
Chris@16
|
4012 }
|
Chris@16
|
4013 BOOST_UBLAS_INLINE
|
Chris@16
|
4014 bool operator < (const iterator1 &it) const {
|
Chris@16
|
4015 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4016 return it_ < it.it_;
|
Chris@16
|
4017 }
|
Chris@16
|
4018
|
Chris@16
|
4019 private:
|
Chris@16
|
4020 subiterator_type it_;
|
Chris@16
|
4021
|
Chris@16
|
4022 friend class const_iterator1;
|
Chris@16
|
4023 };
|
Chris@16
|
4024 #endif
|
Chris@16
|
4025
|
Chris@16
|
4026 BOOST_UBLAS_INLINE
|
Chris@16
|
4027 iterator1 begin1 () {
|
Chris@16
|
4028 return find1 (0, 0, 0);
|
Chris@16
|
4029 }
|
Chris@16
|
4030 BOOST_UBLAS_INLINE
|
Chris@16
|
4031 iterator1 end1 () {
|
Chris@16
|
4032 return find1 (0, size1_, 0);
|
Chris@16
|
4033 }
|
Chris@16
|
4034
|
Chris@16
|
4035 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4036 class const_iterator2:
|
Chris@16
|
4037 public container_const_reference<c_matrix>,
|
Chris@16
|
4038 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
4039 const_iterator2, value_type> {
|
Chris@16
|
4040 public:
|
Chris@16
|
4041 typedef typename c_matrix::difference_type difference_type;
|
Chris@16
|
4042 typedef typename c_matrix::value_type value_type;
|
Chris@16
|
4043 typedef typename c_matrix::const_reference reference;
|
Chris@16
|
4044 typedef typename c_matrix::const_reference pointer;
|
Chris@16
|
4045
|
Chris@16
|
4046 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
4047 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
4048
|
Chris@16
|
4049 // Construction and destruction
|
Chris@16
|
4050 BOOST_UBLAS_INLINE
|
Chris@16
|
4051 const_iterator2 ():
|
Chris@16
|
4052 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
4053 BOOST_UBLAS_INLINE
|
Chris@16
|
4054 const_iterator2 (const self_type &m, const const_subiterator_type &it):
|
Chris@16
|
4055 container_const_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
4056 BOOST_UBLAS_INLINE
|
Chris@16
|
4057 const_iterator2 (const iterator2 &it):
|
Chris@16
|
4058 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
4059
|
Chris@16
|
4060 // Arithmetic
|
Chris@16
|
4061 BOOST_UBLAS_INLINE
|
Chris@16
|
4062 const_iterator2 &operator ++ () {
|
Chris@16
|
4063 ++ it_;
|
Chris@16
|
4064 return *this;
|
Chris@16
|
4065 }
|
Chris@16
|
4066 BOOST_UBLAS_INLINE
|
Chris@16
|
4067 const_iterator2 &operator -- () {
|
Chris@16
|
4068 -- it_;
|
Chris@16
|
4069 return *this;
|
Chris@16
|
4070 }
|
Chris@16
|
4071 BOOST_UBLAS_INLINE
|
Chris@16
|
4072 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
4073 it_ += n;
|
Chris@16
|
4074 return *this;
|
Chris@16
|
4075 }
|
Chris@16
|
4076 BOOST_UBLAS_INLINE
|
Chris@16
|
4077 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
4078 it_ -= n;
|
Chris@16
|
4079 return *this;
|
Chris@16
|
4080 }
|
Chris@16
|
4081 BOOST_UBLAS_INLINE
|
Chris@16
|
4082 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
4083 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4084 return it_ - it.it_;
|
Chris@16
|
4085 }
|
Chris@16
|
4086
|
Chris@16
|
4087 // Dereference
|
Chris@16
|
4088 BOOST_UBLAS_INLINE
|
Chris@16
|
4089 const_reference operator * () const {
|
Chris@16
|
4090 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
4091 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
4092 return *it_;
|
Chris@16
|
4093 }
|
Chris@16
|
4094 BOOST_UBLAS_INLINE
|
Chris@16
|
4095 const_reference operator [] (difference_type n) const {
|
Chris@16
|
4096 return *(*this + n);
|
Chris@16
|
4097 }
|
Chris@16
|
4098
|
Chris@16
|
4099 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4100 BOOST_UBLAS_INLINE
|
Chris@16
|
4101 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4102 typename self_type::
|
Chris@16
|
4103 #endif
|
Chris@16
|
4104 const_iterator1 begin () const {
|
Chris@16
|
4105 const self_type &m = (*this) ();
|
Chris@16
|
4106 return m.find1 (1, 0, index2 ());
|
Chris@16
|
4107 }
|
Chris@16
|
4108 BOOST_UBLAS_INLINE
|
Chris@16
|
4109 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4110 typename self_type::
|
Chris@16
|
4111 #endif
|
Chris@16
|
4112 const_iterator1 end () const {
|
Chris@16
|
4113 const self_type &m = (*this) ();
|
Chris@16
|
4114 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
4115 }
|
Chris@16
|
4116 BOOST_UBLAS_INLINE
|
Chris@16
|
4117 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4118 typename self_type::
|
Chris@16
|
4119 #endif
|
Chris@16
|
4120 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
4121 return const_reverse_iterator1 (end ());
|
Chris@16
|
4122 }
|
Chris@16
|
4123 BOOST_UBLAS_INLINE
|
Chris@16
|
4124 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4125 typename self_type::
|
Chris@16
|
4126 #endif
|
Chris@16
|
4127 const_reverse_iterator1 rend () const {
|
Chris@16
|
4128 return const_reverse_iterator1 (begin ());
|
Chris@16
|
4129 }
|
Chris@16
|
4130 #endif
|
Chris@16
|
4131
|
Chris@16
|
4132 // Indices
|
Chris@16
|
4133 BOOST_UBLAS_INLINE
|
Chris@16
|
4134 size_type index1 () const {
|
Chris@16
|
4135 const self_type &m = (*this) ();
|
Chris@16
|
4136 return (it_ - m.begin2 ().it_) / M;
|
Chris@16
|
4137 }
|
Chris@16
|
4138 BOOST_UBLAS_INLINE
|
Chris@16
|
4139 size_type index2 () const {
|
Chris@16
|
4140 const self_type &m = (*this) ();
|
Chris@16
|
4141 return (it_ - m.begin2 ().it_) % M;
|
Chris@16
|
4142 }
|
Chris@16
|
4143
|
Chris@16
|
4144 // Assignment
|
Chris@16
|
4145 BOOST_UBLAS_INLINE
|
Chris@16
|
4146 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
4147 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
4148 it_ = it.it_;
|
Chris@16
|
4149 return *this;
|
Chris@16
|
4150 }
|
Chris@16
|
4151
|
Chris@16
|
4152 // Comparison
|
Chris@16
|
4153 BOOST_UBLAS_INLINE
|
Chris@16
|
4154 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
4155 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4156 return it_ == it.it_;
|
Chris@16
|
4157 }
|
Chris@16
|
4158 BOOST_UBLAS_INLINE
|
Chris@16
|
4159 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
4160 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4161 return it_ < it.it_;
|
Chris@16
|
4162 }
|
Chris@16
|
4163
|
Chris@16
|
4164 private:
|
Chris@16
|
4165 const_subiterator_type it_;
|
Chris@16
|
4166
|
Chris@16
|
4167 friend class iterator2;
|
Chris@16
|
4168 };
|
Chris@16
|
4169 #endif
|
Chris@16
|
4170
|
Chris@16
|
4171 BOOST_UBLAS_INLINE
|
Chris@16
|
4172 const_iterator2 begin2 () const {
|
Chris@16
|
4173 return find2 (0, 0, 0);
|
Chris@16
|
4174 }
|
Chris@16
|
4175 BOOST_UBLAS_INLINE
|
Chris@16
|
4176 const_iterator2 end2 () const {
|
Chris@16
|
4177 return find2 (0, 0, size2_);
|
Chris@16
|
4178 }
|
Chris@16
|
4179
|
Chris@16
|
4180 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4181 class iterator2:
|
Chris@16
|
4182 public container_reference<c_matrix>,
|
Chris@16
|
4183 public random_access_iterator_base<dense_random_access_iterator_tag,
|
Chris@16
|
4184 iterator2, value_type> {
|
Chris@16
|
4185 public:
|
Chris@16
|
4186 typedef typename c_matrix::difference_type difference_type;
|
Chris@16
|
4187 typedef typename c_matrix::value_type value_type;
|
Chris@16
|
4188 typedef typename c_matrix::reference reference;
|
Chris@16
|
4189 typedef typename c_matrix::pointer pointer;
|
Chris@16
|
4190
|
Chris@16
|
4191 typedef iterator1 dual_iterator_type;
|
Chris@16
|
4192 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
4193
|
Chris@16
|
4194 // Construction and destruction
|
Chris@16
|
4195 BOOST_UBLAS_INLINE
|
Chris@16
|
4196 iterator2 ():
|
Chris@16
|
4197 container_reference<self_type> (), it_ () {}
|
Chris@16
|
4198 BOOST_UBLAS_INLINE
|
Chris@16
|
4199 iterator2 (self_type &m, const subiterator_type &it):
|
Chris@16
|
4200 container_reference<self_type> (m), it_ (it) {}
|
Chris@16
|
4201
|
Chris@16
|
4202 // Arithmetic
|
Chris@16
|
4203 BOOST_UBLAS_INLINE
|
Chris@16
|
4204 iterator2 &operator ++ () {
|
Chris@16
|
4205 ++ it_;
|
Chris@16
|
4206 return *this;
|
Chris@16
|
4207 }
|
Chris@16
|
4208 BOOST_UBLAS_INLINE
|
Chris@16
|
4209 iterator2 &operator -- () {
|
Chris@16
|
4210 -- it_;
|
Chris@16
|
4211 return *this;
|
Chris@16
|
4212 }
|
Chris@16
|
4213 BOOST_UBLAS_INLINE
|
Chris@16
|
4214 iterator2 &operator += (difference_type n) {
|
Chris@16
|
4215 it_ += n;
|
Chris@16
|
4216 return *this;
|
Chris@16
|
4217 }
|
Chris@16
|
4218 BOOST_UBLAS_INLINE
|
Chris@16
|
4219 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
4220 it_ -= n;
|
Chris@16
|
4221 return *this;
|
Chris@16
|
4222 }
|
Chris@16
|
4223 BOOST_UBLAS_INLINE
|
Chris@16
|
4224 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
4225 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4226 return it_ - it.it_;
|
Chris@16
|
4227 }
|
Chris@16
|
4228
|
Chris@16
|
4229 // Dereference
|
Chris@16
|
4230 BOOST_UBLAS_INLINE
|
Chris@16
|
4231 reference operator * () const {
|
Chris@16
|
4232 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
4233 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
4234 return *it_;
|
Chris@16
|
4235 }
|
Chris@16
|
4236 BOOST_UBLAS_INLINE
|
Chris@16
|
4237 reference operator [] (difference_type n) const {
|
Chris@16
|
4238 return *(*this + n);
|
Chris@16
|
4239 }
|
Chris@16
|
4240
|
Chris@16
|
4241 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4242 BOOST_UBLAS_INLINE
|
Chris@16
|
4243 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4244 typename self_type::
|
Chris@16
|
4245 #endif
|
Chris@16
|
4246 iterator1 begin () const {
|
Chris@16
|
4247 self_type &m = (*this) ();
|
Chris@16
|
4248 return m.find1 (1, 0, index2 ());
|
Chris@16
|
4249 }
|
Chris@16
|
4250 BOOST_UBLAS_INLINE
|
Chris@16
|
4251 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4252 typename self_type::
|
Chris@16
|
4253 #endif
|
Chris@16
|
4254 iterator1 end () const {
|
Chris@16
|
4255 self_type &m = (*this) ();
|
Chris@16
|
4256 return m.find1 (1, m.size1 (), index2 ());
|
Chris@16
|
4257 }
|
Chris@16
|
4258 BOOST_UBLAS_INLINE
|
Chris@16
|
4259 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4260 typename self_type::
|
Chris@16
|
4261 #endif
|
Chris@16
|
4262 reverse_iterator1 rbegin () const {
|
Chris@16
|
4263 return reverse_iterator1 (end ());
|
Chris@16
|
4264 }
|
Chris@16
|
4265 BOOST_UBLAS_INLINE
|
Chris@16
|
4266 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4267 typename self_type::
|
Chris@16
|
4268 #endif
|
Chris@16
|
4269 reverse_iterator1 rend () const {
|
Chris@16
|
4270 return reverse_iterator1 (begin ());
|
Chris@16
|
4271 }
|
Chris@16
|
4272 #endif
|
Chris@16
|
4273
|
Chris@16
|
4274 // Indices
|
Chris@16
|
4275 BOOST_UBLAS_INLINE
|
Chris@16
|
4276 size_type index1 () const {
|
Chris@16
|
4277 const self_type &m = (*this) ();
|
Chris@16
|
4278 return (it_ - m.begin2 ().it_) / M;
|
Chris@16
|
4279 }
|
Chris@16
|
4280 BOOST_UBLAS_INLINE
|
Chris@16
|
4281 size_type index2 () const {
|
Chris@16
|
4282 const self_type &m = (*this) ();
|
Chris@16
|
4283 return (it_ - m.begin2 ().it_) % M;
|
Chris@16
|
4284 }
|
Chris@16
|
4285
|
Chris@16
|
4286 // Assignment
|
Chris@16
|
4287 BOOST_UBLAS_INLINE
|
Chris@16
|
4288 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
4289 container_reference<self_type>::assign (&it ());
|
Chris@16
|
4290 it_ = it.it_;
|
Chris@16
|
4291 return *this;
|
Chris@16
|
4292 }
|
Chris@16
|
4293
|
Chris@16
|
4294 // Comparison
|
Chris@16
|
4295 BOOST_UBLAS_INLINE
|
Chris@16
|
4296 bool operator == (const iterator2 &it) const {
|
Chris@16
|
4297 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4298 return it_ == it.it_;
|
Chris@16
|
4299 }
|
Chris@16
|
4300 BOOST_UBLAS_INLINE
|
Chris@16
|
4301 bool operator < (const iterator2 &it) const {
|
Chris@16
|
4302 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
4303 return it_ < it.it_;
|
Chris@16
|
4304 }
|
Chris@16
|
4305
|
Chris@16
|
4306 private:
|
Chris@16
|
4307 subiterator_type it_;
|
Chris@16
|
4308
|
Chris@16
|
4309 friend class const_iterator2;
|
Chris@16
|
4310 };
|
Chris@16
|
4311 #endif
|
Chris@16
|
4312
|
Chris@16
|
4313 BOOST_UBLAS_INLINE
|
Chris@16
|
4314 iterator2 begin2 () {
|
Chris@16
|
4315 return find2 (0, 0, 0);
|
Chris@16
|
4316 }
|
Chris@16
|
4317 BOOST_UBLAS_INLINE
|
Chris@16
|
4318 iterator2 end2 () {
|
Chris@16
|
4319 return find2 (0, 0, size2_);
|
Chris@16
|
4320 }
|
Chris@16
|
4321
|
Chris@16
|
4322 // Reverse iterators
|
Chris@16
|
4323
|
Chris@16
|
4324 BOOST_UBLAS_INLINE
|
Chris@16
|
4325 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
4326 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
4327 }
|
Chris@16
|
4328 BOOST_UBLAS_INLINE
|
Chris@16
|
4329 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
4330 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
4331 }
|
Chris@16
|
4332
|
Chris@16
|
4333 BOOST_UBLAS_INLINE
|
Chris@16
|
4334 reverse_iterator1 rbegin1 () {
|
Chris@16
|
4335 return reverse_iterator1 (end1 ());
|
Chris@16
|
4336 }
|
Chris@16
|
4337 BOOST_UBLAS_INLINE
|
Chris@16
|
4338 reverse_iterator1 rend1 () {
|
Chris@16
|
4339 return reverse_iterator1 (begin1 ());
|
Chris@16
|
4340 }
|
Chris@16
|
4341
|
Chris@16
|
4342 BOOST_UBLAS_INLINE
|
Chris@16
|
4343 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
4344 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
4345 }
|
Chris@16
|
4346 BOOST_UBLAS_INLINE
|
Chris@16
|
4347 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
4348 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
4349 }
|
Chris@16
|
4350
|
Chris@16
|
4351 BOOST_UBLAS_INLINE
|
Chris@16
|
4352 reverse_iterator2 rbegin2 () {
|
Chris@16
|
4353 return reverse_iterator2 (end2 ());
|
Chris@16
|
4354 }
|
Chris@16
|
4355 BOOST_UBLAS_INLINE
|
Chris@16
|
4356 reverse_iterator2 rend2 () {
|
Chris@16
|
4357 return reverse_iterator2 (begin2 ());
|
Chris@16
|
4358 }
|
Chris@16
|
4359
|
Chris@16
|
4360 // Serialization
|
Chris@16
|
4361 template<class Archive>
|
Chris@16
|
4362 void serialize(Archive & ar, const unsigned int /* file_version */){
|
Chris@16
|
4363
|
Chris@16
|
4364 // we need to copy to a collection_size_type to get a portable
|
Chris@16
|
4365 // and efficient serialization
|
Chris@16
|
4366 serialization::collection_size_type s1 (size1_);
|
Chris@16
|
4367 serialization::collection_size_type s2 (size2_);
|
Chris@16
|
4368
|
Chris@16
|
4369 // serialize the sizes
|
Chris@16
|
4370 ar & serialization::make_nvp("size1",s1)
|
Chris@16
|
4371 & serialization::make_nvp("size2",s2);
|
Chris@16
|
4372
|
Chris@16
|
4373 // copy the values back if loading
|
Chris@16
|
4374 if (Archive::is_loading::value) {
|
Chris@16
|
4375 size1_ = s1;
|
Chris@16
|
4376 size2_ = s2;
|
Chris@16
|
4377 }
|
Chris@16
|
4378 // could probably use make_array( &(data[0][0]), N*M )
|
Chris@16
|
4379 ar & serialization::make_array(data_, N);
|
Chris@16
|
4380 }
|
Chris@16
|
4381
|
Chris@16
|
4382 private:
|
Chris@16
|
4383 size_type size1_;
|
Chris@16
|
4384 size_type size2_;
|
Chris@16
|
4385 value_type data_ [N] [M];
|
Chris@16
|
4386 };
|
Chris@16
|
4387
|
Chris@16
|
4388 }}}
|
Chris@16
|
4389
|
Chris@16
|
4390 #endif
|