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