Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2000-2002
|
Chris@16
|
3 // Joerg Walter, Mathias Koch
|
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_PROXY_
|
Chris@16
|
14 #define _BOOST_UBLAS_MATRIX_PROXY_
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/numeric/ublas/matrix_expression.hpp>
|
Chris@16
|
17 #include <boost/numeric/ublas/detail/vector_assign.hpp>
|
Chris@16
|
18 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
|
Chris@16
|
19 #include <boost/numeric/ublas/detail/temporary.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 // Iterators based on ideas of Jeremy Siek
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost { namespace numeric { namespace ublas {
|
Chris@16
|
24
|
Chris@16
|
25 /** \brief
|
Chris@16
|
26 */
|
Chris@16
|
27 template<class M>
|
Chris@16
|
28 class matrix_row:
|
Chris@16
|
29 public vector_expression<matrix_row<M> > {
|
Chris@16
|
30
|
Chris@16
|
31 typedef matrix_row<M> self_type;
|
Chris@16
|
32 public:
|
Chris@16
|
33 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
34 using vector_expression<self_type>::operator ();
|
Chris@16
|
35 #endif
|
Chris@16
|
36 typedef M matrix_type;
|
Chris@16
|
37 typedef typename M::size_type size_type;
|
Chris@16
|
38 typedef typename M::difference_type difference_type;
|
Chris@16
|
39 typedef typename M::value_type value_type;
|
Chris@16
|
40 typedef typename M::const_reference const_reference;
|
Chris@16
|
41 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
42 typename M::const_reference,
|
Chris@16
|
43 typename M::reference>::type reference;
|
Chris@16
|
44 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
45 typename M::const_closure_type,
|
Chris@16
|
46 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
47 typedef const self_type const_closure_type;
|
Chris@16
|
48 typedef self_type closure_type;
|
Chris@16
|
49 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
50 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
51
|
Chris@16
|
52 // Construction and destruction
|
Chris@16
|
53 BOOST_UBLAS_INLINE
|
Chris@16
|
54 matrix_row (matrix_type &data, size_type i):
|
Chris@16
|
55 data_ (data), i_ (i) {
|
Chris@16
|
56 // Early checking of preconditions here.
|
Chris@16
|
57 // BOOST_UBLAS_CHECK (i_ < data_.size1 (), bad_index ());
|
Chris@16
|
58 }
|
Chris@16
|
59
|
Chris@16
|
60 // Accessors
|
Chris@16
|
61 BOOST_UBLAS_INLINE
|
Chris@16
|
62 size_type size () const {
|
Chris@16
|
63 return data_.size2 ();
|
Chris@16
|
64 }
|
Chris@16
|
65 BOOST_UBLAS_INLINE
|
Chris@16
|
66 size_type index () const {
|
Chris@16
|
67 return i_;
|
Chris@16
|
68 }
|
Chris@16
|
69
|
Chris@16
|
70 // Storage accessors
|
Chris@16
|
71 BOOST_UBLAS_INLINE
|
Chris@16
|
72 const matrix_closure_type &data () const {
|
Chris@16
|
73 return data_;
|
Chris@16
|
74 }
|
Chris@16
|
75 BOOST_UBLAS_INLINE
|
Chris@16
|
76 matrix_closure_type &data () {
|
Chris@16
|
77 return data_;
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 // Element access
|
Chris@16
|
81 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
82 BOOST_UBLAS_INLINE
|
Chris@16
|
83 const_reference operator () (size_type j) const {
|
Chris@16
|
84 return data_ (i_, j);
|
Chris@16
|
85 }
|
Chris@16
|
86 BOOST_UBLAS_INLINE
|
Chris@16
|
87 reference operator () (size_type j) {
|
Chris@16
|
88 return data_ (i_, j);
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 BOOST_UBLAS_INLINE
|
Chris@16
|
92 const_reference operator [] (size_type j) const {
|
Chris@16
|
93 return (*this) (j);
|
Chris@16
|
94 }
|
Chris@16
|
95 BOOST_UBLAS_INLINE
|
Chris@16
|
96 reference operator [] (size_type j) {
|
Chris@16
|
97 return (*this) (j);
|
Chris@16
|
98 }
|
Chris@16
|
99 #else
|
Chris@16
|
100 BOOST_UBLAS_INLINE
|
Chris@16
|
101 reference operator () (size_type j) const {
|
Chris@16
|
102 return data_ (i_, j);
|
Chris@16
|
103 }
|
Chris@16
|
104
|
Chris@16
|
105 BOOST_UBLAS_INLINE
|
Chris@16
|
106 reference operator [] (size_type j) const {
|
Chris@16
|
107 return (*this) (j);
|
Chris@16
|
108 }
|
Chris@16
|
109 #endif
|
Chris@16
|
110
|
Chris@16
|
111 // Assignment
|
Chris@16
|
112 BOOST_UBLAS_INLINE
|
Chris@16
|
113 matrix_row &operator = (const matrix_row &mr) {
|
Chris@16
|
114 // ISSUE need a temporary, proxy can be overlaping alias
|
Chris@16
|
115 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mr));
|
Chris@16
|
116 return *this;
|
Chris@16
|
117 }
|
Chris@16
|
118 BOOST_UBLAS_INLINE
|
Chris@16
|
119 matrix_row &assign_temporary (matrix_row &mr) {
|
Chris@16
|
120 // assign elements, proxied container remains the same
|
Chris@16
|
121 vector_assign<scalar_assign> (*this, mr);
|
Chris@16
|
122 return *this;
|
Chris@16
|
123 }
|
Chris@16
|
124 template<class AE>
|
Chris@16
|
125 BOOST_UBLAS_INLINE
|
Chris@16
|
126 matrix_row &operator = (const vector_expression<AE> &ae) {
|
Chris@16
|
127 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
|
Chris@16
|
128 return *this;
|
Chris@16
|
129 }
|
Chris@16
|
130 template<class AE>
|
Chris@16
|
131 BOOST_UBLAS_INLINE
|
Chris@16
|
132 matrix_row &assign (const vector_expression<AE> &ae) {
|
Chris@16
|
133 vector_assign<scalar_assign> (*this, ae);
|
Chris@16
|
134 return *this;
|
Chris@16
|
135 }
|
Chris@16
|
136 template<class AE>
|
Chris@16
|
137 BOOST_UBLAS_INLINE
|
Chris@16
|
138 matrix_row &operator += (const vector_expression<AE> &ae) {
|
Chris@16
|
139 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
140 return *this;
|
Chris@16
|
141 }
|
Chris@16
|
142 template<class AE>
|
Chris@16
|
143 BOOST_UBLAS_INLINE
|
Chris@16
|
144 matrix_row &plus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
145 vector_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
146 return *this;
|
Chris@16
|
147 }
|
Chris@16
|
148 template<class AE>
|
Chris@16
|
149 BOOST_UBLAS_INLINE
|
Chris@16
|
150 matrix_row &operator -= (const vector_expression<AE> &ae) {
|
Chris@16
|
151 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
152 return *this;
|
Chris@16
|
153 }
|
Chris@16
|
154 template<class AE>
|
Chris@16
|
155 BOOST_UBLAS_INLINE
|
Chris@16
|
156 matrix_row &minus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
157 vector_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
158 return *this;
|
Chris@16
|
159 }
|
Chris@16
|
160 template<class AT>
|
Chris@16
|
161 BOOST_UBLAS_INLINE
|
Chris@16
|
162 matrix_row &operator *= (const AT &at) {
|
Chris@16
|
163 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
164 return *this;
|
Chris@16
|
165 }
|
Chris@16
|
166 template<class AT>
|
Chris@16
|
167 BOOST_UBLAS_INLINE
|
Chris@16
|
168 matrix_row &operator /= (const AT &at) {
|
Chris@16
|
169 vector_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
170 return *this;
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 // Closure comparison
|
Chris@16
|
174 BOOST_UBLAS_INLINE
|
Chris@16
|
175 bool same_closure (const matrix_row &mr) const {
|
Chris@16
|
176 return (*this).data_.same_closure (mr.data_);
|
Chris@16
|
177 }
|
Chris@16
|
178
|
Chris@16
|
179 // Comparison
|
Chris@16
|
180 BOOST_UBLAS_INLINE
|
Chris@16
|
181 bool operator == (const matrix_row &mr) const {
|
Chris@16
|
182 return (*this).data_ == mr.data_ && index () == mr.index ();
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 // Swapping
|
Chris@16
|
186 BOOST_UBLAS_INLINE
|
Chris@16
|
187 void swap (matrix_row mr) {
|
Chris@16
|
188 if (this != &mr) {
|
Chris@16
|
189 BOOST_UBLAS_CHECK (size () == mr.size (), bad_size ());
|
Chris@16
|
190 // Sparse ranges may be nonconformant now.
|
Chris@16
|
191 // std::swap_ranges (begin (), end (), mr.begin ());
|
Chris@16
|
192 vector_swap<scalar_swap> (*this, mr);
|
Chris@16
|
193 }
|
Chris@16
|
194 }
|
Chris@16
|
195 BOOST_UBLAS_INLINE
|
Chris@16
|
196 friend void swap (matrix_row mr1, matrix_row mr2) {
|
Chris@16
|
197 mr1.swap (mr2);
|
Chris@16
|
198 }
|
Chris@16
|
199
|
Chris@16
|
200 // Iterator types
|
Chris@16
|
201 private:
|
Chris@16
|
202 typedef typename M::const_iterator2 const_subiterator_type;
|
Chris@16
|
203 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
204 typename M::const_iterator2,
|
Chris@16
|
205 typename M::iterator2>::type subiterator_type;
|
Chris@16
|
206
|
Chris@16
|
207 public:
|
Chris@16
|
208 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
209 typedef indexed_iterator<matrix_row<matrix_type>,
|
Chris@16
|
210 typename subiterator_type::iterator_category> iterator;
|
Chris@16
|
211 typedef indexed_const_iterator<matrix_row<matrix_type>,
|
Chris@16
|
212 typename const_subiterator_type::iterator_category> const_iterator;
|
Chris@16
|
213 #else
|
Chris@16
|
214 class const_iterator;
|
Chris@16
|
215 class iterator;
|
Chris@16
|
216 #endif
|
Chris@16
|
217
|
Chris@16
|
218 // Element lookup
|
Chris@16
|
219 BOOST_UBLAS_INLINE
|
Chris@16
|
220 const_iterator find (size_type j) const {
|
Chris@16
|
221 const_subiterator_type it2 (data_.find2 (1, i_, j));
|
Chris@16
|
222 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
223 return const_iterator (*this, it2.index2 ());
|
Chris@16
|
224 #else
|
Chris@16
|
225 return const_iterator (*this, it2);
|
Chris@16
|
226 #endif
|
Chris@16
|
227 }
|
Chris@16
|
228 BOOST_UBLAS_INLINE
|
Chris@16
|
229 iterator find (size_type j) {
|
Chris@16
|
230 subiterator_type it2 (data_.find2 (1, i_, j));
|
Chris@16
|
231 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
232 return iterator (*this, it2.index2 ());
|
Chris@16
|
233 #else
|
Chris@16
|
234 return iterator (*this, it2);
|
Chris@16
|
235 #endif
|
Chris@16
|
236 }
|
Chris@16
|
237
|
Chris@16
|
238 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
239 class const_iterator:
|
Chris@16
|
240 public container_const_reference<matrix_row>,
|
Chris@16
|
241 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
|
Chris@16
|
242 iterator_base<const_iterator, value_type>::type {
|
Chris@16
|
243 public:
|
Chris@16
|
244 typedef typename const_subiterator_type::value_type value_type;
|
Chris@16
|
245 typedef typename const_subiterator_type::difference_type difference_type;
|
Chris@16
|
246 typedef typename const_subiterator_type::reference reference;
|
Chris@16
|
247 typedef typename const_subiterator_type::pointer pointer;
|
Chris@16
|
248
|
Chris@16
|
249 // Construction and destruction
|
Chris@16
|
250 BOOST_UBLAS_INLINE
|
Chris@16
|
251 const_iterator ():
|
Chris@16
|
252 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
253 BOOST_UBLAS_INLINE
|
Chris@16
|
254 const_iterator (const self_type &mr, const const_subiterator_type &it):
|
Chris@16
|
255 container_const_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
256 BOOST_UBLAS_INLINE
|
Chris@16
|
257 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
|
Chris@16
|
258 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
259
|
Chris@16
|
260 // Arithmetic
|
Chris@16
|
261 BOOST_UBLAS_INLINE
|
Chris@16
|
262 const_iterator &operator ++ () {
|
Chris@16
|
263 ++ it_;
|
Chris@16
|
264 return *this;
|
Chris@16
|
265 }
|
Chris@16
|
266 BOOST_UBLAS_INLINE
|
Chris@16
|
267 const_iterator &operator -- () {
|
Chris@16
|
268 -- it_;
|
Chris@16
|
269 return *this;
|
Chris@16
|
270 }
|
Chris@16
|
271 BOOST_UBLAS_INLINE
|
Chris@16
|
272 const_iterator &operator += (difference_type n) {
|
Chris@16
|
273 it_ += n;
|
Chris@16
|
274 return *this;
|
Chris@16
|
275 }
|
Chris@16
|
276 BOOST_UBLAS_INLINE
|
Chris@16
|
277 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
278 it_ -= n;
|
Chris@16
|
279 return *this;
|
Chris@16
|
280 }
|
Chris@16
|
281 BOOST_UBLAS_INLINE
|
Chris@16
|
282 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
283 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
284 return it_ - it.it_;
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287 // Dereference
|
Chris@16
|
288 BOOST_UBLAS_INLINE
|
Chris@16
|
289 const_reference operator * () const {
|
Chris@16
|
290 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
291 return *it_;
|
Chris@16
|
292 }
|
Chris@16
|
293 BOOST_UBLAS_INLINE
|
Chris@16
|
294 const_reference operator [] (difference_type n) const {
|
Chris@16
|
295 return *(*this + n);
|
Chris@16
|
296 }
|
Chris@16
|
297
|
Chris@16
|
298 // Index
|
Chris@16
|
299 BOOST_UBLAS_INLINE
|
Chris@16
|
300 size_type index () const {
|
Chris@16
|
301 return it_.index2 ();
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 // Assignment
|
Chris@16
|
305 BOOST_UBLAS_INLINE
|
Chris@16
|
306 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
307 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
308 it_ = it.it_;
|
Chris@16
|
309 return *this;
|
Chris@16
|
310 }
|
Chris@16
|
311
|
Chris@16
|
312 // Comparison
|
Chris@16
|
313 BOOST_UBLAS_INLINE
|
Chris@16
|
314 bool operator == (const const_iterator &it) const {
|
Chris@16
|
315 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
316 return it_ == it.it_;
|
Chris@16
|
317 }
|
Chris@16
|
318 BOOST_UBLAS_INLINE
|
Chris@16
|
319 bool operator < (const const_iterator &it) const {
|
Chris@16
|
320 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
321 return it_ < it.it_;
|
Chris@16
|
322 }
|
Chris@16
|
323
|
Chris@16
|
324 private:
|
Chris@16
|
325 const_subiterator_type it_;
|
Chris@16
|
326 };
|
Chris@16
|
327 #endif
|
Chris@16
|
328
|
Chris@16
|
329 BOOST_UBLAS_INLINE
|
Chris@16
|
330 const_iterator begin () const {
|
Chris@16
|
331 return find (0);
|
Chris@16
|
332 }
|
Chris@16
|
333 BOOST_UBLAS_INLINE
|
Chris@101
|
334 const_iterator cbegin () const {
|
Chris@101
|
335 return begin ();
|
Chris@101
|
336 }
|
Chris@101
|
337 BOOST_UBLAS_INLINE
|
Chris@16
|
338 const_iterator end () const {
|
Chris@16
|
339 return find (size ());
|
Chris@16
|
340 }
|
Chris@101
|
341 BOOST_UBLAS_INLINE
|
Chris@101
|
342 const_iterator cend () const {
|
Chris@101
|
343 return end ();
|
Chris@101
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
347 class iterator:
|
Chris@16
|
348 public container_reference<matrix_row>,
|
Chris@16
|
349 public iterator_base_traits<typename subiterator_type::iterator_category>::template
|
Chris@16
|
350 iterator_base<iterator, value_type>::type {
|
Chris@16
|
351 public:
|
Chris@16
|
352 typedef typename subiterator_type::value_type value_type;
|
Chris@16
|
353 typedef typename subiterator_type::difference_type difference_type;
|
Chris@16
|
354 typedef typename subiterator_type::reference reference;
|
Chris@16
|
355 typedef typename subiterator_type::pointer pointer;
|
Chris@16
|
356
|
Chris@16
|
357 // Construction and destruction
|
Chris@16
|
358 BOOST_UBLAS_INLINE
|
Chris@16
|
359 iterator ():
|
Chris@16
|
360 container_reference<self_type> (), it_ () {}
|
Chris@16
|
361 BOOST_UBLAS_INLINE
|
Chris@16
|
362 iterator (self_type &mr, const subiterator_type &it):
|
Chris@16
|
363 container_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
364
|
Chris@16
|
365 // Arithmetic
|
Chris@16
|
366 BOOST_UBLAS_INLINE
|
Chris@16
|
367 iterator &operator ++ () {
|
Chris@16
|
368 ++ it_;
|
Chris@16
|
369 return *this;
|
Chris@16
|
370 }
|
Chris@16
|
371 BOOST_UBLAS_INLINE
|
Chris@16
|
372 iterator &operator -- () {
|
Chris@16
|
373 -- it_;
|
Chris@16
|
374 return *this;
|
Chris@16
|
375 }
|
Chris@16
|
376 BOOST_UBLAS_INLINE
|
Chris@16
|
377 iterator &operator += (difference_type n) {
|
Chris@16
|
378 it_ += n;
|
Chris@16
|
379 return *this;
|
Chris@16
|
380 }
|
Chris@16
|
381 BOOST_UBLAS_INLINE
|
Chris@16
|
382 iterator &operator -= (difference_type n) {
|
Chris@16
|
383 it_ -= n;
|
Chris@16
|
384 return *this;
|
Chris@16
|
385 }
|
Chris@16
|
386 BOOST_UBLAS_INLINE
|
Chris@16
|
387 difference_type operator - (const iterator &it) const {
|
Chris@16
|
388 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
389 return it_ - it.it_;
|
Chris@16
|
390 }
|
Chris@16
|
391
|
Chris@16
|
392 // Dereference
|
Chris@16
|
393 BOOST_UBLAS_INLINE
|
Chris@16
|
394 reference operator * () const {
|
Chris@16
|
395 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
396 return *it_;
|
Chris@16
|
397 }
|
Chris@16
|
398 BOOST_UBLAS_INLINE
|
Chris@16
|
399 reference operator [] (difference_type n) const {
|
Chris@16
|
400 return *(*this + n);
|
Chris@16
|
401 }
|
Chris@16
|
402
|
Chris@16
|
403 // Index
|
Chris@16
|
404 BOOST_UBLAS_INLINE
|
Chris@16
|
405 size_type index () const {
|
Chris@16
|
406 return it_.index2 ();
|
Chris@16
|
407 }
|
Chris@16
|
408
|
Chris@16
|
409 // Assignment
|
Chris@16
|
410 BOOST_UBLAS_INLINE
|
Chris@16
|
411 iterator &operator = (const iterator &it) {
|
Chris@16
|
412 container_reference<self_type>::assign (&it ());
|
Chris@16
|
413 it_ = it.it_;
|
Chris@16
|
414 return *this;
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 // Comparison
|
Chris@16
|
418 BOOST_UBLAS_INLINE
|
Chris@16
|
419 bool operator == (const iterator &it) const {
|
Chris@16
|
420 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
421 return it_ == it.it_;
|
Chris@16
|
422 }
|
Chris@16
|
423 BOOST_UBLAS_INLINE
|
Chris@16
|
424 bool operator < (const iterator &it) const {
|
Chris@16
|
425 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
426 return it_ < it.it_;
|
Chris@16
|
427 }
|
Chris@16
|
428
|
Chris@16
|
429 private:
|
Chris@16
|
430 subiterator_type it_;
|
Chris@16
|
431
|
Chris@16
|
432 friend class const_iterator;
|
Chris@16
|
433 };
|
Chris@16
|
434 #endif
|
Chris@16
|
435
|
Chris@16
|
436 BOOST_UBLAS_INLINE
|
Chris@16
|
437 iterator begin () {
|
Chris@16
|
438 return find (0);
|
Chris@16
|
439 }
|
Chris@16
|
440 BOOST_UBLAS_INLINE
|
Chris@16
|
441 iterator end () {
|
Chris@16
|
442 return find (size ());
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 // Reverse iterator
|
Chris@16
|
446 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
Chris@16
|
447 typedef reverse_iterator_base<iterator> reverse_iterator;
|
Chris@16
|
448
|
Chris@16
|
449 BOOST_UBLAS_INLINE
|
Chris@16
|
450 const_reverse_iterator rbegin () const {
|
Chris@16
|
451 return const_reverse_iterator (end ());
|
Chris@16
|
452 }
|
Chris@16
|
453 BOOST_UBLAS_INLINE
|
Chris@101
|
454 const_reverse_iterator crbegin () const {
|
Chris@101
|
455 return rbegin ();
|
Chris@101
|
456 }
|
Chris@101
|
457 BOOST_UBLAS_INLINE
|
Chris@16
|
458 const_reverse_iterator rend () const {
|
Chris@16
|
459 return const_reverse_iterator (begin ());
|
Chris@16
|
460 }
|
Chris@16
|
461 BOOST_UBLAS_INLINE
|
Chris@101
|
462 const_reverse_iterator crend () const {
|
Chris@101
|
463 return rend ();
|
Chris@101
|
464 }
|
Chris@101
|
465 BOOST_UBLAS_INLINE
|
Chris@16
|
466 reverse_iterator rbegin () {
|
Chris@16
|
467 return reverse_iterator (end ());
|
Chris@16
|
468 }
|
Chris@16
|
469 BOOST_UBLAS_INLINE
|
Chris@16
|
470 reverse_iterator rend () {
|
Chris@16
|
471 return reverse_iterator (begin ());
|
Chris@16
|
472 }
|
Chris@16
|
473
|
Chris@16
|
474 private:
|
Chris@16
|
475 matrix_closure_type data_;
|
Chris@16
|
476 size_type i_;
|
Chris@16
|
477 };
|
Chris@16
|
478
|
Chris@16
|
479 // Projections
|
Chris@16
|
480 template<class M>
|
Chris@16
|
481 BOOST_UBLAS_INLINE
|
Chris@16
|
482 matrix_row<M> row (M &data, typename M::size_type i) {
|
Chris@16
|
483 return matrix_row<M> (data, i);
|
Chris@16
|
484 }
|
Chris@16
|
485 template<class M>
|
Chris@16
|
486 BOOST_UBLAS_INLINE
|
Chris@16
|
487 const matrix_row<const M> row (const M &data, typename M::size_type i) {
|
Chris@16
|
488 return matrix_row<const M> (data, i);
|
Chris@16
|
489 }
|
Chris@16
|
490
|
Chris@16
|
491 // Specialize temporary
|
Chris@16
|
492 template <class M>
|
Chris@16
|
493 struct vector_temporary_traits< matrix_row<M> >
|
Chris@16
|
494 : vector_temporary_traits< M > {} ;
|
Chris@16
|
495 template <class M>
|
Chris@16
|
496 struct vector_temporary_traits< const matrix_row<M> >
|
Chris@16
|
497 : vector_temporary_traits< M > {} ;
|
Chris@16
|
498
|
Chris@16
|
499 // Matrix based column vector class
|
Chris@16
|
500 template<class M>
|
Chris@16
|
501 class matrix_column:
|
Chris@16
|
502 public vector_expression<matrix_column<M> > {
|
Chris@16
|
503
|
Chris@16
|
504 typedef matrix_column<M> self_type;
|
Chris@16
|
505 public:
|
Chris@16
|
506 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
507 using vector_expression<self_type>::operator ();
|
Chris@16
|
508 #endif
|
Chris@16
|
509 typedef M matrix_type;
|
Chris@16
|
510 typedef typename M::size_type size_type;
|
Chris@16
|
511 typedef typename M::difference_type difference_type;
|
Chris@16
|
512 typedef typename M::value_type value_type;
|
Chris@16
|
513 typedef typename M::const_reference const_reference;
|
Chris@16
|
514 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
515 typename M::const_reference,
|
Chris@16
|
516 typename M::reference>::type reference;
|
Chris@16
|
517 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
518 typename M::const_closure_type,
|
Chris@16
|
519 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
520 typedef const self_type const_closure_type;
|
Chris@16
|
521 typedef self_type closure_type;
|
Chris@16
|
522 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
523 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
524
|
Chris@16
|
525 // Construction and destruction
|
Chris@16
|
526 BOOST_UBLAS_INLINE
|
Chris@16
|
527 matrix_column (matrix_type &data, size_type j):
|
Chris@16
|
528 data_ (data), j_ (j) {
|
Chris@16
|
529 // Early checking of preconditions here.
|
Chris@16
|
530 // BOOST_UBLAS_CHECK (j_ < data_.size2 (), bad_index ());
|
Chris@16
|
531 }
|
Chris@16
|
532
|
Chris@16
|
533 // Accessors
|
Chris@16
|
534 BOOST_UBLAS_INLINE
|
Chris@16
|
535 size_type size () const {
|
Chris@16
|
536 return data_.size1 ();
|
Chris@16
|
537 }
|
Chris@16
|
538 BOOST_UBLAS_INLINE
|
Chris@16
|
539 size_type index () const {
|
Chris@16
|
540 return j_;
|
Chris@16
|
541 }
|
Chris@16
|
542
|
Chris@16
|
543 // Storage accessors
|
Chris@16
|
544 BOOST_UBLAS_INLINE
|
Chris@16
|
545 const matrix_closure_type &data () const {
|
Chris@16
|
546 return data_;
|
Chris@16
|
547 }
|
Chris@16
|
548 BOOST_UBLAS_INLINE
|
Chris@16
|
549 matrix_closure_type &data () {
|
Chris@16
|
550 return data_;
|
Chris@16
|
551 }
|
Chris@16
|
552
|
Chris@16
|
553 // Element access
|
Chris@16
|
554 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
555 BOOST_UBLAS_INLINE
|
Chris@16
|
556 const_reference operator () (size_type i) const {
|
Chris@16
|
557 return data_ (i, j_);
|
Chris@16
|
558 }
|
Chris@16
|
559 BOOST_UBLAS_INLINE
|
Chris@16
|
560 reference operator () (size_type i) {
|
Chris@16
|
561 return data_ (i, j_);
|
Chris@16
|
562 }
|
Chris@16
|
563
|
Chris@16
|
564 BOOST_UBLAS_INLINE
|
Chris@16
|
565 const_reference operator [] (size_type i) const {
|
Chris@16
|
566 return (*this) (i);
|
Chris@16
|
567 }
|
Chris@16
|
568 BOOST_UBLAS_INLINE
|
Chris@16
|
569 reference operator [] (size_type i) {
|
Chris@16
|
570 return (*this) (i);
|
Chris@16
|
571 }
|
Chris@16
|
572 #else
|
Chris@16
|
573 BOOST_UBLAS_INLINE
|
Chris@16
|
574 reference operator () (size_type i) const {
|
Chris@16
|
575 return data_ (i, j_);
|
Chris@16
|
576 }
|
Chris@16
|
577
|
Chris@16
|
578 BOOST_UBLAS_INLINE
|
Chris@16
|
579 reference operator [] (size_type i) const {
|
Chris@16
|
580 return (*this) (i);
|
Chris@16
|
581 }
|
Chris@16
|
582 #endif
|
Chris@16
|
583
|
Chris@16
|
584 // Assignment
|
Chris@16
|
585 BOOST_UBLAS_INLINE
|
Chris@16
|
586 matrix_column &operator = (const matrix_column &mc) {
|
Chris@16
|
587 // ISSUE need a temporary, proxy can be overlaping alias
|
Chris@16
|
588 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mc));
|
Chris@16
|
589 return *this;
|
Chris@16
|
590 }
|
Chris@16
|
591 BOOST_UBLAS_INLINE
|
Chris@16
|
592 matrix_column &assign_temporary (matrix_column &mc) {
|
Chris@16
|
593 // assign elements, proxied container remains the same
|
Chris@16
|
594 vector_assign<scalar_assign> (*this, mc);
|
Chris@16
|
595 return *this;
|
Chris@16
|
596 }
|
Chris@16
|
597 template<class AE>
|
Chris@16
|
598 BOOST_UBLAS_INLINE
|
Chris@16
|
599 matrix_column &operator = (const vector_expression<AE> &ae) {
|
Chris@16
|
600 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
|
Chris@16
|
601 return *this;
|
Chris@16
|
602 }
|
Chris@16
|
603 template<class AE>
|
Chris@16
|
604 BOOST_UBLAS_INLINE
|
Chris@16
|
605 matrix_column &assign (const vector_expression<AE> &ae) {
|
Chris@16
|
606 vector_assign<scalar_assign> (*this, ae);
|
Chris@16
|
607 return *this;
|
Chris@16
|
608 }
|
Chris@16
|
609 template<class AE>
|
Chris@16
|
610 BOOST_UBLAS_INLINE
|
Chris@16
|
611 matrix_column &operator += (const vector_expression<AE> &ae) {
|
Chris@16
|
612 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
613 return *this;
|
Chris@16
|
614 }
|
Chris@16
|
615 template<class AE>
|
Chris@16
|
616 BOOST_UBLAS_INLINE
|
Chris@16
|
617 matrix_column &plus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
618 vector_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
619 return *this;
|
Chris@16
|
620 }
|
Chris@16
|
621 template<class AE>
|
Chris@16
|
622 BOOST_UBLAS_INLINE
|
Chris@16
|
623 matrix_column &operator -= (const vector_expression<AE> &ae) {
|
Chris@16
|
624 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
625 return *this;
|
Chris@16
|
626 }
|
Chris@16
|
627 template<class AE>
|
Chris@16
|
628 BOOST_UBLAS_INLINE
|
Chris@16
|
629 matrix_column &minus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
630 vector_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
631 return *this;
|
Chris@16
|
632 }
|
Chris@16
|
633 template<class AT>
|
Chris@16
|
634 BOOST_UBLAS_INLINE
|
Chris@16
|
635 matrix_column &operator *= (const AT &at) {
|
Chris@16
|
636 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
637 return *this;
|
Chris@16
|
638 }
|
Chris@16
|
639 template<class AT>
|
Chris@16
|
640 BOOST_UBLAS_INLINE
|
Chris@16
|
641 matrix_column &operator /= (const AT &at) {
|
Chris@16
|
642 vector_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
643 return *this;
|
Chris@16
|
644 }
|
Chris@16
|
645
|
Chris@16
|
646 // Closure comparison
|
Chris@16
|
647 BOOST_UBLAS_INLINE
|
Chris@16
|
648 bool same_closure (const matrix_column &mc) const {
|
Chris@16
|
649 return (*this).data_.same_closure (mc.data_);
|
Chris@16
|
650 }
|
Chris@16
|
651
|
Chris@16
|
652 // Comparison
|
Chris@16
|
653 BOOST_UBLAS_INLINE
|
Chris@16
|
654 bool operator == (const matrix_column &mc) const {
|
Chris@16
|
655 return (*this).data_ == mc.data_ && index () == mc.index ();
|
Chris@16
|
656 }
|
Chris@16
|
657
|
Chris@16
|
658 // Swapping
|
Chris@16
|
659 BOOST_UBLAS_INLINE
|
Chris@16
|
660 void swap (matrix_column mc) {
|
Chris@16
|
661 if (this != &mc) {
|
Chris@16
|
662 BOOST_UBLAS_CHECK (size () == mc.size (), bad_size ());
|
Chris@16
|
663 // Sparse ranges may be nonconformant now.
|
Chris@16
|
664 // std::swap_ranges (begin (), end (), mc.begin ());
|
Chris@16
|
665 vector_swap<scalar_swap> (*this, mc);
|
Chris@16
|
666 }
|
Chris@16
|
667 }
|
Chris@16
|
668 BOOST_UBLAS_INLINE
|
Chris@16
|
669 friend void swap (matrix_column mc1, matrix_column mc2) {
|
Chris@16
|
670 mc1.swap (mc2);
|
Chris@16
|
671 }
|
Chris@16
|
672
|
Chris@16
|
673 // Iterator types
|
Chris@16
|
674 private:
|
Chris@16
|
675 typedef typename M::const_iterator1 const_subiterator_type;
|
Chris@16
|
676 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
677 typename M::const_iterator1,
|
Chris@16
|
678 typename M::iterator1>::type subiterator_type;
|
Chris@16
|
679
|
Chris@16
|
680 public:
|
Chris@16
|
681 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
682 typedef indexed_iterator<matrix_column<matrix_type>,
|
Chris@16
|
683 typename subiterator_type::iterator_category> iterator;
|
Chris@16
|
684 typedef indexed_const_iterator<matrix_column<matrix_type>,
|
Chris@16
|
685 typename const_subiterator_type::iterator_category> const_iterator;
|
Chris@16
|
686 #else
|
Chris@16
|
687 class const_iterator;
|
Chris@16
|
688 class iterator;
|
Chris@16
|
689 #endif
|
Chris@16
|
690
|
Chris@16
|
691 // Element lookup
|
Chris@16
|
692 BOOST_UBLAS_INLINE
|
Chris@16
|
693 const_iterator find (size_type i) const {
|
Chris@16
|
694 const_subiterator_type it1 (data_.find1 (1, i, j_));
|
Chris@16
|
695 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
696 return const_iterator (*this, it1.index1 ());
|
Chris@16
|
697 #else
|
Chris@16
|
698 return const_iterator (*this, it1);
|
Chris@16
|
699 #endif
|
Chris@16
|
700 }
|
Chris@16
|
701 BOOST_UBLAS_INLINE
|
Chris@16
|
702 iterator find (size_type i) {
|
Chris@16
|
703 subiterator_type it1 (data_.find1 (1, i, j_));
|
Chris@16
|
704 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
705 return iterator (*this, it1.index1 ());
|
Chris@16
|
706 #else
|
Chris@16
|
707 return iterator (*this, it1);
|
Chris@16
|
708 #endif
|
Chris@16
|
709 }
|
Chris@16
|
710
|
Chris@16
|
711 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
712 class const_iterator:
|
Chris@16
|
713 public container_const_reference<matrix_column>,
|
Chris@16
|
714 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
|
Chris@16
|
715 iterator_base<const_iterator, value_type>::type {
|
Chris@16
|
716 public:
|
Chris@16
|
717 typedef typename const_subiterator_type::value_type value_type;
|
Chris@16
|
718 typedef typename const_subiterator_type::difference_type difference_type;
|
Chris@16
|
719 typedef typename const_subiterator_type::reference reference;
|
Chris@16
|
720 typedef typename const_subiterator_type::pointer pointer;
|
Chris@16
|
721
|
Chris@16
|
722 // Construction and destruction
|
Chris@16
|
723 BOOST_UBLAS_INLINE
|
Chris@16
|
724 const_iterator ():
|
Chris@16
|
725 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
726 BOOST_UBLAS_INLINE
|
Chris@16
|
727 const_iterator (const self_type &mc, const const_subiterator_type &it):
|
Chris@16
|
728 container_const_reference<self_type> (mc), it_ (it) {}
|
Chris@16
|
729 BOOST_UBLAS_INLINE
|
Chris@16
|
730 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
|
Chris@16
|
731 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
732
|
Chris@16
|
733 // Arithmetic
|
Chris@16
|
734 BOOST_UBLAS_INLINE
|
Chris@16
|
735 const_iterator &operator ++ () {
|
Chris@16
|
736 ++ it_;
|
Chris@16
|
737 return *this;
|
Chris@16
|
738 }
|
Chris@16
|
739 BOOST_UBLAS_INLINE
|
Chris@16
|
740 const_iterator &operator -- () {
|
Chris@16
|
741 -- it_;
|
Chris@16
|
742 return *this;
|
Chris@16
|
743 }
|
Chris@16
|
744 BOOST_UBLAS_INLINE
|
Chris@16
|
745 const_iterator &operator += (difference_type n) {
|
Chris@16
|
746 it_ += n;
|
Chris@16
|
747 return *this;
|
Chris@16
|
748 }
|
Chris@16
|
749 BOOST_UBLAS_INLINE
|
Chris@16
|
750 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
751 it_ -= n;
|
Chris@16
|
752 return *this;
|
Chris@16
|
753 }
|
Chris@16
|
754 BOOST_UBLAS_INLINE
|
Chris@16
|
755 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
756 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
757 return it_ - it.it_;
|
Chris@16
|
758 }
|
Chris@16
|
759
|
Chris@16
|
760 // Dereference
|
Chris@16
|
761 BOOST_UBLAS_INLINE
|
Chris@16
|
762 const_reference operator * () const {
|
Chris@16
|
763 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
764 return *it_;
|
Chris@16
|
765 }
|
Chris@16
|
766 BOOST_UBLAS_INLINE
|
Chris@16
|
767 const_reference operator [] (difference_type n) const {
|
Chris@16
|
768 return *(*this + n);
|
Chris@16
|
769 }
|
Chris@16
|
770
|
Chris@16
|
771 // Index
|
Chris@16
|
772 BOOST_UBLAS_INLINE
|
Chris@16
|
773 size_type index () const {
|
Chris@16
|
774 return it_.index1 ();
|
Chris@16
|
775 }
|
Chris@16
|
776
|
Chris@16
|
777 // Assignment
|
Chris@16
|
778 BOOST_UBLAS_INLINE
|
Chris@16
|
779 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
780 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
781 it_ = it.it_;
|
Chris@16
|
782 return *this;
|
Chris@16
|
783 }
|
Chris@16
|
784
|
Chris@16
|
785 // Comparison
|
Chris@16
|
786 BOOST_UBLAS_INLINE
|
Chris@16
|
787 bool operator == (const const_iterator &it) const {
|
Chris@16
|
788 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
789 return it_ == it.it_;
|
Chris@16
|
790 }
|
Chris@16
|
791 BOOST_UBLAS_INLINE
|
Chris@16
|
792 bool operator < (const const_iterator &it) const {
|
Chris@16
|
793 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
794 return it_ < it.it_;
|
Chris@16
|
795 }
|
Chris@16
|
796
|
Chris@16
|
797 private:
|
Chris@16
|
798 const_subiterator_type it_;
|
Chris@16
|
799 };
|
Chris@16
|
800 #endif
|
Chris@16
|
801
|
Chris@16
|
802 BOOST_UBLAS_INLINE
|
Chris@16
|
803 const_iterator begin () const {
|
Chris@16
|
804 return find (0);
|
Chris@16
|
805 }
|
Chris@16
|
806 BOOST_UBLAS_INLINE
|
Chris@101
|
807 const_iterator cbegin () const {
|
Chris@101
|
808 return begin ();
|
Chris@101
|
809 }
|
Chris@101
|
810 BOOST_UBLAS_INLINE
|
Chris@16
|
811 const_iterator end () const {
|
Chris@16
|
812 return find (size ());
|
Chris@16
|
813 }
|
Chris@101
|
814 BOOST_UBLAS_INLINE
|
Chris@101
|
815 const_iterator cend () const {
|
Chris@101
|
816 return end ();
|
Chris@101
|
817 }
|
Chris@16
|
818
|
Chris@16
|
819 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
820 class iterator:
|
Chris@16
|
821 public container_reference<matrix_column>,
|
Chris@16
|
822 public iterator_base_traits<typename subiterator_type::iterator_category>::template
|
Chris@16
|
823 iterator_base<iterator, value_type>::type {
|
Chris@16
|
824 public:
|
Chris@16
|
825 typedef typename subiterator_type::value_type value_type;
|
Chris@16
|
826 typedef typename subiterator_type::difference_type difference_type;
|
Chris@16
|
827 typedef typename subiterator_type::reference reference;
|
Chris@16
|
828 typedef typename subiterator_type::pointer pointer;
|
Chris@16
|
829
|
Chris@16
|
830 // Construction and destruction
|
Chris@16
|
831 BOOST_UBLAS_INLINE
|
Chris@16
|
832 iterator ():
|
Chris@16
|
833 container_reference<self_type> (), it_ () {}
|
Chris@16
|
834 BOOST_UBLAS_INLINE
|
Chris@16
|
835 iterator (self_type &mc, const subiterator_type &it):
|
Chris@16
|
836 container_reference<self_type> (mc), it_ (it) {}
|
Chris@16
|
837
|
Chris@16
|
838 // Arithmetic
|
Chris@16
|
839 BOOST_UBLAS_INLINE
|
Chris@16
|
840 iterator &operator ++ () {
|
Chris@16
|
841 ++ it_;
|
Chris@16
|
842 return *this;
|
Chris@16
|
843 }
|
Chris@16
|
844 BOOST_UBLAS_INLINE
|
Chris@16
|
845 iterator &operator -- () {
|
Chris@16
|
846 -- it_;
|
Chris@16
|
847 return *this;
|
Chris@16
|
848 }
|
Chris@16
|
849 BOOST_UBLAS_INLINE
|
Chris@16
|
850 iterator &operator += (difference_type n) {
|
Chris@16
|
851 it_ += n;
|
Chris@16
|
852 return *this;
|
Chris@16
|
853 }
|
Chris@16
|
854 BOOST_UBLAS_INLINE
|
Chris@16
|
855 iterator &operator -= (difference_type n) {
|
Chris@16
|
856 it_ -= n;
|
Chris@16
|
857 return *this;
|
Chris@16
|
858 }
|
Chris@16
|
859 BOOST_UBLAS_INLINE
|
Chris@16
|
860 difference_type operator - (const iterator &it) const {
|
Chris@16
|
861 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
862 return it_ - it.it_;
|
Chris@16
|
863 }
|
Chris@16
|
864
|
Chris@16
|
865 // Dereference
|
Chris@16
|
866 BOOST_UBLAS_INLINE
|
Chris@16
|
867 reference operator * () const {
|
Chris@16
|
868 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
869 return *it_;
|
Chris@16
|
870 }
|
Chris@16
|
871 BOOST_UBLAS_INLINE
|
Chris@16
|
872 reference operator [] (difference_type n) const {
|
Chris@16
|
873 return *(*this + n);
|
Chris@16
|
874 }
|
Chris@16
|
875
|
Chris@16
|
876 // Index
|
Chris@16
|
877 BOOST_UBLAS_INLINE
|
Chris@16
|
878 size_type index () const {
|
Chris@16
|
879 return it_.index1 ();
|
Chris@16
|
880 }
|
Chris@16
|
881
|
Chris@16
|
882 // Assignment
|
Chris@16
|
883 BOOST_UBLAS_INLINE
|
Chris@16
|
884 iterator &operator = (const iterator &it) {
|
Chris@16
|
885 container_reference<self_type>::assign (&it ());
|
Chris@16
|
886 it_ = it.it_;
|
Chris@16
|
887 return *this;
|
Chris@16
|
888 }
|
Chris@16
|
889
|
Chris@16
|
890 // Comparison
|
Chris@16
|
891 BOOST_UBLAS_INLINE
|
Chris@16
|
892 bool operator == (const iterator &it) const {
|
Chris@16
|
893 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
894 return it_ == it.it_;
|
Chris@16
|
895 }
|
Chris@16
|
896 BOOST_UBLAS_INLINE
|
Chris@16
|
897 bool operator < (const iterator &it) const {
|
Chris@16
|
898 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
899 return it_ < it.it_;
|
Chris@16
|
900 }
|
Chris@16
|
901
|
Chris@16
|
902 private:
|
Chris@16
|
903 subiterator_type it_;
|
Chris@16
|
904
|
Chris@16
|
905 friend class const_iterator;
|
Chris@16
|
906 };
|
Chris@16
|
907 #endif
|
Chris@16
|
908
|
Chris@16
|
909 BOOST_UBLAS_INLINE
|
Chris@16
|
910 iterator begin () {
|
Chris@16
|
911 return find (0);
|
Chris@16
|
912 }
|
Chris@16
|
913 BOOST_UBLAS_INLINE
|
Chris@16
|
914 iterator end () {
|
Chris@16
|
915 return find (size ());
|
Chris@16
|
916 }
|
Chris@16
|
917
|
Chris@16
|
918 // Reverse iterator
|
Chris@16
|
919 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
Chris@16
|
920 typedef reverse_iterator_base<iterator> reverse_iterator;
|
Chris@16
|
921
|
Chris@16
|
922 BOOST_UBLAS_INLINE
|
Chris@16
|
923 const_reverse_iterator rbegin () const {
|
Chris@16
|
924 return const_reverse_iterator (end ());
|
Chris@16
|
925 }
|
Chris@16
|
926 BOOST_UBLAS_INLINE
|
Chris@101
|
927 const_reverse_iterator crbegin () const {
|
Chris@101
|
928 return rbegin ();
|
Chris@101
|
929 }
|
Chris@101
|
930 BOOST_UBLAS_INLINE
|
Chris@16
|
931 const_reverse_iterator rend () const {
|
Chris@16
|
932 return const_reverse_iterator (begin ());
|
Chris@16
|
933 }
|
Chris@101
|
934 BOOST_UBLAS_INLINE
|
Chris@101
|
935 const_reverse_iterator crend () const {
|
Chris@101
|
936 return rend ();
|
Chris@101
|
937 }
|
Chris@16
|
938 reverse_iterator rbegin () {
|
Chris@16
|
939 return reverse_iterator (end ());
|
Chris@16
|
940 }
|
Chris@16
|
941 BOOST_UBLAS_INLINE
|
Chris@16
|
942 reverse_iterator rend () {
|
Chris@16
|
943 return reverse_iterator (begin ());
|
Chris@16
|
944 }
|
Chris@16
|
945
|
Chris@16
|
946 private:
|
Chris@16
|
947 matrix_closure_type data_;
|
Chris@16
|
948 size_type j_;
|
Chris@16
|
949 };
|
Chris@16
|
950
|
Chris@16
|
951 // Projections
|
Chris@16
|
952 template<class M>
|
Chris@16
|
953 BOOST_UBLAS_INLINE
|
Chris@16
|
954 matrix_column<M> column (M &data, typename M::size_type j) {
|
Chris@16
|
955 return matrix_column<M> (data, j);
|
Chris@16
|
956 }
|
Chris@16
|
957 template<class M>
|
Chris@16
|
958 BOOST_UBLAS_INLINE
|
Chris@16
|
959 const matrix_column<const M> column (const M &data, typename M::size_type j) {
|
Chris@16
|
960 return matrix_column<const M> (data, j);
|
Chris@16
|
961 }
|
Chris@16
|
962
|
Chris@16
|
963 // Specialize temporary
|
Chris@16
|
964 template <class M>
|
Chris@16
|
965 struct vector_temporary_traits< matrix_column<M> >
|
Chris@16
|
966 : vector_temporary_traits< M > {} ;
|
Chris@16
|
967 template <class M>
|
Chris@16
|
968 struct vector_temporary_traits< const matrix_column<M> >
|
Chris@16
|
969 : vector_temporary_traits< M > {} ;
|
Chris@16
|
970
|
Chris@16
|
971 // Matrix based vector range class
|
Chris@16
|
972 template<class M>
|
Chris@16
|
973 class matrix_vector_range:
|
Chris@16
|
974 public vector_expression<matrix_vector_range<M> > {
|
Chris@16
|
975
|
Chris@16
|
976 typedef matrix_vector_range<M> self_type;
|
Chris@16
|
977 public:
|
Chris@16
|
978 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
979 using vector_expression<self_type>::operator ();
|
Chris@16
|
980 #endif
|
Chris@16
|
981 typedef M matrix_type;
|
Chris@16
|
982 typedef typename M::size_type size_type;
|
Chris@16
|
983 typedef typename M::difference_type difference_type;
|
Chris@16
|
984 typedef typename M::value_type value_type;
|
Chris@16
|
985 typedef typename M::const_reference const_reference;
|
Chris@16
|
986 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
987 typename M::const_reference,
|
Chris@16
|
988 typename M::reference>::type reference;
|
Chris@16
|
989 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
990 typename M::const_closure_type,
|
Chris@16
|
991 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
992 typedef basic_range<size_type, difference_type> range_type;
|
Chris@16
|
993 typedef const self_type const_closure_type;
|
Chris@16
|
994 typedef self_type closure_type;
|
Chris@16
|
995 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
996 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
997
|
Chris@16
|
998 // Construction and destruction
|
Chris@16
|
999 BOOST_UBLAS_INLINE
|
Chris@16
|
1000 matrix_vector_range (matrix_type &data, const range_type &r1, const range_type &r2):
|
Chris@16
|
1001 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
|
Chris@16
|
1002 // Early checking of preconditions here.
|
Chris@16
|
1003 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
|
Chris@16
|
1004 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
|
Chris@16
|
1005 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
|
Chris@16
|
1006 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
|
Chris@16
|
1007 // BOOST_UBLAS_CHECK (r1_.size () == r2_.size (), bad_size ());
|
Chris@16
|
1008 }
|
Chris@16
|
1009
|
Chris@16
|
1010 // Accessors
|
Chris@16
|
1011 BOOST_UBLAS_INLINE
|
Chris@16
|
1012 size_type start1 () const {
|
Chris@16
|
1013 return r1_.start ();
|
Chris@16
|
1014 }
|
Chris@16
|
1015 BOOST_UBLAS_INLINE
|
Chris@16
|
1016 size_type start2 () const {
|
Chris@16
|
1017 return r2_.start ();
|
Chris@16
|
1018 }
|
Chris@16
|
1019 BOOST_UBLAS_INLINE
|
Chris@16
|
1020 size_type size () const {
|
Chris@16
|
1021 return BOOST_UBLAS_SAME (r1_.size (), r2_.size ());
|
Chris@16
|
1022 }
|
Chris@16
|
1023
|
Chris@16
|
1024 // Storage accessors
|
Chris@16
|
1025 BOOST_UBLAS_INLINE
|
Chris@16
|
1026 const matrix_closure_type &data () const {
|
Chris@16
|
1027 return data_;
|
Chris@16
|
1028 }
|
Chris@16
|
1029 BOOST_UBLAS_INLINE
|
Chris@16
|
1030 matrix_closure_type &data () {
|
Chris@16
|
1031 return data_;
|
Chris@16
|
1032 }
|
Chris@16
|
1033
|
Chris@16
|
1034 // Element access
|
Chris@16
|
1035 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
1036 BOOST_UBLAS_INLINE
|
Chris@16
|
1037 const_reference operator () (size_type i) const {
|
Chris@16
|
1038 return data_ (r1_ (i), r2_ (i));
|
Chris@16
|
1039 }
|
Chris@16
|
1040 BOOST_UBLAS_INLINE
|
Chris@16
|
1041 reference operator () (size_type i) {
|
Chris@16
|
1042 return data_ (r1_ (i), r2_ (i));
|
Chris@16
|
1043 }
|
Chris@16
|
1044
|
Chris@16
|
1045 BOOST_UBLAS_INLINE
|
Chris@16
|
1046 const_reference operator [] (size_type i) const {
|
Chris@16
|
1047 return (*this) (i);
|
Chris@16
|
1048 }
|
Chris@16
|
1049 BOOST_UBLAS_INLINE
|
Chris@16
|
1050 reference operator [] (size_type i) {
|
Chris@16
|
1051 return (*this) (i);
|
Chris@16
|
1052 }
|
Chris@16
|
1053 #else
|
Chris@16
|
1054 BOOST_UBLAS_INLINE
|
Chris@16
|
1055 reference operator () (size_type i) const {
|
Chris@16
|
1056 return data_ (r1_ (i), r2_ (i));
|
Chris@16
|
1057 }
|
Chris@16
|
1058
|
Chris@16
|
1059 BOOST_UBLAS_INLINE
|
Chris@16
|
1060 reference operator [] (size_type i) const {
|
Chris@16
|
1061 return (*this) (i);
|
Chris@16
|
1062 }
|
Chris@16
|
1063 #endif
|
Chris@16
|
1064
|
Chris@16
|
1065 // Assignment
|
Chris@16
|
1066 BOOST_UBLAS_INLINE
|
Chris@16
|
1067 matrix_vector_range &operator = (const matrix_vector_range &mvr) {
|
Chris@16
|
1068 // ISSUE need a temporary, proxy can be overlaping alias
|
Chris@16
|
1069 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvr));
|
Chris@16
|
1070 return *this;
|
Chris@16
|
1071 }
|
Chris@16
|
1072 BOOST_UBLAS_INLINE
|
Chris@16
|
1073 matrix_vector_range &assign_temporary (matrix_vector_range &mvr) {
|
Chris@16
|
1074 // assign elements, proxied container remains the same
|
Chris@16
|
1075 vector_assign<scalar_assign> (*this, mvr);
|
Chris@16
|
1076 return *this;
|
Chris@16
|
1077 }
|
Chris@16
|
1078 template<class AE>
|
Chris@16
|
1079 BOOST_UBLAS_INLINE
|
Chris@16
|
1080 matrix_vector_range &operator = (const vector_expression<AE> &ae) {
|
Chris@16
|
1081 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
|
Chris@16
|
1082 return *this;
|
Chris@16
|
1083 }
|
Chris@16
|
1084 template<class AE>
|
Chris@16
|
1085 BOOST_UBLAS_INLINE
|
Chris@16
|
1086 matrix_vector_range &assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1087 vector_assign<scalar_assign> (*this, ae);
|
Chris@16
|
1088 return *this;
|
Chris@16
|
1089 }
|
Chris@16
|
1090 template<class AE>
|
Chris@16
|
1091 BOOST_UBLAS_INLINE
|
Chris@16
|
1092 matrix_vector_range &operator += (const vector_expression<AE> &ae) {
|
Chris@16
|
1093 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
1094 return *this;
|
Chris@16
|
1095 }
|
Chris@16
|
1096 template<class AE>
|
Chris@16
|
1097 BOOST_UBLAS_INLINE
|
Chris@16
|
1098 matrix_vector_range &plus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1099 vector_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
1100 return *this;
|
Chris@16
|
1101 }
|
Chris@16
|
1102 template<class AE>
|
Chris@16
|
1103 BOOST_UBLAS_INLINE
|
Chris@16
|
1104 matrix_vector_range &operator -= (const vector_expression<AE> &ae) {
|
Chris@16
|
1105 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
1106 return *this;
|
Chris@16
|
1107 }
|
Chris@16
|
1108 template<class AE>
|
Chris@16
|
1109 BOOST_UBLAS_INLINE
|
Chris@16
|
1110 matrix_vector_range &minus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1111 vector_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
1112 return *this;
|
Chris@16
|
1113 }
|
Chris@16
|
1114 template<class AT>
|
Chris@16
|
1115 BOOST_UBLAS_INLINE
|
Chris@16
|
1116 matrix_vector_range &operator *= (const AT &at) {
|
Chris@16
|
1117 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
1118 return *this;
|
Chris@16
|
1119 }
|
Chris@16
|
1120 template<class AT>
|
Chris@16
|
1121 BOOST_UBLAS_INLINE
|
Chris@16
|
1122 matrix_vector_range &operator /= (const AT &at) {
|
Chris@16
|
1123 vector_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
1124 return *this;
|
Chris@16
|
1125 }
|
Chris@16
|
1126
|
Chris@16
|
1127 // Closure comparison
|
Chris@16
|
1128 BOOST_UBLAS_INLINE
|
Chris@16
|
1129 bool same_closure (const matrix_vector_range &mvr) const {
|
Chris@16
|
1130 return (*this).data_.same_closure (mvr.data_);
|
Chris@16
|
1131 }
|
Chris@16
|
1132
|
Chris@16
|
1133 // Comparison
|
Chris@16
|
1134 BOOST_UBLAS_INLINE
|
Chris@16
|
1135 bool operator == (const matrix_vector_range &mvr) const {
|
Chris@16
|
1136 return (*this).data_ == mvr.data_ && r1_ == mvr.r1_ && r2_ == mvr.r2_;
|
Chris@16
|
1137 }
|
Chris@16
|
1138
|
Chris@16
|
1139 // Swapping
|
Chris@16
|
1140 BOOST_UBLAS_INLINE
|
Chris@16
|
1141 void swap (matrix_vector_range mvr) {
|
Chris@16
|
1142 if (this != &mvr) {
|
Chris@16
|
1143 BOOST_UBLAS_CHECK (size () == mvr.size (), bad_size ());
|
Chris@16
|
1144 // Sparse ranges may be nonconformant now.
|
Chris@16
|
1145 // std::swap_ranges (begin (), end (), mvr.begin ());
|
Chris@16
|
1146 vector_swap<scalar_swap> (*this, mvr);
|
Chris@16
|
1147 }
|
Chris@16
|
1148 }
|
Chris@16
|
1149 BOOST_UBLAS_INLINE
|
Chris@16
|
1150 friend void swap (matrix_vector_range mvr1, matrix_vector_range mvr2) {
|
Chris@16
|
1151 mvr1.swap (mvr2);
|
Chris@16
|
1152 }
|
Chris@16
|
1153
|
Chris@16
|
1154 // Iterator types
|
Chris@16
|
1155 private:
|
Chris@16
|
1156 // Use range as an index - FIXME this fails for packed assignment
|
Chris@16
|
1157 typedef typename range_type::const_iterator const_subiterator1_type;
|
Chris@16
|
1158 typedef typename range_type::const_iterator subiterator1_type;
|
Chris@16
|
1159 typedef typename range_type::const_iterator const_subiterator2_type;
|
Chris@16
|
1160 typedef typename range_type::const_iterator subiterator2_type;
|
Chris@16
|
1161
|
Chris@16
|
1162 public:
|
Chris@16
|
1163 class const_iterator;
|
Chris@16
|
1164 class iterator;
|
Chris@16
|
1165
|
Chris@16
|
1166 // Element lookup
|
Chris@16
|
1167 BOOST_UBLAS_INLINE
|
Chris@16
|
1168 const_iterator find (size_type i) const {
|
Chris@16
|
1169 return const_iterator (*this, r1_.begin () + i, r2_.begin () + i);
|
Chris@16
|
1170 }
|
Chris@16
|
1171 BOOST_UBLAS_INLINE
|
Chris@16
|
1172 iterator find (size_type i) {
|
Chris@16
|
1173 return iterator (*this, r1_.begin () + i, r2_.begin () + i);
|
Chris@16
|
1174 }
|
Chris@16
|
1175
|
Chris@16
|
1176 class const_iterator:
|
Chris@16
|
1177 public container_const_reference<matrix_vector_range>,
|
Chris@16
|
1178 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
|
Chris@16
|
1179 iterator_base<const_iterator, value_type>::type {
|
Chris@16
|
1180 public:
|
Chris@16
|
1181 // FIXME Iterator can never be different code was:
|
Chris@16
|
1182 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
1183 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
1184
|
Chris@16
|
1185 typedef typename matrix_vector_range::value_type value_type;
|
Chris@16
|
1186 typedef typename matrix_vector_range::difference_type difference_type;
|
Chris@16
|
1187 typedef typename matrix_vector_range::const_reference reference;
|
Chris@16
|
1188 typedef const typename matrix_vector_range::value_type *pointer;
|
Chris@16
|
1189
|
Chris@16
|
1190 // Construction and destruction
|
Chris@16
|
1191 BOOST_UBLAS_INLINE
|
Chris@16
|
1192 const_iterator ():
|
Chris@16
|
1193 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1194 BOOST_UBLAS_INLINE
|
Chris@16
|
1195 const_iterator (const self_type &mvr, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
1196 container_const_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1197 BOOST_UBLAS_INLINE
|
Chris@16
|
1198 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
|
Chris@16
|
1199 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
1200
|
Chris@16
|
1201 // Arithmetic
|
Chris@16
|
1202 BOOST_UBLAS_INLINE
|
Chris@16
|
1203 const_iterator &operator ++ () {
|
Chris@16
|
1204 ++ it1_;
|
Chris@16
|
1205 ++ it2_;
|
Chris@16
|
1206 return *this;
|
Chris@16
|
1207 }
|
Chris@16
|
1208 BOOST_UBLAS_INLINE
|
Chris@16
|
1209 const_iterator &operator -- () {
|
Chris@16
|
1210 -- it1_;
|
Chris@16
|
1211 -- it2_;
|
Chris@16
|
1212 return *this;
|
Chris@16
|
1213 }
|
Chris@16
|
1214 BOOST_UBLAS_INLINE
|
Chris@16
|
1215 const_iterator &operator += (difference_type n) {
|
Chris@16
|
1216 it1_ += n;
|
Chris@16
|
1217 it2_ += n;
|
Chris@16
|
1218 return *this;
|
Chris@16
|
1219 }
|
Chris@16
|
1220 BOOST_UBLAS_INLINE
|
Chris@16
|
1221 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
1222 it1_ -= n;
|
Chris@16
|
1223 it2_ -= n;
|
Chris@16
|
1224 return *this;
|
Chris@16
|
1225 }
|
Chris@16
|
1226 BOOST_UBLAS_INLINE
|
Chris@16
|
1227 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
1228 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1229 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
1230 }
|
Chris@16
|
1231
|
Chris@16
|
1232 // Dereference
|
Chris@16
|
1233 BOOST_UBLAS_INLINE
|
Chris@16
|
1234 const_reference operator * () const {
|
Chris@16
|
1235 // FIXME replace find with at_element
|
Chris@16
|
1236 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
1237 }
|
Chris@16
|
1238 BOOST_UBLAS_INLINE
|
Chris@16
|
1239 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1240 return *(*this + n);
|
Chris@16
|
1241 }
|
Chris@16
|
1242
|
Chris@16
|
1243 // Index
|
Chris@16
|
1244 BOOST_UBLAS_INLINE
|
Chris@16
|
1245 size_type index () const {
|
Chris@16
|
1246 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
1247 }
|
Chris@16
|
1248
|
Chris@16
|
1249 // Assignment
|
Chris@16
|
1250 BOOST_UBLAS_INLINE
|
Chris@16
|
1251 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
1252 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
1253 it1_ = it.it1_;
|
Chris@16
|
1254 it2_ = it.it2_;
|
Chris@16
|
1255 return *this;
|
Chris@16
|
1256 }
|
Chris@16
|
1257
|
Chris@16
|
1258 // Comparison
|
Chris@16
|
1259 BOOST_UBLAS_INLINE
|
Chris@16
|
1260 bool operator == (const const_iterator &it) const {
|
Chris@16
|
1261 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1262 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
1263 }
|
Chris@16
|
1264 BOOST_UBLAS_INLINE
|
Chris@16
|
1265 bool operator < (const const_iterator &it) const {
|
Chris@16
|
1266 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1267 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
1268 }
|
Chris@16
|
1269
|
Chris@16
|
1270 private:
|
Chris@16
|
1271 const_subiterator1_type it1_;
|
Chris@16
|
1272 const_subiterator2_type it2_;
|
Chris@16
|
1273 };
|
Chris@16
|
1274
|
Chris@16
|
1275 BOOST_UBLAS_INLINE
|
Chris@16
|
1276 const_iterator begin () const {
|
Chris@16
|
1277 return find (0);
|
Chris@16
|
1278 }
|
Chris@16
|
1279 BOOST_UBLAS_INLINE
|
Chris@101
|
1280 const_iterator cbegin () const {
|
Chris@101
|
1281 return begin ();
|
Chris@101
|
1282 }
|
Chris@101
|
1283 BOOST_UBLAS_INLINE
|
Chris@16
|
1284 const_iterator end () const {
|
Chris@16
|
1285 return find (size ());
|
Chris@16
|
1286 }
|
Chris@101
|
1287 BOOST_UBLAS_INLINE
|
Chris@101
|
1288 const_iterator cend () const {
|
Chris@101
|
1289 return end ();
|
Chris@101
|
1290 }
|
Chris@16
|
1291
|
Chris@16
|
1292 class iterator:
|
Chris@16
|
1293 public container_reference<matrix_vector_range>,
|
Chris@16
|
1294 public iterator_base_traits<typename M::iterator1::iterator_category>::template
|
Chris@16
|
1295 iterator_base<iterator, value_type>::type {
|
Chris@16
|
1296 public:
|
Chris@16
|
1297 // FIXME Iterator can never be different code was:
|
Chris@16
|
1298 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
1299 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
1300
|
Chris@16
|
1301 typedef typename matrix_vector_range::value_type value_type;
|
Chris@16
|
1302 typedef typename matrix_vector_range::difference_type difference_type;
|
Chris@16
|
1303 typedef typename matrix_vector_range::reference reference;
|
Chris@16
|
1304 typedef typename matrix_vector_range::value_type *pointer;
|
Chris@16
|
1305
|
Chris@16
|
1306 // Construction and destruction
|
Chris@16
|
1307 BOOST_UBLAS_INLINE
|
Chris@16
|
1308 iterator ():
|
Chris@16
|
1309 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1310 BOOST_UBLAS_INLINE
|
Chris@16
|
1311 iterator (self_type &mvr, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
1312 container_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1313
|
Chris@16
|
1314 // Arithmetic
|
Chris@16
|
1315 BOOST_UBLAS_INLINE
|
Chris@16
|
1316 iterator &operator ++ () {
|
Chris@16
|
1317 ++ it1_;
|
Chris@16
|
1318 ++ it2_;
|
Chris@16
|
1319 return *this;
|
Chris@16
|
1320 }
|
Chris@16
|
1321 BOOST_UBLAS_INLINE
|
Chris@16
|
1322 iterator &operator -- () {
|
Chris@16
|
1323 -- it1_;
|
Chris@16
|
1324 -- it2_;
|
Chris@16
|
1325 return *this;
|
Chris@16
|
1326 }
|
Chris@16
|
1327 BOOST_UBLAS_INLINE
|
Chris@16
|
1328 iterator &operator += (difference_type n) {
|
Chris@16
|
1329 it1_ += n;
|
Chris@16
|
1330 it2_ += n;
|
Chris@16
|
1331 return *this;
|
Chris@16
|
1332 }
|
Chris@16
|
1333 BOOST_UBLAS_INLINE
|
Chris@16
|
1334 iterator &operator -= (difference_type n) {
|
Chris@16
|
1335 it1_ -= n;
|
Chris@16
|
1336 it2_ -= n;
|
Chris@16
|
1337 return *this;
|
Chris@16
|
1338 }
|
Chris@16
|
1339 BOOST_UBLAS_INLINE
|
Chris@16
|
1340 difference_type operator - (const iterator &it) const {
|
Chris@16
|
1341 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1342 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
1343 }
|
Chris@16
|
1344
|
Chris@16
|
1345 // Dereference
|
Chris@16
|
1346 BOOST_UBLAS_INLINE
|
Chris@16
|
1347 reference operator * () const {
|
Chris@16
|
1348 // FIXME replace find with at_element
|
Chris@16
|
1349 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
1350 }
|
Chris@16
|
1351 BOOST_UBLAS_INLINE
|
Chris@16
|
1352 reference operator [] (difference_type n) const {
|
Chris@16
|
1353 return *(*this + n);
|
Chris@16
|
1354 }
|
Chris@16
|
1355
|
Chris@16
|
1356 // Index
|
Chris@16
|
1357 BOOST_UBLAS_INLINE
|
Chris@16
|
1358 size_type index () const {
|
Chris@16
|
1359 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
1360 }
|
Chris@16
|
1361
|
Chris@16
|
1362 // Assignment
|
Chris@16
|
1363 BOOST_UBLAS_INLINE
|
Chris@16
|
1364 iterator &operator = (const iterator &it) {
|
Chris@16
|
1365 container_reference<self_type>::assign (&it ());
|
Chris@16
|
1366 it1_ = it.it1_;
|
Chris@16
|
1367 it2_ = it.it2_;
|
Chris@16
|
1368 return *this;
|
Chris@16
|
1369 }
|
Chris@16
|
1370
|
Chris@16
|
1371 // Comparison
|
Chris@16
|
1372 BOOST_UBLAS_INLINE
|
Chris@16
|
1373 bool operator == (const iterator &it) const {
|
Chris@16
|
1374 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1375 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
1376 }
|
Chris@16
|
1377 BOOST_UBLAS_INLINE
|
Chris@16
|
1378 bool operator < (const iterator &it) const {
|
Chris@16
|
1379 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1380 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
1381 }
|
Chris@16
|
1382
|
Chris@16
|
1383 private:
|
Chris@16
|
1384 subiterator1_type it1_;
|
Chris@16
|
1385 subiterator2_type it2_;
|
Chris@16
|
1386
|
Chris@16
|
1387 friend class const_iterator;
|
Chris@16
|
1388 };
|
Chris@16
|
1389
|
Chris@16
|
1390 BOOST_UBLAS_INLINE
|
Chris@16
|
1391 iterator begin () {
|
Chris@16
|
1392 return find (0);
|
Chris@16
|
1393 }
|
Chris@16
|
1394 BOOST_UBLAS_INLINE
|
Chris@16
|
1395 iterator end () {
|
Chris@16
|
1396 return find (size ());
|
Chris@16
|
1397 }
|
Chris@16
|
1398
|
Chris@16
|
1399 // Reverse iterator
|
Chris@16
|
1400 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
Chris@16
|
1401 typedef reverse_iterator_base<iterator> reverse_iterator;
|
Chris@16
|
1402
|
Chris@16
|
1403 BOOST_UBLAS_INLINE
|
Chris@16
|
1404 const_reverse_iterator rbegin () const {
|
Chris@16
|
1405 return const_reverse_iterator (end ());
|
Chris@16
|
1406 }
|
Chris@16
|
1407 BOOST_UBLAS_INLINE
|
Chris@101
|
1408 const_reverse_iterator crbegin () const {
|
Chris@101
|
1409 return rbegin ();
|
Chris@101
|
1410 }
|
Chris@101
|
1411 BOOST_UBLAS_INLINE
|
Chris@16
|
1412 const_reverse_iterator rend () const {
|
Chris@16
|
1413 return const_reverse_iterator (begin ());
|
Chris@16
|
1414 }
|
Chris@16
|
1415 BOOST_UBLAS_INLINE
|
Chris@101
|
1416 const_reverse_iterator crend () const {
|
Chris@101
|
1417 return rend ();
|
Chris@101
|
1418 }
|
Chris@101
|
1419 BOOST_UBLAS_INLINE
|
Chris@16
|
1420 reverse_iterator rbegin () {
|
Chris@16
|
1421 return reverse_iterator (end ());
|
Chris@16
|
1422 }
|
Chris@16
|
1423 BOOST_UBLAS_INLINE
|
Chris@16
|
1424 reverse_iterator rend () {
|
Chris@16
|
1425 return reverse_iterator (begin ());
|
Chris@16
|
1426 }
|
Chris@16
|
1427
|
Chris@16
|
1428 private:
|
Chris@16
|
1429 matrix_closure_type data_;
|
Chris@16
|
1430 range_type r1_;
|
Chris@16
|
1431 range_type r2_;
|
Chris@16
|
1432 };
|
Chris@16
|
1433
|
Chris@16
|
1434 // Specialize temporary
|
Chris@16
|
1435 template <class M>
|
Chris@16
|
1436 struct vector_temporary_traits< matrix_vector_range<M> >
|
Chris@16
|
1437 : vector_temporary_traits< M > {} ;
|
Chris@16
|
1438 template <class M>
|
Chris@16
|
1439 struct vector_temporary_traits< const matrix_vector_range<M> >
|
Chris@16
|
1440 : vector_temporary_traits< M > {} ;
|
Chris@16
|
1441
|
Chris@16
|
1442 // Matrix based vector slice class
|
Chris@16
|
1443 template<class M>
|
Chris@16
|
1444 class matrix_vector_slice:
|
Chris@16
|
1445 public vector_expression<matrix_vector_slice<M> > {
|
Chris@16
|
1446
|
Chris@16
|
1447 typedef matrix_vector_slice<M> self_type;
|
Chris@16
|
1448 public:
|
Chris@16
|
1449 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
1450 using vector_expression<self_type>::operator ();
|
Chris@16
|
1451 #endif
|
Chris@16
|
1452 typedef M matrix_type;
|
Chris@16
|
1453 typedef typename M::size_type size_type;
|
Chris@16
|
1454 typedef typename M::difference_type difference_type;
|
Chris@16
|
1455 typedef typename M::value_type value_type;
|
Chris@16
|
1456 typedef typename M::const_reference const_reference;
|
Chris@16
|
1457 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
1458 typename M::const_reference,
|
Chris@16
|
1459 typename M::reference>::type reference;
|
Chris@16
|
1460 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
1461 typename M::const_closure_type,
|
Chris@16
|
1462 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
1463 typedef basic_range<size_type, difference_type> range_type;
|
Chris@16
|
1464 typedef basic_slice<size_type, difference_type> slice_type;
|
Chris@16
|
1465 typedef const self_type const_closure_type;
|
Chris@16
|
1466 typedef self_type closure_type;
|
Chris@16
|
1467 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
1468 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
1469
|
Chris@16
|
1470 // Construction and destruction
|
Chris@16
|
1471 BOOST_UBLAS_INLINE
|
Chris@16
|
1472 matrix_vector_slice (matrix_type &data, const slice_type &s1, const slice_type &s2):
|
Chris@16
|
1473 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
|
Chris@16
|
1474 // Early checking of preconditions here.
|
Chris@16
|
1475 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
|
Chris@16
|
1476 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
|
Chris@16
|
1477 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
|
Chris@16
|
1478 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
|
Chris@16
|
1479 }
|
Chris@16
|
1480
|
Chris@16
|
1481 // Accessors
|
Chris@16
|
1482 BOOST_UBLAS_INLINE
|
Chris@16
|
1483 size_type start1 () const {
|
Chris@16
|
1484 return s1_.start ();
|
Chris@16
|
1485 }
|
Chris@16
|
1486 BOOST_UBLAS_INLINE
|
Chris@16
|
1487 size_type start2 () const {
|
Chris@16
|
1488 return s2_.start ();
|
Chris@16
|
1489 }
|
Chris@16
|
1490 BOOST_UBLAS_INLINE
|
Chris@16
|
1491 difference_type stride1 () const {
|
Chris@16
|
1492 return s1_.stride ();
|
Chris@16
|
1493 }
|
Chris@16
|
1494 BOOST_UBLAS_INLINE
|
Chris@16
|
1495 difference_type stride2 () const {
|
Chris@16
|
1496 return s2_.stride ();
|
Chris@16
|
1497 }
|
Chris@16
|
1498 BOOST_UBLAS_INLINE
|
Chris@16
|
1499 size_type size () const {
|
Chris@16
|
1500 return BOOST_UBLAS_SAME (s1_.size (), s2_.size ());
|
Chris@16
|
1501 }
|
Chris@16
|
1502
|
Chris@16
|
1503 // Storage accessors
|
Chris@16
|
1504 BOOST_UBLAS_INLINE
|
Chris@16
|
1505 const matrix_closure_type &data () const {
|
Chris@16
|
1506 return data_;
|
Chris@16
|
1507 }
|
Chris@16
|
1508 BOOST_UBLAS_INLINE
|
Chris@16
|
1509 matrix_closure_type &data () {
|
Chris@16
|
1510 return data_;
|
Chris@16
|
1511 }
|
Chris@16
|
1512
|
Chris@16
|
1513 // Element access
|
Chris@16
|
1514 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
1515 BOOST_UBLAS_INLINE
|
Chris@16
|
1516 const_reference operator () (size_type i) const {
|
Chris@16
|
1517 return data_ (s1_ (i), s2_ (i));
|
Chris@16
|
1518 }
|
Chris@16
|
1519 BOOST_UBLAS_INLINE
|
Chris@16
|
1520 reference operator () (size_type i) {
|
Chris@16
|
1521 return data_ (s1_ (i), s2_ (i));
|
Chris@16
|
1522 }
|
Chris@16
|
1523
|
Chris@16
|
1524 BOOST_UBLAS_INLINE
|
Chris@16
|
1525 const_reference operator [] (size_type i) const {
|
Chris@16
|
1526 return (*this) (i);
|
Chris@16
|
1527 }
|
Chris@16
|
1528 BOOST_UBLAS_INLINE
|
Chris@16
|
1529 reference operator [] (size_type i) {
|
Chris@16
|
1530 return (*this) (i);
|
Chris@16
|
1531 }
|
Chris@16
|
1532 #else
|
Chris@16
|
1533 BOOST_UBLAS_INLINE
|
Chris@16
|
1534 reference operator () (size_type i) const {
|
Chris@16
|
1535 return data_ (s1_ (i), s2_ (i));
|
Chris@16
|
1536 }
|
Chris@16
|
1537
|
Chris@16
|
1538 BOOST_UBLAS_INLINE
|
Chris@16
|
1539 reference operator [] (size_type i) const {
|
Chris@16
|
1540 return (*this) (i);
|
Chris@16
|
1541 }
|
Chris@16
|
1542 #endif
|
Chris@16
|
1543
|
Chris@16
|
1544 // Assignment
|
Chris@16
|
1545 BOOST_UBLAS_INLINE
|
Chris@16
|
1546 matrix_vector_slice &operator = (const matrix_vector_slice &mvs) {
|
Chris@16
|
1547 // ISSUE need a temporary, proxy can be overlaping alias
|
Chris@16
|
1548 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvs));
|
Chris@16
|
1549 return *this;
|
Chris@16
|
1550 }
|
Chris@16
|
1551 BOOST_UBLAS_INLINE
|
Chris@16
|
1552 matrix_vector_slice &assign_temporary (matrix_vector_slice &mvs) {
|
Chris@16
|
1553 // assign elements, proxied container remains the same
|
Chris@16
|
1554 vector_assign<scalar_assign> (*this, mvs);
|
Chris@16
|
1555 return *this;
|
Chris@16
|
1556 }
|
Chris@16
|
1557 template<class AE>
|
Chris@16
|
1558 BOOST_UBLAS_INLINE
|
Chris@16
|
1559 matrix_vector_slice &operator = (const vector_expression<AE> &ae) {
|
Chris@16
|
1560 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
|
Chris@16
|
1561 return *this;
|
Chris@16
|
1562 }
|
Chris@16
|
1563 template<class AE>
|
Chris@16
|
1564 BOOST_UBLAS_INLINE
|
Chris@16
|
1565 matrix_vector_slice &assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1566 vector_assign<scalar_assign> (*this, ae);
|
Chris@16
|
1567 return *this;
|
Chris@16
|
1568 }
|
Chris@16
|
1569 template<class AE>
|
Chris@16
|
1570 BOOST_UBLAS_INLINE
|
Chris@16
|
1571 matrix_vector_slice &operator += (const vector_expression<AE> &ae) {
|
Chris@16
|
1572 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
1573 return *this;
|
Chris@16
|
1574 }
|
Chris@16
|
1575 template<class AE>
|
Chris@16
|
1576 BOOST_UBLAS_INLINE
|
Chris@16
|
1577 matrix_vector_slice &plus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1578 vector_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
1579 return *this;
|
Chris@16
|
1580 }
|
Chris@16
|
1581 template<class AE>
|
Chris@16
|
1582 BOOST_UBLAS_INLINE
|
Chris@16
|
1583 matrix_vector_slice &operator -= (const vector_expression<AE> &ae) {
|
Chris@16
|
1584 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
1585 return *this;
|
Chris@16
|
1586 }
|
Chris@16
|
1587 template<class AE>
|
Chris@16
|
1588 BOOST_UBLAS_INLINE
|
Chris@16
|
1589 matrix_vector_slice &minus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
1590 vector_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
1591 return *this;
|
Chris@16
|
1592 }
|
Chris@16
|
1593 template<class AT>
|
Chris@16
|
1594 BOOST_UBLAS_INLINE
|
Chris@16
|
1595 matrix_vector_slice &operator *= (const AT &at) {
|
Chris@16
|
1596 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
1597 return *this;
|
Chris@16
|
1598 }
|
Chris@16
|
1599 template<class AT>
|
Chris@16
|
1600 BOOST_UBLAS_INLINE
|
Chris@16
|
1601 matrix_vector_slice &operator /= (const AT &at) {
|
Chris@16
|
1602 vector_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
1603 return *this;
|
Chris@16
|
1604 }
|
Chris@16
|
1605
|
Chris@16
|
1606 // Closure comparison
|
Chris@16
|
1607 BOOST_UBLAS_INLINE
|
Chris@16
|
1608 bool same_closure (const matrix_vector_slice &mvs) const {
|
Chris@16
|
1609 return (*this).data_.same_closure (mvs.data_);
|
Chris@16
|
1610 }
|
Chris@16
|
1611
|
Chris@16
|
1612 // Comparison
|
Chris@16
|
1613 BOOST_UBLAS_INLINE
|
Chris@16
|
1614 bool operator == (const matrix_vector_slice &mvs) const {
|
Chris@16
|
1615 return (*this).data_ == mvs.data_ && s1_ == mvs.s1_ && s2_ == mvs.s2_;
|
Chris@16
|
1616 }
|
Chris@16
|
1617
|
Chris@16
|
1618 // Swapping
|
Chris@16
|
1619 BOOST_UBLAS_INLINE
|
Chris@16
|
1620 void swap (matrix_vector_slice mvs) {
|
Chris@16
|
1621 if (this != &mvs) {
|
Chris@16
|
1622 BOOST_UBLAS_CHECK (size () == mvs.size (), bad_size ());
|
Chris@16
|
1623 // Sparse ranges may be nonconformant now.
|
Chris@16
|
1624 // std::swap_ranges (begin (), end (), mvs.begin ());
|
Chris@16
|
1625 vector_swap<scalar_swap> (*this, mvs);
|
Chris@16
|
1626 }
|
Chris@16
|
1627 }
|
Chris@16
|
1628 BOOST_UBLAS_INLINE
|
Chris@16
|
1629 friend void swap (matrix_vector_slice mvs1, matrix_vector_slice mvs2) {
|
Chris@16
|
1630 mvs1.swap (mvs2);
|
Chris@16
|
1631 }
|
Chris@16
|
1632
|
Chris@16
|
1633 // Iterator types
|
Chris@16
|
1634 private:
|
Chris@16
|
1635 // Use slice as an index - FIXME this fails for packed assignment
|
Chris@16
|
1636 typedef typename slice_type::const_iterator const_subiterator1_type;
|
Chris@16
|
1637 typedef typename slice_type::const_iterator subiterator1_type;
|
Chris@16
|
1638 typedef typename slice_type::const_iterator const_subiterator2_type;
|
Chris@16
|
1639 typedef typename slice_type::const_iterator subiterator2_type;
|
Chris@16
|
1640
|
Chris@16
|
1641 public:
|
Chris@16
|
1642 class const_iterator;
|
Chris@16
|
1643 class iterator;
|
Chris@16
|
1644
|
Chris@16
|
1645 // Element lookup
|
Chris@16
|
1646 BOOST_UBLAS_INLINE
|
Chris@16
|
1647 const_iterator find (size_type i) const {
|
Chris@16
|
1648 return const_iterator (*this, s1_.begin () + i, s2_.begin () + i);
|
Chris@16
|
1649 }
|
Chris@16
|
1650 BOOST_UBLAS_INLINE
|
Chris@16
|
1651 iterator find (size_type i) {
|
Chris@16
|
1652 return iterator (*this, s1_.begin () + i, s2_.begin () + i);
|
Chris@16
|
1653 }
|
Chris@16
|
1654
|
Chris@16
|
1655 // Iterators simply are indices.
|
Chris@16
|
1656
|
Chris@16
|
1657 class const_iterator:
|
Chris@16
|
1658 public container_const_reference<matrix_vector_slice>,
|
Chris@16
|
1659 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
|
Chris@16
|
1660 iterator_base<const_iterator, value_type>::type {
|
Chris@16
|
1661 public:
|
Chris@16
|
1662 // FIXME Iterator can never be different code was:
|
Chris@16
|
1663 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
1664 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
1665
|
Chris@16
|
1666 typedef typename matrix_vector_slice::value_type value_type;
|
Chris@16
|
1667 typedef typename matrix_vector_slice::difference_type difference_type;
|
Chris@16
|
1668 typedef typename matrix_vector_slice::const_reference reference;
|
Chris@16
|
1669 typedef const typename matrix_vector_slice::value_type *pointer;
|
Chris@16
|
1670
|
Chris@16
|
1671 // Construction and destruction
|
Chris@16
|
1672 BOOST_UBLAS_INLINE
|
Chris@16
|
1673 const_iterator ():
|
Chris@16
|
1674 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1675 BOOST_UBLAS_INLINE
|
Chris@16
|
1676 const_iterator (const self_type &mvs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
1677 container_const_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1678 BOOST_UBLAS_INLINE
|
Chris@16
|
1679 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
|
Chris@16
|
1680 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
1681
|
Chris@16
|
1682 // Arithmetic
|
Chris@16
|
1683 BOOST_UBLAS_INLINE
|
Chris@16
|
1684 const_iterator &operator ++ () {
|
Chris@16
|
1685 ++ it1_;
|
Chris@16
|
1686 ++ it2_;
|
Chris@16
|
1687 return *this;
|
Chris@16
|
1688 }
|
Chris@16
|
1689 BOOST_UBLAS_INLINE
|
Chris@16
|
1690 const_iterator &operator -- () {
|
Chris@16
|
1691 -- it1_;
|
Chris@16
|
1692 -- it2_;
|
Chris@16
|
1693 return *this;
|
Chris@16
|
1694 }
|
Chris@16
|
1695 BOOST_UBLAS_INLINE
|
Chris@16
|
1696 const_iterator &operator += (difference_type n) {
|
Chris@16
|
1697 it1_ += n;
|
Chris@16
|
1698 it2_ += n;
|
Chris@16
|
1699 return *this;
|
Chris@16
|
1700 }
|
Chris@16
|
1701 BOOST_UBLAS_INLINE
|
Chris@16
|
1702 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
1703 it1_ -= n;
|
Chris@16
|
1704 it2_ -= n;
|
Chris@16
|
1705 return *this;
|
Chris@16
|
1706 }
|
Chris@16
|
1707 BOOST_UBLAS_INLINE
|
Chris@16
|
1708 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
1709 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1710 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
1711 }
|
Chris@16
|
1712
|
Chris@16
|
1713 // Dereference
|
Chris@16
|
1714 BOOST_UBLAS_INLINE
|
Chris@16
|
1715 const_reference operator * () const {
|
Chris@16
|
1716 // FIXME replace find with at_element
|
Chris@16
|
1717 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
1718 }
|
Chris@16
|
1719 BOOST_UBLAS_INLINE
|
Chris@16
|
1720 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1721 return *(*this + n);
|
Chris@16
|
1722 }
|
Chris@16
|
1723
|
Chris@16
|
1724 // Index
|
Chris@16
|
1725 BOOST_UBLAS_INLINE
|
Chris@16
|
1726 size_type index () const {
|
Chris@16
|
1727 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
1728 }
|
Chris@16
|
1729
|
Chris@16
|
1730 // Assignment
|
Chris@16
|
1731 BOOST_UBLAS_INLINE
|
Chris@16
|
1732 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
1733 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
1734 it1_ = it.it1_;
|
Chris@16
|
1735 it2_ = it.it2_;
|
Chris@16
|
1736 return *this;
|
Chris@16
|
1737 }
|
Chris@16
|
1738
|
Chris@16
|
1739 // Comparison
|
Chris@16
|
1740 BOOST_UBLAS_INLINE
|
Chris@16
|
1741 bool operator == (const const_iterator &it) const {
|
Chris@16
|
1742 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1743 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
1744 }
|
Chris@16
|
1745 BOOST_UBLAS_INLINE
|
Chris@16
|
1746 bool operator < (const const_iterator &it) const {
|
Chris@16
|
1747 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1748 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
1749 }
|
Chris@16
|
1750
|
Chris@16
|
1751 private:
|
Chris@16
|
1752 const_subiterator1_type it1_;
|
Chris@16
|
1753 const_subiterator2_type it2_;
|
Chris@16
|
1754 };
|
Chris@16
|
1755
|
Chris@16
|
1756 BOOST_UBLAS_INLINE
|
Chris@16
|
1757 const_iterator begin () const {
|
Chris@16
|
1758 return find (0);
|
Chris@16
|
1759 }
|
Chris@16
|
1760 BOOST_UBLAS_INLINE
|
Chris@101
|
1761 const_iterator cbegin () const {
|
Chris@101
|
1762 return begin ();
|
Chris@101
|
1763 }
|
Chris@101
|
1764 BOOST_UBLAS_INLINE
|
Chris@16
|
1765 const_iterator end () const {
|
Chris@16
|
1766 return find (size ());
|
Chris@16
|
1767 }
|
Chris@101
|
1768 BOOST_UBLAS_INLINE
|
Chris@101
|
1769 const_iterator cend () const {
|
Chris@101
|
1770 return end ();
|
Chris@101
|
1771 }
|
Chris@16
|
1772
|
Chris@16
|
1773 class iterator:
|
Chris@16
|
1774 public container_reference<matrix_vector_slice>,
|
Chris@16
|
1775 public iterator_base_traits<typename M::iterator1::iterator_category>::template
|
Chris@16
|
1776 iterator_base<iterator, value_type>::type {
|
Chris@16
|
1777 public:
|
Chris@16
|
1778 // FIXME Iterator can never be different code was:
|
Chris@16
|
1779 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
1780 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
1781
|
Chris@16
|
1782 typedef typename matrix_vector_slice::value_type value_type;
|
Chris@16
|
1783 typedef typename matrix_vector_slice::difference_type difference_type;
|
Chris@16
|
1784 typedef typename matrix_vector_slice::reference reference;
|
Chris@16
|
1785 typedef typename matrix_vector_slice::value_type *pointer;
|
Chris@16
|
1786
|
Chris@16
|
1787 // Construction and destruction
|
Chris@16
|
1788 BOOST_UBLAS_INLINE
|
Chris@16
|
1789 iterator ():
|
Chris@16
|
1790 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1791 BOOST_UBLAS_INLINE
|
Chris@16
|
1792 iterator (self_type &mvs, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
1793 container_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1794
|
Chris@16
|
1795 // Arithmetic
|
Chris@16
|
1796 BOOST_UBLAS_INLINE
|
Chris@16
|
1797 iterator &operator ++ () {
|
Chris@16
|
1798 ++ it1_;
|
Chris@16
|
1799 ++ it2_;
|
Chris@16
|
1800 return *this;
|
Chris@16
|
1801 }
|
Chris@16
|
1802 BOOST_UBLAS_INLINE
|
Chris@16
|
1803 iterator &operator -- () {
|
Chris@16
|
1804 -- it1_;
|
Chris@16
|
1805 -- it2_;
|
Chris@16
|
1806 return *this;
|
Chris@16
|
1807 }
|
Chris@16
|
1808 BOOST_UBLAS_INLINE
|
Chris@16
|
1809 iterator &operator += (difference_type n) {
|
Chris@16
|
1810 it1_ += n;
|
Chris@16
|
1811 it2_ += n;
|
Chris@16
|
1812 return *this;
|
Chris@16
|
1813 }
|
Chris@16
|
1814 BOOST_UBLAS_INLINE
|
Chris@16
|
1815 iterator &operator -= (difference_type n) {
|
Chris@16
|
1816 it1_ -= n;
|
Chris@16
|
1817 it2_ -= n;
|
Chris@16
|
1818 return *this;
|
Chris@16
|
1819 }
|
Chris@16
|
1820 BOOST_UBLAS_INLINE
|
Chris@16
|
1821 difference_type operator - (const iterator &it) const {
|
Chris@16
|
1822 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1823 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
1824 }
|
Chris@16
|
1825
|
Chris@16
|
1826 // Dereference
|
Chris@16
|
1827 BOOST_UBLAS_INLINE
|
Chris@16
|
1828 reference operator * () const {
|
Chris@16
|
1829 // FIXME replace find with at_element
|
Chris@16
|
1830 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
1831 }
|
Chris@16
|
1832 BOOST_UBLAS_INLINE
|
Chris@16
|
1833 reference operator [] (difference_type n) const {
|
Chris@16
|
1834 return *(*this + n);
|
Chris@16
|
1835 }
|
Chris@16
|
1836
|
Chris@16
|
1837 // Index
|
Chris@16
|
1838 BOOST_UBLAS_INLINE
|
Chris@16
|
1839 size_type index () const {
|
Chris@16
|
1840 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
1841 }
|
Chris@16
|
1842
|
Chris@16
|
1843 // Assignment
|
Chris@16
|
1844 BOOST_UBLAS_INLINE
|
Chris@16
|
1845 iterator &operator = (const iterator &it) {
|
Chris@16
|
1846 container_reference<self_type>::assign (&it ());
|
Chris@16
|
1847 it1_ = it.it1_;
|
Chris@16
|
1848 it2_ = it.it2_;
|
Chris@16
|
1849 return *this;
|
Chris@16
|
1850 }
|
Chris@16
|
1851
|
Chris@16
|
1852 // Comparison
|
Chris@16
|
1853 BOOST_UBLAS_INLINE
|
Chris@16
|
1854 bool operator == (const iterator &it) const {
|
Chris@16
|
1855 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1856 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
1857 }
|
Chris@16
|
1858 BOOST_UBLAS_INLINE
|
Chris@16
|
1859 bool operator < (const iterator &it) const {
|
Chris@16
|
1860 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
1861 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
1862 }
|
Chris@16
|
1863
|
Chris@16
|
1864 private:
|
Chris@16
|
1865 subiterator1_type it1_;
|
Chris@16
|
1866 subiterator2_type it2_;
|
Chris@16
|
1867
|
Chris@16
|
1868 friend class const_iterator;
|
Chris@16
|
1869 };
|
Chris@16
|
1870
|
Chris@16
|
1871 BOOST_UBLAS_INLINE
|
Chris@16
|
1872 iterator begin () {
|
Chris@16
|
1873 return find (0);
|
Chris@16
|
1874 }
|
Chris@16
|
1875 BOOST_UBLAS_INLINE
|
Chris@16
|
1876 iterator end () {
|
Chris@16
|
1877 return find (size ());
|
Chris@16
|
1878 }
|
Chris@16
|
1879
|
Chris@16
|
1880 // Reverse iterator
|
Chris@16
|
1881 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
Chris@16
|
1882 typedef reverse_iterator_base<iterator> reverse_iterator;
|
Chris@16
|
1883
|
Chris@16
|
1884 BOOST_UBLAS_INLINE
|
Chris@16
|
1885 const_reverse_iterator rbegin () const {
|
Chris@16
|
1886 return const_reverse_iterator (end ());
|
Chris@16
|
1887 }
|
Chris@16
|
1888 BOOST_UBLAS_INLINE
|
Chris@101
|
1889 const_reverse_iterator crbegin () const {
|
Chris@101
|
1890 return rbegin ();
|
Chris@101
|
1891 }
|
Chris@101
|
1892 BOOST_UBLAS_INLINE
|
Chris@16
|
1893 const_reverse_iterator rend () const {
|
Chris@16
|
1894 return const_reverse_iterator (begin ());
|
Chris@16
|
1895 }
|
Chris@16
|
1896 BOOST_UBLAS_INLINE
|
Chris@101
|
1897 const_reverse_iterator crend () const {
|
Chris@101
|
1898 return rend ();
|
Chris@101
|
1899 }
|
Chris@101
|
1900 BOOST_UBLAS_INLINE
|
Chris@16
|
1901 reverse_iterator rbegin () {
|
Chris@16
|
1902 return reverse_iterator (end ());
|
Chris@16
|
1903 }
|
Chris@16
|
1904 BOOST_UBLAS_INLINE
|
Chris@16
|
1905 reverse_iterator rend () {
|
Chris@16
|
1906 return reverse_iterator (begin ());
|
Chris@16
|
1907 }
|
Chris@16
|
1908
|
Chris@16
|
1909 private:
|
Chris@16
|
1910 matrix_closure_type data_;
|
Chris@16
|
1911 slice_type s1_;
|
Chris@16
|
1912 slice_type s2_;
|
Chris@16
|
1913 };
|
Chris@16
|
1914
|
Chris@16
|
1915 // Specialize temporary
|
Chris@16
|
1916 template <class M>
|
Chris@16
|
1917 struct vector_temporary_traits< matrix_vector_slice<M> >
|
Chris@16
|
1918 : vector_temporary_traits< M > {} ;
|
Chris@16
|
1919 template <class M>
|
Chris@16
|
1920 struct vector_temporary_traits< const matrix_vector_slice<M> >
|
Chris@16
|
1921 : vector_temporary_traits< M > {} ;
|
Chris@16
|
1922
|
Chris@16
|
1923 // Matrix based vector indirection class
|
Chris@16
|
1924
|
Chris@16
|
1925 template<class M, class IA>
|
Chris@16
|
1926 class matrix_vector_indirect:
|
Chris@16
|
1927 public vector_expression<matrix_vector_indirect<M, IA> > {
|
Chris@16
|
1928
|
Chris@16
|
1929 typedef matrix_vector_indirect<M, IA> self_type;
|
Chris@16
|
1930 public:
|
Chris@16
|
1931 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
1932 using vector_expression<self_type>::operator ();
|
Chris@16
|
1933 #endif
|
Chris@16
|
1934 typedef M matrix_type;
|
Chris@16
|
1935 typedef IA indirect_array_type;
|
Chris@16
|
1936 typedef typename M::size_type size_type;
|
Chris@16
|
1937 typedef typename M::difference_type difference_type;
|
Chris@16
|
1938 typedef typename M::value_type value_type;
|
Chris@16
|
1939 typedef typename M::const_reference const_reference;
|
Chris@16
|
1940 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
1941 typename M::const_reference,
|
Chris@16
|
1942 typename M::reference>::type reference;
|
Chris@16
|
1943 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
1944 typename M::const_closure_type,
|
Chris@16
|
1945 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
1946 typedef const self_type const_closure_type;
|
Chris@16
|
1947 typedef self_type closure_type;
|
Chris@16
|
1948 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
1949 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
1950
|
Chris@16
|
1951 // Construction and destruction
|
Chris@16
|
1952 BOOST_UBLAS_INLINE
|
Chris@16
|
1953 matrix_vector_indirect (matrix_type &data, size_type size):
|
Chris@16
|
1954 data_ (data), ia1_ (size), ia2_ (size) {}
|
Chris@16
|
1955 BOOST_UBLAS_INLINE
|
Chris@16
|
1956 matrix_vector_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2):
|
Chris@16
|
1957 data_ (data), ia1_ (ia1), ia2_ (ia2) {
|
Chris@16
|
1958 // Early checking of preconditions here.
|
Chris@16
|
1959 // BOOST_UBLAS_CHECK (ia1_.size () == ia2_.size (), bad_size ());
|
Chris@16
|
1960 }
|
Chris@16
|
1961
|
Chris@16
|
1962 // Accessors
|
Chris@16
|
1963 BOOST_UBLAS_INLINE
|
Chris@16
|
1964 size_type size () const {
|
Chris@16
|
1965 return BOOST_UBLAS_SAME (ia1_.size (), ia2_.size ());
|
Chris@16
|
1966 }
|
Chris@16
|
1967 BOOST_UBLAS_INLINE
|
Chris@16
|
1968 const indirect_array_type &indirect1 () const {
|
Chris@16
|
1969 return ia1_;
|
Chris@16
|
1970 }
|
Chris@16
|
1971 BOOST_UBLAS_INLINE
|
Chris@16
|
1972 indirect_array_type &indirect1 () {
|
Chris@16
|
1973 return ia1_;
|
Chris@16
|
1974 }
|
Chris@16
|
1975 BOOST_UBLAS_INLINE
|
Chris@16
|
1976 const indirect_array_type &indirect2 () const {
|
Chris@16
|
1977 return ia2_;
|
Chris@16
|
1978 }
|
Chris@16
|
1979 BOOST_UBLAS_INLINE
|
Chris@16
|
1980 indirect_array_type &indirect2 () {
|
Chris@16
|
1981 return ia2_;
|
Chris@16
|
1982 }
|
Chris@16
|
1983
|
Chris@16
|
1984 // Storage accessors
|
Chris@16
|
1985 BOOST_UBLAS_INLINE
|
Chris@16
|
1986 const matrix_closure_type &data () const {
|
Chris@16
|
1987 return data_;
|
Chris@16
|
1988 }
|
Chris@16
|
1989 BOOST_UBLAS_INLINE
|
Chris@16
|
1990 matrix_closure_type &data () {
|
Chris@16
|
1991 return data_;
|
Chris@16
|
1992 }
|
Chris@16
|
1993
|
Chris@16
|
1994 // Element access
|
Chris@16
|
1995 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
1996 BOOST_UBLAS_INLINE
|
Chris@16
|
1997 const_reference operator () (size_type i) const {
|
Chris@16
|
1998 return data_ (ia1_ (i), ia2_ (i));
|
Chris@16
|
1999 }
|
Chris@16
|
2000 BOOST_UBLAS_INLINE
|
Chris@16
|
2001 reference operator () (size_type i) {
|
Chris@16
|
2002 return data_ (ia1_ (i), ia2_ (i));
|
Chris@16
|
2003 }
|
Chris@16
|
2004
|
Chris@16
|
2005 BOOST_UBLAS_INLINE
|
Chris@16
|
2006 const_reference operator [] (size_type i) const {
|
Chris@16
|
2007 return (*this) (i);
|
Chris@16
|
2008 }
|
Chris@16
|
2009 BOOST_UBLAS_INLINE
|
Chris@16
|
2010 reference operator [] (size_type i) {
|
Chris@16
|
2011 return (*this) (i);
|
Chris@16
|
2012 }
|
Chris@16
|
2013 #else
|
Chris@16
|
2014 BOOST_UBLAS_INLINE
|
Chris@16
|
2015 reference operator () (size_type i) const {
|
Chris@16
|
2016 return data_ (ia1_ (i), ia2_ (i));
|
Chris@16
|
2017 }
|
Chris@16
|
2018
|
Chris@16
|
2019 BOOST_UBLAS_INLINE
|
Chris@16
|
2020 reference operator [] (size_type i) const {
|
Chris@16
|
2021 return (*this) (i);
|
Chris@16
|
2022 }
|
Chris@16
|
2023 #endif
|
Chris@16
|
2024
|
Chris@16
|
2025 // Assignment
|
Chris@16
|
2026 BOOST_UBLAS_INLINE
|
Chris@16
|
2027 matrix_vector_indirect &operator = (const matrix_vector_indirect &mvi) {
|
Chris@16
|
2028 // ISSUE need a temporary, proxy can be overlaping alias
|
Chris@16
|
2029 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvi));
|
Chris@16
|
2030 return *this;
|
Chris@16
|
2031 }
|
Chris@16
|
2032 BOOST_UBLAS_INLINE
|
Chris@16
|
2033 matrix_vector_indirect &assign_temporary (matrix_vector_indirect &mvi) {
|
Chris@16
|
2034 // assign elements, proxied container remains the same
|
Chris@16
|
2035 vector_assign<scalar_assign> (*this, mvi);
|
Chris@16
|
2036 return *this;
|
Chris@16
|
2037 }
|
Chris@16
|
2038 template<class AE>
|
Chris@16
|
2039 BOOST_UBLAS_INLINE
|
Chris@16
|
2040 matrix_vector_indirect &operator = (const vector_expression<AE> &ae) {
|
Chris@16
|
2041 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
|
Chris@16
|
2042 return *this;
|
Chris@16
|
2043 }
|
Chris@16
|
2044 template<class AE>
|
Chris@16
|
2045 BOOST_UBLAS_INLINE
|
Chris@16
|
2046 matrix_vector_indirect &assign (const vector_expression<AE> &ae) {
|
Chris@16
|
2047 vector_assign<scalar_assign> (*this, ae);
|
Chris@16
|
2048 return *this;
|
Chris@16
|
2049 }
|
Chris@16
|
2050 template<class AE>
|
Chris@16
|
2051 BOOST_UBLAS_INLINE
|
Chris@16
|
2052 matrix_vector_indirect &operator += (const vector_expression<AE> &ae) {
|
Chris@16
|
2053 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
2054 return *this;
|
Chris@16
|
2055 }
|
Chris@16
|
2056 template<class AE>
|
Chris@16
|
2057 BOOST_UBLAS_INLINE
|
Chris@16
|
2058 matrix_vector_indirect &plus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
2059 vector_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
2060 return *this;
|
Chris@16
|
2061 }
|
Chris@16
|
2062 template<class AE>
|
Chris@16
|
2063 BOOST_UBLAS_INLINE
|
Chris@16
|
2064 matrix_vector_indirect &operator -= (const vector_expression<AE> &ae) {
|
Chris@16
|
2065 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
2066 return *this;
|
Chris@16
|
2067 }
|
Chris@16
|
2068 template<class AE>
|
Chris@16
|
2069 BOOST_UBLAS_INLINE
|
Chris@16
|
2070 matrix_vector_indirect &minus_assign (const vector_expression<AE> &ae) {
|
Chris@16
|
2071 vector_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
2072 return *this;
|
Chris@16
|
2073 }
|
Chris@16
|
2074 template<class AT>
|
Chris@16
|
2075 BOOST_UBLAS_INLINE
|
Chris@16
|
2076 matrix_vector_indirect &operator *= (const AT &at) {
|
Chris@16
|
2077 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
2078 return *this;
|
Chris@16
|
2079 }
|
Chris@16
|
2080 template<class AT>
|
Chris@16
|
2081 BOOST_UBLAS_INLINE
|
Chris@16
|
2082 matrix_vector_indirect &operator /= (const AT &at) {
|
Chris@16
|
2083 vector_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
2084 return *this;
|
Chris@16
|
2085 }
|
Chris@16
|
2086
|
Chris@16
|
2087 // Closure comparison
|
Chris@16
|
2088 BOOST_UBLAS_INLINE
|
Chris@16
|
2089 bool same_closure (const matrix_vector_indirect &mvi) const {
|
Chris@16
|
2090 return (*this).data_.same_closure (mvi.data_);
|
Chris@16
|
2091 }
|
Chris@16
|
2092
|
Chris@16
|
2093 // Comparison
|
Chris@16
|
2094 BOOST_UBLAS_INLINE
|
Chris@16
|
2095 bool operator == (const matrix_vector_indirect &mvi) const {
|
Chris@16
|
2096 return (*this).data_ == mvi.data_ && ia1_ == mvi.ia1_ && ia2_ == mvi.ia2_;
|
Chris@16
|
2097 }
|
Chris@16
|
2098
|
Chris@16
|
2099 // Swapping
|
Chris@16
|
2100 BOOST_UBLAS_INLINE
|
Chris@16
|
2101 void swap (matrix_vector_indirect mvi) {
|
Chris@16
|
2102 if (this != &mvi) {
|
Chris@16
|
2103 BOOST_UBLAS_CHECK (size () == mvi.size (), bad_size ());
|
Chris@16
|
2104 // Sparse ranges may be nonconformant now.
|
Chris@16
|
2105 // std::swap_ranges (begin (), end (), mvi.begin ());
|
Chris@16
|
2106 vector_swap<scalar_swap> (*this, mvi);
|
Chris@16
|
2107 }
|
Chris@16
|
2108 }
|
Chris@16
|
2109 BOOST_UBLAS_INLINE
|
Chris@16
|
2110 friend void swap (matrix_vector_indirect mvi1, matrix_vector_indirect mvi2) {
|
Chris@16
|
2111 mvi1.swap (mvi2);
|
Chris@16
|
2112 }
|
Chris@16
|
2113
|
Chris@16
|
2114 // Iterator types
|
Chris@16
|
2115 private:
|
Chris@16
|
2116 // Use indirect array as an index - FIXME this fails for packed assignment
|
Chris@16
|
2117 typedef typename IA::const_iterator const_subiterator1_type;
|
Chris@16
|
2118 typedef typename IA::const_iterator subiterator1_type;
|
Chris@16
|
2119 typedef typename IA::const_iterator const_subiterator2_type;
|
Chris@16
|
2120 typedef typename IA::const_iterator subiterator2_type;
|
Chris@16
|
2121
|
Chris@16
|
2122 public:
|
Chris@16
|
2123 class const_iterator;
|
Chris@16
|
2124 class iterator;
|
Chris@16
|
2125
|
Chris@16
|
2126 // Element lookup
|
Chris@16
|
2127 BOOST_UBLAS_INLINE
|
Chris@16
|
2128 const_iterator find (size_type i) const {
|
Chris@16
|
2129 return const_iterator (*this, ia1_.begin () + i, ia2_.begin () + i);
|
Chris@16
|
2130 }
|
Chris@16
|
2131 BOOST_UBLAS_INLINE
|
Chris@16
|
2132 iterator find (size_type i) {
|
Chris@16
|
2133 return iterator (*this, ia1_.begin () + i, ia2_.begin () + i);
|
Chris@16
|
2134 }
|
Chris@16
|
2135
|
Chris@16
|
2136 // Iterators simply are indices.
|
Chris@16
|
2137
|
Chris@16
|
2138 class const_iterator:
|
Chris@16
|
2139 public container_const_reference<matrix_vector_indirect>,
|
Chris@16
|
2140 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
|
Chris@16
|
2141 iterator_base<const_iterator, value_type>::type {
|
Chris@16
|
2142 public:
|
Chris@16
|
2143 // FIXME Iterator can never be different code was:
|
Chris@16
|
2144 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
2145 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
2146
|
Chris@16
|
2147 typedef typename matrix_vector_indirect::value_type value_type;
|
Chris@16
|
2148 typedef typename matrix_vector_indirect::difference_type difference_type;
|
Chris@16
|
2149 typedef typename matrix_vector_indirect::const_reference reference;
|
Chris@16
|
2150 typedef const typename matrix_vector_indirect::value_type *pointer;
|
Chris@16
|
2151
|
Chris@16
|
2152 // Construction and destruction
|
Chris@16
|
2153 BOOST_UBLAS_INLINE
|
Chris@16
|
2154 const_iterator ():
|
Chris@16
|
2155 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
2156 BOOST_UBLAS_INLINE
|
Chris@16
|
2157 const_iterator (const self_type &mvi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
2158 container_const_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
2159 BOOST_UBLAS_INLINE
|
Chris@16
|
2160 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
|
Chris@16
|
2161 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
2162
|
Chris@16
|
2163 // Arithmetic
|
Chris@16
|
2164 BOOST_UBLAS_INLINE
|
Chris@16
|
2165 const_iterator &operator ++ () {
|
Chris@16
|
2166 ++ it1_;
|
Chris@16
|
2167 ++ it2_;
|
Chris@16
|
2168 return *this;
|
Chris@16
|
2169 }
|
Chris@16
|
2170 BOOST_UBLAS_INLINE
|
Chris@16
|
2171 const_iterator &operator -- () {
|
Chris@16
|
2172 -- it1_;
|
Chris@16
|
2173 -- it2_;
|
Chris@16
|
2174 return *this;
|
Chris@16
|
2175 }
|
Chris@16
|
2176 BOOST_UBLAS_INLINE
|
Chris@16
|
2177 const_iterator &operator += (difference_type n) {
|
Chris@16
|
2178 it1_ += n;
|
Chris@16
|
2179 it2_ += n;
|
Chris@16
|
2180 return *this;
|
Chris@16
|
2181 }
|
Chris@16
|
2182 BOOST_UBLAS_INLINE
|
Chris@16
|
2183 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
2184 it1_ -= n;
|
Chris@16
|
2185 it2_ -= n;
|
Chris@16
|
2186 return *this;
|
Chris@16
|
2187 }
|
Chris@16
|
2188 BOOST_UBLAS_INLINE
|
Chris@16
|
2189 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
2190 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2191 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
2192 }
|
Chris@16
|
2193
|
Chris@16
|
2194 // Dereference
|
Chris@16
|
2195 BOOST_UBLAS_INLINE
|
Chris@16
|
2196 const_reference operator * () const {
|
Chris@16
|
2197 // FIXME replace find with at_element
|
Chris@16
|
2198 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
2199 }
|
Chris@16
|
2200 BOOST_UBLAS_INLINE
|
Chris@16
|
2201 const_reference operator [] (difference_type n) const {
|
Chris@16
|
2202 return *(*this + n);
|
Chris@16
|
2203 }
|
Chris@16
|
2204
|
Chris@16
|
2205 // Index
|
Chris@16
|
2206 BOOST_UBLAS_INLINE
|
Chris@16
|
2207 size_type index () const {
|
Chris@16
|
2208 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
2209 }
|
Chris@16
|
2210
|
Chris@16
|
2211 // Assignment
|
Chris@16
|
2212 BOOST_UBLAS_INLINE
|
Chris@16
|
2213 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
2214 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2215 it1_ = it.it1_;
|
Chris@16
|
2216 it2_ = it.it2_;
|
Chris@16
|
2217 return *this;
|
Chris@16
|
2218 }
|
Chris@16
|
2219
|
Chris@16
|
2220 // Comparison
|
Chris@16
|
2221 BOOST_UBLAS_INLINE
|
Chris@16
|
2222 bool operator == (const const_iterator &it) const {
|
Chris@16
|
2223 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2224 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
2225 }
|
Chris@16
|
2226 BOOST_UBLAS_INLINE
|
Chris@16
|
2227 bool operator < (const const_iterator &it) const {
|
Chris@16
|
2228 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2229 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
2230 }
|
Chris@16
|
2231
|
Chris@16
|
2232 private:
|
Chris@16
|
2233 const_subiterator1_type it1_;
|
Chris@16
|
2234 const_subiterator2_type it2_;
|
Chris@16
|
2235 };
|
Chris@16
|
2236
|
Chris@16
|
2237 BOOST_UBLAS_INLINE
|
Chris@16
|
2238 const_iterator begin () const {
|
Chris@16
|
2239 return find (0);
|
Chris@16
|
2240 }
|
Chris@16
|
2241 BOOST_UBLAS_INLINE
|
Chris@101
|
2242 const_iterator cbegin () const {
|
Chris@101
|
2243 return begin ();
|
Chris@101
|
2244 }
|
Chris@101
|
2245 BOOST_UBLAS_INLINE
|
Chris@16
|
2246 const_iterator end () const {
|
Chris@16
|
2247 return find (size ());
|
Chris@16
|
2248 }
|
Chris@101
|
2249 BOOST_UBLAS_INLINE
|
Chris@101
|
2250 const_iterator cend () const {
|
Chris@101
|
2251 return end ();
|
Chris@101
|
2252 }
|
Chris@16
|
2253
|
Chris@16
|
2254 class iterator:
|
Chris@16
|
2255 public container_reference<matrix_vector_indirect>,
|
Chris@16
|
2256 public iterator_base_traits<typename M::iterator1::iterator_category>::template
|
Chris@16
|
2257 iterator_base<iterator, value_type>::type {
|
Chris@16
|
2258 public:
|
Chris@16
|
2259 // FIXME Iterator can never be different code was:
|
Chris@16
|
2260 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
|
Chris@16
|
2261 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
|
Chris@16
|
2262
|
Chris@16
|
2263 typedef typename matrix_vector_indirect::value_type value_type;
|
Chris@16
|
2264 typedef typename matrix_vector_indirect::difference_type difference_type;
|
Chris@16
|
2265 typedef typename matrix_vector_indirect::reference reference;
|
Chris@16
|
2266 typedef typename matrix_vector_indirect::value_type *pointer;
|
Chris@16
|
2267
|
Chris@16
|
2268 // Construction and destruction
|
Chris@16
|
2269 BOOST_UBLAS_INLINE
|
Chris@16
|
2270 iterator ():
|
Chris@16
|
2271 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
2272 BOOST_UBLAS_INLINE
|
Chris@16
|
2273 iterator (self_type &mvi, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
2274 container_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
2275
|
Chris@16
|
2276 // Arithmetic
|
Chris@16
|
2277 BOOST_UBLAS_INLINE
|
Chris@16
|
2278 iterator &operator ++ () {
|
Chris@16
|
2279 ++ it1_;
|
Chris@16
|
2280 ++ it2_;
|
Chris@16
|
2281 return *this;
|
Chris@16
|
2282 }
|
Chris@16
|
2283 BOOST_UBLAS_INLINE
|
Chris@16
|
2284 iterator &operator -- () {
|
Chris@16
|
2285 -- it1_;
|
Chris@16
|
2286 -- it2_;
|
Chris@16
|
2287 return *this;
|
Chris@16
|
2288 }
|
Chris@16
|
2289 BOOST_UBLAS_INLINE
|
Chris@16
|
2290 iterator &operator += (difference_type n) {
|
Chris@16
|
2291 it1_ += n;
|
Chris@16
|
2292 it2_ += n;
|
Chris@16
|
2293 return *this;
|
Chris@16
|
2294 }
|
Chris@16
|
2295 BOOST_UBLAS_INLINE
|
Chris@16
|
2296 iterator &operator -= (difference_type n) {
|
Chris@16
|
2297 it1_ -= n;
|
Chris@16
|
2298 it2_ -= n;
|
Chris@16
|
2299 return *this;
|
Chris@16
|
2300 }
|
Chris@16
|
2301 BOOST_UBLAS_INLINE
|
Chris@16
|
2302 difference_type operator - (const iterator &it) const {
|
Chris@16
|
2303 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2304 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
|
Chris@16
|
2305 }
|
Chris@16
|
2306
|
Chris@16
|
2307 // Dereference
|
Chris@16
|
2308 BOOST_UBLAS_INLINE
|
Chris@16
|
2309 reference operator * () const {
|
Chris@16
|
2310 // FIXME replace find with at_element
|
Chris@16
|
2311 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
2312 }
|
Chris@16
|
2313 BOOST_UBLAS_INLINE
|
Chris@16
|
2314 reference operator [] (difference_type n) const {
|
Chris@16
|
2315 return *(*this + n);
|
Chris@16
|
2316 }
|
Chris@16
|
2317
|
Chris@16
|
2318 // Index
|
Chris@16
|
2319 BOOST_UBLAS_INLINE
|
Chris@16
|
2320 size_type index () const {
|
Chris@16
|
2321 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
|
Chris@16
|
2322 }
|
Chris@16
|
2323
|
Chris@16
|
2324 // Assignment
|
Chris@16
|
2325 BOOST_UBLAS_INLINE
|
Chris@16
|
2326 iterator &operator = (const iterator &it) {
|
Chris@16
|
2327 container_reference<self_type>::assign (&it ());
|
Chris@16
|
2328 it1_ = it.it1_;
|
Chris@16
|
2329 it2_ = it.it2_;
|
Chris@16
|
2330 return *this;
|
Chris@16
|
2331 }
|
Chris@16
|
2332
|
Chris@16
|
2333 // Comparison
|
Chris@16
|
2334 BOOST_UBLAS_INLINE
|
Chris@16
|
2335 bool operator == (const iterator &it) const {
|
Chris@16
|
2336 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2337 return it1_ == it.it1_ && it2_ == it.it2_;
|
Chris@16
|
2338 }
|
Chris@16
|
2339 BOOST_UBLAS_INLINE
|
Chris@16
|
2340 bool operator < (const iterator &it) const {
|
Chris@16
|
2341 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2342 return it1_ < it.it1_ && it2_ < it.it2_;
|
Chris@16
|
2343 }
|
Chris@16
|
2344
|
Chris@16
|
2345 private:
|
Chris@16
|
2346 subiterator1_type it1_;
|
Chris@16
|
2347 subiterator2_type it2_;
|
Chris@16
|
2348
|
Chris@16
|
2349 friend class const_iterator;
|
Chris@16
|
2350 };
|
Chris@16
|
2351
|
Chris@16
|
2352 BOOST_UBLAS_INLINE
|
Chris@16
|
2353 iterator begin () {
|
Chris@16
|
2354 return find (0);
|
Chris@16
|
2355 }
|
Chris@16
|
2356 BOOST_UBLAS_INLINE
|
Chris@16
|
2357 iterator end () {
|
Chris@16
|
2358 return find (size ());
|
Chris@16
|
2359 }
|
Chris@16
|
2360
|
Chris@16
|
2361 // Reverse iterator
|
Chris@16
|
2362 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
Chris@16
|
2363 typedef reverse_iterator_base<iterator> reverse_iterator;
|
Chris@16
|
2364
|
Chris@16
|
2365 BOOST_UBLAS_INLINE
|
Chris@16
|
2366 const_reverse_iterator rbegin () const {
|
Chris@16
|
2367 return const_reverse_iterator (end ());
|
Chris@16
|
2368 }
|
Chris@16
|
2369 BOOST_UBLAS_INLINE
|
Chris@101
|
2370 const_reverse_iterator crbegin () const {
|
Chris@101
|
2371 return rbegin ();
|
Chris@101
|
2372 }
|
Chris@101
|
2373 BOOST_UBLAS_INLINE
|
Chris@16
|
2374 const_reverse_iterator rend () const {
|
Chris@16
|
2375 return const_reverse_iterator (begin ());
|
Chris@16
|
2376 }
|
Chris@16
|
2377 BOOST_UBLAS_INLINE
|
Chris@101
|
2378 const_reverse_iterator crend () const {
|
Chris@101
|
2379 return rend ();
|
Chris@101
|
2380 }
|
Chris@101
|
2381 BOOST_UBLAS_INLINE
|
Chris@16
|
2382 reverse_iterator rbegin () {
|
Chris@16
|
2383 return reverse_iterator (end ());
|
Chris@16
|
2384 }
|
Chris@16
|
2385 BOOST_UBLAS_INLINE
|
Chris@16
|
2386 reverse_iterator rend () {
|
Chris@16
|
2387 return reverse_iterator (begin ());
|
Chris@16
|
2388 }
|
Chris@16
|
2389
|
Chris@16
|
2390 private:
|
Chris@16
|
2391 matrix_closure_type data_;
|
Chris@16
|
2392 indirect_array_type ia1_;
|
Chris@16
|
2393 indirect_array_type ia2_;
|
Chris@16
|
2394 };
|
Chris@16
|
2395
|
Chris@16
|
2396 // Specialize temporary
|
Chris@16
|
2397 template <class M, class IA>
|
Chris@16
|
2398 struct vector_temporary_traits< matrix_vector_indirect<M,IA> >
|
Chris@16
|
2399 : vector_temporary_traits< M > {} ;
|
Chris@16
|
2400 template <class M, class IA>
|
Chris@16
|
2401 struct vector_temporary_traits< const matrix_vector_indirect<M,IA> >
|
Chris@16
|
2402 : vector_temporary_traits< M > {} ;
|
Chris@16
|
2403
|
Chris@16
|
2404 // Matrix based range class
|
Chris@16
|
2405 template<class M>
|
Chris@16
|
2406 class matrix_range:
|
Chris@16
|
2407 public matrix_expression<matrix_range<M> > {
|
Chris@16
|
2408
|
Chris@16
|
2409 typedef matrix_range<M> self_type;
|
Chris@16
|
2410 public:
|
Chris@16
|
2411 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
2412 using matrix_expression<self_type>::operator ();
|
Chris@16
|
2413 #endif
|
Chris@16
|
2414 typedef M matrix_type;
|
Chris@16
|
2415 typedef typename M::size_type size_type;
|
Chris@16
|
2416 typedef typename M::difference_type difference_type;
|
Chris@16
|
2417 typedef typename M::value_type value_type;
|
Chris@16
|
2418 typedef typename M::const_reference const_reference;
|
Chris@16
|
2419 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
2420 typename M::const_reference,
|
Chris@16
|
2421 typename M::reference>::type reference;
|
Chris@16
|
2422 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
2423 typename M::const_closure_type,
|
Chris@16
|
2424 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
2425 typedef basic_range<size_type, difference_type> range_type;
|
Chris@16
|
2426 typedef const self_type const_closure_type;
|
Chris@16
|
2427 typedef self_type closure_type;
|
Chris@16
|
2428 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
2429 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
2430 typedef typename M::orientation_category orientation_category;
|
Chris@16
|
2431
|
Chris@16
|
2432 // Construction and destruction
|
Chris@16
|
2433 BOOST_UBLAS_INLINE
|
Chris@16
|
2434 matrix_range (matrix_type &data, const range_type &r1, const range_type &r2):
|
Chris@16
|
2435 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
|
Chris@16
|
2436 // Early checking of preconditions here.
|
Chris@16
|
2437 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
|
Chris@16
|
2438 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
|
Chris@16
|
2439 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
|
Chris@16
|
2440 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
|
Chris@16
|
2441 }
|
Chris@16
|
2442 BOOST_UBLAS_INLINE
|
Chris@16
|
2443 matrix_range (const matrix_closure_type &data, const range_type &r1, const range_type &r2, int):
|
Chris@16
|
2444 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
|
Chris@16
|
2445 // Early checking of preconditions here.
|
Chris@16
|
2446 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
|
Chris@16
|
2447 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
|
Chris@16
|
2448 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
|
Chris@16
|
2449 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
|
Chris@16
|
2450 }
|
Chris@16
|
2451
|
Chris@16
|
2452 // Accessors
|
Chris@16
|
2453 BOOST_UBLAS_INLINE
|
Chris@16
|
2454 size_type start1 () const {
|
Chris@16
|
2455 return r1_.start ();
|
Chris@16
|
2456 }
|
Chris@16
|
2457 BOOST_UBLAS_INLINE
|
Chris@16
|
2458 size_type size1 () const {
|
Chris@16
|
2459 return r1_.size ();
|
Chris@16
|
2460 }
|
Chris@16
|
2461 BOOST_UBLAS_INLINE
|
Chris@16
|
2462 size_type start2() const {
|
Chris@16
|
2463 return r2_.start ();
|
Chris@16
|
2464 }
|
Chris@16
|
2465 BOOST_UBLAS_INLINE
|
Chris@16
|
2466 size_type size2 () const {
|
Chris@16
|
2467 return r2_.size ();
|
Chris@16
|
2468 }
|
Chris@16
|
2469
|
Chris@16
|
2470 // Storage accessors
|
Chris@16
|
2471 BOOST_UBLAS_INLINE
|
Chris@16
|
2472 const matrix_closure_type &data () const {
|
Chris@16
|
2473 return data_;
|
Chris@16
|
2474 }
|
Chris@16
|
2475 BOOST_UBLAS_INLINE
|
Chris@16
|
2476 matrix_closure_type &data () {
|
Chris@16
|
2477 return data_;
|
Chris@16
|
2478 }
|
Chris@16
|
2479
|
Chris@16
|
2480 // Element access
|
Chris@16
|
2481 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
2482 BOOST_UBLAS_INLINE
|
Chris@16
|
2483 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
2484 return data_ (r1_ (i), r2_ (j));
|
Chris@16
|
2485 }
|
Chris@16
|
2486 BOOST_UBLAS_INLINE
|
Chris@16
|
2487 reference operator () (size_type i, size_type j) {
|
Chris@16
|
2488 return data_ (r1_ (i), r2_ (j));
|
Chris@16
|
2489 }
|
Chris@16
|
2490 #else
|
Chris@16
|
2491 BOOST_UBLAS_INLINE
|
Chris@16
|
2492 reference operator () (size_type i, size_type j) const {
|
Chris@16
|
2493 return data_ (r1_ (i), r2_ (j));
|
Chris@16
|
2494 }
|
Chris@16
|
2495 #endif
|
Chris@16
|
2496
|
Chris@16
|
2497 // ISSUE can this be done in free project function?
|
Chris@16
|
2498 // Although a const function can create a non-const proxy to a non-const object
|
Chris@16
|
2499 // Critical is that matrix_type and data_ (vector_closure_type) are const correct
|
Chris@16
|
2500 BOOST_UBLAS_INLINE
|
Chris@16
|
2501 matrix_range<matrix_type> project (const range_type &r1, const range_type &r2) const {
|
Chris@16
|
2502 return matrix_range<matrix_type> (data_, r1_.compose (r1.preprocess (data_.size1 ())), r2_.compose (r2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
2503 }
|
Chris@16
|
2504
|
Chris@16
|
2505 // Assignment
|
Chris@16
|
2506 BOOST_UBLAS_INLINE
|
Chris@16
|
2507 matrix_range &operator = (const matrix_range &mr) {
|
Chris@16
|
2508 matrix_assign<scalar_assign> (*this, mr);
|
Chris@16
|
2509 return *this;
|
Chris@16
|
2510 }
|
Chris@16
|
2511 BOOST_UBLAS_INLINE
|
Chris@16
|
2512 matrix_range &assign_temporary (matrix_range &mr) {
|
Chris@16
|
2513 return *this = mr;
|
Chris@16
|
2514 }
|
Chris@16
|
2515 template<class AE>
|
Chris@16
|
2516 BOOST_UBLAS_INLINE
|
Chris@16
|
2517 matrix_range &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
2518 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
|
Chris@16
|
2519 return *this;
|
Chris@16
|
2520 }
|
Chris@16
|
2521 template<class AE>
|
Chris@16
|
2522 BOOST_UBLAS_INLINE
|
Chris@16
|
2523 matrix_range &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
2524 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
2525 return *this;
|
Chris@16
|
2526 }
|
Chris@16
|
2527 template<class AE>
|
Chris@16
|
2528 BOOST_UBLAS_INLINE
|
Chris@16
|
2529 matrix_range& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
2530 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
2531 return *this;
|
Chris@16
|
2532 }
|
Chris@16
|
2533 template<class AE>
|
Chris@16
|
2534 BOOST_UBLAS_INLINE
|
Chris@16
|
2535 matrix_range &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
2536 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
2537 return *this;
|
Chris@16
|
2538 }
|
Chris@16
|
2539 template<class AE>
|
Chris@16
|
2540 BOOST_UBLAS_INLINE
|
Chris@16
|
2541 matrix_range& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
2542 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
2543 return *this;
|
Chris@16
|
2544 }
|
Chris@16
|
2545 template<class AE>
|
Chris@16
|
2546 BOOST_UBLAS_INLINE
|
Chris@16
|
2547 matrix_range &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
2548 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
2549 return *this;
|
Chris@16
|
2550 }
|
Chris@16
|
2551 template<class AT>
|
Chris@16
|
2552 BOOST_UBLAS_INLINE
|
Chris@16
|
2553 matrix_range& operator *= (const AT &at) {
|
Chris@16
|
2554 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
2555 return *this;
|
Chris@16
|
2556 }
|
Chris@16
|
2557 template<class AT>
|
Chris@16
|
2558 BOOST_UBLAS_INLINE
|
Chris@16
|
2559 matrix_range& operator /= (const AT &at) {
|
Chris@16
|
2560 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
2561 return *this;
|
Chris@16
|
2562 }
|
Chris@16
|
2563
|
Chris@16
|
2564 // Closure comparison
|
Chris@16
|
2565 BOOST_UBLAS_INLINE
|
Chris@16
|
2566 bool same_closure (const matrix_range &mr) const {
|
Chris@16
|
2567 return (*this).data_.same_closure (mr.data_);
|
Chris@16
|
2568 }
|
Chris@16
|
2569
|
Chris@16
|
2570 // Comparison
|
Chris@16
|
2571 BOOST_UBLAS_INLINE
|
Chris@16
|
2572 bool operator == (const matrix_range &mr) const {
|
Chris@16
|
2573 return (*this).data_ == (mr.data_) && r1_ == mr.r1_ && r2_ == mr.r2_;
|
Chris@16
|
2574 }
|
Chris@16
|
2575
|
Chris@16
|
2576 // Swapping
|
Chris@16
|
2577 BOOST_UBLAS_INLINE
|
Chris@16
|
2578 void swap (matrix_range mr) {
|
Chris@16
|
2579 if (this != &mr) {
|
Chris@16
|
2580 BOOST_UBLAS_CHECK (size1 () == mr.size1 (), bad_size ());
|
Chris@16
|
2581 BOOST_UBLAS_CHECK (size2 () == mr.size2 (), bad_size ());
|
Chris@16
|
2582 matrix_swap<scalar_swap> (*this, mr);
|
Chris@16
|
2583 }
|
Chris@16
|
2584 }
|
Chris@16
|
2585 BOOST_UBLAS_INLINE
|
Chris@16
|
2586 friend void swap (matrix_range mr1, matrix_range mr2) {
|
Chris@16
|
2587 mr1.swap (mr2);
|
Chris@16
|
2588 }
|
Chris@16
|
2589
|
Chris@16
|
2590 // Iterator types
|
Chris@16
|
2591 private:
|
Chris@16
|
2592 typedef typename M::const_iterator1 const_subiterator1_type;
|
Chris@16
|
2593 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
2594 typename M::const_iterator1,
|
Chris@16
|
2595 typename M::iterator1>::type subiterator1_type;
|
Chris@16
|
2596 typedef typename M::const_iterator2 const_subiterator2_type;
|
Chris@16
|
2597 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
2598 typename M::const_iterator2,
|
Chris@16
|
2599 typename M::iterator2>::type subiterator2_type;
|
Chris@16
|
2600
|
Chris@16
|
2601 public:
|
Chris@16
|
2602 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2603 typedef indexed_iterator1<matrix_range<matrix_type>,
|
Chris@16
|
2604 typename subiterator1_type::iterator_category> iterator1;
|
Chris@16
|
2605 typedef indexed_iterator2<matrix_range<matrix_type>,
|
Chris@16
|
2606 typename subiterator2_type::iterator_category> iterator2;
|
Chris@16
|
2607 typedef indexed_const_iterator1<matrix_range<matrix_type>,
|
Chris@16
|
2608 typename const_subiterator1_type::iterator_category> const_iterator1;
|
Chris@16
|
2609 typedef indexed_const_iterator2<matrix_range<matrix_type>,
|
Chris@16
|
2610 typename const_subiterator2_type::iterator_category> const_iterator2;
|
Chris@16
|
2611 #else
|
Chris@16
|
2612 class const_iterator1;
|
Chris@16
|
2613 class iterator1;
|
Chris@16
|
2614 class const_iterator2;
|
Chris@16
|
2615 class iterator2;
|
Chris@16
|
2616 #endif
|
Chris@16
|
2617 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
2618 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
2619 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
2620 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
2621
|
Chris@16
|
2622 // Element lookup
|
Chris@16
|
2623 BOOST_UBLAS_INLINE
|
Chris@16
|
2624 const_iterator1 find1 (int rank, size_type i, size_type j) const {
|
Chris@16
|
2625 const_subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j));
|
Chris@16
|
2626 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2627 return const_iterator1 (*this, it1.index1 (), it1.index2 ());
|
Chris@16
|
2628 #else
|
Chris@16
|
2629 return const_iterator1 (*this, it1);
|
Chris@16
|
2630 #endif
|
Chris@16
|
2631 }
|
Chris@16
|
2632 BOOST_UBLAS_INLINE
|
Chris@16
|
2633 iterator1 find1 (int rank, size_type i, size_type j) {
|
Chris@16
|
2634 subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j));
|
Chris@16
|
2635 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2636 return iterator1 (*this, it1.index1 (), it1.index2 ());
|
Chris@16
|
2637 #else
|
Chris@16
|
2638 return iterator1 (*this, it1);
|
Chris@16
|
2639 #endif
|
Chris@16
|
2640 }
|
Chris@16
|
2641 BOOST_UBLAS_INLINE
|
Chris@16
|
2642 const_iterator2 find2 (int rank, size_type i, size_type j) const {
|
Chris@16
|
2643 const_subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j));
|
Chris@16
|
2644 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2645 return const_iterator2 (*this, it2.index1 (), it2.index2 ());
|
Chris@16
|
2646 #else
|
Chris@16
|
2647 return const_iterator2 (*this, it2);
|
Chris@16
|
2648 #endif
|
Chris@16
|
2649 }
|
Chris@16
|
2650 BOOST_UBLAS_INLINE
|
Chris@16
|
2651 iterator2 find2 (int rank, size_type i, size_type j) {
|
Chris@16
|
2652 subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j));
|
Chris@16
|
2653 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2654 return iterator2 (*this, it2.index1 (), it2.index2 ());
|
Chris@16
|
2655 #else
|
Chris@16
|
2656 return iterator2 (*this, it2);
|
Chris@16
|
2657 #endif
|
Chris@16
|
2658 }
|
Chris@16
|
2659
|
Chris@16
|
2660
|
Chris@16
|
2661 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2662 class const_iterator1:
|
Chris@16
|
2663 public container_const_reference<matrix_range>,
|
Chris@16
|
2664 public iterator_base_traits<typename const_subiterator1_type::iterator_category>::template
|
Chris@16
|
2665 iterator_base<const_iterator1, value_type>::type {
|
Chris@16
|
2666 public:
|
Chris@16
|
2667 typedef typename const_subiterator1_type::value_type value_type;
|
Chris@16
|
2668 typedef typename const_subiterator1_type::difference_type difference_type;
|
Chris@16
|
2669 typedef typename const_subiterator1_type::reference reference;
|
Chris@16
|
2670 typedef typename const_subiterator1_type::pointer pointer;
|
Chris@16
|
2671 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
2672 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
2673
|
Chris@16
|
2674 // Construction and destruction
|
Chris@16
|
2675 BOOST_UBLAS_INLINE
|
Chris@16
|
2676 const_iterator1 ():
|
Chris@16
|
2677 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
2678 BOOST_UBLAS_INLINE
|
Chris@16
|
2679 const_iterator1 (const self_type &mr, const const_subiterator1_type &it):
|
Chris@16
|
2680 container_const_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
2681 BOOST_UBLAS_INLINE
|
Chris@16
|
2682 const_iterator1 (const iterator1 &it):
|
Chris@16
|
2683 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
2684
|
Chris@16
|
2685 // Arithmetic
|
Chris@16
|
2686 BOOST_UBLAS_INLINE
|
Chris@16
|
2687 const_iterator1 &operator ++ () {
|
Chris@16
|
2688 ++ it_;
|
Chris@16
|
2689 return *this;
|
Chris@16
|
2690 }
|
Chris@16
|
2691 BOOST_UBLAS_INLINE
|
Chris@16
|
2692 const_iterator1 &operator -- () {
|
Chris@16
|
2693 -- it_;
|
Chris@16
|
2694 return *this;
|
Chris@16
|
2695 }
|
Chris@16
|
2696 BOOST_UBLAS_INLINE
|
Chris@16
|
2697 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
2698 it_ += n;
|
Chris@16
|
2699 return *this;
|
Chris@16
|
2700 }
|
Chris@16
|
2701 BOOST_UBLAS_INLINE
|
Chris@16
|
2702 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
2703 it_ -= n;
|
Chris@16
|
2704 return *this;
|
Chris@16
|
2705 }
|
Chris@16
|
2706 BOOST_UBLAS_INLINE
|
Chris@16
|
2707 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
2708 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2709 return it_ - it.it_;
|
Chris@16
|
2710 }
|
Chris@16
|
2711
|
Chris@16
|
2712 // Dereference
|
Chris@16
|
2713 BOOST_UBLAS_INLINE
|
Chris@16
|
2714 const_reference operator * () const {
|
Chris@16
|
2715 return *it_;
|
Chris@16
|
2716 }
|
Chris@16
|
2717 BOOST_UBLAS_INLINE
|
Chris@16
|
2718 const_reference operator [] (difference_type n) const {
|
Chris@16
|
2719 return *(*this + n);
|
Chris@16
|
2720 }
|
Chris@16
|
2721
|
Chris@16
|
2722 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2723 BOOST_UBLAS_INLINE
|
Chris@16
|
2724 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2725 typename self_type::
|
Chris@16
|
2726 #endif
|
Chris@16
|
2727 const_iterator2 begin () const {
|
Chris@16
|
2728 const self_type &mr = (*this) ();
|
Chris@16
|
2729 return mr.find2 (1, index1 (), 0);
|
Chris@16
|
2730 }
|
Chris@16
|
2731 BOOST_UBLAS_INLINE
|
Chris@16
|
2732 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2733 typename self_type::
|
Chris@16
|
2734 #endif
|
Chris@101
|
2735 const_iterator2 cbegin () const {
|
Chris@101
|
2736 return begin ();
|
Chris@101
|
2737 }
|
Chris@101
|
2738 BOOST_UBLAS_INLINE
|
Chris@101
|
2739 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
2740 typename self_type::
|
Chris@101
|
2741 #endif
|
Chris@16
|
2742 const_iterator2 end () const {
|
Chris@16
|
2743 const self_type &mr = (*this) ();
|
Chris@16
|
2744 return mr.find2 (1, index1 (), mr.size2 ());
|
Chris@16
|
2745 }
|
Chris@16
|
2746 BOOST_UBLAS_INLINE
|
Chris@16
|
2747 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2748 typename self_type::
|
Chris@16
|
2749 #endif
|
Chris@101
|
2750 const_iterator2 cend () const {
|
Chris@101
|
2751 return end ();
|
Chris@101
|
2752 }
|
Chris@101
|
2753 BOOST_UBLAS_INLINE
|
Chris@101
|
2754 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
2755 typename self_type::
|
Chris@101
|
2756 #endif
|
Chris@16
|
2757 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
2758 return const_reverse_iterator2 (end ());
|
Chris@16
|
2759 }
|
Chris@16
|
2760 BOOST_UBLAS_INLINE
|
Chris@16
|
2761 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2762 typename self_type::
|
Chris@16
|
2763 #endif
|
Chris@101
|
2764 const_reverse_iterator2 crbegin () const {
|
Chris@101
|
2765 return rbegin ();
|
Chris@101
|
2766 }
|
Chris@101
|
2767 BOOST_UBLAS_INLINE
|
Chris@101
|
2768 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
2769 typename self_type::
|
Chris@101
|
2770 #endif
|
Chris@16
|
2771 const_reverse_iterator2 rend () const {
|
Chris@16
|
2772 return const_reverse_iterator2 (begin ());
|
Chris@16
|
2773 }
|
Chris@101
|
2774 BOOST_UBLAS_INLINE
|
Chris@101
|
2775 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
2776 typename self_type::
|
Chris@101
|
2777 #endif
|
Chris@101
|
2778 const_reverse_iterator2 crend () const {
|
Chris@101
|
2779 return rend ();
|
Chris@101
|
2780 }
|
Chris@16
|
2781 #endif
|
Chris@16
|
2782
|
Chris@16
|
2783 // Indices
|
Chris@16
|
2784 BOOST_UBLAS_INLINE
|
Chris@16
|
2785 size_type index1 () const {
|
Chris@16
|
2786 return it_.index1 () - (*this) ().start1 ();
|
Chris@16
|
2787 }
|
Chris@16
|
2788 BOOST_UBLAS_INLINE
|
Chris@16
|
2789 size_type index2 () const {
|
Chris@16
|
2790 return it_.index2 () - (*this) ().start2 ();
|
Chris@16
|
2791 }
|
Chris@16
|
2792
|
Chris@16
|
2793 // Assignment
|
Chris@16
|
2794 BOOST_UBLAS_INLINE
|
Chris@16
|
2795 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
2796 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
2797 it_ = it.it_;
|
Chris@16
|
2798 return *this;
|
Chris@16
|
2799 }
|
Chris@16
|
2800
|
Chris@16
|
2801 // Comparison
|
Chris@16
|
2802 BOOST_UBLAS_INLINE
|
Chris@16
|
2803 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
2804 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2805 return it_ == it.it_;
|
Chris@16
|
2806 }
|
Chris@16
|
2807 BOOST_UBLAS_INLINE
|
Chris@16
|
2808 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
2809 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2810 return it_ < it.it_;
|
Chris@16
|
2811 }
|
Chris@16
|
2812
|
Chris@16
|
2813 private:
|
Chris@16
|
2814 const_subiterator1_type it_;
|
Chris@16
|
2815 };
|
Chris@16
|
2816 #endif
|
Chris@16
|
2817
|
Chris@16
|
2818 BOOST_UBLAS_INLINE
|
Chris@16
|
2819 const_iterator1 begin1 () const {
|
Chris@16
|
2820 return find1 (0, 0, 0);
|
Chris@16
|
2821 }
|
Chris@16
|
2822 BOOST_UBLAS_INLINE
|
Chris@101
|
2823 const_iterator1 cbegin1 () const {
|
Chris@101
|
2824 return begin1 ();
|
Chris@101
|
2825 }
|
Chris@101
|
2826 BOOST_UBLAS_INLINE
|
Chris@16
|
2827 const_iterator1 end1 () const {
|
Chris@16
|
2828 return find1 (0, size1 (), 0);
|
Chris@16
|
2829 }
|
Chris@101
|
2830 BOOST_UBLAS_INLINE
|
Chris@101
|
2831 const_iterator1 cend1 () const {
|
Chris@101
|
2832 return end1 ();
|
Chris@101
|
2833 }
|
Chris@16
|
2834
|
Chris@16
|
2835 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2836 class iterator1:
|
Chris@16
|
2837 public container_reference<matrix_range>,
|
Chris@16
|
2838 public iterator_base_traits<typename subiterator1_type::iterator_category>::template
|
Chris@16
|
2839 iterator_base<iterator1, value_type>::type {
|
Chris@16
|
2840 public:
|
Chris@16
|
2841 typedef typename subiterator1_type::value_type value_type;
|
Chris@16
|
2842 typedef typename subiterator1_type::difference_type difference_type;
|
Chris@16
|
2843 typedef typename subiterator1_type::reference reference;
|
Chris@16
|
2844 typedef typename subiterator1_type::pointer pointer;
|
Chris@16
|
2845 typedef iterator2 dual_iterator_type;
|
Chris@16
|
2846 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
2847
|
Chris@16
|
2848 // Construction and destruction
|
Chris@16
|
2849 BOOST_UBLAS_INLINE
|
Chris@16
|
2850 iterator1 ():
|
Chris@16
|
2851 container_reference<self_type> (), it_ () {}
|
Chris@16
|
2852 BOOST_UBLAS_INLINE
|
Chris@16
|
2853 iterator1 (self_type &mr, const subiterator1_type &it):
|
Chris@16
|
2854 container_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
2855
|
Chris@16
|
2856 // Arithmetic
|
Chris@16
|
2857 BOOST_UBLAS_INLINE
|
Chris@16
|
2858 iterator1 &operator ++ () {
|
Chris@16
|
2859 ++ it_;
|
Chris@16
|
2860 return *this;
|
Chris@16
|
2861 }
|
Chris@16
|
2862 BOOST_UBLAS_INLINE
|
Chris@16
|
2863 iterator1 &operator -- () {
|
Chris@16
|
2864 -- it_;
|
Chris@16
|
2865 return *this;
|
Chris@16
|
2866 }
|
Chris@16
|
2867 BOOST_UBLAS_INLINE
|
Chris@16
|
2868 iterator1 &operator += (difference_type n) {
|
Chris@16
|
2869 it_ += n;
|
Chris@16
|
2870 return *this;
|
Chris@16
|
2871 }
|
Chris@16
|
2872 BOOST_UBLAS_INLINE
|
Chris@16
|
2873 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
2874 it_ -= n;
|
Chris@16
|
2875 return *this;
|
Chris@16
|
2876 }
|
Chris@16
|
2877 BOOST_UBLAS_INLINE
|
Chris@16
|
2878 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
2879 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2880 return it_ - it.it_;
|
Chris@16
|
2881 }
|
Chris@16
|
2882
|
Chris@16
|
2883 // Dereference
|
Chris@16
|
2884 BOOST_UBLAS_INLINE
|
Chris@16
|
2885 reference operator * () const {
|
Chris@16
|
2886 return *it_;
|
Chris@16
|
2887 }
|
Chris@16
|
2888 BOOST_UBLAS_INLINE
|
Chris@16
|
2889 reference operator [] (difference_type n) const {
|
Chris@16
|
2890 return *(*this + n);
|
Chris@16
|
2891 }
|
Chris@16
|
2892
|
Chris@16
|
2893 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
2894 BOOST_UBLAS_INLINE
|
Chris@16
|
2895 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2896 typename self_type::
|
Chris@16
|
2897 #endif
|
Chris@16
|
2898 iterator2 begin () const {
|
Chris@16
|
2899 self_type &mr = (*this) ();
|
Chris@16
|
2900 return mr.find2 (1, index1 (), 0);
|
Chris@16
|
2901 }
|
Chris@16
|
2902 BOOST_UBLAS_INLINE
|
Chris@16
|
2903 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2904 typename self_type::
|
Chris@16
|
2905 #endif
|
Chris@16
|
2906 iterator2 end () const {
|
Chris@16
|
2907 self_type &mr = (*this) ();
|
Chris@16
|
2908 return mr.find2 (1, index1 (), mr.size2 ());
|
Chris@16
|
2909 }
|
Chris@16
|
2910 BOOST_UBLAS_INLINE
|
Chris@16
|
2911 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2912 typename self_type::
|
Chris@16
|
2913 #endif
|
Chris@16
|
2914 reverse_iterator2 rbegin () const {
|
Chris@16
|
2915 return reverse_iterator2 (end ());
|
Chris@16
|
2916 }
|
Chris@16
|
2917 BOOST_UBLAS_INLINE
|
Chris@16
|
2918 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
2919 typename self_type::
|
Chris@16
|
2920 #endif
|
Chris@16
|
2921 reverse_iterator2 rend () const {
|
Chris@16
|
2922 return reverse_iterator2 (begin ());
|
Chris@16
|
2923 }
|
Chris@16
|
2924 #endif
|
Chris@16
|
2925
|
Chris@16
|
2926 // Indices
|
Chris@16
|
2927 BOOST_UBLAS_INLINE
|
Chris@16
|
2928 size_type index1 () const {
|
Chris@16
|
2929 return it_.index1 () - (*this) ().start1 ();
|
Chris@16
|
2930 }
|
Chris@16
|
2931 BOOST_UBLAS_INLINE
|
Chris@16
|
2932 size_type index2 () const {
|
Chris@16
|
2933 return it_.index2 () - (*this) ().start2 ();
|
Chris@16
|
2934 }
|
Chris@16
|
2935
|
Chris@16
|
2936 // Assignment
|
Chris@16
|
2937 BOOST_UBLAS_INLINE
|
Chris@16
|
2938 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
2939 container_reference<self_type>::assign (&it ());
|
Chris@16
|
2940 it_ = it.it_;
|
Chris@16
|
2941 return *this;
|
Chris@16
|
2942 }
|
Chris@16
|
2943
|
Chris@16
|
2944 // Comparison
|
Chris@16
|
2945 BOOST_UBLAS_INLINE
|
Chris@16
|
2946 bool operator == (const iterator1 &it) const {
|
Chris@16
|
2947 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2948 return it_ == it.it_;
|
Chris@16
|
2949 }
|
Chris@16
|
2950 BOOST_UBLAS_INLINE
|
Chris@16
|
2951 bool operator < (const iterator1 &it) const {
|
Chris@16
|
2952 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
2953 return it_ < it.it_;
|
Chris@16
|
2954 }
|
Chris@16
|
2955
|
Chris@16
|
2956 private:
|
Chris@16
|
2957 subiterator1_type it_;
|
Chris@16
|
2958
|
Chris@16
|
2959 friend class const_iterator1;
|
Chris@16
|
2960 };
|
Chris@16
|
2961 #endif
|
Chris@16
|
2962
|
Chris@16
|
2963 BOOST_UBLAS_INLINE
|
Chris@16
|
2964 iterator1 begin1 () {
|
Chris@16
|
2965 return find1 (0, 0, 0);
|
Chris@16
|
2966 }
|
Chris@16
|
2967 BOOST_UBLAS_INLINE
|
Chris@16
|
2968 iterator1 end1 () {
|
Chris@16
|
2969 return find1 (0, size1 (), 0);
|
Chris@16
|
2970 }
|
Chris@16
|
2971
|
Chris@16
|
2972 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
2973 class const_iterator2:
|
Chris@16
|
2974 public container_const_reference<matrix_range>,
|
Chris@16
|
2975 public iterator_base_traits<typename const_subiterator2_type::iterator_category>::template
|
Chris@16
|
2976 iterator_base<const_iterator2, value_type>::type {
|
Chris@16
|
2977 public:
|
Chris@16
|
2978 typedef typename const_subiterator2_type::value_type value_type;
|
Chris@16
|
2979 typedef typename const_subiterator2_type::difference_type difference_type;
|
Chris@16
|
2980 typedef typename const_subiterator2_type::reference reference;
|
Chris@16
|
2981 typedef typename const_subiterator2_type::pointer pointer;
|
Chris@16
|
2982 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
2983 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
2984
|
Chris@16
|
2985 // Construction and destruction
|
Chris@16
|
2986 BOOST_UBLAS_INLINE
|
Chris@16
|
2987 const_iterator2 ():
|
Chris@16
|
2988 container_const_reference<self_type> (), it_ () {}
|
Chris@16
|
2989 BOOST_UBLAS_INLINE
|
Chris@16
|
2990 const_iterator2 (const self_type &mr, const const_subiterator2_type &it):
|
Chris@16
|
2991 container_const_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
2992 BOOST_UBLAS_INLINE
|
Chris@16
|
2993 const_iterator2 (const iterator2 &it):
|
Chris@16
|
2994 container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
Chris@16
|
2995
|
Chris@16
|
2996 // Arithmetic
|
Chris@16
|
2997 BOOST_UBLAS_INLINE
|
Chris@16
|
2998 const_iterator2 &operator ++ () {
|
Chris@16
|
2999 ++ it_;
|
Chris@16
|
3000 return *this;
|
Chris@16
|
3001 }
|
Chris@16
|
3002 BOOST_UBLAS_INLINE
|
Chris@16
|
3003 const_iterator2 &operator -- () {
|
Chris@16
|
3004 -- it_;
|
Chris@16
|
3005 return *this;
|
Chris@16
|
3006 }
|
Chris@16
|
3007 BOOST_UBLAS_INLINE
|
Chris@16
|
3008 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
3009 it_ += n;
|
Chris@16
|
3010 return *this;
|
Chris@16
|
3011 }
|
Chris@16
|
3012 BOOST_UBLAS_INLINE
|
Chris@16
|
3013 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
3014 it_ -= n;
|
Chris@16
|
3015 return *this;
|
Chris@16
|
3016 }
|
Chris@16
|
3017 BOOST_UBLAS_INLINE
|
Chris@16
|
3018 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
3019 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3020 return it_ - it.it_;
|
Chris@16
|
3021 }
|
Chris@16
|
3022
|
Chris@16
|
3023 // Dereference
|
Chris@16
|
3024 BOOST_UBLAS_INLINE
|
Chris@16
|
3025 const_reference operator * () const {
|
Chris@16
|
3026 return *it_;
|
Chris@16
|
3027 }
|
Chris@16
|
3028 BOOST_UBLAS_INLINE
|
Chris@16
|
3029 const_reference operator [] (difference_type n) const {
|
Chris@16
|
3030 return *(*this + n);
|
Chris@16
|
3031 }
|
Chris@16
|
3032
|
Chris@16
|
3033 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3034 BOOST_UBLAS_INLINE
|
Chris@16
|
3035 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3036 typename self_type::
|
Chris@16
|
3037 #endif
|
Chris@16
|
3038 const_iterator1 begin () const {
|
Chris@16
|
3039 const self_type &mr = (*this) ();
|
Chris@16
|
3040 return mr.find1 (1, 0, index2 ());
|
Chris@16
|
3041 }
|
Chris@16
|
3042 BOOST_UBLAS_INLINE
|
Chris@16
|
3043 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3044 typename self_type::
|
Chris@16
|
3045 #endif
|
Chris@101
|
3046 const_iterator1 cbegin () const {
|
Chris@101
|
3047 return begin ();
|
Chris@101
|
3048 }
|
Chris@101
|
3049 BOOST_UBLAS_INLINE
|
Chris@101
|
3050 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3051 typename self_type::
|
Chris@101
|
3052 #endif
|
Chris@16
|
3053 const_iterator1 end () const {
|
Chris@16
|
3054 const self_type &mr = (*this) ();
|
Chris@16
|
3055 return mr.find1 (1, mr.size1 (), index2 ());
|
Chris@16
|
3056 }
|
Chris@16
|
3057 BOOST_UBLAS_INLINE
|
Chris@16
|
3058 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3059 typename self_type::
|
Chris@16
|
3060 #endif
|
Chris@101
|
3061 const_iterator1 cend () const {
|
Chris@101
|
3062 return end ();
|
Chris@101
|
3063 }
|
Chris@101
|
3064 BOOST_UBLAS_INLINE
|
Chris@101
|
3065 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3066 typename self_type::
|
Chris@101
|
3067 #endif
|
Chris@16
|
3068 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
3069 return const_reverse_iterator1 (end ());
|
Chris@16
|
3070 }
|
Chris@16
|
3071 BOOST_UBLAS_INLINE
|
Chris@16
|
3072 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3073 typename self_type::
|
Chris@16
|
3074 #endif
|
Chris@101
|
3075 const_reverse_iterator1 crbegin () const {
|
Chris@101
|
3076 return rbegin ();
|
Chris@101
|
3077 }
|
Chris@101
|
3078 BOOST_UBLAS_INLINE
|
Chris@101
|
3079 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3080 typename self_type::
|
Chris@101
|
3081 #endif
|
Chris@16
|
3082 const_reverse_iterator1 rend () const {
|
Chris@16
|
3083 return const_reverse_iterator1 (begin ());
|
Chris@16
|
3084 }
|
Chris@101
|
3085 BOOST_UBLAS_INLINE
|
Chris@101
|
3086 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3087 typename self_type::
|
Chris@101
|
3088 #endif
|
Chris@101
|
3089 const_reverse_iterator1 crend () const {
|
Chris@101
|
3090 return rend ();
|
Chris@101
|
3091 }
|
Chris@16
|
3092 #endif
|
Chris@16
|
3093
|
Chris@16
|
3094 // Indices
|
Chris@16
|
3095 BOOST_UBLAS_INLINE
|
Chris@16
|
3096 size_type index1 () const {
|
Chris@16
|
3097 return it_.index1 () - (*this) ().start1 ();
|
Chris@16
|
3098 }
|
Chris@16
|
3099 BOOST_UBLAS_INLINE
|
Chris@16
|
3100 size_type index2 () const {
|
Chris@16
|
3101 return it_.index2 () - (*this) ().start2 ();
|
Chris@16
|
3102 }
|
Chris@16
|
3103
|
Chris@16
|
3104 // Assignment
|
Chris@16
|
3105 BOOST_UBLAS_INLINE
|
Chris@16
|
3106 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
3107 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
3108 it_ = it.it_;
|
Chris@16
|
3109 return *this;
|
Chris@16
|
3110 }
|
Chris@16
|
3111
|
Chris@16
|
3112 // Comparison
|
Chris@16
|
3113 BOOST_UBLAS_INLINE
|
Chris@16
|
3114 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
3115 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3116 return it_ == it.it_;
|
Chris@16
|
3117 }
|
Chris@16
|
3118 BOOST_UBLAS_INLINE
|
Chris@16
|
3119 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
3120 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3121 return it_ < it.it_;
|
Chris@16
|
3122 }
|
Chris@16
|
3123
|
Chris@16
|
3124 private:
|
Chris@16
|
3125 const_subiterator2_type it_;
|
Chris@16
|
3126 };
|
Chris@16
|
3127 #endif
|
Chris@16
|
3128
|
Chris@16
|
3129 BOOST_UBLAS_INLINE
|
Chris@16
|
3130 const_iterator2 begin2 () const {
|
Chris@16
|
3131 return find2 (0, 0, 0);
|
Chris@16
|
3132 }
|
Chris@16
|
3133 BOOST_UBLAS_INLINE
|
Chris@101
|
3134 const_iterator2 cbegin2 () const {
|
Chris@101
|
3135 return begin2 ();
|
Chris@101
|
3136 }
|
Chris@101
|
3137 BOOST_UBLAS_INLINE
|
Chris@16
|
3138 const_iterator2 end2 () const {
|
Chris@16
|
3139 return find2 (0, 0, size2 ());
|
Chris@16
|
3140 }
|
Chris@101
|
3141 BOOST_UBLAS_INLINE
|
Chris@101
|
3142 const_iterator2 cend2 () const {
|
Chris@101
|
3143 return end2 ();
|
Chris@101
|
3144 }
|
Chris@16
|
3145
|
Chris@16
|
3146 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3147 class iterator2:
|
Chris@16
|
3148 public container_reference<matrix_range>,
|
Chris@16
|
3149 public iterator_base_traits<typename subiterator2_type::iterator_category>::template
|
Chris@16
|
3150 iterator_base<iterator2, value_type>::type {
|
Chris@16
|
3151 public:
|
Chris@16
|
3152 typedef typename subiterator2_type::value_type value_type;
|
Chris@16
|
3153 typedef typename subiterator2_type::difference_type difference_type;
|
Chris@16
|
3154 typedef typename subiterator2_type::reference reference;
|
Chris@16
|
3155 typedef typename subiterator2_type::pointer pointer;
|
Chris@16
|
3156 typedef iterator1 dual_iterator_type;
|
Chris@16
|
3157 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
3158
|
Chris@16
|
3159 // Construction and destruction
|
Chris@16
|
3160 BOOST_UBLAS_INLINE
|
Chris@16
|
3161 iterator2 ():
|
Chris@16
|
3162 container_reference<self_type> (), it_ () {}
|
Chris@16
|
3163 BOOST_UBLAS_INLINE
|
Chris@16
|
3164 iterator2 (self_type &mr, const subiterator2_type &it):
|
Chris@16
|
3165 container_reference<self_type> (mr), it_ (it) {}
|
Chris@16
|
3166
|
Chris@16
|
3167 // Arithmetic
|
Chris@16
|
3168 BOOST_UBLAS_INLINE
|
Chris@16
|
3169 iterator2 &operator ++ () {
|
Chris@16
|
3170 ++ it_;
|
Chris@16
|
3171 return *this;
|
Chris@16
|
3172 }
|
Chris@16
|
3173 BOOST_UBLAS_INLINE
|
Chris@16
|
3174 iterator2 &operator -- () {
|
Chris@16
|
3175 -- it_;
|
Chris@16
|
3176 return *this;
|
Chris@16
|
3177 }
|
Chris@16
|
3178 BOOST_UBLAS_INLINE
|
Chris@16
|
3179 iterator2 &operator += (difference_type n) {
|
Chris@16
|
3180 it_ += n;
|
Chris@16
|
3181 return *this;
|
Chris@16
|
3182 }
|
Chris@16
|
3183 BOOST_UBLAS_INLINE
|
Chris@16
|
3184 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
3185 it_ -= n;
|
Chris@16
|
3186 return *this;
|
Chris@16
|
3187 }
|
Chris@16
|
3188 BOOST_UBLAS_INLINE
|
Chris@16
|
3189 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
3190 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3191 return it_ - it.it_;
|
Chris@16
|
3192 }
|
Chris@16
|
3193
|
Chris@16
|
3194 // Dereference
|
Chris@16
|
3195 BOOST_UBLAS_INLINE
|
Chris@16
|
3196 reference operator * () const {
|
Chris@16
|
3197 return *it_;
|
Chris@16
|
3198 }
|
Chris@16
|
3199 BOOST_UBLAS_INLINE
|
Chris@16
|
3200 reference operator [] (difference_type n) const {
|
Chris@16
|
3201 return *(*this + n);
|
Chris@16
|
3202 }
|
Chris@16
|
3203
|
Chris@16
|
3204 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3205 BOOST_UBLAS_INLINE
|
Chris@16
|
3206 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3207 typename self_type::
|
Chris@16
|
3208 #endif
|
Chris@16
|
3209 iterator1 begin () const {
|
Chris@16
|
3210 self_type &mr = (*this) ();
|
Chris@16
|
3211 return mr.find1 (1, 0, index2 ());
|
Chris@16
|
3212 }
|
Chris@16
|
3213 BOOST_UBLAS_INLINE
|
Chris@16
|
3214 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3215 typename self_type::
|
Chris@16
|
3216 #endif
|
Chris@16
|
3217 iterator1 end () const {
|
Chris@16
|
3218 self_type &mr = (*this) ();
|
Chris@16
|
3219 return mr.find1 (1, mr.size1 (), index2 ());
|
Chris@16
|
3220 }
|
Chris@16
|
3221 BOOST_UBLAS_INLINE
|
Chris@16
|
3222 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3223 typename self_type::
|
Chris@16
|
3224 #endif
|
Chris@16
|
3225 reverse_iterator1 rbegin () const {
|
Chris@16
|
3226 return reverse_iterator1 (end ());
|
Chris@16
|
3227 }
|
Chris@16
|
3228 BOOST_UBLAS_INLINE
|
Chris@16
|
3229 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3230 typename self_type::
|
Chris@16
|
3231 #endif
|
Chris@16
|
3232 reverse_iterator1 rend () const {
|
Chris@16
|
3233 return reverse_iterator1 (begin ());
|
Chris@16
|
3234 }
|
Chris@16
|
3235 #endif
|
Chris@16
|
3236
|
Chris@16
|
3237 // Indices
|
Chris@16
|
3238 BOOST_UBLAS_INLINE
|
Chris@16
|
3239 size_type index1 () const {
|
Chris@16
|
3240 return it_.index1 () - (*this) ().start1 ();
|
Chris@16
|
3241 }
|
Chris@16
|
3242 BOOST_UBLAS_INLINE
|
Chris@16
|
3243 size_type index2 () const {
|
Chris@16
|
3244 return it_.index2 () - (*this) ().start2 ();
|
Chris@16
|
3245 }
|
Chris@16
|
3246
|
Chris@16
|
3247 // Assignment
|
Chris@16
|
3248 BOOST_UBLAS_INLINE
|
Chris@16
|
3249 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
3250 container_reference<self_type>::assign (&it ());
|
Chris@16
|
3251 it_ = it.it_;
|
Chris@16
|
3252 return *this;
|
Chris@16
|
3253 }
|
Chris@16
|
3254
|
Chris@16
|
3255 // Comparison
|
Chris@16
|
3256 BOOST_UBLAS_INLINE
|
Chris@16
|
3257 bool operator == (const iterator2 &it) const {
|
Chris@16
|
3258 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3259 return it_ == it.it_;
|
Chris@16
|
3260 }
|
Chris@16
|
3261 BOOST_UBLAS_INLINE
|
Chris@16
|
3262 bool operator < (const iterator2 &it) const {
|
Chris@16
|
3263 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3264 return it_ < it.it_;
|
Chris@16
|
3265 }
|
Chris@16
|
3266
|
Chris@16
|
3267 private:
|
Chris@16
|
3268 subiterator2_type it_;
|
Chris@16
|
3269
|
Chris@16
|
3270 friend class const_iterator2;
|
Chris@16
|
3271 };
|
Chris@16
|
3272 #endif
|
Chris@16
|
3273
|
Chris@16
|
3274 BOOST_UBLAS_INLINE
|
Chris@16
|
3275 iterator2 begin2 () {
|
Chris@16
|
3276 return find2 (0, 0, 0);
|
Chris@16
|
3277 }
|
Chris@16
|
3278 BOOST_UBLAS_INLINE
|
Chris@16
|
3279 iterator2 end2 () {
|
Chris@16
|
3280 return find2 (0, 0, size2 ());
|
Chris@16
|
3281 }
|
Chris@16
|
3282
|
Chris@16
|
3283 // Reverse iterators
|
Chris@16
|
3284
|
Chris@16
|
3285 BOOST_UBLAS_INLINE
|
Chris@16
|
3286 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
3287 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
3288 }
|
Chris@16
|
3289 BOOST_UBLAS_INLINE
|
Chris@101
|
3290 const_reverse_iterator1 crbegin1 () const {
|
Chris@101
|
3291 return rbegin1 ();
|
Chris@101
|
3292 }
|
Chris@101
|
3293 BOOST_UBLAS_INLINE
|
Chris@16
|
3294 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
3295 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
3296 }
|
Chris@101
|
3297 BOOST_UBLAS_INLINE
|
Chris@101
|
3298 const_reverse_iterator1 crend1 () const {
|
Chris@101
|
3299 return rend1 ();
|
Chris@101
|
3300 }
|
Chris@16
|
3301
|
Chris@16
|
3302 BOOST_UBLAS_INLINE
|
Chris@16
|
3303 reverse_iterator1 rbegin1 () {
|
Chris@16
|
3304 return reverse_iterator1 (end1 ());
|
Chris@16
|
3305 }
|
Chris@16
|
3306 BOOST_UBLAS_INLINE
|
Chris@16
|
3307 reverse_iterator1 rend1 () {
|
Chris@16
|
3308 return reverse_iterator1 (begin1 ());
|
Chris@16
|
3309 }
|
Chris@16
|
3310
|
Chris@16
|
3311 BOOST_UBLAS_INLINE
|
Chris@16
|
3312 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
3313 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
3314 }
|
Chris@16
|
3315 BOOST_UBLAS_INLINE
|
Chris@101
|
3316 const_reverse_iterator2 crbegin2 () const {
|
Chris@101
|
3317 return rbegin2 ();
|
Chris@101
|
3318 }
|
Chris@101
|
3319 BOOST_UBLAS_INLINE
|
Chris@16
|
3320 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
3321 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
3322 }
|
Chris@101
|
3323 BOOST_UBLAS_INLINE
|
Chris@101
|
3324 const_reverse_iterator2 crend2 () const {
|
Chris@101
|
3325 return rend2 ();
|
Chris@101
|
3326 }
|
Chris@16
|
3327
|
Chris@16
|
3328 BOOST_UBLAS_INLINE
|
Chris@16
|
3329 reverse_iterator2 rbegin2 () {
|
Chris@16
|
3330 return reverse_iterator2 (end2 ());
|
Chris@16
|
3331 }
|
Chris@16
|
3332 BOOST_UBLAS_INLINE
|
Chris@16
|
3333 reverse_iterator2 rend2 () {
|
Chris@16
|
3334 return reverse_iterator2 (begin2 ());
|
Chris@16
|
3335 }
|
Chris@16
|
3336
|
Chris@16
|
3337 private:
|
Chris@16
|
3338 matrix_closure_type data_;
|
Chris@16
|
3339 range_type r1_;
|
Chris@16
|
3340 range_type r2_;
|
Chris@16
|
3341 };
|
Chris@16
|
3342
|
Chris@16
|
3343 // Simple Projections
|
Chris@16
|
3344 template<class M>
|
Chris@16
|
3345 BOOST_UBLAS_INLINE
|
Chris@16
|
3346 matrix_range<M> subrange (M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) {
|
Chris@16
|
3347 typedef basic_range<typename M::size_type, typename M::difference_type> range_type;
|
Chris@16
|
3348 return matrix_range<M> (data, range_type (start1, stop1), range_type (start2, stop2));
|
Chris@16
|
3349 }
|
Chris@16
|
3350 template<class M>
|
Chris@16
|
3351 BOOST_UBLAS_INLINE
|
Chris@16
|
3352 matrix_range<const M> subrange (const M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) {
|
Chris@16
|
3353 typedef basic_range<typename M::size_type, typename M::difference_type> range_type;
|
Chris@16
|
3354 return matrix_range<const M> (data, range_type (start1, stop1), range_type (start2, stop2));
|
Chris@16
|
3355 }
|
Chris@16
|
3356
|
Chris@16
|
3357 // Generic Projections
|
Chris@16
|
3358 template<class M>
|
Chris@16
|
3359 BOOST_UBLAS_INLINE
|
Chris@16
|
3360 matrix_range<M> project (M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
3361 return matrix_range<M> (data, r1, r2);
|
Chris@16
|
3362 }
|
Chris@16
|
3363 template<class M>
|
Chris@16
|
3364 BOOST_UBLAS_INLINE
|
Chris@16
|
3365 const matrix_range<const M> project (const M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
3366 // ISSUE was: return matrix_range<M> (const_cast<M &> (data), r1, r2);
|
Chris@16
|
3367 return matrix_range<const M> (data, r1, r2);
|
Chris@16
|
3368 }
|
Chris@16
|
3369 template<class M>
|
Chris@16
|
3370 BOOST_UBLAS_INLINE
|
Chris@16
|
3371 matrix_range<M> project (matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
3372 return data.project (r1, r2);
|
Chris@16
|
3373 }
|
Chris@16
|
3374 template<class M>
|
Chris@16
|
3375 BOOST_UBLAS_INLINE
|
Chris@16
|
3376 const matrix_range<M> project (const matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
3377 return data.project (r1, r2);
|
Chris@16
|
3378 }
|
Chris@16
|
3379
|
Chris@16
|
3380 // Specialization of temporary_traits
|
Chris@16
|
3381 template <class M>
|
Chris@16
|
3382 struct matrix_temporary_traits< matrix_range<M> >
|
Chris@16
|
3383 : matrix_temporary_traits< M > {} ;
|
Chris@16
|
3384 template <class M>
|
Chris@16
|
3385 struct matrix_temporary_traits< const matrix_range<M> >
|
Chris@16
|
3386 : matrix_temporary_traits< M > {} ;
|
Chris@16
|
3387
|
Chris@16
|
3388 template <class M>
|
Chris@16
|
3389 struct vector_temporary_traits< matrix_range<M> >
|
Chris@16
|
3390 : vector_temporary_traits< M > {} ;
|
Chris@16
|
3391 template <class M>
|
Chris@16
|
3392 struct vector_temporary_traits< const matrix_range<M> >
|
Chris@16
|
3393 : vector_temporary_traits< M > {} ;
|
Chris@16
|
3394
|
Chris@16
|
3395 // Matrix based slice class
|
Chris@16
|
3396 template<class M>
|
Chris@16
|
3397 class matrix_slice:
|
Chris@16
|
3398 public matrix_expression<matrix_slice<M> > {
|
Chris@16
|
3399
|
Chris@16
|
3400 typedef matrix_slice<M> self_type;
|
Chris@16
|
3401 public:
|
Chris@16
|
3402 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
3403 using matrix_expression<self_type>::operator ();
|
Chris@16
|
3404 #endif
|
Chris@16
|
3405 typedef M matrix_type;
|
Chris@16
|
3406 typedef typename M::size_type size_type;
|
Chris@16
|
3407 typedef typename M::difference_type difference_type;
|
Chris@16
|
3408 typedef typename M::value_type value_type;
|
Chris@16
|
3409 typedef typename M::const_reference const_reference;
|
Chris@16
|
3410 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
3411 typename M::const_reference,
|
Chris@16
|
3412 typename M::reference>::type reference;
|
Chris@16
|
3413 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
3414 typename M::const_closure_type,
|
Chris@16
|
3415 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
3416 typedef basic_range<size_type, difference_type> range_type;
|
Chris@16
|
3417 typedef basic_slice<size_type, difference_type> slice_type;
|
Chris@16
|
3418 typedef const self_type const_closure_type;
|
Chris@16
|
3419 typedef self_type closure_type;
|
Chris@16
|
3420 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
3421 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
3422 typedef typename M::orientation_category orientation_category;
|
Chris@16
|
3423
|
Chris@16
|
3424 // Construction and destruction
|
Chris@16
|
3425 BOOST_UBLAS_INLINE
|
Chris@16
|
3426 matrix_slice (matrix_type &data, const slice_type &s1, const slice_type &s2):
|
Chris@16
|
3427 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
|
Chris@16
|
3428 // Early checking of preconditions here.
|
Chris@16
|
3429 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
|
Chris@16
|
3430 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
|
Chris@16
|
3431 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
|
Chris@16
|
3432 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
|
Chris@16
|
3433 }
|
Chris@16
|
3434 BOOST_UBLAS_INLINE
|
Chris@16
|
3435 matrix_slice (const matrix_closure_type &data, const slice_type &s1, const slice_type &s2, int):
|
Chris@16
|
3436 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
|
Chris@16
|
3437 // Early checking of preconditions.
|
Chris@16
|
3438 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
|
Chris@16
|
3439 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
|
Chris@16
|
3440 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
|
Chris@16
|
3441 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
|
Chris@16
|
3442 }
|
Chris@16
|
3443
|
Chris@16
|
3444 // Accessors
|
Chris@16
|
3445 BOOST_UBLAS_INLINE
|
Chris@16
|
3446 size_type start1 () const {
|
Chris@16
|
3447 return s1_.start ();
|
Chris@16
|
3448 }
|
Chris@16
|
3449 BOOST_UBLAS_INLINE
|
Chris@16
|
3450 size_type start2 () const {
|
Chris@16
|
3451 return s2_.start ();
|
Chris@16
|
3452 }
|
Chris@16
|
3453 BOOST_UBLAS_INLINE
|
Chris@16
|
3454 difference_type stride1 () const {
|
Chris@16
|
3455 return s1_.stride ();
|
Chris@16
|
3456 }
|
Chris@16
|
3457 BOOST_UBLAS_INLINE
|
Chris@16
|
3458 difference_type stride2 () const {
|
Chris@16
|
3459 return s2_.stride ();
|
Chris@16
|
3460 }
|
Chris@16
|
3461 BOOST_UBLAS_INLINE
|
Chris@16
|
3462 size_type size1 () const {
|
Chris@16
|
3463 return s1_.size ();
|
Chris@16
|
3464 }
|
Chris@16
|
3465 BOOST_UBLAS_INLINE
|
Chris@16
|
3466 size_type size2 () const {
|
Chris@16
|
3467 return s2_.size ();
|
Chris@16
|
3468 }
|
Chris@16
|
3469
|
Chris@16
|
3470 // Storage accessors
|
Chris@16
|
3471 BOOST_UBLAS_INLINE
|
Chris@16
|
3472 const matrix_closure_type &data () const {
|
Chris@16
|
3473 return data_;
|
Chris@16
|
3474 }
|
Chris@16
|
3475 BOOST_UBLAS_INLINE
|
Chris@16
|
3476 matrix_closure_type &data () {
|
Chris@16
|
3477 return data_;
|
Chris@16
|
3478 }
|
Chris@16
|
3479
|
Chris@16
|
3480 // Element access
|
Chris@16
|
3481 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
3482 BOOST_UBLAS_INLINE
|
Chris@16
|
3483 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
3484 return data_ (s1_ (i), s2_ (j));
|
Chris@16
|
3485 }
|
Chris@16
|
3486 BOOST_UBLAS_INLINE
|
Chris@16
|
3487 reference operator () (size_type i, size_type j) {
|
Chris@16
|
3488 return data_ (s1_ (i), s2_ (j));
|
Chris@16
|
3489 }
|
Chris@16
|
3490 #else
|
Chris@16
|
3491 BOOST_UBLAS_INLINE
|
Chris@16
|
3492 reference operator () (size_type i, size_type j) const {
|
Chris@16
|
3493 return data_ (s1_ (i), s2_ (j));
|
Chris@16
|
3494 }
|
Chris@16
|
3495 #endif
|
Chris@16
|
3496
|
Chris@16
|
3497 // ISSUE can this be done in free project function?
|
Chris@16
|
3498 // Although a const function can create a non-const proxy to a non-const object
|
Chris@16
|
3499 // Critical is that matrix_type and data_ (vector_closure_type) are const correct
|
Chris@16
|
3500 BOOST_UBLAS_INLINE
|
Chris@16
|
3501 matrix_slice<matrix_type> project (const range_type &r1, const range_type &r2) const {
|
Chris@16
|
3502 return matrix_slice<matrix_type> (data_, s1_.compose (r1.preprocess (data_.size1 ())), s2_.compose (r2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
3503 }
|
Chris@16
|
3504 BOOST_UBLAS_INLINE
|
Chris@16
|
3505 matrix_slice<matrix_type> project (const slice_type &s1, const slice_type &s2) const {
|
Chris@16
|
3506 return matrix_slice<matrix_type> (data_, s1_.compose (s1.preprocess (data_.size1 ())), s2_.compose (s2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
3507 }
|
Chris@16
|
3508
|
Chris@16
|
3509 // Assignment
|
Chris@16
|
3510 BOOST_UBLAS_INLINE
|
Chris@16
|
3511 matrix_slice &operator = (const matrix_slice &ms) {
|
Chris@16
|
3512 matrix_assign<scalar_assign> (*this, ms);
|
Chris@16
|
3513 return *this;
|
Chris@16
|
3514 }
|
Chris@16
|
3515 BOOST_UBLAS_INLINE
|
Chris@16
|
3516 matrix_slice &assign_temporary (matrix_slice &ms) {
|
Chris@16
|
3517 return *this = ms;
|
Chris@16
|
3518 }
|
Chris@16
|
3519 template<class AE>
|
Chris@16
|
3520 BOOST_UBLAS_INLINE
|
Chris@16
|
3521 matrix_slice &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
3522 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
|
Chris@16
|
3523 return *this;
|
Chris@16
|
3524 }
|
Chris@16
|
3525 template<class AE>
|
Chris@16
|
3526 BOOST_UBLAS_INLINE
|
Chris@16
|
3527 matrix_slice &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3528 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
3529 return *this;
|
Chris@16
|
3530 }
|
Chris@16
|
3531 template<class AE>
|
Chris@16
|
3532 BOOST_UBLAS_INLINE
|
Chris@16
|
3533 matrix_slice& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
3534 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
3535 return *this;
|
Chris@16
|
3536 }
|
Chris@16
|
3537 template<class AE>
|
Chris@16
|
3538 BOOST_UBLAS_INLINE
|
Chris@16
|
3539 matrix_slice &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3540 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
3541 return *this;
|
Chris@16
|
3542 }
|
Chris@16
|
3543 template<class AE>
|
Chris@16
|
3544 BOOST_UBLAS_INLINE
|
Chris@16
|
3545 matrix_slice& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
3546 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
3547 return *this;
|
Chris@16
|
3548 }
|
Chris@16
|
3549 template<class AE>
|
Chris@16
|
3550 BOOST_UBLAS_INLINE
|
Chris@16
|
3551 matrix_slice &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
3552 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
3553 return *this;
|
Chris@16
|
3554 }
|
Chris@16
|
3555 template<class AT>
|
Chris@16
|
3556 BOOST_UBLAS_INLINE
|
Chris@16
|
3557 matrix_slice& operator *= (const AT &at) {
|
Chris@16
|
3558 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
3559 return *this;
|
Chris@16
|
3560 }
|
Chris@16
|
3561 template<class AT>
|
Chris@16
|
3562 BOOST_UBLAS_INLINE
|
Chris@16
|
3563 matrix_slice& operator /= (const AT &at) {
|
Chris@16
|
3564 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
3565 return *this;
|
Chris@16
|
3566 }
|
Chris@16
|
3567
|
Chris@16
|
3568 // Closure comparison
|
Chris@16
|
3569 BOOST_UBLAS_INLINE
|
Chris@16
|
3570 bool same_closure (const matrix_slice &ms) const {
|
Chris@16
|
3571 return (*this).data_.same_closure (ms.data_);
|
Chris@16
|
3572 }
|
Chris@16
|
3573
|
Chris@16
|
3574 // Comparison
|
Chris@16
|
3575 BOOST_UBLAS_INLINE
|
Chris@16
|
3576 bool operator == (const matrix_slice &ms) const {
|
Chris@16
|
3577 return (*this).data_ == ms.data_ && s1_ == ms.s1_ && s2_ == ms.s2_;
|
Chris@16
|
3578 }
|
Chris@16
|
3579
|
Chris@16
|
3580 // Swapping
|
Chris@16
|
3581 BOOST_UBLAS_INLINE
|
Chris@16
|
3582 void swap (matrix_slice ms) {
|
Chris@16
|
3583 if (this != &ms) {
|
Chris@16
|
3584 BOOST_UBLAS_CHECK (size1 () == ms.size1 (), bad_size ());
|
Chris@16
|
3585 BOOST_UBLAS_CHECK (size2 () == ms.size2 (), bad_size ());
|
Chris@16
|
3586 matrix_swap<scalar_swap> (*this, ms);
|
Chris@16
|
3587 }
|
Chris@16
|
3588 }
|
Chris@16
|
3589 BOOST_UBLAS_INLINE
|
Chris@16
|
3590 friend void swap (matrix_slice ms1, matrix_slice ms2) {
|
Chris@16
|
3591 ms1.swap (ms2);
|
Chris@16
|
3592 }
|
Chris@16
|
3593
|
Chris@16
|
3594 // Iterator types
|
Chris@16
|
3595 private:
|
Chris@16
|
3596 // Use slice as an index - FIXME this fails for packed assignment
|
Chris@16
|
3597 typedef typename slice_type::const_iterator const_subiterator1_type;
|
Chris@16
|
3598 typedef typename slice_type::const_iterator subiterator1_type;
|
Chris@16
|
3599 typedef typename slice_type::const_iterator const_subiterator2_type;
|
Chris@16
|
3600 typedef typename slice_type::const_iterator subiterator2_type;
|
Chris@16
|
3601
|
Chris@16
|
3602 public:
|
Chris@16
|
3603 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3604 typedef indexed_iterator1<matrix_slice<matrix_type>,
|
Chris@16
|
3605 typename matrix_type::iterator1::iterator_category> iterator1;
|
Chris@16
|
3606 typedef indexed_iterator2<matrix_slice<matrix_type>,
|
Chris@16
|
3607 typename matrix_type::iterator2::iterator_category> iterator2;
|
Chris@16
|
3608 typedef indexed_const_iterator1<matrix_slice<matrix_type>,
|
Chris@16
|
3609 typename matrix_type::const_iterator1::iterator_category> const_iterator1;
|
Chris@16
|
3610 typedef indexed_const_iterator2<matrix_slice<matrix_type>,
|
Chris@16
|
3611 typename matrix_type::const_iterator2::iterator_category> const_iterator2;
|
Chris@16
|
3612 #else
|
Chris@16
|
3613 class const_iterator1;
|
Chris@16
|
3614 class iterator1;
|
Chris@16
|
3615 class const_iterator2;
|
Chris@16
|
3616 class iterator2;
|
Chris@16
|
3617 #endif
|
Chris@16
|
3618 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
3619 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
3620 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
3621 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
3622
|
Chris@16
|
3623 // Element lookup
|
Chris@16
|
3624 BOOST_UBLAS_INLINE
|
Chris@16
|
3625 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
3626 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3627 return const_iterator1 (*this, i, j);
|
Chris@16
|
3628 #else
|
Chris@16
|
3629 return const_iterator1 (*this, s1_.begin () + i, s2_.begin () + j);
|
Chris@16
|
3630 #endif
|
Chris@16
|
3631 }
|
Chris@16
|
3632 BOOST_UBLAS_INLINE
|
Chris@16
|
3633 iterator1 find1 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
3634 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3635 return iterator1 (*this, i, j);
|
Chris@16
|
3636 #else
|
Chris@16
|
3637 return iterator1 (*this, s1_.begin () + i, s2_.begin () + j);
|
Chris@16
|
3638 #endif
|
Chris@16
|
3639 }
|
Chris@16
|
3640 BOOST_UBLAS_INLINE
|
Chris@16
|
3641 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
3642 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3643 return const_iterator2 (*this, i, j);
|
Chris@16
|
3644 #else
|
Chris@16
|
3645 return const_iterator2 (*this, s1_.begin () + i, s2_.begin () + j);
|
Chris@16
|
3646 #endif
|
Chris@16
|
3647 }
|
Chris@16
|
3648 BOOST_UBLAS_INLINE
|
Chris@16
|
3649 iterator2 find2 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
3650 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3651 return iterator2 (*this, i, j);
|
Chris@16
|
3652 #else
|
Chris@16
|
3653 return iterator2 (*this, s1_.begin () + i, s2_.begin () + j);
|
Chris@16
|
3654 #endif
|
Chris@16
|
3655 }
|
Chris@16
|
3656
|
Chris@16
|
3657 // Iterators simply are indices.
|
Chris@16
|
3658
|
Chris@16
|
3659 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3660 class const_iterator1:
|
Chris@16
|
3661 public container_const_reference<matrix_slice>,
|
Chris@16
|
3662 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
|
Chris@16
|
3663 iterator_base<const_iterator1, value_type>::type {
|
Chris@16
|
3664 public:
|
Chris@16
|
3665 typedef typename M::const_iterator1::value_type value_type;
|
Chris@16
|
3666 typedef typename M::const_iterator1::difference_type difference_type;
|
Chris@16
|
3667 typedef typename M::const_reference reference; //FIXME due to indexing access
|
Chris@16
|
3668 typedef typename M::const_iterator1::pointer pointer;
|
Chris@16
|
3669 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
3670 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
3671
|
Chris@16
|
3672 // Construction and destruction
|
Chris@16
|
3673 BOOST_UBLAS_INLINE
|
Chris@16
|
3674 const_iterator1 ():
|
Chris@16
|
3675 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
3676 BOOST_UBLAS_INLINE
|
Chris@16
|
3677 const_iterator1 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
3678 container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
3679 BOOST_UBLAS_INLINE
|
Chris@16
|
3680 const_iterator1 (const iterator1 &it):
|
Chris@16
|
3681 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
3682
|
Chris@16
|
3683 // Arithmetic
|
Chris@16
|
3684 BOOST_UBLAS_INLINE
|
Chris@16
|
3685 const_iterator1 &operator ++ () {
|
Chris@16
|
3686 ++ it1_;
|
Chris@16
|
3687 return *this;
|
Chris@16
|
3688 }
|
Chris@16
|
3689 BOOST_UBLAS_INLINE
|
Chris@16
|
3690 const_iterator1 &operator -- () {
|
Chris@16
|
3691 -- it1_;
|
Chris@16
|
3692 return *this;
|
Chris@16
|
3693 }
|
Chris@16
|
3694 BOOST_UBLAS_INLINE
|
Chris@16
|
3695 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
3696 it1_ += n;
|
Chris@16
|
3697 return *this;
|
Chris@16
|
3698 }
|
Chris@16
|
3699 BOOST_UBLAS_INLINE
|
Chris@16
|
3700 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
3701 it1_ -= n;
|
Chris@16
|
3702 return *this;
|
Chris@16
|
3703 }
|
Chris@16
|
3704 BOOST_UBLAS_INLINE
|
Chris@16
|
3705 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
3706 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3707 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3708 return it1_ - it.it1_;
|
Chris@16
|
3709 }
|
Chris@16
|
3710
|
Chris@16
|
3711 // Dereference
|
Chris@16
|
3712 BOOST_UBLAS_INLINE
|
Chris@16
|
3713 const_reference operator * () const {
|
Chris@16
|
3714 // FIXME replace find with at_element
|
Chris@16
|
3715 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
3716 }
|
Chris@16
|
3717 BOOST_UBLAS_INLINE
|
Chris@16
|
3718 const_reference operator [] (difference_type n) const {
|
Chris@16
|
3719 return *(*this + n);
|
Chris@16
|
3720 }
|
Chris@16
|
3721
|
Chris@16
|
3722 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3723 BOOST_UBLAS_INLINE
|
Chris@16
|
3724 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3725 typename self_type::
|
Chris@16
|
3726 #endif
|
Chris@16
|
3727 const_iterator2 begin () const {
|
Chris@16
|
3728 return const_iterator2 ((*this) (), it1_, it2_ ().begin ());
|
Chris@16
|
3729 }
|
Chris@16
|
3730 BOOST_UBLAS_INLINE
|
Chris@16
|
3731 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3732 typename self_type::
|
Chris@16
|
3733 #endif
|
Chris@101
|
3734 const_iterator2 cbegin () const {
|
Chris@101
|
3735 return begin ();
|
Chris@101
|
3736 }
|
Chris@101
|
3737 BOOST_UBLAS_INLINE
|
Chris@101
|
3738 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3739 typename self_type::
|
Chris@101
|
3740 #endif
|
Chris@16
|
3741 const_iterator2 end () const {
|
Chris@16
|
3742 return const_iterator2 ((*this) (), it1_, it2_ ().end ());
|
Chris@16
|
3743 }
|
Chris@16
|
3744 BOOST_UBLAS_INLINE
|
Chris@16
|
3745 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3746 typename self_type::
|
Chris@16
|
3747 #endif
|
Chris@101
|
3748 const_iterator2 cend () const {
|
Chris@101
|
3749 return end ();
|
Chris@101
|
3750 }
|
Chris@101
|
3751 BOOST_UBLAS_INLINE
|
Chris@101
|
3752 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3753 typename self_type::
|
Chris@101
|
3754 #endif
|
Chris@16
|
3755 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
3756 return const_reverse_iterator2 (end ());
|
Chris@16
|
3757 }
|
Chris@16
|
3758 BOOST_UBLAS_INLINE
|
Chris@16
|
3759 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3760 typename self_type::
|
Chris@16
|
3761 #endif
|
Chris@101
|
3762 const_reverse_iterator2 crbegin () const {
|
Chris@101
|
3763 return rbegin ();
|
Chris@101
|
3764 }
|
Chris@101
|
3765 BOOST_UBLAS_INLINE
|
Chris@101
|
3766 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3767 typename self_type::
|
Chris@101
|
3768 #endif
|
Chris@16
|
3769 const_reverse_iterator2 rend () const {
|
Chris@16
|
3770 return const_reverse_iterator2 (begin ());
|
Chris@16
|
3771 }
|
Chris@101
|
3772 BOOST_UBLAS_INLINE
|
Chris@101
|
3773 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
3774 typename self_type::
|
Chris@101
|
3775 #endif
|
Chris@101
|
3776 const_reverse_iterator2 crend () const {
|
Chris@101
|
3777 return rend ();
|
Chris@101
|
3778 }
|
Chris@16
|
3779 #endif
|
Chris@16
|
3780
|
Chris@16
|
3781 // Indices
|
Chris@16
|
3782 BOOST_UBLAS_INLINE
|
Chris@16
|
3783 size_type index1 () const {
|
Chris@16
|
3784 return it1_.index ();
|
Chris@16
|
3785 }
|
Chris@16
|
3786 BOOST_UBLAS_INLINE
|
Chris@16
|
3787 size_type index2 () const {
|
Chris@16
|
3788 return it2_.index ();
|
Chris@16
|
3789 }
|
Chris@16
|
3790
|
Chris@16
|
3791 // Assignment
|
Chris@16
|
3792 BOOST_UBLAS_INLINE
|
Chris@16
|
3793 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
3794 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
3795 it1_ = it.it1_;
|
Chris@16
|
3796 it2_ = it.it2_;
|
Chris@16
|
3797 return *this;
|
Chris@16
|
3798 }
|
Chris@16
|
3799
|
Chris@16
|
3800 // Comparison
|
Chris@16
|
3801 BOOST_UBLAS_INLINE
|
Chris@16
|
3802 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
3803 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3804 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3805 return it1_ == it.it1_;
|
Chris@16
|
3806 }
|
Chris@16
|
3807 BOOST_UBLAS_INLINE
|
Chris@16
|
3808 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
3809 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3810 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3811 return it1_ < it.it1_;
|
Chris@16
|
3812 }
|
Chris@16
|
3813
|
Chris@16
|
3814 private:
|
Chris@16
|
3815 const_subiterator1_type it1_;
|
Chris@16
|
3816 const_subiterator2_type it2_;
|
Chris@16
|
3817 };
|
Chris@16
|
3818 #endif
|
Chris@16
|
3819
|
Chris@16
|
3820 BOOST_UBLAS_INLINE
|
Chris@16
|
3821 const_iterator1 begin1 () const {
|
Chris@16
|
3822 return find1 (0, 0, 0);
|
Chris@16
|
3823 }
|
Chris@16
|
3824 BOOST_UBLAS_INLINE
|
Chris@101
|
3825 const_iterator1 cbegin1 () const {
|
Chris@101
|
3826 return begin1 ();
|
Chris@101
|
3827 }
|
Chris@101
|
3828 BOOST_UBLAS_INLINE
|
Chris@16
|
3829 const_iterator1 end1 () const {
|
Chris@16
|
3830 return find1 (0, size1 (), 0);
|
Chris@16
|
3831 }
|
Chris@101
|
3832 BOOST_UBLAS_INLINE
|
Chris@101
|
3833 const_iterator1 cend1 () const {
|
Chris@101
|
3834 return end1 ();
|
Chris@101
|
3835 }
|
Chris@16
|
3836
|
Chris@16
|
3837 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3838 class iterator1:
|
Chris@16
|
3839 public container_reference<matrix_slice>,
|
Chris@16
|
3840 public iterator_base_traits<typename M::iterator1::iterator_category>::template
|
Chris@16
|
3841 iterator_base<iterator1, value_type>::type {
|
Chris@16
|
3842 public:
|
Chris@16
|
3843 typedef typename M::iterator1::value_type value_type;
|
Chris@16
|
3844 typedef typename M::iterator1::difference_type difference_type;
|
Chris@16
|
3845 typedef typename M::reference reference; //FIXME due to indexing access
|
Chris@16
|
3846 typedef typename M::iterator1::pointer pointer;
|
Chris@16
|
3847 typedef iterator2 dual_iterator_type;
|
Chris@16
|
3848 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
3849
|
Chris@16
|
3850 // Construction and destruction
|
Chris@16
|
3851 BOOST_UBLAS_INLINE
|
Chris@16
|
3852 iterator1 ():
|
Chris@16
|
3853 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
3854 BOOST_UBLAS_INLINE
|
Chris@16
|
3855 iterator1 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
3856 container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
3857
|
Chris@16
|
3858 // Arithmetic
|
Chris@16
|
3859 BOOST_UBLAS_INLINE
|
Chris@16
|
3860 iterator1 &operator ++ () {
|
Chris@16
|
3861 ++ it1_;
|
Chris@16
|
3862 return *this;
|
Chris@16
|
3863 }
|
Chris@16
|
3864 BOOST_UBLAS_INLINE
|
Chris@16
|
3865 iterator1 &operator -- () {
|
Chris@16
|
3866 -- it1_;
|
Chris@16
|
3867 return *this;
|
Chris@16
|
3868 }
|
Chris@16
|
3869 BOOST_UBLAS_INLINE
|
Chris@16
|
3870 iterator1 &operator += (difference_type n) {
|
Chris@16
|
3871 it1_ += n;
|
Chris@16
|
3872 return *this;
|
Chris@16
|
3873 }
|
Chris@16
|
3874 BOOST_UBLAS_INLINE
|
Chris@16
|
3875 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
3876 it1_ -= n;
|
Chris@16
|
3877 return *this;
|
Chris@16
|
3878 }
|
Chris@16
|
3879 BOOST_UBLAS_INLINE
|
Chris@16
|
3880 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
3881 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3882 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3883 return it1_ - it.it1_;
|
Chris@16
|
3884 }
|
Chris@16
|
3885
|
Chris@16
|
3886 // Dereference
|
Chris@16
|
3887 BOOST_UBLAS_INLINE
|
Chris@16
|
3888 reference operator * () const {
|
Chris@16
|
3889 // FIXME replace find with at_element
|
Chris@16
|
3890 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
3891 }
|
Chris@16
|
3892 BOOST_UBLAS_INLINE
|
Chris@16
|
3893 reference operator [] (difference_type n) const {
|
Chris@16
|
3894 return *(*this + n);
|
Chris@16
|
3895 }
|
Chris@16
|
3896
|
Chris@16
|
3897 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
3898 BOOST_UBLAS_INLINE
|
Chris@16
|
3899 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3900 typename self_type::
|
Chris@16
|
3901 #endif
|
Chris@16
|
3902 iterator2 begin () const {
|
Chris@16
|
3903 return iterator2 ((*this) (), it1_, it2_ ().begin ());
|
Chris@16
|
3904 }
|
Chris@16
|
3905 BOOST_UBLAS_INLINE
|
Chris@16
|
3906 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3907 typename self_type::
|
Chris@16
|
3908 #endif
|
Chris@16
|
3909 iterator2 end () const {
|
Chris@16
|
3910 return iterator2 ((*this) (), it1_, it2_ ().end ());
|
Chris@16
|
3911 }
|
Chris@16
|
3912 BOOST_UBLAS_INLINE
|
Chris@16
|
3913 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3914 typename self_type::
|
Chris@16
|
3915 #endif
|
Chris@16
|
3916 reverse_iterator2 rbegin () const {
|
Chris@16
|
3917 return reverse_iterator2 (end ());
|
Chris@16
|
3918 }
|
Chris@16
|
3919 BOOST_UBLAS_INLINE
|
Chris@16
|
3920 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
3921 typename self_type::
|
Chris@16
|
3922 #endif
|
Chris@16
|
3923 reverse_iterator2 rend () const {
|
Chris@16
|
3924 return reverse_iterator2 (begin ());
|
Chris@16
|
3925 }
|
Chris@16
|
3926 #endif
|
Chris@16
|
3927
|
Chris@16
|
3928 // Indices
|
Chris@16
|
3929 BOOST_UBLAS_INLINE
|
Chris@16
|
3930 size_type index1 () const {
|
Chris@16
|
3931 return it1_.index ();
|
Chris@16
|
3932 }
|
Chris@16
|
3933 BOOST_UBLAS_INLINE
|
Chris@16
|
3934 size_type index2 () const {
|
Chris@16
|
3935 return it2_.index ();
|
Chris@16
|
3936 }
|
Chris@16
|
3937
|
Chris@16
|
3938 // Assignment
|
Chris@16
|
3939 BOOST_UBLAS_INLINE
|
Chris@16
|
3940 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
3941 container_reference<self_type>::assign (&it ());
|
Chris@16
|
3942 it1_ = it.it1_;
|
Chris@16
|
3943 it2_ = it.it2_;
|
Chris@16
|
3944 return *this;
|
Chris@16
|
3945 }
|
Chris@16
|
3946
|
Chris@16
|
3947 // Comparison
|
Chris@16
|
3948 BOOST_UBLAS_INLINE
|
Chris@16
|
3949 bool operator == (const iterator1 &it) const {
|
Chris@16
|
3950 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3951 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3952 return it1_ == it.it1_;
|
Chris@16
|
3953 }
|
Chris@16
|
3954 BOOST_UBLAS_INLINE
|
Chris@16
|
3955 bool operator < (const iterator1 &it) const {
|
Chris@16
|
3956 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
3957 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
3958 return it1_ < it.it1_;
|
Chris@16
|
3959 }
|
Chris@16
|
3960
|
Chris@16
|
3961 private:
|
Chris@16
|
3962 subiterator1_type it1_;
|
Chris@16
|
3963 subiterator2_type it2_;
|
Chris@16
|
3964
|
Chris@16
|
3965 friend class const_iterator1;
|
Chris@16
|
3966 };
|
Chris@16
|
3967 #endif
|
Chris@16
|
3968
|
Chris@16
|
3969 BOOST_UBLAS_INLINE
|
Chris@16
|
3970 iterator1 begin1 () {
|
Chris@16
|
3971 return find1 (0, 0, 0);
|
Chris@16
|
3972 }
|
Chris@16
|
3973 BOOST_UBLAS_INLINE
|
Chris@16
|
3974 iterator1 end1 () {
|
Chris@16
|
3975 return find1 (0, size1 (), 0);
|
Chris@16
|
3976 }
|
Chris@16
|
3977
|
Chris@16
|
3978 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
3979 class const_iterator2:
|
Chris@16
|
3980 public container_const_reference<matrix_slice>,
|
Chris@16
|
3981 public iterator_base_traits<typename M::const_iterator2::iterator_category>::template
|
Chris@16
|
3982 iterator_base<const_iterator2, value_type>::type {
|
Chris@16
|
3983 public:
|
Chris@16
|
3984 typedef typename M::const_iterator2::value_type value_type;
|
Chris@16
|
3985 typedef typename M::const_iterator2::difference_type difference_type;
|
Chris@16
|
3986 typedef typename M::const_reference reference; //FIXME due to indexing access
|
Chris@16
|
3987 typedef typename M::const_iterator2::pointer pointer;
|
Chris@16
|
3988 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
3989 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
3990
|
Chris@16
|
3991 // Construction and destruction
|
Chris@16
|
3992 BOOST_UBLAS_INLINE
|
Chris@16
|
3993 const_iterator2 ():
|
Chris@16
|
3994 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
3995 BOOST_UBLAS_INLINE
|
Chris@16
|
3996 const_iterator2 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
3997 container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
3998 BOOST_UBLAS_INLINE
|
Chris@16
|
3999 const_iterator2 (const iterator2 &it):
|
Chris@16
|
4000 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
4001
|
Chris@16
|
4002 // Arithmetic
|
Chris@16
|
4003 BOOST_UBLAS_INLINE
|
Chris@16
|
4004 const_iterator2 &operator ++ () {
|
Chris@16
|
4005 ++ it2_;
|
Chris@16
|
4006 return *this;
|
Chris@16
|
4007 }
|
Chris@16
|
4008 BOOST_UBLAS_INLINE
|
Chris@16
|
4009 const_iterator2 &operator -- () {
|
Chris@16
|
4010 -- it2_;
|
Chris@16
|
4011 return *this;
|
Chris@16
|
4012 }
|
Chris@16
|
4013 BOOST_UBLAS_INLINE
|
Chris@16
|
4014 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
4015 it2_ += n;
|
Chris@16
|
4016 return *this;
|
Chris@16
|
4017 }
|
Chris@16
|
4018 BOOST_UBLAS_INLINE
|
Chris@16
|
4019 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
4020 it2_ -= n;
|
Chris@16
|
4021 return *this;
|
Chris@16
|
4022 }
|
Chris@16
|
4023 BOOST_UBLAS_INLINE
|
Chris@16
|
4024 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
4025 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4026 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4027 return it2_ - it.it2_;
|
Chris@16
|
4028 }
|
Chris@16
|
4029
|
Chris@16
|
4030 // Dereference
|
Chris@16
|
4031 BOOST_UBLAS_INLINE
|
Chris@16
|
4032 const_reference operator * () const {
|
Chris@16
|
4033 // FIXME replace find with at_element
|
Chris@16
|
4034 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
4035 }
|
Chris@16
|
4036 BOOST_UBLAS_INLINE
|
Chris@16
|
4037 const_reference operator [] (difference_type n) const {
|
Chris@16
|
4038 return *(*this + n);
|
Chris@16
|
4039 }
|
Chris@16
|
4040
|
Chris@16
|
4041 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4042 BOOST_UBLAS_INLINE
|
Chris@16
|
4043 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4044 typename self_type::
|
Chris@16
|
4045 #endif
|
Chris@16
|
4046 const_iterator1 begin () const {
|
Chris@16
|
4047 return const_iterator1 ((*this) (), it1_ ().begin (), it2_);
|
Chris@16
|
4048 }
|
Chris@16
|
4049 BOOST_UBLAS_INLINE
|
Chris@16
|
4050 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4051 typename self_type::
|
Chris@16
|
4052 #endif
|
Chris@101
|
4053 const_iterator1 cbegin () const {
|
Chris@101
|
4054 return begin ();
|
Chris@101
|
4055 }
|
Chris@101
|
4056 BOOST_UBLAS_INLINE
|
Chris@101
|
4057 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4058 typename self_type::
|
Chris@101
|
4059 #endif
|
Chris@16
|
4060 const_iterator1 end () const {
|
Chris@16
|
4061 return const_iterator1 ((*this) (), it1_ ().end (), it2_);
|
Chris@16
|
4062 }
|
Chris@16
|
4063 BOOST_UBLAS_INLINE
|
Chris@16
|
4064 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4065 typename self_type::
|
Chris@16
|
4066 #endif
|
Chris@101
|
4067 const_iterator1 cend () const {
|
Chris@101
|
4068 return end ();
|
Chris@101
|
4069 }
|
Chris@101
|
4070 BOOST_UBLAS_INLINE
|
Chris@101
|
4071 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4072 typename self_type::
|
Chris@101
|
4073 #endif
|
Chris@16
|
4074 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
4075 return const_reverse_iterator1 (end ());
|
Chris@16
|
4076 }
|
Chris@16
|
4077 BOOST_UBLAS_INLINE
|
Chris@16
|
4078 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4079 typename self_type::
|
Chris@16
|
4080 #endif
|
Chris@101
|
4081 const_reverse_iterator1 crbegin () const {
|
Chris@101
|
4082 return rbegin ();
|
Chris@101
|
4083 }
|
Chris@101
|
4084 BOOST_UBLAS_INLINE
|
Chris@101
|
4085 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4086 typename self_type::
|
Chris@101
|
4087 #endif
|
Chris@16
|
4088 const_reverse_iterator1 rend () const {
|
Chris@16
|
4089 return const_reverse_iterator1 (begin ());
|
Chris@16
|
4090 }
|
Chris@101
|
4091 BOOST_UBLAS_INLINE
|
Chris@101
|
4092 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4093 typename self_type::
|
Chris@101
|
4094 #endif
|
Chris@101
|
4095 const_reverse_iterator1 crend () const {
|
Chris@101
|
4096 return rend ();
|
Chris@101
|
4097 }
|
Chris@16
|
4098 #endif
|
Chris@16
|
4099
|
Chris@16
|
4100 // Indices
|
Chris@16
|
4101 BOOST_UBLAS_INLINE
|
Chris@16
|
4102 size_type index1 () const {
|
Chris@16
|
4103 return it1_.index ();
|
Chris@16
|
4104 }
|
Chris@16
|
4105 BOOST_UBLAS_INLINE
|
Chris@16
|
4106 size_type index2 () const {
|
Chris@16
|
4107 return it2_.index ();
|
Chris@16
|
4108 }
|
Chris@16
|
4109
|
Chris@16
|
4110 // Assignment
|
Chris@16
|
4111 BOOST_UBLAS_INLINE
|
Chris@16
|
4112 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
4113 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
4114 it1_ = it.it1_;
|
Chris@16
|
4115 it2_ = it.it2_;
|
Chris@16
|
4116 return *this;
|
Chris@16
|
4117 }
|
Chris@16
|
4118
|
Chris@16
|
4119 // Comparison
|
Chris@16
|
4120 BOOST_UBLAS_INLINE
|
Chris@16
|
4121 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
4122 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4123 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4124 return it2_ == it.it2_;
|
Chris@16
|
4125 }
|
Chris@16
|
4126 BOOST_UBLAS_INLINE
|
Chris@16
|
4127 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
4128 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4129 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4130 return it2_ < it.it2_;
|
Chris@16
|
4131 }
|
Chris@16
|
4132
|
Chris@16
|
4133 private:
|
Chris@16
|
4134 const_subiterator1_type it1_;
|
Chris@16
|
4135 const_subiterator2_type it2_;
|
Chris@16
|
4136 };
|
Chris@16
|
4137 #endif
|
Chris@16
|
4138
|
Chris@16
|
4139 BOOST_UBLAS_INLINE
|
Chris@16
|
4140 const_iterator2 begin2 () const {
|
Chris@16
|
4141 return find2 (0, 0, 0);
|
Chris@16
|
4142 }
|
Chris@16
|
4143 BOOST_UBLAS_INLINE
|
Chris@101
|
4144 const_iterator2 cbegin2 () const {
|
Chris@101
|
4145 return begin2 ();
|
Chris@101
|
4146 }
|
Chris@101
|
4147 BOOST_UBLAS_INLINE
|
Chris@16
|
4148 const_iterator2 end2 () const {
|
Chris@16
|
4149 return find2 (0, 0, size2 ());
|
Chris@16
|
4150 }
|
Chris@101
|
4151 BOOST_UBLAS_INLINE
|
Chris@101
|
4152 const_iterator2 cend2 () const {
|
Chris@101
|
4153 return end2 ();
|
Chris@101
|
4154 }
|
Chris@16
|
4155
|
Chris@16
|
4156 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4157 class iterator2:
|
Chris@16
|
4158 public container_reference<matrix_slice>,
|
Chris@16
|
4159 public iterator_base_traits<typename M::iterator2::iterator_category>::template
|
Chris@16
|
4160 iterator_base<iterator2, value_type>::type {
|
Chris@16
|
4161 public:
|
Chris@16
|
4162 typedef typename M::iterator2::value_type value_type;
|
Chris@16
|
4163 typedef typename M::iterator2::difference_type difference_type;
|
Chris@16
|
4164 typedef typename M::reference reference; //FIXME due to indexing access
|
Chris@16
|
4165 typedef typename M::iterator2::pointer pointer;
|
Chris@16
|
4166 typedef iterator1 dual_iterator_type;
|
Chris@16
|
4167 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
4168
|
Chris@16
|
4169 // Construction and destruction
|
Chris@16
|
4170 BOOST_UBLAS_INLINE
|
Chris@16
|
4171 iterator2 ():
|
Chris@16
|
4172 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
4173 BOOST_UBLAS_INLINE
|
Chris@16
|
4174 iterator2 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
4175 container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
4176
|
Chris@16
|
4177 // Arithmetic
|
Chris@16
|
4178 BOOST_UBLAS_INLINE
|
Chris@16
|
4179 iterator2 &operator ++ () {
|
Chris@16
|
4180 ++ it2_;
|
Chris@16
|
4181 return *this;
|
Chris@16
|
4182 }
|
Chris@16
|
4183 BOOST_UBLAS_INLINE
|
Chris@16
|
4184 iterator2 &operator -- () {
|
Chris@16
|
4185 -- it2_;
|
Chris@16
|
4186 return *this;
|
Chris@16
|
4187 }
|
Chris@16
|
4188 BOOST_UBLAS_INLINE
|
Chris@16
|
4189 iterator2 &operator += (difference_type n) {
|
Chris@16
|
4190 it2_ += n;
|
Chris@16
|
4191 return *this;
|
Chris@16
|
4192 }
|
Chris@16
|
4193 BOOST_UBLAS_INLINE
|
Chris@16
|
4194 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
4195 it2_ -= n;
|
Chris@16
|
4196 return *this;
|
Chris@16
|
4197 }
|
Chris@16
|
4198 BOOST_UBLAS_INLINE
|
Chris@16
|
4199 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
4200 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4201 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4202 return it2_ - it.it2_;
|
Chris@16
|
4203 }
|
Chris@16
|
4204
|
Chris@16
|
4205 // Dereference
|
Chris@16
|
4206 BOOST_UBLAS_INLINE
|
Chris@16
|
4207 reference operator * () const {
|
Chris@16
|
4208 // FIXME replace find with at_element
|
Chris@16
|
4209 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
4210 }
|
Chris@16
|
4211 BOOST_UBLAS_INLINE
|
Chris@16
|
4212 reference operator [] (difference_type n) const {
|
Chris@16
|
4213 return *(*this + n);
|
Chris@16
|
4214 }
|
Chris@16
|
4215
|
Chris@16
|
4216 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4217 BOOST_UBLAS_INLINE
|
Chris@16
|
4218 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4219 typename self_type::
|
Chris@16
|
4220 #endif
|
Chris@16
|
4221 iterator1 begin () const {
|
Chris@16
|
4222 return iterator1 ((*this) (), it1_ ().begin (), it2_);
|
Chris@16
|
4223 }
|
Chris@16
|
4224 BOOST_UBLAS_INLINE
|
Chris@16
|
4225 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4226 typename self_type::
|
Chris@16
|
4227 #endif
|
Chris@16
|
4228 iterator1 end () const {
|
Chris@16
|
4229 return iterator1 ((*this) (), it1_ ().end (), it2_);
|
Chris@16
|
4230 }
|
Chris@16
|
4231 BOOST_UBLAS_INLINE
|
Chris@16
|
4232 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4233 typename self_type::
|
Chris@16
|
4234 #endif
|
Chris@16
|
4235 reverse_iterator1 rbegin () const {
|
Chris@16
|
4236 return reverse_iterator1 (end ());
|
Chris@16
|
4237 }
|
Chris@16
|
4238 BOOST_UBLAS_INLINE
|
Chris@16
|
4239 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4240 typename self_type::
|
Chris@16
|
4241 #endif
|
Chris@16
|
4242 reverse_iterator1 rend () const {
|
Chris@16
|
4243 return reverse_iterator1 (begin ());
|
Chris@16
|
4244 }
|
Chris@16
|
4245 #endif
|
Chris@16
|
4246
|
Chris@16
|
4247 // Indices
|
Chris@16
|
4248 BOOST_UBLAS_INLINE
|
Chris@16
|
4249 size_type index1 () const {
|
Chris@16
|
4250 return it1_.index ();
|
Chris@16
|
4251 }
|
Chris@16
|
4252 BOOST_UBLAS_INLINE
|
Chris@16
|
4253 size_type index2 () const {
|
Chris@16
|
4254 return it2_.index ();
|
Chris@16
|
4255 }
|
Chris@16
|
4256
|
Chris@16
|
4257 // Assignment
|
Chris@16
|
4258 BOOST_UBLAS_INLINE
|
Chris@16
|
4259 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
4260 container_reference<self_type>::assign (&it ());
|
Chris@16
|
4261 it1_ = it.it1_;
|
Chris@16
|
4262 it2_ = it.it2_;
|
Chris@16
|
4263 return *this;
|
Chris@16
|
4264 }
|
Chris@16
|
4265
|
Chris@16
|
4266 // Comparison
|
Chris@16
|
4267 BOOST_UBLAS_INLINE
|
Chris@16
|
4268 bool operator == (const iterator2 &it) const {
|
Chris@16
|
4269 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4270 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4271 return it2_ == it.it2_;
|
Chris@16
|
4272 }
|
Chris@16
|
4273 BOOST_UBLAS_INLINE
|
Chris@16
|
4274 bool operator < (const iterator2 &it) const {
|
Chris@16
|
4275 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4276 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
4277 return it2_ < it.it2_;
|
Chris@16
|
4278 }
|
Chris@16
|
4279
|
Chris@16
|
4280 private:
|
Chris@16
|
4281 subiterator1_type it1_;
|
Chris@16
|
4282 subiterator2_type it2_;
|
Chris@16
|
4283
|
Chris@16
|
4284 friend class const_iterator2;
|
Chris@16
|
4285 };
|
Chris@16
|
4286 #endif
|
Chris@16
|
4287
|
Chris@16
|
4288 BOOST_UBLAS_INLINE
|
Chris@16
|
4289 iterator2 begin2 () {
|
Chris@16
|
4290 return find2 (0, 0, 0);
|
Chris@16
|
4291 }
|
Chris@16
|
4292 BOOST_UBLAS_INLINE
|
Chris@16
|
4293 iterator2 end2 () {
|
Chris@16
|
4294 return find2 (0, 0, size2 ());
|
Chris@16
|
4295 }
|
Chris@16
|
4296
|
Chris@16
|
4297 // Reverse iterators
|
Chris@16
|
4298
|
Chris@16
|
4299 BOOST_UBLAS_INLINE
|
Chris@16
|
4300 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
4301 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
4302 }
|
Chris@16
|
4303 BOOST_UBLAS_INLINE
|
Chris@101
|
4304 const_reverse_iterator1 crbegin1 () const {
|
Chris@101
|
4305 return rbegin1 ();
|
Chris@101
|
4306 }
|
Chris@101
|
4307 BOOST_UBLAS_INLINE
|
Chris@16
|
4308 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
4309 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
4310 }
|
Chris@101
|
4311 BOOST_UBLAS_INLINE
|
Chris@101
|
4312 const_reverse_iterator1 crend1 () const {
|
Chris@101
|
4313 return rend1 ();
|
Chris@101
|
4314 }
|
Chris@16
|
4315
|
Chris@16
|
4316 BOOST_UBLAS_INLINE
|
Chris@16
|
4317 reverse_iterator1 rbegin1 () {
|
Chris@16
|
4318 return reverse_iterator1 (end1 ());
|
Chris@16
|
4319 }
|
Chris@16
|
4320 BOOST_UBLAS_INLINE
|
Chris@16
|
4321 reverse_iterator1 rend1 () {
|
Chris@16
|
4322 return reverse_iterator1 (begin1 ());
|
Chris@16
|
4323 }
|
Chris@16
|
4324
|
Chris@16
|
4325 BOOST_UBLAS_INLINE
|
Chris@16
|
4326 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
4327 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
4328 }
|
Chris@16
|
4329 BOOST_UBLAS_INLINE
|
Chris@101
|
4330 const_reverse_iterator2 crbegin2 () const {
|
Chris@101
|
4331 return rbegin2 ();
|
Chris@101
|
4332 }
|
Chris@101
|
4333 BOOST_UBLAS_INLINE
|
Chris@16
|
4334 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
4335 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
4336 }
|
Chris@101
|
4337 BOOST_UBLAS_INLINE
|
Chris@101
|
4338 const_reverse_iterator2 crend2 () const {
|
Chris@101
|
4339 return rend2 ();
|
Chris@101
|
4340 }
|
Chris@16
|
4341
|
Chris@16
|
4342 BOOST_UBLAS_INLINE
|
Chris@16
|
4343 reverse_iterator2 rbegin2 () {
|
Chris@16
|
4344 return reverse_iterator2 (end2 ());
|
Chris@16
|
4345 }
|
Chris@16
|
4346 BOOST_UBLAS_INLINE
|
Chris@16
|
4347 reverse_iterator2 rend2 () {
|
Chris@16
|
4348 return reverse_iterator2 (begin2 ());
|
Chris@16
|
4349 }
|
Chris@16
|
4350
|
Chris@16
|
4351 private:
|
Chris@16
|
4352 matrix_closure_type data_;
|
Chris@16
|
4353 slice_type s1_;
|
Chris@16
|
4354 slice_type s2_;
|
Chris@16
|
4355 };
|
Chris@16
|
4356
|
Chris@16
|
4357 // Simple Projections
|
Chris@16
|
4358 template<class M>
|
Chris@16
|
4359 BOOST_UBLAS_INLINE
|
Chris@16
|
4360 matrix_slice<M> subslice (M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) {
|
Chris@16
|
4361 typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type;
|
Chris@16
|
4362 return matrix_slice<M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2));
|
Chris@16
|
4363 }
|
Chris@16
|
4364 template<class M>
|
Chris@16
|
4365 BOOST_UBLAS_INLINE
|
Chris@16
|
4366 matrix_slice<const M> subslice (const M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) {
|
Chris@16
|
4367 typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type;
|
Chris@16
|
4368 return matrix_slice<const M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2));
|
Chris@16
|
4369 }
|
Chris@16
|
4370
|
Chris@16
|
4371 // Generic Projections
|
Chris@16
|
4372 template<class M>
|
Chris@16
|
4373 BOOST_UBLAS_INLINE
|
Chris@16
|
4374 matrix_slice<M> project (M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
Chris@16
|
4375 return matrix_slice<M> (data, s1, s2);
|
Chris@16
|
4376 }
|
Chris@16
|
4377 template<class M>
|
Chris@16
|
4378 BOOST_UBLAS_INLINE
|
Chris@16
|
4379 const matrix_slice<const M> project (const M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
Chris@16
|
4380 // ISSUE was: return matrix_slice<M> (const_cast<M &> (data), s1, s2);
|
Chris@16
|
4381 return matrix_slice<const M> (data, s1, s2);
|
Chris@16
|
4382 }
|
Chris@16
|
4383 // ISSUE in the following two functions it would be logical to use matrix_slice<V>::range_type but this confuses VC7.1 and 8.0
|
Chris@16
|
4384 template<class M>
|
Chris@16
|
4385 BOOST_UBLAS_INLINE
|
Chris@16
|
4386 matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
4387 return data.project (r1, r2);
|
Chris@16
|
4388 }
|
Chris@16
|
4389 template<class M>
|
Chris@16
|
4390 BOOST_UBLAS_INLINE
|
Chris@16
|
4391 const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
Chris@16
|
4392 return data.project (r1, r2);
|
Chris@16
|
4393 }
|
Chris@16
|
4394 template<class M>
|
Chris@16
|
4395 BOOST_UBLAS_INLINE
|
Chris@16
|
4396 matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
Chris@16
|
4397 return data.project (s1, s2);
|
Chris@16
|
4398 }
|
Chris@16
|
4399 template<class M>
|
Chris@16
|
4400 BOOST_UBLAS_INLINE
|
Chris@16
|
4401 const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
Chris@16
|
4402 return data.project (s1, s2);
|
Chris@16
|
4403 }
|
Chris@16
|
4404
|
Chris@16
|
4405 // Specialization of temporary_traits
|
Chris@16
|
4406 template <class M>
|
Chris@16
|
4407 struct matrix_temporary_traits< matrix_slice<M> >
|
Chris@16
|
4408 : matrix_temporary_traits< M > {};
|
Chris@16
|
4409 template <class M>
|
Chris@16
|
4410 struct matrix_temporary_traits< const matrix_slice<M> >
|
Chris@16
|
4411 : matrix_temporary_traits< M > {};
|
Chris@16
|
4412
|
Chris@16
|
4413 template <class M>
|
Chris@16
|
4414 struct vector_temporary_traits< matrix_slice<M> >
|
Chris@16
|
4415 : vector_temporary_traits< M > {};
|
Chris@16
|
4416 template <class M>
|
Chris@16
|
4417 struct vector_temporary_traits< const matrix_slice<M> >
|
Chris@16
|
4418 : vector_temporary_traits< M > {};
|
Chris@16
|
4419
|
Chris@16
|
4420 // Matrix based indirection class
|
Chris@16
|
4421 // Contributed by Toon Knapen.
|
Chris@16
|
4422 // Extended and optimized by Kresimir Fresl.
|
Chris@16
|
4423 /** \brief A matrix referencing a non continuous submatrix of elements given another matrix of indices.
|
Chris@16
|
4424 *
|
Chris@16
|
4425 * It is the most general version of any submatrices because it uses another matrix of indices to reference
|
Chris@16
|
4426 * the submatrix.
|
Chris@16
|
4427 *
|
Chris@16
|
4428 * The matrix of indices can be of any type with the restriction that its elements must be
|
Chris@16
|
4429 * type-compatible with the size_type \c of the container. In practice, the following are good candidates:
|
Chris@16
|
4430 * - \c boost::numeric::ublas::indirect_array<A> where \c A can be \c int, \c size_t, \c long, etc...
|
Chris@16
|
4431 * - \c boost::numeric::ublas::matrix<int> can work too (\c int can be replaced by another integer type)
|
Chris@16
|
4432 * - etc...
|
Chris@16
|
4433 *
|
Chris@16
|
4434 * An indirect matrix can be used as a normal matrix in any expression. If the specified indirect matrix
|
Chris@16
|
4435 * falls outside that of the indices of the matrix, then the \c matrix_indirect is not a well formed
|
Chris@16
|
4436 * \i Matrix \i Expression and access to an element outside of indices of the matrix is \b undefined.
|
Chris@16
|
4437 *
|
Chris@16
|
4438 * \tparam V the type of the referenced matrix, for example \c matrix<double>)
|
Chris@16
|
4439 * \tparam IA the type of index matrix. Default is \c ublas::indirect_array<>
|
Chris@16
|
4440 */
|
Chris@16
|
4441 template<class M, class IA>
|
Chris@16
|
4442 class matrix_indirect:
|
Chris@16
|
4443 public matrix_expression<matrix_indirect<M, IA> > {
|
Chris@16
|
4444
|
Chris@16
|
4445 typedef matrix_indirect<M, IA> self_type;
|
Chris@16
|
4446 public:
|
Chris@16
|
4447 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
Chris@16
|
4448 using matrix_expression<self_type>::operator ();
|
Chris@16
|
4449 #endif
|
Chris@16
|
4450 typedef M matrix_type;
|
Chris@16
|
4451 typedef IA indirect_array_type;
|
Chris@16
|
4452 typedef typename M::size_type size_type;
|
Chris@16
|
4453 typedef typename M::difference_type difference_type;
|
Chris@16
|
4454 typedef typename M::value_type value_type;
|
Chris@16
|
4455 typedef typename M::const_reference const_reference;
|
Chris@16
|
4456 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
4457 typename M::const_reference,
|
Chris@16
|
4458 typename M::reference>::type reference;
|
Chris@16
|
4459 typedef typename boost::mpl::if_<boost::is_const<M>,
|
Chris@16
|
4460 typename M::const_closure_type,
|
Chris@16
|
4461 typename M::closure_type>::type matrix_closure_type;
|
Chris@16
|
4462 typedef basic_range<size_type, difference_type> range_type;
|
Chris@16
|
4463 typedef basic_slice<size_type, difference_type> slice_type;
|
Chris@16
|
4464 typedef const self_type const_closure_type;
|
Chris@16
|
4465 typedef self_type closure_type;
|
Chris@16
|
4466 typedef typename storage_restrict_traits<typename M::storage_category,
|
Chris@16
|
4467 dense_proxy_tag>::storage_category storage_category;
|
Chris@16
|
4468 typedef typename M::orientation_category orientation_category;
|
Chris@16
|
4469
|
Chris@16
|
4470 // Construction and destruction
|
Chris@16
|
4471 BOOST_UBLAS_INLINE
|
Chris@16
|
4472 matrix_indirect (matrix_type &data, size_type size1, size_type size2):
|
Chris@16
|
4473 data_ (data), ia1_ (size1), ia2_ (size2) {}
|
Chris@16
|
4474 BOOST_UBLAS_INLINE
|
Chris@16
|
4475 matrix_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2):
|
Chris@16
|
4476 data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {}
|
Chris@16
|
4477 BOOST_UBLAS_INLINE
|
Chris@16
|
4478 matrix_indirect (const matrix_closure_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2, int):
|
Chris@16
|
4479 data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {}
|
Chris@16
|
4480
|
Chris@16
|
4481 // Accessors
|
Chris@16
|
4482 BOOST_UBLAS_INLINE
|
Chris@16
|
4483 size_type size1 () const {
|
Chris@16
|
4484 return ia1_.size ();
|
Chris@16
|
4485 }
|
Chris@16
|
4486 BOOST_UBLAS_INLINE
|
Chris@16
|
4487 size_type size2 () const {
|
Chris@16
|
4488 return ia2_.size ();
|
Chris@16
|
4489 }
|
Chris@16
|
4490 BOOST_UBLAS_INLINE
|
Chris@16
|
4491 const indirect_array_type &indirect1 () const {
|
Chris@16
|
4492 return ia1_;
|
Chris@16
|
4493 }
|
Chris@16
|
4494 BOOST_UBLAS_INLINE
|
Chris@16
|
4495 indirect_array_type &indirect1 () {
|
Chris@16
|
4496 return ia1_;
|
Chris@16
|
4497 }
|
Chris@16
|
4498 BOOST_UBLAS_INLINE
|
Chris@16
|
4499 const indirect_array_type &indirect2 () const {
|
Chris@16
|
4500 return ia2_;
|
Chris@16
|
4501 }
|
Chris@16
|
4502 BOOST_UBLAS_INLINE
|
Chris@16
|
4503 indirect_array_type &indirect2 () {
|
Chris@16
|
4504 return ia2_;
|
Chris@16
|
4505 }
|
Chris@16
|
4506
|
Chris@16
|
4507 // Storage accessors
|
Chris@16
|
4508 BOOST_UBLAS_INLINE
|
Chris@16
|
4509 const matrix_closure_type &data () const {
|
Chris@16
|
4510 return data_;
|
Chris@16
|
4511 }
|
Chris@16
|
4512 BOOST_UBLAS_INLINE
|
Chris@16
|
4513 matrix_closure_type &data () {
|
Chris@16
|
4514 return data_;
|
Chris@16
|
4515 }
|
Chris@16
|
4516
|
Chris@16
|
4517 // Element access
|
Chris@16
|
4518 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
|
Chris@16
|
4519 BOOST_UBLAS_INLINE
|
Chris@16
|
4520 const_reference operator () (size_type i, size_type j) const {
|
Chris@16
|
4521 return data_ (ia1_ (i), ia2_ (j));
|
Chris@16
|
4522 }
|
Chris@16
|
4523 BOOST_UBLAS_INLINE
|
Chris@16
|
4524 reference operator () (size_type i, size_type j) {
|
Chris@16
|
4525 return data_ (ia1_ (i), ia2_ (j));
|
Chris@16
|
4526 }
|
Chris@16
|
4527 #else
|
Chris@16
|
4528 BOOST_UBLAS_INLINE
|
Chris@16
|
4529 reference operator () (size_type i, size_type j) const {
|
Chris@16
|
4530 return data_ (ia1_ (i), ia2_ (j));
|
Chris@16
|
4531 }
|
Chris@16
|
4532 #endif
|
Chris@16
|
4533
|
Chris@16
|
4534 // ISSUE can this be done in free project function?
|
Chris@16
|
4535 // Although a const function can create a non-const proxy to a non-const object
|
Chris@16
|
4536 // Critical is that matrix_type and data_ (vector_closure_type) are const correct
|
Chris@16
|
4537 BOOST_UBLAS_INLINE
|
Chris@16
|
4538 matrix_indirect<matrix_type, indirect_array_type> project (const range_type &r1, const range_type &r2) const {
|
Chris@16
|
4539 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (r1.preprocess (data_.size1 ())), ia2_.compose (r2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
4540 }
|
Chris@16
|
4541 BOOST_UBLAS_INLINE
|
Chris@16
|
4542 matrix_indirect<matrix_type, indirect_array_type> project (const slice_type &s1, const slice_type &s2) const {
|
Chris@16
|
4543 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (s1.preprocess (data_.size1 ())), ia2_.compose (s2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
4544 }
|
Chris@16
|
4545 BOOST_UBLAS_INLINE
|
Chris@16
|
4546 matrix_indirect<matrix_type, indirect_array_type> project (const indirect_array_type &ia1, const indirect_array_type &ia2) const {
|
Chris@16
|
4547 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (ia1.preprocess (data_.size1 ())), ia2_.compose (ia2.preprocess (data_.size2 ())), 0);
|
Chris@16
|
4548 }
|
Chris@16
|
4549
|
Chris@16
|
4550 // Assignment
|
Chris@16
|
4551 BOOST_UBLAS_INLINE
|
Chris@16
|
4552 matrix_indirect &operator = (const matrix_indirect &mi) {
|
Chris@16
|
4553 matrix_assign<scalar_assign> (*this, mi);
|
Chris@16
|
4554 return *this;
|
Chris@16
|
4555 }
|
Chris@16
|
4556 BOOST_UBLAS_INLINE
|
Chris@16
|
4557 matrix_indirect &assign_temporary (matrix_indirect &mi) {
|
Chris@16
|
4558 return *this = mi;
|
Chris@16
|
4559 }
|
Chris@16
|
4560 template<class AE>
|
Chris@16
|
4561 BOOST_UBLAS_INLINE
|
Chris@16
|
4562 matrix_indirect &operator = (const matrix_expression<AE> &ae) {
|
Chris@16
|
4563 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
|
Chris@16
|
4564 return *this;
|
Chris@16
|
4565 }
|
Chris@16
|
4566 template<class AE>
|
Chris@16
|
4567 BOOST_UBLAS_INLINE
|
Chris@16
|
4568 matrix_indirect &assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
4569 matrix_assign<scalar_assign> (*this, ae);
|
Chris@16
|
4570 return *this;
|
Chris@16
|
4571 }
|
Chris@16
|
4572 template<class AE>
|
Chris@16
|
4573 BOOST_UBLAS_INLINE
|
Chris@16
|
4574 matrix_indirect& operator += (const matrix_expression<AE> &ae) {
|
Chris@16
|
4575 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
|
Chris@16
|
4576 return *this;
|
Chris@16
|
4577 }
|
Chris@16
|
4578 template<class AE>
|
Chris@16
|
4579 BOOST_UBLAS_INLINE
|
Chris@16
|
4580 matrix_indirect &plus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
4581 matrix_assign<scalar_plus_assign> (*this, ae);
|
Chris@16
|
4582 return *this;
|
Chris@16
|
4583 }
|
Chris@16
|
4584 template<class AE>
|
Chris@16
|
4585 BOOST_UBLAS_INLINE
|
Chris@16
|
4586 matrix_indirect& operator -= (const matrix_expression<AE> &ae) {
|
Chris@16
|
4587 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
|
Chris@16
|
4588 return *this;
|
Chris@16
|
4589 }
|
Chris@16
|
4590 template<class AE>
|
Chris@16
|
4591 BOOST_UBLAS_INLINE
|
Chris@16
|
4592 matrix_indirect &minus_assign (const matrix_expression<AE> &ae) {
|
Chris@16
|
4593 matrix_assign<scalar_minus_assign> (*this, ae);
|
Chris@16
|
4594 return *this;
|
Chris@16
|
4595 }
|
Chris@16
|
4596 template<class AT>
|
Chris@16
|
4597 BOOST_UBLAS_INLINE
|
Chris@16
|
4598 matrix_indirect& operator *= (const AT &at) {
|
Chris@16
|
4599 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
|
Chris@16
|
4600 return *this;
|
Chris@16
|
4601 }
|
Chris@16
|
4602 template<class AT>
|
Chris@16
|
4603 BOOST_UBLAS_INLINE
|
Chris@16
|
4604 matrix_indirect& operator /= (const AT &at) {
|
Chris@16
|
4605 matrix_assign_scalar<scalar_divides_assign> (*this, at);
|
Chris@16
|
4606 return *this;
|
Chris@16
|
4607 }
|
Chris@16
|
4608
|
Chris@16
|
4609 // Closure comparison
|
Chris@16
|
4610 BOOST_UBLAS_INLINE
|
Chris@16
|
4611 bool same_closure (const matrix_indirect &mi) const {
|
Chris@16
|
4612 return (*this).data_.same_closure (mi.data_);
|
Chris@16
|
4613 }
|
Chris@16
|
4614
|
Chris@16
|
4615 // Comparison
|
Chris@16
|
4616 BOOST_UBLAS_INLINE
|
Chris@16
|
4617 bool operator == (const matrix_indirect &mi) const {
|
Chris@16
|
4618 return (*this).data_ == mi.data_ && ia1_ == mi.ia1_ && ia2_ == mi.ia2_;
|
Chris@16
|
4619 }
|
Chris@16
|
4620
|
Chris@16
|
4621 // Swapping
|
Chris@16
|
4622 BOOST_UBLAS_INLINE
|
Chris@16
|
4623 void swap (matrix_indirect mi) {
|
Chris@16
|
4624 if (this != &mi) {
|
Chris@16
|
4625 BOOST_UBLAS_CHECK (size1 () == mi.size1 (), bad_size ());
|
Chris@16
|
4626 BOOST_UBLAS_CHECK (size2 () == mi.size2 (), bad_size ());
|
Chris@16
|
4627 matrix_swap<scalar_swap> (*this, mi);
|
Chris@16
|
4628 }
|
Chris@16
|
4629 }
|
Chris@16
|
4630 BOOST_UBLAS_INLINE
|
Chris@16
|
4631 friend void swap (matrix_indirect mi1, matrix_indirect mi2) {
|
Chris@16
|
4632 mi1.swap (mi2);
|
Chris@16
|
4633 }
|
Chris@16
|
4634
|
Chris@16
|
4635 // Iterator types
|
Chris@16
|
4636 private:
|
Chris@16
|
4637 typedef typename IA::const_iterator const_subiterator1_type;
|
Chris@16
|
4638 typedef typename IA::const_iterator subiterator1_type;
|
Chris@16
|
4639 typedef typename IA::const_iterator const_subiterator2_type;
|
Chris@16
|
4640 typedef typename IA::const_iterator subiterator2_type;
|
Chris@16
|
4641
|
Chris@16
|
4642 public:
|
Chris@16
|
4643 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4644 typedef indexed_iterator1<matrix_indirect<matrix_type, indirect_array_type>,
|
Chris@16
|
4645 typename matrix_type::iterator1::iterator_category> iterator1;
|
Chris@16
|
4646 typedef indexed_iterator2<matrix_indirect<matrix_type, indirect_array_type>,
|
Chris@16
|
4647 typename matrix_type::iterator2::iterator_category> iterator2;
|
Chris@16
|
4648 typedef indexed_const_iterator1<matrix_indirect<matrix_type, indirect_array_type>,
|
Chris@16
|
4649 typename matrix_type::const_iterator1::iterator_category> const_iterator1;
|
Chris@16
|
4650 typedef indexed_const_iterator2<matrix_indirect<matrix_type, indirect_array_type>,
|
Chris@16
|
4651 typename matrix_type::const_iterator2::iterator_category> const_iterator2;
|
Chris@16
|
4652 #else
|
Chris@16
|
4653 class const_iterator1;
|
Chris@16
|
4654 class iterator1;
|
Chris@16
|
4655 class const_iterator2;
|
Chris@16
|
4656 class iterator2;
|
Chris@16
|
4657 #endif
|
Chris@16
|
4658 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
|
Chris@16
|
4659 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
|
Chris@16
|
4660 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
|
Chris@16
|
4661 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
|
Chris@16
|
4662
|
Chris@16
|
4663 // Element lookup
|
Chris@16
|
4664 BOOST_UBLAS_INLINE
|
Chris@16
|
4665 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
4666 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4667 return const_iterator1 (*this, i, j);
|
Chris@16
|
4668 #else
|
Chris@16
|
4669 return const_iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j);
|
Chris@16
|
4670 #endif
|
Chris@16
|
4671 }
|
Chris@16
|
4672 BOOST_UBLAS_INLINE
|
Chris@16
|
4673 iterator1 find1 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
4674 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4675 return iterator1 (*this, i, j);
|
Chris@16
|
4676 #else
|
Chris@16
|
4677 return iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j);
|
Chris@16
|
4678 #endif
|
Chris@16
|
4679 }
|
Chris@16
|
4680 BOOST_UBLAS_INLINE
|
Chris@16
|
4681 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
|
Chris@16
|
4682 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4683 return const_iterator2 (*this, i, j);
|
Chris@16
|
4684 #else
|
Chris@16
|
4685 return const_iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j);
|
Chris@16
|
4686 #endif
|
Chris@16
|
4687 }
|
Chris@16
|
4688 BOOST_UBLAS_INLINE
|
Chris@16
|
4689 iterator2 find2 (int /* rank */, size_type i, size_type j) {
|
Chris@16
|
4690 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4691 return iterator2 (*this, i, j);
|
Chris@16
|
4692 #else
|
Chris@16
|
4693 return iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j);
|
Chris@16
|
4694 #endif
|
Chris@16
|
4695 }
|
Chris@16
|
4696
|
Chris@16
|
4697 // Iterators simply are indices.
|
Chris@16
|
4698
|
Chris@16
|
4699 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4700 class const_iterator1:
|
Chris@16
|
4701 public container_const_reference<matrix_indirect>,
|
Chris@16
|
4702 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
|
Chris@16
|
4703 iterator_base<const_iterator1, value_type>::type {
|
Chris@16
|
4704 public:
|
Chris@16
|
4705 typedef typename M::const_iterator1::value_type value_type;
|
Chris@16
|
4706 typedef typename M::const_iterator1::difference_type difference_type;
|
Chris@16
|
4707 typedef typename M::const_reference reference; //FIXME due to indexing access
|
Chris@16
|
4708 typedef typename M::const_iterator1::pointer pointer;
|
Chris@16
|
4709 typedef const_iterator2 dual_iterator_type;
|
Chris@16
|
4710 typedef const_reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
4711
|
Chris@16
|
4712 // Construction and destruction
|
Chris@16
|
4713 BOOST_UBLAS_INLINE
|
Chris@16
|
4714 const_iterator1 ():
|
Chris@16
|
4715 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
4716 BOOST_UBLAS_INLINE
|
Chris@16
|
4717 const_iterator1 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
4718 container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
4719 BOOST_UBLAS_INLINE
|
Chris@16
|
4720 const_iterator1 (const iterator1 &it):
|
Chris@16
|
4721 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
4722
|
Chris@16
|
4723 // Arithmetic
|
Chris@16
|
4724 BOOST_UBLAS_INLINE
|
Chris@16
|
4725 const_iterator1 &operator ++ () {
|
Chris@16
|
4726 ++ it1_;
|
Chris@16
|
4727 return *this;
|
Chris@16
|
4728 }
|
Chris@16
|
4729 BOOST_UBLAS_INLINE
|
Chris@16
|
4730 const_iterator1 &operator -- () {
|
Chris@16
|
4731 -- it1_;
|
Chris@16
|
4732 return *this;
|
Chris@16
|
4733 }
|
Chris@16
|
4734 BOOST_UBLAS_INLINE
|
Chris@16
|
4735 const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
4736 it1_ += n;
|
Chris@16
|
4737 return *this;
|
Chris@16
|
4738 }
|
Chris@16
|
4739 BOOST_UBLAS_INLINE
|
Chris@16
|
4740 const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
4741 it1_ -= n;
|
Chris@16
|
4742 return *this;
|
Chris@16
|
4743 }
|
Chris@16
|
4744 BOOST_UBLAS_INLINE
|
Chris@16
|
4745 difference_type operator - (const const_iterator1 &it) const {
|
Chris@16
|
4746 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4747 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4748 return it1_ - it.it1_;
|
Chris@16
|
4749 }
|
Chris@16
|
4750
|
Chris@16
|
4751 // Dereference
|
Chris@16
|
4752 BOOST_UBLAS_INLINE
|
Chris@16
|
4753 const_reference operator * () const {
|
Chris@16
|
4754 // FIXME replace find with at_element
|
Chris@16
|
4755 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
4756 }
|
Chris@16
|
4757 BOOST_UBLAS_INLINE
|
Chris@16
|
4758 const_reference operator [] (difference_type n) const {
|
Chris@16
|
4759 return *(*this + n);
|
Chris@16
|
4760 }
|
Chris@16
|
4761
|
Chris@16
|
4762 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4763 BOOST_UBLAS_INLINE
|
Chris@16
|
4764 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4765 typename self_type::
|
Chris@16
|
4766 #endif
|
Chris@16
|
4767 const_iterator2 begin () const {
|
Chris@16
|
4768 return const_iterator2 ((*this) (), it1_, it2_ ().begin ());
|
Chris@16
|
4769 }
|
Chris@16
|
4770 BOOST_UBLAS_INLINE
|
Chris@16
|
4771 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4772 typename self_type::
|
Chris@16
|
4773 #endif
|
Chris@101
|
4774 const_iterator2 cbegin () const {
|
Chris@101
|
4775 return begin ();
|
Chris@101
|
4776 }
|
Chris@101
|
4777 BOOST_UBLAS_INLINE
|
Chris@101
|
4778 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4779 typename self_type::
|
Chris@101
|
4780 #endif
|
Chris@16
|
4781 const_iterator2 end () const {
|
Chris@16
|
4782 return const_iterator2 ((*this) (), it1_, it2_ ().end ());
|
Chris@16
|
4783 }
|
Chris@16
|
4784 BOOST_UBLAS_INLINE
|
Chris@16
|
4785 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4786 typename self_type::
|
Chris@16
|
4787 #endif
|
Chris@101
|
4788 const_iterator2 cend () const {
|
Chris@101
|
4789 return end ();
|
Chris@101
|
4790 }
|
Chris@101
|
4791 BOOST_UBLAS_INLINE
|
Chris@101
|
4792 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4793 typename self_type::
|
Chris@101
|
4794 #endif
|
Chris@16
|
4795 const_reverse_iterator2 rbegin () const {
|
Chris@16
|
4796 return const_reverse_iterator2 (end ());
|
Chris@16
|
4797 }
|
Chris@16
|
4798 BOOST_UBLAS_INLINE
|
Chris@16
|
4799 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4800 typename self_type::
|
Chris@16
|
4801 #endif
|
Chris@101
|
4802 const_reverse_iterator2 crbegin () const {
|
Chris@101
|
4803 return rbegin ();
|
Chris@101
|
4804 }
|
Chris@101
|
4805 BOOST_UBLAS_INLINE
|
Chris@101
|
4806 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4807 typename self_type::
|
Chris@101
|
4808 #endif
|
Chris@16
|
4809 const_reverse_iterator2 rend () const {
|
Chris@16
|
4810 return const_reverse_iterator2 (begin ());
|
Chris@16
|
4811 }
|
Chris@101
|
4812 BOOST_UBLAS_INLINE
|
Chris@101
|
4813 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
4814 typename self_type::
|
Chris@101
|
4815 #endif
|
Chris@101
|
4816 const_reverse_iterator2 crend () const {
|
Chris@101
|
4817 return rend ();
|
Chris@101
|
4818 }
|
Chris@16
|
4819 #endif
|
Chris@16
|
4820
|
Chris@16
|
4821 // Indices
|
Chris@16
|
4822 BOOST_UBLAS_INLINE
|
Chris@16
|
4823 size_type index1 () const {
|
Chris@16
|
4824 return it1_.index ();
|
Chris@16
|
4825 }
|
Chris@16
|
4826 BOOST_UBLAS_INLINE
|
Chris@16
|
4827 size_type index2 () const {
|
Chris@16
|
4828 return it2_.index ();
|
Chris@16
|
4829 }
|
Chris@16
|
4830
|
Chris@16
|
4831 // Assignment
|
Chris@16
|
4832 BOOST_UBLAS_INLINE
|
Chris@16
|
4833 const_iterator1 &operator = (const const_iterator1 &it) {
|
Chris@16
|
4834 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
4835 it1_ = it.it1_;
|
Chris@16
|
4836 it2_ = it.it2_;
|
Chris@16
|
4837 return *this;
|
Chris@16
|
4838 }
|
Chris@16
|
4839
|
Chris@16
|
4840 // Comparison
|
Chris@16
|
4841 BOOST_UBLAS_INLINE
|
Chris@16
|
4842 bool operator == (const const_iterator1 &it) const {
|
Chris@16
|
4843 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4844 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4845 return it1_ == it.it1_;
|
Chris@16
|
4846 }
|
Chris@16
|
4847 BOOST_UBLAS_INLINE
|
Chris@16
|
4848 bool operator < (const const_iterator1 &it) const {
|
Chris@16
|
4849 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4850 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4851 return it1_ < it.it1_;
|
Chris@16
|
4852 }
|
Chris@16
|
4853
|
Chris@16
|
4854 private:
|
Chris@16
|
4855 const_subiterator1_type it1_;
|
Chris@16
|
4856 const_subiterator2_type it2_;
|
Chris@16
|
4857 };
|
Chris@16
|
4858 #endif
|
Chris@16
|
4859
|
Chris@16
|
4860 BOOST_UBLAS_INLINE
|
Chris@16
|
4861 const_iterator1 begin1 () const {
|
Chris@16
|
4862 return find1 (0, 0, 0);
|
Chris@16
|
4863 }
|
Chris@16
|
4864 BOOST_UBLAS_INLINE
|
Chris@101
|
4865 const_iterator1 cbegin1 () const {
|
Chris@101
|
4866 return begin1 ();
|
Chris@101
|
4867 }
|
Chris@101
|
4868 BOOST_UBLAS_INLINE
|
Chris@16
|
4869 const_iterator1 end1 () const {
|
Chris@16
|
4870 return find1 (0, size1 (), 0);
|
Chris@16
|
4871 }
|
Chris@101
|
4872 BOOST_UBLAS_INLINE
|
Chris@101
|
4873 const_iterator1 cend1 () const {
|
Chris@101
|
4874 return end1 ();
|
Chris@101
|
4875 }
|
Chris@16
|
4876
|
Chris@16
|
4877 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
4878 class iterator1:
|
Chris@16
|
4879 public container_reference<matrix_indirect>,
|
Chris@16
|
4880 public iterator_base_traits<typename M::iterator1::iterator_category>::template
|
Chris@16
|
4881 iterator_base<iterator1, value_type>::type {
|
Chris@16
|
4882 public:
|
Chris@16
|
4883 typedef typename M::iterator1::value_type value_type;
|
Chris@16
|
4884 typedef typename M::iterator1::difference_type difference_type;
|
Chris@16
|
4885 typedef typename M::reference reference; //FIXME due to indexing access
|
Chris@16
|
4886 typedef typename M::iterator1::pointer pointer;
|
Chris@16
|
4887 typedef iterator2 dual_iterator_type;
|
Chris@16
|
4888 typedef reverse_iterator2 dual_reverse_iterator_type;
|
Chris@16
|
4889
|
Chris@16
|
4890 // Construction and destruction
|
Chris@16
|
4891 BOOST_UBLAS_INLINE
|
Chris@16
|
4892 iterator1 ():
|
Chris@16
|
4893 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
4894 BOOST_UBLAS_INLINE
|
Chris@16
|
4895 iterator1 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
4896 container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
4897
|
Chris@16
|
4898 // Arithmetic
|
Chris@16
|
4899 BOOST_UBLAS_INLINE
|
Chris@16
|
4900 iterator1 &operator ++ () {
|
Chris@16
|
4901 ++ it1_;
|
Chris@16
|
4902 return *this;
|
Chris@16
|
4903 }
|
Chris@16
|
4904 BOOST_UBLAS_INLINE
|
Chris@16
|
4905 iterator1 &operator -- () {
|
Chris@16
|
4906 -- it1_;
|
Chris@16
|
4907 return *this;
|
Chris@16
|
4908 }
|
Chris@16
|
4909 BOOST_UBLAS_INLINE
|
Chris@16
|
4910 iterator1 &operator += (difference_type n) {
|
Chris@16
|
4911 it1_ += n;
|
Chris@16
|
4912 return *this;
|
Chris@16
|
4913 }
|
Chris@16
|
4914 BOOST_UBLAS_INLINE
|
Chris@16
|
4915 iterator1 &operator -= (difference_type n) {
|
Chris@16
|
4916 it1_ -= n;
|
Chris@16
|
4917 return *this;
|
Chris@16
|
4918 }
|
Chris@16
|
4919 BOOST_UBLAS_INLINE
|
Chris@16
|
4920 difference_type operator - (const iterator1 &it) const {
|
Chris@16
|
4921 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4922 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4923 return it1_ - it.it1_;
|
Chris@16
|
4924 }
|
Chris@16
|
4925
|
Chris@16
|
4926 // Dereference
|
Chris@16
|
4927 BOOST_UBLAS_INLINE
|
Chris@16
|
4928 reference operator * () const {
|
Chris@16
|
4929 // FIXME replace find with at_element
|
Chris@16
|
4930 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
4931 }
|
Chris@16
|
4932 BOOST_UBLAS_INLINE
|
Chris@16
|
4933 reference operator [] (difference_type n) const {
|
Chris@16
|
4934 return *(*this + n);
|
Chris@16
|
4935 }
|
Chris@16
|
4936
|
Chris@16
|
4937 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
4938 BOOST_UBLAS_INLINE
|
Chris@16
|
4939 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4940 typename self_type::
|
Chris@16
|
4941 #endif
|
Chris@16
|
4942 iterator2 begin () const {
|
Chris@16
|
4943 return iterator2 ((*this) (), it1_, it2_ ().begin ());
|
Chris@16
|
4944 }
|
Chris@16
|
4945 BOOST_UBLAS_INLINE
|
Chris@16
|
4946 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4947 typename self_type::
|
Chris@16
|
4948 #endif
|
Chris@16
|
4949 iterator2 end () const {
|
Chris@16
|
4950 return iterator2 ((*this) (), it1_, it2_ ().end ());
|
Chris@16
|
4951 }
|
Chris@16
|
4952 BOOST_UBLAS_INLINE
|
Chris@16
|
4953 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4954 typename self_type::
|
Chris@16
|
4955 #endif
|
Chris@16
|
4956 reverse_iterator2 rbegin () const {
|
Chris@16
|
4957 return reverse_iterator2 (end ());
|
Chris@16
|
4958 }
|
Chris@16
|
4959 BOOST_UBLAS_INLINE
|
Chris@16
|
4960 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
4961 typename self_type::
|
Chris@16
|
4962 #endif
|
Chris@16
|
4963 reverse_iterator2 rend () const {
|
Chris@16
|
4964 return reverse_iterator2 (begin ());
|
Chris@16
|
4965 }
|
Chris@16
|
4966 #endif
|
Chris@16
|
4967
|
Chris@16
|
4968 // Indices
|
Chris@16
|
4969 BOOST_UBLAS_INLINE
|
Chris@16
|
4970 size_type index1 () const {
|
Chris@16
|
4971 return it1_.index ();
|
Chris@16
|
4972 }
|
Chris@16
|
4973 BOOST_UBLAS_INLINE
|
Chris@16
|
4974 size_type index2 () const {
|
Chris@16
|
4975 return it2_.index ();
|
Chris@16
|
4976 }
|
Chris@16
|
4977
|
Chris@16
|
4978 // Assignment
|
Chris@16
|
4979 BOOST_UBLAS_INLINE
|
Chris@16
|
4980 iterator1 &operator = (const iterator1 &it) {
|
Chris@16
|
4981 container_reference<self_type>::assign (&it ());
|
Chris@16
|
4982 it1_ = it.it1_;
|
Chris@16
|
4983 it2_ = it.it2_;
|
Chris@16
|
4984 return *this;
|
Chris@16
|
4985 }
|
Chris@16
|
4986
|
Chris@16
|
4987 // Comparison
|
Chris@16
|
4988 BOOST_UBLAS_INLINE
|
Chris@16
|
4989 bool operator == (const iterator1 &it) const {
|
Chris@16
|
4990 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4991 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4992 return it1_ == it.it1_;
|
Chris@16
|
4993 }
|
Chris@16
|
4994 BOOST_UBLAS_INLINE
|
Chris@16
|
4995 bool operator < (const iterator1 &it) const {
|
Chris@16
|
4996 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
4997 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
4998 return it1_ < it.it1_;
|
Chris@16
|
4999 }
|
Chris@16
|
5000
|
Chris@16
|
5001 private:
|
Chris@16
|
5002 subiterator1_type it1_;
|
Chris@16
|
5003 subiterator2_type it2_;
|
Chris@16
|
5004
|
Chris@16
|
5005 friend class const_iterator1;
|
Chris@16
|
5006 };
|
Chris@16
|
5007 #endif
|
Chris@16
|
5008
|
Chris@16
|
5009 BOOST_UBLAS_INLINE
|
Chris@16
|
5010 iterator1 begin1 () {
|
Chris@16
|
5011 return find1 (0, 0, 0);
|
Chris@16
|
5012 }
|
Chris@16
|
5013 BOOST_UBLAS_INLINE
|
Chris@16
|
5014 iterator1 end1 () {
|
Chris@16
|
5015 return find1 (0, size1 (), 0);
|
Chris@16
|
5016 }
|
Chris@16
|
5017
|
Chris@16
|
5018 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
5019 class const_iterator2:
|
Chris@16
|
5020 public container_const_reference<matrix_indirect>,
|
Chris@16
|
5021 public iterator_base_traits<typename M::const_iterator2::iterator_category>::template
|
Chris@16
|
5022 iterator_base<const_iterator2, value_type>::type {
|
Chris@16
|
5023 public:
|
Chris@16
|
5024 typedef typename M::const_iterator2::value_type value_type;
|
Chris@16
|
5025 typedef typename M::const_iterator2::difference_type difference_type;
|
Chris@16
|
5026 typedef typename M::const_reference reference; //FIXME due to indexing access
|
Chris@16
|
5027 typedef typename M::const_iterator2::pointer pointer;
|
Chris@16
|
5028 typedef const_iterator1 dual_iterator_type;
|
Chris@16
|
5029 typedef const_reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
5030
|
Chris@16
|
5031 // Construction and destruction
|
Chris@16
|
5032 BOOST_UBLAS_INLINE
|
Chris@16
|
5033 const_iterator2 ():
|
Chris@16
|
5034 container_const_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
5035 BOOST_UBLAS_INLINE
|
Chris@16
|
5036 const_iterator2 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
|
Chris@16
|
5037 container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
5038 BOOST_UBLAS_INLINE
|
Chris@16
|
5039 const_iterator2 (const iterator2 &it):
|
Chris@16
|
5040 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
|
Chris@16
|
5041
|
Chris@16
|
5042 // Arithmetic
|
Chris@16
|
5043 BOOST_UBLAS_INLINE
|
Chris@16
|
5044 const_iterator2 &operator ++ () {
|
Chris@16
|
5045 ++ it2_;
|
Chris@16
|
5046 return *this;
|
Chris@16
|
5047 }
|
Chris@16
|
5048 BOOST_UBLAS_INLINE
|
Chris@16
|
5049 const_iterator2 &operator -- () {
|
Chris@16
|
5050 -- it2_;
|
Chris@16
|
5051 return *this;
|
Chris@16
|
5052 }
|
Chris@16
|
5053 BOOST_UBLAS_INLINE
|
Chris@16
|
5054 const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
5055 it2_ += n;
|
Chris@16
|
5056 return *this;
|
Chris@16
|
5057 }
|
Chris@16
|
5058 BOOST_UBLAS_INLINE
|
Chris@16
|
5059 const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
5060 it2_ -= n;
|
Chris@16
|
5061 return *this;
|
Chris@16
|
5062 }
|
Chris@16
|
5063 BOOST_UBLAS_INLINE
|
Chris@16
|
5064 difference_type operator - (const const_iterator2 &it) const {
|
Chris@16
|
5065 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5066 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5067 return it2_ - it.it2_;
|
Chris@16
|
5068 }
|
Chris@16
|
5069
|
Chris@16
|
5070 // Dereference
|
Chris@16
|
5071 BOOST_UBLAS_INLINE
|
Chris@16
|
5072 const_reference operator * () const {
|
Chris@16
|
5073 // FIXME replace find with at_element
|
Chris@16
|
5074 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
5075 }
|
Chris@16
|
5076 BOOST_UBLAS_INLINE
|
Chris@16
|
5077 const_reference operator [] (difference_type n) const {
|
Chris@16
|
5078 return *(*this + n);
|
Chris@16
|
5079 }
|
Chris@16
|
5080
|
Chris@16
|
5081 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
5082 BOOST_UBLAS_INLINE
|
Chris@16
|
5083 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5084 typename self_type::
|
Chris@16
|
5085 #endif
|
Chris@16
|
5086 const_iterator1 begin () const {
|
Chris@16
|
5087 return const_iterator1 ((*this) (), it1_ ().begin (), it2_);
|
Chris@16
|
5088 }
|
Chris@16
|
5089 BOOST_UBLAS_INLINE
|
Chris@16
|
5090 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5091 typename self_type::
|
Chris@16
|
5092 #endif
|
Chris@101
|
5093 const_iterator1 cbegin () const {
|
Chris@101
|
5094 return begin ();
|
Chris@101
|
5095 }
|
Chris@101
|
5096 BOOST_UBLAS_INLINE
|
Chris@101
|
5097 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
5098 typename self_type::
|
Chris@101
|
5099 #endif
|
Chris@16
|
5100 const_iterator1 end () const {
|
Chris@16
|
5101 return const_iterator1 ((*this) (), it1_ ().end (), it2_);
|
Chris@16
|
5102 }
|
Chris@16
|
5103 BOOST_UBLAS_INLINE
|
Chris@16
|
5104 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5105 typename self_type::
|
Chris@16
|
5106 #endif
|
Chris@101
|
5107 const_iterator1 cend () const {
|
Chris@101
|
5108 return end ();
|
Chris@101
|
5109 }
|
Chris@101
|
5110 BOOST_UBLAS_INLINE
|
Chris@101
|
5111 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
5112 typename self_type::
|
Chris@101
|
5113 #endif
|
Chris@16
|
5114 const_reverse_iterator1 rbegin () const {
|
Chris@16
|
5115 return const_reverse_iterator1 (end ());
|
Chris@16
|
5116 }
|
Chris@16
|
5117 BOOST_UBLAS_INLINE
|
Chris@16
|
5118 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5119 typename self_type::
|
Chris@16
|
5120 #endif
|
Chris@101
|
5121 const_reverse_iterator1 crbegin () const {
|
Chris@101
|
5122 return rbegin ();
|
Chris@101
|
5123 }
|
Chris@101
|
5124 BOOST_UBLAS_INLINE
|
Chris@101
|
5125 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
5126 typename self_type::
|
Chris@101
|
5127 #endif
|
Chris@16
|
5128 const_reverse_iterator1 rend () const {
|
Chris@16
|
5129 return const_reverse_iterator1 (begin ());
|
Chris@16
|
5130 }
|
Chris@101
|
5131 BOOST_UBLAS_INLINE
|
Chris@101
|
5132 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@101
|
5133 typename self_type::
|
Chris@101
|
5134 #endif
|
Chris@101
|
5135 const_reverse_iterator1 crend () const {
|
Chris@101
|
5136 return rend ();
|
Chris@101
|
5137 }
|
Chris@16
|
5138 #endif
|
Chris@16
|
5139
|
Chris@16
|
5140 // Indices
|
Chris@16
|
5141 BOOST_UBLAS_INLINE
|
Chris@16
|
5142 size_type index1 () const {
|
Chris@16
|
5143 return it1_.index ();
|
Chris@16
|
5144 }
|
Chris@16
|
5145 BOOST_UBLAS_INLINE
|
Chris@16
|
5146 size_type index2 () const {
|
Chris@16
|
5147 return it2_.index ();
|
Chris@16
|
5148 }
|
Chris@16
|
5149
|
Chris@16
|
5150 // Assignment
|
Chris@16
|
5151 BOOST_UBLAS_INLINE
|
Chris@16
|
5152 const_iterator2 &operator = (const const_iterator2 &it) {
|
Chris@16
|
5153 container_const_reference<self_type>::assign (&it ());
|
Chris@16
|
5154 it1_ = it.it1_;
|
Chris@16
|
5155 it2_ = it.it2_;
|
Chris@16
|
5156 return *this;
|
Chris@16
|
5157 }
|
Chris@16
|
5158
|
Chris@16
|
5159 // Comparison
|
Chris@16
|
5160 BOOST_UBLAS_INLINE
|
Chris@16
|
5161 bool operator == (const const_iterator2 &it) const {
|
Chris@16
|
5162 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5163 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5164 return it2_ == it.it2_;
|
Chris@16
|
5165 }
|
Chris@16
|
5166 BOOST_UBLAS_INLINE
|
Chris@16
|
5167 bool operator < (const const_iterator2 &it) const {
|
Chris@16
|
5168 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5169 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5170 return it2_ < it.it2_;
|
Chris@16
|
5171 }
|
Chris@16
|
5172
|
Chris@16
|
5173 private:
|
Chris@16
|
5174 const_subiterator1_type it1_;
|
Chris@16
|
5175 const_subiterator2_type it2_;
|
Chris@16
|
5176 };
|
Chris@16
|
5177 #endif
|
Chris@16
|
5178
|
Chris@16
|
5179 BOOST_UBLAS_INLINE
|
Chris@16
|
5180 const_iterator2 begin2 () const {
|
Chris@16
|
5181 return find2 (0, 0, 0);
|
Chris@16
|
5182 }
|
Chris@16
|
5183 BOOST_UBLAS_INLINE
|
Chris@101
|
5184 const_iterator2 cbegin2 () const {
|
Chris@101
|
5185 return begin2 ();
|
Chris@101
|
5186 }
|
Chris@101
|
5187 BOOST_UBLAS_INLINE
|
Chris@16
|
5188 const_iterator2 end2 () const {
|
Chris@16
|
5189 return find2 (0, 0, size2 ());
|
Chris@16
|
5190 }
|
Chris@101
|
5191 BOOST_UBLAS_INLINE
|
Chris@101
|
5192 const_iterator2 cend2 () const {
|
Chris@101
|
5193 return end2 ();
|
Chris@101
|
5194 }
|
Chris@16
|
5195
|
Chris@16
|
5196 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
5197 class iterator2:
|
Chris@16
|
5198 public container_reference<matrix_indirect>,
|
Chris@16
|
5199 public iterator_base_traits<typename M::iterator2::iterator_category>::template
|
Chris@16
|
5200 iterator_base<iterator2, value_type>::type {
|
Chris@16
|
5201 public:
|
Chris@16
|
5202 typedef typename M::iterator2::value_type value_type;
|
Chris@16
|
5203 typedef typename M::iterator2::difference_type difference_type;
|
Chris@16
|
5204 typedef typename M::reference reference; //FIXME due to indexing access
|
Chris@16
|
5205 typedef typename M::iterator2::pointer pointer;
|
Chris@16
|
5206 typedef iterator1 dual_iterator_type;
|
Chris@16
|
5207 typedef reverse_iterator1 dual_reverse_iterator_type;
|
Chris@16
|
5208
|
Chris@16
|
5209 // Construction and destruction
|
Chris@16
|
5210 BOOST_UBLAS_INLINE
|
Chris@16
|
5211 iterator2 ():
|
Chris@16
|
5212 container_reference<self_type> (), it1_ (), it2_ () {}
|
Chris@16
|
5213 BOOST_UBLAS_INLINE
|
Chris@16
|
5214 iterator2 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2):
|
Chris@16
|
5215 container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
5216
|
Chris@16
|
5217 // Arithmetic
|
Chris@16
|
5218 BOOST_UBLAS_INLINE
|
Chris@16
|
5219 iterator2 &operator ++ () {
|
Chris@16
|
5220 ++ it2_;
|
Chris@16
|
5221 return *this;
|
Chris@16
|
5222 }
|
Chris@16
|
5223 BOOST_UBLAS_INLINE
|
Chris@16
|
5224 iterator2 &operator -- () {
|
Chris@16
|
5225 -- it2_;
|
Chris@16
|
5226 return *this;
|
Chris@16
|
5227 }
|
Chris@16
|
5228 BOOST_UBLAS_INLINE
|
Chris@16
|
5229 iterator2 &operator += (difference_type n) {
|
Chris@16
|
5230 it2_ += n;
|
Chris@16
|
5231 return *this;
|
Chris@16
|
5232 }
|
Chris@16
|
5233 BOOST_UBLAS_INLINE
|
Chris@16
|
5234 iterator2 &operator -= (difference_type n) {
|
Chris@16
|
5235 it2_ -= n;
|
Chris@16
|
5236 return *this;
|
Chris@16
|
5237 }
|
Chris@16
|
5238 BOOST_UBLAS_INLINE
|
Chris@16
|
5239 difference_type operator - (const iterator2 &it) const {
|
Chris@16
|
5240 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5241 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5242 return it2_ - it.it2_;
|
Chris@16
|
5243 }
|
Chris@16
|
5244
|
Chris@16
|
5245 // Dereference
|
Chris@16
|
5246 BOOST_UBLAS_INLINE
|
Chris@16
|
5247 reference operator * () const {
|
Chris@16
|
5248 // FIXME replace find with at_element
|
Chris@16
|
5249 return (*this) ().data_ (*it1_, *it2_);
|
Chris@16
|
5250 }
|
Chris@16
|
5251 BOOST_UBLAS_INLINE
|
Chris@16
|
5252 reference operator [] (difference_type n) const {
|
Chris@16
|
5253 return *(*this + n);
|
Chris@16
|
5254 }
|
Chris@16
|
5255
|
Chris@16
|
5256 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
5257 BOOST_UBLAS_INLINE
|
Chris@16
|
5258 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5259 typename self_type::
|
Chris@16
|
5260 #endif
|
Chris@16
|
5261 iterator1 begin () const {
|
Chris@16
|
5262 return iterator1 ((*this) (), it1_ ().begin (), it2_);
|
Chris@16
|
5263 }
|
Chris@16
|
5264 BOOST_UBLAS_INLINE
|
Chris@16
|
5265 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5266 typename self_type::
|
Chris@16
|
5267 #endif
|
Chris@16
|
5268 iterator1 end () const {
|
Chris@16
|
5269 return iterator1 ((*this) (), it1_ ().end (), it2_);
|
Chris@16
|
5270 }
|
Chris@16
|
5271 BOOST_UBLAS_INLINE
|
Chris@16
|
5272 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5273 typename self_type::
|
Chris@16
|
5274 #endif
|
Chris@16
|
5275 reverse_iterator1 rbegin () const {
|
Chris@16
|
5276 return reverse_iterator1 (end ());
|
Chris@16
|
5277 }
|
Chris@16
|
5278 BOOST_UBLAS_INLINE
|
Chris@16
|
5279 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
|
Chris@16
|
5280 typename self_type::
|
Chris@16
|
5281 #endif
|
Chris@16
|
5282 reverse_iterator1 rend () const {
|
Chris@16
|
5283 return reverse_iterator1 (begin ());
|
Chris@16
|
5284 }
|
Chris@16
|
5285 #endif
|
Chris@16
|
5286
|
Chris@16
|
5287 // Indices
|
Chris@16
|
5288 BOOST_UBLAS_INLINE
|
Chris@16
|
5289 size_type index1 () const {
|
Chris@16
|
5290 return it1_.index ();
|
Chris@16
|
5291 }
|
Chris@16
|
5292 BOOST_UBLAS_INLINE
|
Chris@16
|
5293 size_type index2 () const {
|
Chris@16
|
5294 return it2_.index ();
|
Chris@16
|
5295 }
|
Chris@16
|
5296
|
Chris@16
|
5297 // Assignment
|
Chris@16
|
5298 BOOST_UBLAS_INLINE
|
Chris@16
|
5299 iterator2 &operator = (const iterator2 &it) {
|
Chris@16
|
5300 container_reference<self_type>::assign (&it ());
|
Chris@16
|
5301 it1_ = it.it1_;
|
Chris@16
|
5302 it2_ = it.it2_;
|
Chris@16
|
5303 return *this;
|
Chris@16
|
5304 }
|
Chris@16
|
5305
|
Chris@16
|
5306 // Comparison
|
Chris@16
|
5307 BOOST_UBLAS_INLINE
|
Chris@16
|
5308 bool operator == (const iterator2 &it) const {
|
Chris@16
|
5309 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5310 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5311 return it2_ == it.it2_;
|
Chris@16
|
5312 }
|
Chris@16
|
5313 BOOST_UBLAS_INLINE
|
Chris@16
|
5314 bool operator < (const iterator2 &it) const {
|
Chris@16
|
5315 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
|
Chris@16
|
5316 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
5317 return it2_ < it.it2_;
|
Chris@16
|
5318 }
|
Chris@16
|
5319
|
Chris@16
|
5320 private:
|
Chris@16
|
5321 subiterator1_type it1_;
|
Chris@16
|
5322 subiterator2_type it2_;
|
Chris@16
|
5323
|
Chris@16
|
5324 friend class const_iterator2;
|
Chris@16
|
5325 };
|
Chris@16
|
5326 #endif
|
Chris@16
|
5327
|
Chris@16
|
5328 BOOST_UBLAS_INLINE
|
Chris@16
|
5329 iterator2 begin2 () {
|
Chris@16
|
5330 return find2 (0, 0, 0);
|
Chris@16
|
5331 }
|
Chris@16
|
5332 BOOST_UBLAS_INLINE
|
Chris@16
|
5333 iterator2 end2 () {
|
Chris@16
|
5334 return find2 (0, 0, size2 ());
|
Chris@16
|
5335 }
|
Chris@16
|
5336
|
Chris@16
|
5337 // Reverse iterators
|
Chris@16
|
5338
|
Chris@16
|
5339 BOOST_UBLAS_INLINE
|
Chris@16
|
5340 const_reverse_iterator1 rbegin1 () const {
|
Chris@16
|
5341 return const_reverse_iterator1 (end1 ());
|
Chris@16
|
5342 }
|
Chris@16
|
5343 BOOST_UBLAS_INLINE
|
Chris@101
|
5344 const_reverse_iterator1 crbegin1 () const {
|
Chris@101
|
5345 return rbegin1 ();
|
Chris@101
|
5346 }
|
Chris@101
|
5347 BOOST_UBLAS_INLINE
|
Chris@16
|
5348 const_reverse_iterator1 rend1 () const {
|
Chris@16
|
5349 return const_reverse_iterator1 (begin1 ());
|
Chris@16
|
5350 }
|
Chris@101
|
5351 BOOST_UBLAS_INLINE
|
Chris@101
|
5352 const_reverse_iterator1 crend1 () const {
|
Chris@101
|
5353 return rend1 ();
|
Chris@101
|
5354 }
|
Chris@16
|
5355
|
Chris@16
|
5356 BOOST_UBLAS_INLINE
|
Chris@16
|
5357 reverse_iterator1 rbegin1 () {
|
Chris@16
|
5358 return reverse_iterator1 (end1 ());
|
Chris@16
|
5359 }
|
Chris@16
|
5360 BOOST_UBLAS_INLINE
|
Chris@16
|
5361 reverse_iterator1 rend1 () {
|
Chris@16
|
5362 return reverse_iterator1 (begin1 ());
|
Chris@16
|
5363 }
|
Chris@16
|
5364
|
Chris@16
|
5365 BOOST_UBLAS_INLINE
|
Chris@16
|
5366 const_reverse_iterator2 rbegin2 () const {
|
Chris@16
|
5367 return const_reverse_iterator2 (end2 ());
|
Chris@16
|
5368 }
|
Chris@16
|
5369 BOOST_UBLAS_INLINE
|
Chris@101
|
5370 const_reverse_iterator2 crbegin2 () const {
|
Chris@101
|
5371 return rbegin2 ();
|
Chris@101
|
5372 }
|
Chris@101
|
5373 BOOST_UBLAS_INLINE
|
Chris@16
|
5374 const_reverse_iterator2 rend2 () const {
|
Chris@16
|
5375 return const_reverse_iterator2 (begin2 ());
|
Chris@16
|
5376 }
|
Chris@101
|
5377 BOOST_UBLAS_INLINE
|
Chris@101
|
5378 const_reverse_iterator2 crend2 () const {
|
Chris@101
|
5379 return rend2 ();
|
Chris@101
|
5380 }
|
Chris@16
|
5381
|
Chris@16
|
5382 BOOST_UBLAS_INLINE
|
Chris@16
|
5383 reverse_iterator2 rbegin2 () {
|
Chris@16
|
5384 return reverse_iterator2 (end2 ());
|
Chris@16
|
5385 }
|
Chris@16
|
5386 BOOST_UBLAS_INLINE
|
Chris@16
|
5387 reverse_iterator2 rend2 () {
|
Chris@16
|
5388 return reverse_iterator2 (begin2 ());
|
Chris@16
|
5389 }
|
Chris@16
|
5390
|
Chris@16
|
5391 private:
|
Chris@16
|
5392 matrix_closure_type data_;
|
Chris@16
|
5393 indirect_array_type ia1_;
|
Chris@16
|
5394 indirect_array_type ia2_;
|
Chris@16
|
5395 };
|
Chris@16
|
5396
|
Chris@16
|
5397 // Projections
|
Chris@16
|
5398 template<class M, class A>
|
Chris@16
|
5399 BOOST_UBLAS_INLINE
|
Chris@16
|
5400 matrix_indirect<M, indirect_array<A> > project (M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
|
Chris@16
|
5401 return matrix_indirect<M, indirect_array<A> > (data, ia1, ia2);
|
Chris@16
|
5402 }
|
Chris@16
|
5403 template<class M, class A>
|
Chris@16
|
5404 BOOST_UBLAS_INLINE
|
Chris@16
|
5405 const matrix_indirect<const M, indirect_array<A> > project (const M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
|
Chris@16
|
5406 // ISSUE was: return matrix_indirect<M, indirect_array<A> > (const_cast<M &> (data), ia1, ia2);
|
Chris@16
|
5407 return matrix_indirect<const M, indirect_array<A> > (data, ia1, ia2);
|
Chris@16
|
5408 }
|
Chris@16
|
5409 template<class M, class IA>
|
Chris@16
|
5410 BOOST_UBLAS_INLINE
|
Chris@16
|
5411 matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) {
|
Chris@16
|
5412 return data.project (r1, r2);
|
Chris@16
|
5413 }
|
Chris@16
|
5414 template<class M, class IA>
|
Chris@16
|
5415 BOOST_UBLAS_INLINE
|
Chris@16
|
5416 const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) {
|
Chris@16
|
5417 return data.project (r1, r2);
|
Chris@16
|
5418 }
|
Chris@16
|
5419 template<class M, class IA>
|
Chris@16
|
5420 BOOST_UBLAS_INLINE
|
Chris@16
|
5421 matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) {
|
Chris@16
|
5422 return data.project (s1, s2);
|
Chris@16
|
5423 }
|
Chris@16
|
5424 template<class M, class IA>
|
Chris@16
|
5425 BOOST_UBLAS_INLINE
|
Chris@16
|
5426 const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) {
|
Chris@16
|
5427 return data.project (s1, s2);
|
Chris@16
|
5428 }
|
Chris@16
|
5429 template<class M, class A>
|
Chris@16
|
5430 BOOST_UBLAS_INLINE
|
Chris@16
|
5431 matrix_indirect<M, indirect_array<A> > project (matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
|
Chris@16
|
5432 return data.project (ia1, ia2);
|
Chris@16
|
5433 }
|
Chris@16
|
5434 template<class M, class A>
|
Chris@16
|
5435 BOOST_UBLAS_INLINE
|
Chris@16
|
5436 const matrix_indirect<M, indirect_array<A> > project (const matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
|
Chris@16
|
5437 return data.project (ia1, ia2);
|
Chris@16
|
5438 }
|
Chris@16
|
5439
|
Chris@16
|
5440 /// Specialization of temporary_traits
|
Chris@16
|
5441 template <class M>
|
Chris@16
|
5442 struct matrix_temporary_traits< matrix_indirect<M> >
|
Chris@16
|
5443 : matrix_temporary_traits< M > {};
|
Chris@16
|
5444 template <class M>
|
Chris@16
|
5445 struct matrix_temporary_traits< const matrix_indirect<M> >
|
Chris@16
|
5446 : matrix_temporary_traits< M > {};
|
Chris@16
|
5447
|
Chris@16
|
5448 template <class M>
|
Chris@16
|
5449 struct vector_temporary_traits< matrix_indirect<M> >
|
Chris@16
|
5450 : vector_temporary_traits< M > {};
|
Chris@16
|
5451 template <class M>
|
Chris@16
|
5452 struct vector_temporary_traits< const matrix_indirect<M> >
|
Chris@16
|
5453 : vector_temporary_traits< M > {};
|
Chris@16
|
5454
|
Chris@16
|
5455 }}}
|
Chris@16
|
5456
|
Chris@16
|
5457 #endif
|