blob: 674c610ed55e5c283f37f35b2885631f2bffd427 [file] [log] [blame]
Brian Silvermandc6866b2018-08-05 00:18:23 -07001//
2// Copyright (c) 2000-2002
3// Joerg Walter, Mathias Koch
4//
5// Distributed under the Boost Software License, Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// The authors gratefully acknowledge the support of
10// GeNeSys mbH & Co. KG in producing this work.
11//
12
13#ifndef _BOOST_UBLAS_CONCEPTS_
14#define _BOOST_UBLAS_CONCEPTS_
15
16#include <boost/concept_check.hpp>
17
18// Concept checks based on ideas of Jeremy Siek
19
20namespace boost { namespace numeric { namespace ublas {
21
22
23 template<class I>
24 struct Indexed1DIteratorConcept {
25 typedef I iterator_type;
26
27 void constraints () {
28 iterator_type it = iterator_type ();
29 // Index
30 it.index ();
31 }
32 };
33
34 template<class I>
35 struct IndexedBidirectional1DIteratorConcept {
36 typedef I iterator_type;
37
38 void constraints () {
39 function_requires< BidirectionalIteratorConcept<iterator_type> >();
40 function_requires< Indexed1DIteratorConcept<iterator_type> >();
41 }
42 };
43
44 template<class I>
45 struct Mutable_IndexedBidirectional1DIteratorConcept {
46 typedef I iterator_type;
47
48 void constraints () {
49 function_requires< Mutable_BidirectionalIteratorConcept<iterator_type> >();
50 function_requires< Indexed1DIteratorConcept<iterator_type> >();
51 }
52 };
53
54 template<class I>
55 struct IndexedRandomAccess1DIteratorConcept {
56 typedef I iterator_type;
57
58 void constraints () {
59 function_requires< RandomAccessIteratorConcept<iterator_type> >();
60 function_requires< Indexed1DIteratorConcept<iterator_type> >();
61 }
62 };
63
64 template<class I>
65 struct Mutable_IndexedRandomAccess1DIteratorConcept {
66 typedef I iterator_type;
67
68 void constraints () {
69 function_requires< Mutable_RandomAccessIteratorConcept<iterator_type> >();
70 function_requires< Indexed1DIteratorConcept<iterator_type> >();
71 }
72 };
73
74 template<class I>
75 struct Indexed2DIteratorConcept {
76 typedef I iterator_type;
77 typedef typename I::dual_iterator_type dual_iterator_type;
78 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
79
80 void constraints () {
81 iterator_type it = iterator_type ();
82 // Indices
83 it.index1 ();
84 it.index2 ();
85 // Iterator begin/end
86 dual_iterator_type it_begin (it.begin ());
87 dual_iterator_type it_end (it.end ());
88 // Reverse iterator begin/end
89 dual_reverse_iterator_type it_rbegin (it.rbegin ());
90 dual_reverse_iterator_type it_rend (it.rend ());
91 ignore_unused_variable_warning (it_begin);
92 ignore_unused_variable_warning (it_end);
93 ignore_unused_variable_warning (it_rbegin);
94 ignore_unused_variable_warning (it_rend);
95 }
96 };
97
98 template<class I1, class I2>
99 struct IndexedBidirectional2DIteratorConcept {
100 typedef I1 subiterator1_type;
101 typedef I2 subiterator2_type;
102
103 void constraints () {
104 function_requires< BidirectionalIteratorConcept<subiterator1_type> >();
105 function_requires< BidirectionalIteratorConcept<subiterator2_type> >();
106 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
107 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
108 }
109 };
110
111 template<class I1, class I2>
112 struct Mutable_IndexedBidirectional2DIteratorConcept {
113 typedef I1 subiterator1_type;
114 typedef I2 subiterator2_type;
115
116 void constraints () {
117 function_requires< Mutable_BidirectionalIteratorConcept<subiterator1_type> >();
118 function_requires< Mutable_BidirectionalIteratorConcept<subiterator2_type> >();
119 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
120 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
121 }
122 };
123
124 template<class I1, class I2>
125 struct IndexedRandomAccess2DIteratorConcept {
126 typedef I1 subiterator1_type;
127 typedef I2 subiterator2_type;
128
129 void constraints () {
130 function_requires< RandomAccessIteratorConcept<subiterator1_type> >();
131 function_requires< RandomAccessIteratorConcept<subiterator2_type> >();
132 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
133 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
134 }
135 };
136
137 template<class I1, class I2>
138 struct Mutable_IndexedRandomAccess2DIteratorConcept {
139 typedef I1 subiterator1_type;
140 typedef I2 subiterator2_type;
141
142 void constraints () {
143 function_requires< Mutable_RandomAccessIteratorConcept<subiterator1_type> >();
144 function_requires< Mutable_RandomAccessIteratorConcept<subiterator2_type> >();
145 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
146 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
147 }
148 };
149
150 template<class C>
151 struct StorageArrayConcept {
152 typedef C container_type;
153 typedef typename C::size_type size_type;
154 typedef typename C::value_type value_type;
155
156 void constraints () {
157 function_requires< RandomAccessContainerConcept<container_type> >();
158 size_type n (0);
159 // Sizing constructor
160 container_type c = container_type (n);
161 // Initialised sizing constructor
162 container_type (n, value_type (5));
163 ignore_unused_variable_warning (c);
164 }
165 };
166
167 template<class C>
168 struct Mutable_StorageArrayConcept {
169 typedef C container_type;
170 typedef typename C::size_type size_type;
171 typedef typename C::value_type value_type;
172 typedef typename C::iterator iterator_type;
173
174 void constraints () {
175 function_requires< Mutable_RandomAccessContainerConcept<container_type> > ();
176 size_type n (0);
177 // Sizing constructor
178 container_type c = container_type (n);
179 // Initialised sizing constructor
180 c = container_type (n, value_type (3));
181 // Resize
182 c.resize (n, value_type (5));
183 // Resize - none preserving
184 c.resize (n);
185 }
186 };
187
188 template<class C>
189 struct StorageSparseConcept {
190 typedef C container_type;
191 typedef typename C::size_type size_type;
192
193 void constraints () {
194 function_requires< ReversibleContainerConcept<container_type> > ();
195 }
196 };
197
198 template<class C>
199 struct Mutable_StorageSparseConcept {
200 typedef C container_type;
201 typedef typename C::size_type size_type;
202 typedef typename C::value_type value_type;
203 typedef typename C::iterator iterator_type;
204
205 void constraints () {
206 // NOTE - Not Mutable_ReversibleContainerConcept
207 function_requires< ReversibleContainerConcept<container_type> >();
208 container_type c = container_type ();
209 value_type t = value_type ();
210 iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type ();
211 // Insert
212 c.insert (it, t);
213 // Erase
214 c.erase (it);
215 // Range erase
216 c.erase (it1, it2);
217 // Clear
218 c.clear ();
219 }
220 };
221
222 template<class G>
223 struct IndexSetConcept {
224 typedef G generator_type;
225 typedef typename G::size_type size_type;
226 typedef typename G::value_type value_type;
227
228 void constraints () {
229 function_requires< AssignableConcept<generator_type> >();
230 function_requires< ReversibleContainerConcept<generator_type> >();
231 generator_type g = generator_type ();
232 size_type n (0);
233 value_type t;
234 // Element access
235 t = g (n);
236 ignore_unused_variable_warning (t);
237 }
238 };
239
240 /** \brief Scalar expression concept.
241 *
242 * requirements
243 * \li \c SE::value_type is the type of the scalar expression
244 * \li \c SE must be convertable to \c SE::value_type
245 * \li the constant \c SE::complexity must exist
246 *
247 * \param SE the type of the scalar expression
248 */
249 template<class SE>
250 struct ScalarExpressionConcept {
251 typedef SE scalar_expression_type;
252 typedef typename SE::value_type value_type;
253
254 static const unsigned complexity = SE::complexity;
255
256 void constraints () {
257 scalar_expression_type *sp;
258 scalar_expression_type s = *sp;
259 value_type t;
260 // Conversion
261 t = s;
262 ignore_unused_variable_warning (t);
263 }
264 };
265
266 /** \brief Vector expression concept.
267 *
268 * requirements
269 * \li \c VE::value_type is the type of the elements
270 * \li \c VE::const_reference The return type when accessing an element of a constant vector
271 * expression. Must be convertable to a \c value_type.
272 * \li \c VE::size_type is the (unsigned) type of the indices
273 * \li \c VE::difference_type is the (signed) type of distances between indices
274 * \li \c VE::category
275 *
276 * \li the constant \c SE::complexity must exist
277 *
278 * \param SE the type of the scalar expression
279 */
280 template<class VE>
281 struct VectorExpressionConcept {
282 typedef VE vector_expression_type;
283 typedef typename VE::type_category type_category;
284 typedef typename VE::size_type size_type;
285 typedef typename VE::difference_type difference_type;
286 typedef typename VE::value_type value_type;
287 typedef typename VE::const_reference const_reference;
288 typedef typename VE::const_iterator const_iterator_type;
289 typedef typename VE::const_reverse_iterator const_reverse_iterator_type;
290
291 void constraints () {
292 vector_expression_type *vp;
293 const vector_expression_type *cvp;
294 vector_expression_type v = *vp;
295 const vector_expression_type cv = *cvp;
296 size_type n (0), i (0);
297 value_type t;
298 // Find (internal?)
299 const_iterator_type cit (v.find (i));
300 // Beginning of range
301 const_iterator_type cit_begin (v.begin ());
302 // End of range
303 const_iterator_type cit_end (v.end ());
304 // Size
305 n = v.size ();
306 // Beginning of reverse range
307 const_reverse_iterator_type crit_begin (cv.rbegin ());
308 // End of reverse range
309 const_reverse_iterator_type crit_end (cv.rend ());
310 // Element access
311 t = v (i);
312 ignore_unused_variable_warning (n);
313 ignore_unused_variable_warning (cit);
314 ignore_unused_variable_warning (cit_begin);
315 ignore_unused_variable_warning (cit_end);
316 ignore_unused_variable_warning (crit_begin);
317 ignore_unused_variable_warning (crit_end);
318 ignore_unused_variable_warning (t);
319 }
320 };
321
322 template<class VE>
323 struct Mutable_VectorExpressionConcept {
324 typedef VE vector_expression_type;
325 typedef typename VE::size_type size_type;
326 typedef typename VE::value_type value_type;
327 typedef typename VE::iterator iterator_type;
328 typedef typename VE::reverse_iterator reverse_iterator_type;
329
330 void constraints () {
331 function_requires< AssignableConcept<vector_expression_type> >();
332 function_requires< VectorExpressionConcept<vector_expression_type> >();
333 vector_expression_type *vp;
334 vector_expression_type v = *vp, v1 = *vp, v2 = *vp;
335 size_type i (0);
336 value_type t = value_type ();
337 // Find (internal?)
338 iterator_type it (v.find (i));
339 // Beginning of range
340 iterator_type it_begin (v.begin ());
341 // End of range
342 iterator_type it_end (v.end ());
343 // Swap
344 v1.swap (v2);
345 // Beginning of reverse range
346 reverse_iterator_type rit_begin (v.rbegin ());
347 // End of reverse range
348 reverse_iterator_type rit_end (v.rend ());
349 // Assignments
350 v2 = v1;
351 v2.assign (v1);
352 v2 += v1;
353 v2.plus_assign (v1);
354 v2 -= v1;
355 v2.minus_assign (v1);
356 v *= t;
357 ignore_unused_variable_warning (it);
358 ignore_unused_variable_warning (it_begin);
359 ignore_unused_variable_warning (it_end);
360 ignore_unused_variable_warning (rit_begin);
361 ignore_unused_variable_warning (rit_end);
362 }
363 };
364
365 template<class ME>
366 struct MatrixExpressionConcept {
367 typedef ME matrix_expression_type;
368 typedef typename ME::type_category type_category;
369 typedef typename ME::size_type size_type;
370 typedef typename ME::value_type value_type;
371 typedef typename ME::const_iterator1 const_subiterator1_type;
372 typedef typename ME::const_iterator2 const_subiterator2_type;
373 typedef typename ME::const_reverse_iterator1 const_reverse_subiterator1_type;
374 typedef typename ME::const_reverse_iterator2 const_reverse_subiterator2_type;
375
376 void constraints () {
377 matrix_expression_type *mp;
378 const matrix_expression_type *cmp;
379 matrix_expression_type m = *mp;
380 const matrix_expression_type cm = *cmp;
381 size_type n (0), i (0), j (0);
382 value_type t;
383 // Find (internal?)
384 const_subiterator1_type cit1 (m.find1 (0, i, j));
385 const_subiterator2_type cit2 (m.find2 (0, i, j));
386 // Beginning of range
387 const_subiterator1_type cit1_begin (m.begin1 ());
388 const_subiterator2_type cit2_begin (m.begin2 ());
389 // End of range
390 const_subiterator1_type cit1_end (m.end1 ());
391 const_subiterator2_type cit2_end (m.end2 ());
392 // Size
393 n = m.size1 ();
394 n = m.size2 ();
395 // Beginning of reverse range
396 const_reverse_subiterator1_type crit1_begin (cm.rbegin1 ());
397 const_reverse_subiterator2_type crit2_begin (cm.rbegin2 ());
398 // End of reverse range
399 const_reverse_subiterator1_type crit1_end (cm.rend1 ());
400 const_reverse_subiterator2_type crit2_end (cm.rend2 ());
401 // Element access
402 t = m (i, j);
403 ignore_unused_variable_warning (n);
404 ignore_unused_variable_warning (cit1);
405 ignore_unused_variable_warning (cit2);
406 ignore_unused_variable_warning (cit1_begin);
407 ignore_unused_variable_warning (cit2_begin);
408 ignore_unused_variable_warning (cit1_end);
409 ignore_unused_variable_warning (cit2_end);
410 ignore_unused_variable_warning (crit1_begin);
411 ignore_unused_variable_warning (crit2_begin);
412 ignore_unused_variable_warning (crit1_end);
413 ignore_unused_variable_warning (crit2_end);
414 ignore_unused_variable_warning (t);
415 }
416 };
417
418 template<class ME>
419 struct Mutable_MatrixExpressionConcept {
420 typedef ME matrix_expression_type;
421 typedef typename ME::size_type size_type;
422 typedef typename ME::value_type value_type;
423 typedef typename ME::iterator1 subiterator1_type;
424 typedef typename ME::iterator2 subiterator2_type;
425 typedef typename ME::reverse_iterator1 reverse_subiterator1_type;
426 typedef typename ME::reverse_iterator2 reverse_subiterator2_type;
427
428 void constraints () {
429 function_requires< AssignableConcept<matrix_expression_type> >();
430 function_requires< MatrixExpressionConcept<matrix_expression_type> >();
431 matrix_expression_type *mp;
432 matrix_expression_type m = *mp, m1 = *mp, m2 = *mp;
433 size_type i (0), j (0);
434 value_type t = value_type ();
435 // Find (internal?)
436 subiterator1_type it1 (m.find1 (0, i, j));
437 subiterator2_type it2 (m.find2 (0, i, j));
438 // Beginning of range
439 subiterator1_type it1_begin (m.begin1 ());
440 subiterator2_type it2_begin (m.begin2 ());
441 // End of range
442 subiterator1_type it1_end (m.end1 ());
443 subiterator2_type it2_end (m.end2 ());
444 // Swap
445 m1.swap (m2);
446 // Beginning of reverse range
447 reverse_subiterator1_type rit1_begin (m.rbegin1 ());
448 reverse_subiterator2_type rit2_begin (m.rbegin2 ());
449 // End of reverse range
450 reverse_subiterator1_type rit1_end (m.rend1 ());
451 reverse_subiterator2_type rit2_end (m.rend2 ());
452 // Assignments
453 m2 = m1;
454 m2.assign (m1);
455 m2 += m1;
456 m2.plus_assign (m1);
457 m2 -= m1;
458 m2.minus_assign (m1);
459 m *= t;
460 ignore_unused_variable_warning (it1);
461 ignore_unused_variable_warning (it2);
462 ignore_unused_variable_warning (it1_begin);
463 ignore_unused_variable_warning (it2_begin);
464 ignore_unused_variable_warning (it1_end);
465 ignore_unused_variable_warning (it2_end);
466 ignore_unused_variable_warning (rit1_begin);
467 ignore_unused_variable_warning (rit2_begin);
468 ignore_unused_variable_warning (rit1_end);
469 ignore_unused_variable_warning (rit2_end);
470 }
471 };
472
473 template<class V>
474 struct VectorConcept {
475 typedef V vector_type;
476 typedef typename V::size_type size_type;
477 typedef typename V::value_type value_type;
478 typedef const value_type *const_pointer;
479
480 void constraints () {
481 function_requires< VectorExpressionConcept<vector_type> >();
482 size_type n (0);
483 size_type i (0);
484 // Sizing constructor
485 vector_type v (n);
486 // Element support
487 const_pointer p = v.find_element (i);
488
489 ignore_unused_variable_warning (p);
490 }
491 };
492
493 template<class V>
494 struct Mutable_VectorConcept {
495 typedef V vector_type;
496 typedef typename V::size_type size_type;
497 typedef typename V::value_type value_type;
498 typedef value_type *pointer;
499
500 void constraints () {
501 function_requires< VectorConcept<vector_type> >();
502 function_requires< DefaultConstructible<vector_type> >();
503 function_requires< Mutable_VectorExpressionConcept<vector_type> >();
504 size_type n (0);
505 value_type t = value_type ();
506 size_type i (0);
507 vector_type v;
508 // Element support
509 pointer p = v.find_element (i);
510 // Element assignment
511 value_type r = v.insert_element (i, t);
512 v.insert_element (i, t) = r;
513 // Zeroing
514 v.clear ();
515 // Resize
516 v.resize (n);
517
518 ignore_unused_variable_warning (p);
519 ignore_unused_variable_warning (r);
520 }
521 };
522
523 template<class V>
524 struct SparseVectorConcept {
525 typedef V vector_type;
526 typedef typename V::size_type size_type;
527
528 void constraints () {
529 function_requires< VectorConcept<vector_type> >();
530 }
531 };
532
533 template<class V>
534 struct Mutable_SparseVectorConcept {
535 typedef V vector_type;
536 typedef typename V::size_type size_type;
537 typedef typename V::value_type value_type;
538
539 void constraints () {
540 function_requires< SparseVectorConcept<vector_type> >();
541 function_requires< Mutable_VectorConcept<vector_type> >();
542 size_type i (0);
543 vector_type v;
544 // Element erasure
545 v.erase_element (i);
546 }
547 };
548
549 template<class M>
550 struct MatrixConcept {
551 typedef M matrix_type;
552 typedef typename M::size_type size_type;
553 typedef typename M::value_type value_type;
554 typedef const value_type *const_pointer;
555
556 void constraints () {
557 function_requires< MatrixExpressionConcept<matrix_type> >();
558 size_type n (0);
559 size_type i (0), j (0);
560 // Sizing constructor
561 matrix_type m (n, n);
562 // Element support
563#ifndef SKIP_BAD
564 const_pointer p = m.find_element (i, j);
565#else
566 const_pointer p;
567 ignore_unused_variable_warning (i);
568 ignore_unused_variable_warning (j);
569#endif
570 ignore_unused_variable_warning (p);
571 }
572 };
573
574 template<class M>
575 struct Mutable_MatrixConcept {
576 typedef M matrix_type;
577 typedef typename M::size_type size_type;
578 typedef typename M::value_type value_type;
579 typedef value_type *pointer;
580
581 void constraints () {
582 function_requires< MatrixConcept<matrix_type> >();
583 function_requires< DefaultConstructible<matrix_type> >();
584 function_requires< Mutable_MatrixExpressionConcept<matrix_type> >();
585 size_type n (0);
586 value_type t = value_type ();
587 size_type i (0), j (0);
588 matrix_type m;
589 // Element support
590#ifndef SKIP_BAD
591 pointer p = m.find_element (i, j);
592 ignore_unused_variable_warning (i);
593 ignore_unused_variable_warning (j);
594#else
595 pointer p;
596#endif
597 // Element assigment
598 value_type r = m.insert_element (i, j, t);
599 m.insert_element (i, j, t) = r;
600 // Zeroing
601 m.clear ();
602 // Resize
603 m.resize (n, n);
604 m.resize (n, n, false);
605
606 ignore_unused_variable_warning (p);
607 ignore_unused_variable_warning (r);
608 }
609 };
610
611 template<class M>
612 struct SparseMatrixConcept {
613 typedef M matrix_type;
614 typedef typename M::size_type size_type;
615
616 void constraints () {
617 function_requires< MatrixConcept<matrix_type> >();
618 }
619 };
620
621 template<class M>
622 struct Mutable_SparseMatrixConcept {
623 typedef M matrix_type;
624 typedef typename M::size_type size_type;
625 typedef typename M::value_type value_type;
626
627 void constraints () {
628 function_requires< SparseMatrixConcept<matrix_type> >();
629 function_requires< Mutable_MatrixConcept<matrix_type> >();
630 size_type i (0), j (0);
631 matrix_type m;
632 // Elemnent erasure
633 m.erase_element (i, j);
634 }
635 };
636
637 /** introduce anonymous namespace to make following functions
638 * local to the current compilation unit.
639 */
640 namespace {
641
642 // Replaced the ZeroElement and OneElement functions with the templated versions
643 // because the former where giving warnings with clang
644 template<class T>
645 T
646 ZeroElement (T) {
647 return T(0.0);
648 }
649
650 template<class T>
651 vector<T>
652 ZeroElement (vector<T>) {
653 return zero_vector<T> ();
654 }
655
656 template<class T>
657 matrix<T>
658 ZeroElement (matrix<T>) {
659 return zero_matrix<T> ();
660 }
661
662 template<class T>
663 T
664 OneElement (T) {
665 return T(0.0);
666 }
667
668 template<class T>
669 vector<T>
670 OneElement (vector<T>) {
671 return zero_vector<T> ();
672 }
673
674 template<class T>
675 matrix<T>
676 OneElement (matrix<T>) {
677 return identity_matrix<T> ();
678 }
679
680// template<>
681// float
682// ZeroElement (float) {
683// return 0.f;
684// }
685// template<>
686// double
687// ZeroElement (double) {
688// return 0.;
689// }
690// template<>
691// vector<float>
692// ZeroElement (vector<float>) {
693// return zero_vector<float> ();
694// }
695// template<>
696// vector<double>
697// ZeroElement (vector<double>) {
698// return zero_vector<double> ();
699// }
700// template<>
701// matrix<float>
702// ZeroElement (matrix<float>) {
703// return zero_matrix<float> ();
704// }
705// template<>
706// matrix<double>
707// ZeroElement (matrix<double>) {
708// return zero_matrix<double> ();
709// }
710// template<>
711// std::complex<float>
712// ZeroElement (std::complex<float>) {
713// return std::complex<float> (0.f);
714// }
715// template<>
716// std::complex<double>
717// ZeroElement (std::complex<double>) {
718// return std::complex<double> (0.);
719// }
720// template<>
721// vector<std::complex<float> >
722// ZeroElement (vector<std::complex<float> >) {
723// return zero_vector<std::complex<float> > ();
724// }
725// template<>
726// vector<std::complex<double> >
727// ZeroElement (vector<std::complex<double> >) {
728// return zero_vector<std::complex<double> > ();
729// }
730// template<>
731// matrix<std::complex<float> >
732// ZeroElement (matrix<std::complex<float> >) {
733// return zero_matrix<std::complex<float> > ();
734// }
735// template<>
736// matrix<std::complex<double> >
737// ZeroElement (matrix<std::complex<double> >) {
738// return zero_matrix<std::complex<double> > ();
739// }
740
741// template<class T>
742// T
743// OneElement (T);
744// template<>
745// float
746// OneElement (float) {
747// return 1.f;
748// }
749// template<>
750// double
751// OneElement (double) {
752// return 1.;
753// }
754// template<>
755// matrix<float>
756// OneElement (matrix<float>) {
757// return identity_matrix<float> ();
758// }
759// template<>
760// matrix<double>
761// OneElement (matrix<double>) {
762// return identity_matrix<double> ();
763// }
764// template<>
765// std::complex<float>
766// OneElement (std::complex<float>) {
767// return std::complex<float> (1.f);
768// }
769// template<>
770// std::complex<double>
771// OneElement (std::complex<double>) {
772// return std::complex<double> (1.);
773// }
774// template<>
775// matrix<std::complex<float> >
776// OneElement (matrix<std::complex<float> >) {
777// return identity_matrix<std::complex<float> > ();
778// }
779// template<>
780// matrix<std::complex<double> >
781// OneElement (matrix<std::complex<double> >) {
782// return identity_matrix<std::complex<double> > ();
783// }
784
785 template<class E1, class E2>
786 bool
787 operator == (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
788 typedef typename promote_traits<typename E1::value_type,
789 typename E2::value_type>::promote_type value_type;
790 typedef typename type_traits<value_type>::real_type real_type;
791 return norm_inf (e1 - e2) == real_type/*zero*/();
792 }
793 template<class E1, class E2>
794 bool
795 operator == (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
796 typedef typename promote_traits<typename E1::value_type,
797 typename E2::value_type>::promote_type value_type;
798 typedef typename type_traits<value_type>::real_type real_type;
799 return norm_inf (e1 - e2) == real_type/*zero*/();
800 }
801
802 template<class T>
803 struct AdditiveAbelianGroupConcept {
804 typedef T value_type;
805
806 void constraints () {
807 bool r;
808 value_type a = value_type (), b = value_type (), c = value_type ();
809 r = (a + b) + c == a + (b + c);
810 r = ZeroElement (value_type ()) + a == a;
811 r = a + ZeroElement (value_type ()) == a;
812 r = a + (- a) == ZeroElement (value_type ());
813 r = (- a) + a == ZeroElement (value_type ());
814 r = a + b == b + a;
815 ignore_unused_variable_warning (r);
816 }
817 };
818
819 template<class T>
820 struct MultiplicativeAbelianGroupConcept {
821 typedef T value_type;
822
823 void constraints () {
824 bool r;
825 value_type a = value_type (), b = value_type (), c = value_type ();
826 r = (a * b) * c == a * (b * c);
827 r = OneElement (value_type ()) * a == a;
828 r = a * OneElement (value_type ()) == a;
829 r = a * (OneElement (value_type ()) / a) == a;
830 r = (OneElement (value_type ()) / a) * a == a;
831 r = a * b == b * a;
832 ignore_unused_variable_warning (r);
833 }
834 };
835
836 template<class T>
837 struct RingWithIdentityConcept {
838 typedef T value_type;
839
840 void constraints () {
841 function_requires< AdditiveAbelianGroupConcept<value_type> >();
842 bool r;
843 value_type a = value_type (), b = value_type (), c = value_type ();
844 r = (a * b) * c == a * (b * c);
845 r = (a + b) * c == a * c + b * c;
846 r = OneElement (value_type ()) * a == a;
847 r = a * OneElement (value_type ()) == a;
848 ignore_unused_variable_warning (r);
849 }
850 };
851
852 template<class T>
853 struct Prod_RingWithIdentityConcept {
854 typedef T value_type;
855
856 void constraints () {
857 function_requires< AdditiveAbelianGroupConcept<value_type> >();
858 bool r;
859 value_type a = value_type (), b = value_type (), c = value_type ();
860 r = prod (T (prod (a, b)), c) == prod (a, T (prod (b, c)));
861 r = prod (a + b, c) == prod (a, c) + prod (b, c);
862 r = prod (OneElement (value_type ()), a) == a;
863 r = prod (a, OneElement (value_type ())) == a;
864 ignore_unused_variable_warning (r);
865 }
866 };
867
868 template<class T>
869 struct CommutativeRingWithIdentityConcept {
870 typedef T value_type;
871
872 void constraints () {
873 function_requires< RingWithIdentityConcept<value_type> >();
874 bool r;
875 value_type a = value_type (), b = value_type ();
876 r = a * b == b * a;
877 ignore_unused_variable_warning (r);
878 }
879 };
880
881 template<class T>
882 struct FieldConcept {
883 typedef T value_type;
884
885 void constraints () {
886 function_requires< CommutativeRingWithIdentityConcept<value_type> >();
887 bool r;
888 value_type a = value_type ();
889 r = a == ZeroElement (value_type ()) || a * (OneElement (value_type ()) / a) == a;
890 r = a == ZeroElement (value_type ()) || (OneElement (value_type ()) / a) * a == a;
891 ignore_unused_variable_warning (r);
892 }
893 };
894
895 template<class T, class V>
896 struct VectorSpaceConcept {
897 typedef T value_type;
898 typedef V vector_type;
899
900 void constraints () {
901 function_requires< FieldConcept<value_type> >();
902 function_requires< AdditiveAbelianGroupConcept<vector_type> >();
903 bool r;
904 value_type alpha = value_type (), beta = value_type ();
905 vector_type a = vector_type (), b = vector_type ();
906 r = alpha * (a + b) == alpha * a + alpha * b;
907 r = (alpha + beta) * a == alpha * a + beta * a;
908 r = (alpha * beta) * a == alpha * (beta * a);
909 r = OneElement (value_type ()) * a == a;
910 ignore_unused_variable_warning (r);
911 }
912 };
913
914 template<class T, class V, class M>
915 struct LinearOperatorConcept {
916 typedef T value_type;
917 typedef V vector_type;
918 typedef M matrix_type;
919
920 void constraints () {
921 function_requires< VectorSpaceConcept<value_type, vector_type> >();
922 bool r;
923 value_type alpha = value_type (), beta = value_type ();
924 vector_type a = vector_type (), b = vector_type ();
925 matrix_type A = matrix_type ();
926 r = prod (A, alpha * a + beta * b) == alpha * prod (A, a) + beta * prod (A, b);
927 ignore_unused_variable_warning (r);
928 }
929 };
930
931inline void concept_checks () {
932
933 // Allow tests to be group to keep down compiler storage requirement
934#ifdef INTERAL
935#define INTERNAL_STORAGE
936#define INTERNAL_VECTOR
937#define INTERNAL_MATRIX
938#define INTERNAL_SPECIAL
939#define INTERNAL_SPARSE
940#define INTERNAL_EXPRESSION
941#endif
942
943 // TODO enable this for development
944 // #define VIEW_CONCEPTS
945
946 // Element value type for tests
947 typedef float T;
948
949 // Storage Array
950#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_DENSE)
951 {
952 typedef std::vector<T> container_model;
953 function_requires< Mutable_StorageArrayConcept<container_model> >();
954 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
955 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
956 }
957
958 {
959 typedef bounded_array<T, 1> container_model;
960 function_requires< Mutable_StorageArrayConcept<container_model> >();
961 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
962 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
963 }
964
965 {
966 typedef unbounded_array<T> container_model;
967 function_requires< Mutable_StorageArrayConcept<container_model> >();
968 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
969 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
970 }
971
972/* FIXME array_adaptors are in progress
973 {
974 typedef array_adaptor<T> container_model;
975 function_requires< Mutable_StorageArrayConcept<container_model> >();
976 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
977 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
978 }
979*/
980
981 {
982 typedef range container_model;
983 function_requires< IndexSetConcept<range> >();
984 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
985 }
986
987 {
988 typedef slice container_model;
989 function_requires< IndexSetConcept<range> >();
990 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
991 }
992
993 {
994 typedef indirect_array<> container_model;
995 function_requires< IndexSetConcept<range> >();
996 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
997 }
998#endif
999
1000 // Storage Sparse
1001#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_SPARSE)
1002 {
1003 typedef map_array<std::size_t, T> container_model;
1004 function_requires< Mutable_StorageSparseConcept<container_model> >();
1005 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
1006 function_requires< RandomAccessIteratorConcept<container_model::iterator> >();
1007 }
1008
1009 {
1010 typedef std::map<std::size_t, T> container_model;
1011 function_requires< Mutable_StorageSparseConcept<container_model > >();
1012 function_requires< BidirectionalIteratorConcept<container_model::const_iterator> >();
1013 function_requires< BidirectionalIteratorConcept<container_model::iterator> >();
1014 }
1015#endif
1016
1017#ifdef VIEW_CONCEPTS
1018 // read only vectors
1019 {
1020 typedef vector_view<T> container_model;
1021 function_requires< RandomAccessContainerConcept<container_model> >();
1022 function_requires< VectorConcept<container_model> >();
1023 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1024 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1025 }
1026#endif
1027
1028 // Vector
1029#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_DENSE)
1030 {
1031 typedef vector<T> container_model;
1032 function_requires< RandomAccessContainerConcept<container_model> >();
1033 function_requires< Mutable_VectorConcept<container_model> >();
1034 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1035 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1036 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1037 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1038 }
1039
1040 {
1041 typedef zero_vector<T> container_model;
1042 function_requires< VectorConcept<container_model> >();
1043 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1044 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1045 }
1046
1047 {
1048 typedef unit_vector<T> container_model;
1049 function_requires< VectorConcept<container_model> >();
1050 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1051 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1052 }
1053
1054 {
1055 typedef scalar_vector<T> container_model;
1056 function_requires< VectorConcept<container_model> >();
1057 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1058 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1059 }
1060
1061 {
1062 typedef c_vector<T, 1> container_model;
1063 function_requires< Mutable_VectorConcept<container_model> >();
1064 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1065 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1066 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1067 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1068 }
1069#endif
1070
1071 // Vector Proxies
1072#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_PROXY)
1073 {
1074 typedef vector_range<vector<T> > container_model;
1075 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1076 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1077 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1078 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1079 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1080 }
1081
1082 {
1083 typedef vector_slice<vector<T> > container_model;
1084 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1085 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1086 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1087 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1088 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1089 }
1090
1091 {
1092 typedef vector_indirect<vector<T> > container_model;
1093 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1094 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1095 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1096 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1097 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1098 }
1099#endif
1100
1101 // Sparse Vector
1102#if defined (INTERNAL_SPARSE) || defined (INTERNAL_VECTOR_SPARSE)
1103 {
1104 typedef mapped_vector<T> container_model;
1105 function_requires< Mutable_SparseVectorConcept<container_model> >();
1106 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1107 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
1108 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1109 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1110 }
1111
1112 {
1113 typedef compressed_vector<T> container_model;
1114 function_requires< Mutable_SparseVectorConcept<container_model> >();
1115 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1116 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
1117 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1118 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1119 }
1120
1121 {
1122 typedef coordinate_vector<T> container_model;
1123 function_requires< Mutable_SparseVectorConcept<container_model> >();
1124 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1125 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
1126 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1127 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1128 }
1129#endif
1130
1131 // Matrix
1132#if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_DENSE)
1133 {
1134 typedef matrix<T> container_model;
1135 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1136 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1137 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1138 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1139 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1140 }
1141
1142 {
1143 typedef vector_of_vector<T> container_model;
1144 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1145 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1146 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1147 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1148 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1149 }
1150
1151 {
1152 typedef zero_matrix<T> container_model;
1153 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1154 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1155 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1156 }
1157
1158 {
1159 typedef identity_matrix<T> container_model;
1160 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1161 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1162 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1163 }
1164
1165 {
1166 typedef scalar_matrix<T> container_model;
1167 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1168 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1169 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1170 }
1171
1172 {
1173 typedef c_matrix<T, 1, 1> container_model;
1174 function_requires< Mutable_MatrixConcept<matrix<T> > >();
1175 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1176 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1177 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1178 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1179 }
1180#endif
1181
1182 // Matrix Proxies
1183#if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_PROXY)
1184 {
1185 typedef matrix_row<matrix<T> > container_model;
1186 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1187 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1188 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1189 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1190 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1191 }
1192
1193 {
1194 typedef matrix_column<matrix<T> > container_model;
1195 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1196 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1197 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1198 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1199 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1200 }
1201
1202 {
1203 typedef matrix_vector_range<matrix<T> > container_model;
1204 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1205 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1206 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1207 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1208 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1209 }
1210
1211 {
1212 typedef matrix_vector_slice<matrix<T> > container_model;
1213 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1214 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1215 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1216 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1217 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1218 }
1219
1220 {
1221 typedef matrix_vector_indirect<matrix<T> > container_model;
1222 function_requires< Mutable_VectorExpressionConcept<container_model> >();
1223 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1224 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1225 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1226 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1227 }
1228
1229 {
1230 typedef matrix_range<matrix<T> > container_model;
1231 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1232 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1233 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1234 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1235 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1236 }
1237
1238 {
1239 typedef matrix_slice<matrix<T> > container_model;
1240 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1241 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1242 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1243 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1244 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1245 }
1246
1247 {
1248 typedef matrix_indirect<matrix<T> > container_model;
1249 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1250 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1251 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1252 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1253 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1254 }
1255#endif
1256
1257 // Banded Matrix
1258#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_BANDED)
1259 {
1260 typedef banded_matrix<T> container_model;
1261 function_requires< Mutable_MatrixConcept<container_model> >();
1262 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1263 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1264 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1265 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1266 }
1267
1268 {
1269 typedef banded_adaptor<matrix<T> > container_model;
1270 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1271 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1272 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1273 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1274 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1275 }
1276#endif
1277
1278 // Triangular Matrix
1279#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_TRIANGULAR)
1280 {
1281 typedef triangular_matrix<T> container_model;
1282 function_requires< Mutable_MatrixConcept<container_model> >();
1283 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1284 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1285 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1286 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1287 }
1288
1289 {
1290 typedef triangular_adaptor<matrix<T> > container_model;
1291 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1292 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1293 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1294 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1295 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1296 }
1297#endif
1298
1299 // Symmetric Matrix
1300#if defined (INTERNA_SPECIAL) || defined (INTERNAL_SYMMETRIC)
1301 {
1302 typedef symmetric_matrix<T> container_model;
1303 function_requires< Mutable_MatrixConcept<container_model> >();
1304 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1305 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1306 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1307 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1308 }
1309
1310 {
1311 typedef banded_adaptor<matrix<T> > container_model;
1312#ifndef SKIP_BAD
1313 // const_iterator (iterator) constructor is bad
1314 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1315#endif
1316 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1317 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1318 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1319 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1320 }
1321#endif
1322
1323 // Hermitian Matrix
1324#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_HERMITIAN)
1325 {
1326 typedef hermitian_matrix<T> container_model;
1327 function_requires< Mutable_MatrixConcept<container_model> >();
1328 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1329 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1330 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1331 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1332 }
1333
1334 {
1335 typedef hermitian_adaptor<matrix<T> > container_model;
1336#ifndef SKIP_BAD
1337 // const_iterator (iterator) constructor is bad
1338 function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1339#endif
1340 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1341 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1342 function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1343 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1344 }
1345#endif
1346
1347 // Sparse Matrix
1348#if defined (INTERNAL_SPARSE) || defined (INTERNAL_MATRIX_SPARSE)
1349 {
1350 typedef mapped_matrix<T> container_model;
1351 function_requires< Mutable_SparseMatrixConcept<container_model> >();
1352 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1353 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1354 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1355 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1356 }
1357 {
1358 typedef mapped_vector_of_mapped_vector<T> container_model;
1359 function_requires< Mutable_SparseMatrixConcept<container_model> >();
1360 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1361 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1362 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1363 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1364 }
1365 {
1366 typedef compressed_matrix<T> container_model;
1367 function_requires< Mutable_SparseMatrixConcept<container_model> >();
1368 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1369 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1370 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1371 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1372 }
1373 {
1374 typedef coordinate_matrix<T> container_model;
1375 function_requires< Mutable_SparseMatrixConcept<container_model> >();
1376 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1377 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1378 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1379 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1380 }
1381 {
1382 typedef generalized_vector_of_vector<T, row_major, vector< coordinate_vector<T> > > container_model;
1383 function_requires< Mutable_SparseMatrixConcept<container_model> >();
1384 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1385 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1386 function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1387 function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1388 }
1389
1390#endif
1391
1392 // Scalar Expressions
1393#if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_VECTOR_EXPRESSION)
1394 function_requires< ScalarExpressionConcept<scalar_value<T> > >();
1395 function_requires< ScalarExpressionConcept<scalar_reference<T> > >();
1396
1397 // Vector Expressions
1398 {
1399 typedef vector_reference<vector<T> > expression_model;
1400 function_requires< VectorExpressionConcept<expression_model> >();
1401 function_requires< Mutable_VectorExpressionConcept<expression_model> >();
1402 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1403 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::iterator> >();
1404 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1405 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::reverse_iterator> >();
1406 }
1407
1408 {
1409 typedef vector_unary<vector<T>, scalar_identity<T> > expression_model;
1410 function_requires< VectorExpressionConcept<expression_model> >();
1411 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1412 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1413 }
1414
1415 {
1416 typedef vector_binary<vector<T>, vector<T>, scalar_plus<T, T> > expression_model;
1417 function_requires< VectorExpressionConcept<expression_model> >();
1418 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1419 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1420 }
1421
1422 {
1423 typedef vector_binary_scalar1<T, vector<T>, scalar_multiplies<T, T> > expression_model;
1424 function_requires< VectorExpressionConcept<expression_model> >();
1425 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1426 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1427 }
1428
1429 {
1430 typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1431 function_requires< VectorExpressionConcept<expression_model> >();
1432 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1433 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1434 }
1435
1436 {
1437 typedef vector_binary_scalar1<scalar_value<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
1438 function_requires< VectorExpressionConcept<expression_model> >();
1439 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1440 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1441 }
1442
1443 {
1444 typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1445 function_requires< VectorExpressionConcept<expression_model> >();
1446 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1447 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1448 }
1449
1450 function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_sum<vector<T> > > > >();
1451 function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_1<vector<T> > > > >();
1452 function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_2<vector<T> > > > >();
1453 function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_inf<vector<T> > > > >();
1454
1455 function_requires< ScalarExpressionConcept<vector_scalar_binary<vector<T>, vector<T>, vector_inner_prod<vector<T>, vector<T>, T> > > >();
1456#endif
1457
1458 // Matrix Expressions
1459#if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_MATRIX_EXPRESSION)
1460 {
1461 typedef matrix_reference<matrix<T> > expression_model;
1462 function_requires< MatrixExpressionConcept<expression_model> >();
1463 function_requires< Mutable_MatrixExpressionConcept<expression_model> >();
1464 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1465 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::iterator1, expression_model::iterator2> >();
1466 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1467 function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::reverse_iterator1, expression_model::reverse_iterator2> >();
1468 }
1469
1470 {
1471 typedef vector_matrix_binary<vector<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
1472 function_requires< MatrixExpressionConcept<expression_model> >();
1473 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1474 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1475 }
1476
1477 {
1478 typedef matrix_unary1<matrix<T>, scalar_identity<T> > expression_model;
1479 function_requires< MatrixExpressionConcept<expression_model> >();
1480 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1481 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1482 }
1483
1484 {
1485 typedef matrix_unary2<matrix<T>, scalar_identity<T> > expression_model;
1486 function_requires< MatrixExpressionConcept<expression_model> >();
1487 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1488 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1489 }
1490
1491 {
1492 typedef matrix_binary<matrix<T>, matrix<T>, scalar_plus<T, T> > expression_model;
1493 function_requires< MatrixExpressionConcept<expression_model> >();
1494 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1495 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1496 }
1497
1498 {
1499 typedef matrix_binary_scalar1<T, matrix<T>, scalar_multiplies<T, T> > expression_model;
1500 function_requires< MatrixExpressionConcept<expression_model> >();
1501 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1502 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1503 }
1504
1505 {
1506 typedef matrix_binary_scalar2<matrix<T>, T, scalar_multiplies<T, T> > expression_model;
1507 function_requires< MatrixExpressionConcept<expression_model> >();
1508 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1509 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1510 }
1511
1512 {
1513 typedef matrix_binary_scalar1<scalar_value<T>, matrix<T>, scalar_multiplies<T, T> > expression_model;
1514 function_requires< MatrixExpressionConcept<expression_model> >();
1515 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1516 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1517 }
1518
1519 {
1520 typedef matrix_binary_scalar2<matrix<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1521 function_requires< MatrixExpressionConcept<expression_model> >();
1522 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1523 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1524 }
1525
1526 {
1527 typedef matrix_vector_binary1<matrix<T>, vector<T>, matrix_vector_prod1<matrix<T>, vector<T>, T> > expression_model;
1528 function_requires< VectorExpressionConcept<expression_model> >();
1529 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1530 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1531 }
1532
1533 {
1534 typedef matrix_vector_binary2<vector<T>, matrix<T>, matrix_vector_prod2<matrix<T>, vector<T>, T > > expression_model;
1535 function_requires< VectorExpressionConcept<expression_model> >();
1536 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1537 function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1538 }
1539
1540 {
1541 typedef matrix_matrix_binary<matrix<T>, matrix<T>, matrix_matrix_prod<matrix<T>, matrix<T>, T > > expression_model;
1542 function_requires< MatrixExpressionConcept<expression_model> >();
1543 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1544 function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1545 }
1546
1547 function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_1<vector<T> > > > >();
1548 function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_frobenius<vector<T> > > > >();
1549 function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_inf<vector<T> > > > >();
1550#endif
1551
1552#ifdef EXTERNAL
1553 function_requires< AdditiveAbelianGroupConcept<T> >();
1554 function_requires< CommutativeRingWithIdentityConcept<T> >();
1555 function_requires< FieldConcept<T> >();
1556 function_requires< VectorSpaceConcept<T, vector<T> > >();
1557 function_requires< Prod_RingWithIdentityConcept<matrix<T> > >();
1558 function_requires< VectorSpaceConcept<T, matrix<T> > >();
1559 function_requires< LinearOperatorConcept<T, vector<T>, matrix<T> > >();
1560
1561 function_requires< AdditiveAbelianGroupConcept<std::complex<T> > >();
1562 function_requires< CommutativeRingWithIdentityConcept<std::complex<T> > >();
1563 function_requires< FieldConcept<std::complex<T> > >();
1564 function_requires< VectorSpaceConcept<std::complex<T>, vector<std::complex<T> > > >();
1565 function_requires< Prod_RingWithIdentityConcept<matrix<std::complex<T> > > >();
1566 function_requires< VectorSpaceConcept<std::complex<T>, matrix<std::complex<T> > > >();
1567 function_requires< LinearOperatorConcept<std::complex<T>, vector<std::complex<T> >, matrix<std::complex<T> > > >();
1568#endif
1569 }
1570
1571 } // end of anonymous namespace
1572
1573}}}
1574
1575#endif