1 //
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 
20 namespace boost { namespace numeric { namespace ublas {
21 
22 
23     template<class I>
24     struct Indexed1DIteratorConcept {
25         typedef I iterator_type;
26 
constraintsboost::numeric::ublas::Indexed1DIteratorConcept27         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 
constraintsboost::numeric::ublas::IndexedBidirectional1DIteratorConcept38         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 
constraintsboost::numeric::ublas::Mutable_IndexedBidirectional1DIteratorConcept48         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 
constraintsboost::numeric::ublas::IndexedRandomAccess1DIteratorConcept58         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 
constraintsboost::numeric::ublas::Mutable_IndexedRandomAccess1DIteratorConcept68         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 
constraintsboost::numeric::ublas::Indexed2DIteratorConcept80         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 
constraintsboost::numeric::ublas::IndexedBidirectional2DIteratorConcept103         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 
constraintsboost::numeric::ublas::Mutable_IndexedBidirectional2DIteratorConcept116         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 
constraintsboost::numeric::ublas::IndexedRandomAccess2DIteratorConcept129         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 
constraintsboost::numeric::ublas::Mutable_IndexedRandomAccess2DIteratorConcept142         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 
constraintsboost::numeric::ublas::StorageArrayConcept156         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 
constraintsboost::numeric::ublas::Mutable_StorageArrayConcept174         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 
constraintsboost::numeric::ublas::StorageSparseConcept193         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 
constraintsboost::numeric::ublas::Mutable_StorageSparseConcept205         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 
constraintsboost::numeric::ublas::IndexSetConcept228         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 
constraintsboost::numeric::ublas::ScalarExpressionConcept256         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 
constraintsboost::numeric::ublas::VectorExpressionConcept291         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 
constraintsboost::numeric::ublas::Mutable_VectorExpressionConcept330         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 
constraintsboost::numeric::ublas::MatrixExpressionConcept376         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 
constraintsboost::numeric::ublas::Mutable_MatrixExpressionConcept428         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 
constraintsboost::numeric::ublas::VectorConcept480         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 
constraintsboost::numeric::ublas::Mutable_VectorConcept500         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 
constraintsboost::numeric::ublas::SparseVectorConcept528         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 
constraintsboost::numeric::ublas::Mutable_SparseVectorConcept539         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 
constraintsboost::numeric::ublas::MatrixConcept556         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 
constraintsboost::numeric::ublas::Mutable_MatrixConcept581         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 
constraintsboost::numeric::ublas::SparseMatrixConcept616         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 
constraintsboost::numeric::ublas::Mutable_SparseMatrixConcept627         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
ZeroElement(T)646     ZeroElement (T) {
647         return T(0.0);
648     }
649 
650     template<class T>
651     vector<T>
ZeroElement(vector<T>)652     ZeroElement (vector<T>) {
653         return zero_vector<T> ();
654     }
655 
656     template<class T>
657     matrix<T>
ZeroElement(matrix<T>)658     ZeroElement (matrix<T>) {
659         return zero_matrix<T> ();
660     }
661 
662     template<class T>
663     T
OneElement(T)664     OneElement (T) {
665         return T(0.0);
666     }
667 
668     template<class T>
669     vector<T>
OneElement(vector<T>)670     OneElement (vector<T>) {
671         return zero_vector<T> ();
672     }
673 
674     template<class T>
675     matrix<T>
OneElement(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
operator ==(const vector_expression<E1> & e1,const vector_expression<E2> & e2)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
operator ==(const matrix_expression<E1> & e1,const matrix_expression<E2> & e2)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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::AdditiveAbelianGroupConcept806         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::MultiplicativeAbelianGroupConcept823         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::RingWithIdentityConcept840         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::Prod_RingWithIdentityConcept856         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::CommutativeRingWithIdentityConcept872         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::FieldConcept885         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::VectorSpaceConcept900         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 
constraintsboost::numeric::ublas::__anon9366ac9d0111::LinearOperatorConcept920         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 
concept_checks()931 inline 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
1576