Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:59

0001 //
0002 //  Copyright (c) 2000-2002
0003 //  Joerg Walter, Mathias Koch
0004 //
0005 //  Distributed under the Boost Software License, Version 1.0. (See
0006 //  accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 //  The authors gratefully acknowledge the support of
0010 //  GeNeSys mbH & Co. KG in producing this work.
0011 //
0012 
0013 #ifndef _BOOST_UBLAS_CONCEPTS_
0014 #define _BOOST_UBLAS_CONCEPTS_
0015 
0016 #include <boost/concept_check.hpp>
0017 
0018 // Concept checks based on ideas of Jeremy Siek
0019 
0020 namespace boost { namespace numeric { namespace ublas {
0021 
0022 
0023     template<class I>
0024     struct Indexed1DIteratorConcept {
0025         typedef I iterator_type;
0026 
0027         void constraints () {
0028             iterator_type it = iterator_type ();
0029             // Index
0030             it.index ();
0031         }
0032     };
0033 
0034     template<class I>
0035     struct IndexedBidirectional1DIteratorConcept {
0036         typedef I iterator_type;
0037 
0038         void constraints () {
0039             function_requires< BidirectionalIteratorConcept<iterator_type> >();
0040             function_requires< Indexed1DIteratorConcept<iterator_type> >();
0041         }
0042     };
0043 
0044     template<class I>
0045     struct Mutable_IndexedBidirectional1DIteratorConcept {
0046         typedef I iterator_type;
0047 
0048         void constraints () {
0049             function_requires< Mutable_BidirectionalIteratorConcept<iterator_type> >();
0050             function_requires< Indexed1DIteratorConcept<iterator_type> >();
0051         }
0052     };
0053 
0054     template<class I>
0055     struct IndexedRandomAccess1DIteratorConcept {
0056         typedef I iterator_type;
0057 
0058         void constraints () {
0059             function_requires< RandomAccessIteratorConcept<iterator_type> >();
0060             function_requires< Indexed1DIteratorConcept<iterator_type> >();
0061         }
0062     };
0063 
0064     template<class I>
0065     struct Mutable_IndexedRandomAccess1DIteratorConcept {
0066         typedef I iterator_type;
0067 
0068         void constraints () {
0069             function_requires< Mutable_RandomAccessIteratorConcept<iterator_type> >();
0070             function_requires< Indexed1DIteratorConcept<iterator_type> >();
0071         }
0072     };
0073 
0074     template<class I>
0075     struct Indexed2DIteratorConcept {
0076         typedef I iterator_type;
0077         typedef typename I::dual_iterator_type dual_iterator_type;
0078         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
0079 
0080         void constraints () {
0081             iterator_type it = iterator_type ();
0082             // Indices
0083             it.index1 ();
0084             it.index2 ();
0085             // Iterator begin/end
0086             dual_iterator_type it_begin (it.begin ());
0087             dual_iterator_type it_end (it.end ());
0088             // Reverse iterator begin/end
0089             dual_reverse_iterator_type it_rbegin (it.rbegin ());
0090             dual_reverse_iterator_type it_rend (it.rend ());
0091             ignore_unused_variable_warning (it_begin);
0092             ignore_unused_variable_warning (it_end);
0093             ignore_unused_variable_warning (it_rbegin);
0094             ignore_unused_variable_warning (it_rend);
0095         }
0096     };
0097 
0098     template<class I1, class I2>
0099     struct IndexedBidirectional2DIteratorConcept {
0100         typedef I1 subiterator1_type;
0101         typedef I2 subiterator2_type;
0102 
0103         void constraints () {
0104             function_requires< BidirectionalIteratorConcept<subiterator1_type> >();
0105             function_requires< BidirectionalIteratorConcept<subiterator2_type> >();
0106             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
0107             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
0108         }
0109     };
0110 
0111     template<class I1, class I2>
0112     struct Mutable_IndexedBidirectional2DIteratorConcept {
0113         typedef I1 subiterator1_type;
0114         typedef I2 subiterator2_type;
0115 
0116         void constraints () {
0117             function_requires< Mutable_BidirectionalIteratorConcept<subiterator1_type> >();
0118             function_requires< Mutable_BidirectionalIteratorConcept<subiterator2_type> >();
0119             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
0120             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
0121         }
0122     };
0123 
0124     template<class I1, class I2>
0125     struct IndexedRandomAccess2DIteratorConcept {
0126         typedef I1 subiterator1_type;
0127         typedef I2 subiterator2_type;
0128 
0129         void constraints () {
0130             function_requires< RandomAccessIteratorConcept<subiterator1_type> >();
0131             function_requires< RandomAccessIteratorConcept<subiterator2_type> >();
0132             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
0133             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
0134         }
0135     };
0136 
0137     template<class I1, class I2>
0138     struct Mutable_IndexedRandomAccess2DIteratorConcept {
0139         typedef I1 subiterator1_type;
0140         typedef I2 subiterator2_type;
0141 
0142         void constraints () {
0143             function_requires< Mutable_RandomAccessIteratorConcept<subiterator1_type> >();
0144             function_requires< Mutable_RandomAccessIteratorConcept<subiterator2_type> >();
0145             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
0146             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
0147         }
0148     };
0149 
0150     template<class C>
0151     struct StorageArrayConcept {
0152         typedef C container_type;
0153         typedef typename C::size_type size_type;
0154         typedef typename C::value_type value_type;
0155 
0156         void constraints () {
0157             function_requires< RandomAccessContainerConcept<container_type> >();
0158             size_type n (0);
0159             // Sizing constructor
0160             container_type c = container_type (n);
0161             // Initialised sizing constructor
0162             container_type (n, value_type (5));
0163             ignore_unused_variable_warning (c);
0164         }
0165     };
0166 
0167     template<class C>
0168     struct Mutable_StorageArrayConcept {
0169         typedef C container_type;
0170         typedef typename C::size_type size_type;
0171         typedef typename C::value_type value_type;
0172         typedef typename C::iterator iterator_type;
0173 
0174         void constraints () {
0175             function_requires< Mutable_RandomAccessContainerConcept<container_type> > ();
0176             size_type n (0);
0177             // Sizing constructor
0178             container_type c = container_type (n);
0179             // Initialised sizing constructor
0180             c = container_type (n, value_type (3));
0181             // Resize
0182             c.resize (n, value_type (5));
0183             // Resize - none preserving
0184             c.resize (n);
0185         }
0186     };
0187 
0188     template<class C>
0189     struct StorageSparseConcept {
0190         typedef C container_type;
0191         typedef typename C::size_type size_type;
0192 
0193         void constraints () {
0194             function_requires< ReversibleContainerConcept<container_type> > ();
0195         }
0196     };
0197 
0198     template<class C>
0199     struct Mutable_StorageSparseConcept {
0200         typedef C container_type;
0201         typedef typename C::size_type size_type;
0202         typedef typename C::value_type value_type;
0203         typedef typename C::iterator iterator_type;
0204 
0205         void constraints () {
0206             // NOTE - Not Mutable_ReversibleContainerConcept
0207             function_requires< ReversibleContainerConcept<container_type> >();
0208             container_type c = container_type ();
0209             value_type t = value_type ();
0210             iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type ();
0211             // Insert
0212             c.insert (it, t);
0213             // Erase
0214             c.erase (it);
0215             // Range erase
0216             c.erase (it1, it2);
0217             // Clear
0218             c.clear ();
0219         }
0220     };
0221 
0222     template<class G>
0223     struct IndexSetConcept {
0224         typedef G generator_type;
0225         typedef typename G::size_type size_type;
0226         typedef typename G::value_type value_type;
0227 
0228         void constraints () {
0229             function_requires< AssignableConcept<generator_type> >();
0230             function_requires< ReversibleContainerConcept<generator_type> >();
0231             generator_type g = generator_type ();
0232             size_type n (0);
0233             value_type t;
0234             // Element access
0235             t = g (n);
0236             ignore_unused_variable_warning (t);
0237         }
0238     };
0239 
0240     /** \brief Scalar expression concept.
0241      *
0242      * requirements
0243      * \li \c SE::value_type is the type of the scalar expression
0244      * \li \c SE must be convertable to \c SE::value_type
0245      * \li the constant \c SE::complexity must exist
0246      *
0247      * \param SE the type of the scalar expression
0248      */
0249     template<class SE>
0250     struct ScalarExpressionConcept {
0251         typedef SE scalar_expression_type;
0252         typedef typename SE::value_type value_type;
0253 
0254         static const unsigned complexity = SE::complexity;
0255 
0256         void constraints () {
0257             scalar_expression_type *sp;
0258             scalar_expression_type s = *sp;
0259             value_type t;
0260             // Conversion
0261             t = s;
0262             ignore_unused_variable_warning (t);
0263         }
0264     };
0265 
0266     /** \brief Vector expression concept.
0267      *
0268      * requirements
0269      * \li \c VE::value_type is the type of the elements
0270      * \li \c VE::const_reference The return type when accessing an element of a constant vector 
0271      * expression. Must be convertable to a \c value_type.
0272      * \li \c VE::size_type is the (unsigned) type of the indices
0273      * \li \c VE::difference_type is the (signed) type of distances between indices
0274      * \li \c VE::category
0275      * 
0276      * \li the constant \c SE::complexity must exist
0277      *
0278      * \param SE the type of the scalar expression
0279      */
0280     template<class VE>
0281     struct VectorExpressionConcept {
0282         typedef VE vector_expression_type;
0283         typedef typename VE::type_category type_category;
0284         typedef typename VE::size_type size_type;
0285         typedef typename VE::difference_type difference_type;
0286         typedef typename VE::value_type value_type;
0287         typedef typename VE::const_reference const_reference;
0288         typedef typename VE::const_iterator const_iterator_type;
0289         typedef typename VE::const_reverse_iterator const_reverse_iterator_type;
0290 
0291         void constraints () {
0292             vector_expression_type *vp;
0293             const vector_expression_type *cvp;
0294             vector_expression_type v = *vp;
0295             const vector_expression_type cv = *cvp;
0296             size_type n (0), i (0);
0297             value_type t;
0298             // Find (internal?)
0299             const_iterator_type cit (v.find (i));
0300             // Beginning of range
0301             const_iterator_type cit_begin (v.begin ());
0302             // End of range
0303             const_iterator_type cit_end (v.end ());
0304             // Size
0305             n = v.size ();
0306             // Beginning of reverse range
0307             const_reverse_iterator_type crit_begin (cv.rbegin ());
0308             // End of reverse range
0309             const_reverse_iterator_type crit_end (cv.rend ());
0310             // Element access
0311             t = v (i);
0312             ignore_unused_variable_warning (n);
0313             ignore_unused_variable_warning (cit);
0314             ignore_unused_variable_warning (cit_begin);
0315             ignore_unused_variable_warning (cit_end);
0316             ignore_unused_variable_warning (crit_begin);
0317             ignore_unused_variable_warning (crit_end);
0318             ignore_unused_variable_warning (t);
0319         }
0320     };
0321 
0322     template<class VE>
0323     struct Mutable_VectorExpressionConcept {
0324         typedef VE vector_expression_type;
0325         typedef typename VE::size_type size_type;
0326         typedef typename VE::value_type value_type;
0327         typedef typename VE::iterator iterator_type;
0328         typedef typename VE::reverse_iterator reverse_iterator_type;
0329 
0330         void constraints () {
0331             function_requires< AssignableConcept<vector_expression_type> >();
0332             function_requires< VectorExpressionConcept<vector_expression_type> >();
0333             vector_expression_type *vp;
0334             vector_expression_type v = *vp, v1 = *vp, v2 = *vp;
0335             size_type i (0);
0336             value_type t = value_type ();
0337             // Find (internal?)
0338             iterator_type it (v.find (i));
0339             // Beginning of range
0340             iterator_type it_begin (v.begin ());
0341             // End of range
0342             iterator_type it_end (v.end ());
0343             // Swap
0344             v1.swap (v2);
0345             // Beginning of reverse range
0346             reverse_iterator_type rit_begin (v.rbegin ());
0347             // End of reverse range
0348             reverse_iterator_type rit_end (v.rend ());
0349             // Assignments
0350             v2 = v1;
0351             v2.assign (v1);
0352             v2 += v1;
0353             v2.plus_assign (v1);
0354             v2 -= v1;
0355             v2.minus_assign (v1);
0356             v *= t;
0357             ignore_unused_variable_warning (it);
0358             ignore_unused_variable_warning (it_begin);
0359             ignore_unused_variable_warning (it_end);
0360             ignore_unused_variable_warning (rit_begin);
0361             ignore_unused_variable_warning (rit_end);
0362         }
0363     };
0364 
0365     template<class ME>
0366     struct MatrixExpressionConcept {
0367         typedef ME matrix_expression_type;
0368         typedef typename ME::type_category type_category;
0369         typedef typename ME::size_type size_type;
0370         typedef typename ME::value_type value_type;
0371         typedef typename ME::const_iterator1 const_subiterator1_type;
0372         typedef typename ME::const_iterator2 const_subiterator2_type;
0373         typedef typename ME::const_reverse_iterator1 const_reverse_subiterator1_type;
0374         typedef typename ME::const_reverse_iterator2 const_reverse_subiterator2_type;
0375 
0376         void constraints () {
0377             matrix_expression_type *mp;
0378             const matrix_expression_type *cmp;
0379             matrix_expression_type m = *mp;
0380             const matrix_expression_type cm = *cmp;
0381             size_type n (0), i (0), j (0);
0382             value_type t;
0383             // Find (internal?)
0384             const_subiterator1_type cit1 (m.find1 (0, i, j));
0385             const_subiterator2_type cit2 (m.find2 (0, i, j));
0386             // Beginning of range
0387             const_subiterator1_type cit1_begin (m.begin1 ());
0388             const_subiterator2_type cit2_begin (m.begin2 ());
0389             // End of range
0390             const_subiterator1_type cit1_end (m.end1 ());
0391             const_subiterator2_type cit2_end (m.end2 ());
0392             // Size
0393             n = m.size1 ();
0394             n = m.size2 ();
0395             // Beginning of reverse range
0396             const_reverse_subiterator1_type crit1_begin (cm.rbegin1 ());
0397             const_reverse_subiterator2_type crit2_begin (cm.rbegin2 ());
0398             // End of reverse range
0399             const_reverse_subiterator1_type crit1_end (cm.rend1 ());
0400             const_reverse_subiterator2_type crit2_end (cm.rend2 ());
0401             // Element access
0402             t = m (i, j);
0403             ignore_unused_variable_warning (n);
0404             ignore_unused_variable_warning (cit1);
0405             ignore_unused_variable_warning (cit2);
0406             ignore_unused_variable_warning (cit1_begin);
0407             ignore_unused_variable_warning (cit2_begin);
0408             ignore_unused_variable_warning (cit1_end);
0409             ignore_unused_variable_warning (cit2_end);
0410             ignore_unused_variable_warning (crit1_begin);
0411             ignore_unused_variable_warning (crit2_begin);
0412             ignore_unused_variable_warning (crit1_end);
0413             ignore_unused_variable_warning (crit2_end);
0414             ignore_unused_variable_warning (t);
0415         }
0416     };
0417 
0418     template<class ME>
0419     struct Mutable_MatrixExpressionConcept {
0420         typedef ME matrix_expression_type;
0421         typedef typename ME::size_type size_type;
0422         typedef typename ME::value_type value_type;
0423         typedef typename ME::iterator1 subiterator1_type;
0424         typedef typename ME::iterator2 subiterator2_type;
0425         typedef typename ME::reverse_iterator1 reverse_subiterator1_type;
0426         typedef typename ME::reverse_iterator2 reverse_subiterator2_type;
0427 
0428         void constraints () {
0429             function_requires< AssignableConcept<matrix_expression_type> >();
0430             function_requires< MatrixExpressionConcept<matrix_expression_type> >();
0431             matrix_expression_type *mp;
0432             matrix_expression_type m = *mp, m1 = *mp, m2 = *mp;
0433             size_type i (0), j (0);
0434             value_type t = value_type ();
0435             // Find (internal?)
0436             subiterator1_type it1 (m.find1 (0, i, j));
0437             subiterator2_type it2 (m.find2 (0, i, j));
0438             // Beginning of range
0439             subiterator1_type it1_begin (m.begin1 ());
0440             subiterator2_type it2_begin (m.begin2 ());
0441             // End of range
0442             subiterator1_type it1_end (m.end1 ());
0443             subiterator2_type it2_end (m.end2 ());
0444             // Swap
0445             m1.swap (m2);
0446             // Beginning of reverse range
0447             reverse_subiterator1_type rit1_begin (m.rbegin1 ());
0448             reverse_subiterator2_type rit2_begin (m.rbegin2 ());
0449             // End of reverse range
0450             reverse_subiterator1_type rit1_end (m.rend1 ());
0451             reverse_subiterator2_type rit2_end (m.rend2 ());
0452             // Assignments
0453             m2 = m1;
0454             m2.assign (m1);
0455             m2 += m1;
0456             m2.plus_assign (m1);
0457             m2 -= m1;
0458             m2.minus_assign (m1);
0459             m *= t;
0460             ignore_unused_variable_warning (it1);
0461             ignore_unused_variable_warning (it2);
0462             ignore_unused_variable_warning (it1_begin);
0463             ignore_unused_variable_warning (it2_begin);
0464             ignore_unused_variable_warning (it1_end);
0465             ignore_unused_variable_warning (it2_end);
0466             ignore_unused_variable_warning (rit1_begin);
0467             ignore_unused_variable_warning (rit2_begin);
0468             ignore_unused_variable_warning (rit1_end);
0469             ignore_unused_variable_warning (rit2_end);
0470         }
0471     };
0472 
0473     template<class V>
0474     struct VectorConcept {
0475         typedef V vector_type;
0476         typedef typename V::size_type size_type;
0477         typedef typename V::value_type value_type;
0478         typedef const value_type *const_pointer;
0479 
0480         void constraints () {
0481             function_requires< VectorExpressionConcept<vector_type> >();
0482             size_type n (0);
0483             size_type i (0);
0484             // Sizing constructor
0485             vector_type v (n);
0486             // Element support
0487             const_pointer p = v.find_element (i);
0488 
0489             ignore_unused_variable_warning (p);
0490         }
0491     };
0492 
0493     template<class V>
0494     struct Mutable_VectorConcept {
0495         typedef V vector_type;
0496         typedef typename V::size_type size_type;
0497         typedef typename V::value_type value_type;
0498         typedef value_type *pointer;
0499 
0500         void constraints () {
0501             function_requires< VectorConcept<vector_type> >();
0502             function_requires< DefaultConstructible<vector_type> >();
0503             function_requires< Mutable_VectorExpressionConcept<vector_type> >();
0504             size_type n (0);
0505             value_type t = value_type ();
0506             size_type i (0);
0507             vector_type v;
0508             // Element support
0509             pointer p = v.find_element (i);
0510             // Element assignment
0511             value_type r = v.insert_element (i, t);
0512             v.insert_element (i, t) = r;
0513             // Zeroing
0514             v.clear ();
0515             // Resize
0516             v.resize (n);
0517 
0518             ignore_unused_variable_warning (p);
0519             ignore_unused_variable_warning (r);
0520         }
0521     };
0522 
0523     template<class V>
0524     struct SparseVectorConcept {
0525         typedef V vector_type;
0526         typedef typename V::size_type size_type;
0527 
0528         void constraints () {
0529             function_requires< VectorConcept<vector_type> >();
0530         }
0531     };
0532 
0533     template<class V>
0534     struct Mutable_SparseVectorConcept {
0535         typedef V vector_type;
0536         typedef typename V::size_type size_type;
0537         typedef typename V::value_type value_type;
0538 
0539         void constraints () {
0540             function_requires< SparseVectorConcept<vector_type> >();
0541             function_requires< Mutable_VectorConcept<vector_type> >();
0542             size_type i (0);
0543             vector_type v;
0544             // Element erasure
0545             v.erase_element (i);
0546         }
0547     };
0548 
0549     template<class M>
0550     struct MatrixConcept {
0551         typedef M matrix_type;
0552         typedef typename M::size_type size_type;
0553         typedef typename M::value_type value_type;
0554         typedef const value_type *const_pointer;
0555 
0556         void constraints () {
0557             function_requires< MatrixExpressionConcept<matrix_type> >();
0558             size_type n (0);
0559             size_type i (0), j (0);
0560             // Sizing constructor
0561             matrix_type m (n, n);
0562             // Element support
0563 #ifndef SKIP_BAD
0564             const_pointer p = m.find_element (i, j);
0565 #else
0566             const_pointer p;
0567             ignore_unused_variable_warning (i);
0568             ignore_unused_variable_warning (j);
0569 #endif
0570             ignore_unused_variable_warning (p);
0571         }
0572     };
0573 
0574     template<class M>
0575     struct Mutable_MatrixConcept {
0576         typedef M matrix_type;
0577         typedef typename M::size_type size_type;
0578         typedef typename M::value_type value_type;
0579         typedef value_type *pointer;
0580 
0581         void constraints () {
0582             function_requires< MatrixConcept<matrix_type> >();
0583             function_requires< DefaultConstructible<matrix_type> >();
0584             function_requires< Mutable_MatrixExpressionConcept<matrix_type> >();
0585             size_type n (0);
0586             value_type t = value_type ();
0587             size_type i (0), j (0);
0588             matrix_type m;
0589             // Element support
0590 #ifndef SKIP_BAD
0591             pointer p = m.find_element (i, j);
0592             ignore_unused_variable_warning (i);
0593             ignore_unused_variable_warning (j);
0594 #else
0595             pointer p;
0596 #endif
0597             // Element assigment
0598             value_type r = m.insert_element (i, j, t);
0599             m.insert_element (i, j, t) = r;
0600             // Zeroing
0601             m.clear ();
0602             // Resize
0603             m.resize (n, n);
0604             m.resize (n, n, false);
0605 
0606             ignore_unused_variable_warning (p);
0607             ignore_unused_variable_warning (r);
0608         }
0609     };
0610 
0611     template<class M>
0612     struct SparseMatrixConcept {
0613         typedef M matrix_type;
0614         typedef typename M::size_type size_type;
0615 
0616         void constraints () {
0617             function_requires< MatrixConcept<matrix_type> >();
0618         }
0619     };
0620 
0621     template<class M>
0622     struct Mutable_SparseMatrixConcept {
0623         typedef M matrix_type;
0624         typedef typename M::size_type size_type;
0625         typedef typename M::value_type value_type;
0626 
0627         void constraints () {
0628             function_requires< SparseMatrixConcept<matrix_type> >();
0629             function_requires< Mutable_MatrixConcept<matrix_type> >();
0630             size_type i (0), j (0);
0631             matrix_type m;
0632             // Elemnent erasure
0633             m.erase_element (i, j);
0634         }
0635     };
0636 
0637     /** introduce anonymous namespace to make following functions
0638      * local to the current compilation unit.
0639      */
0640     namespace {
0641 
0642     // Replaced the ZeroElement and OneElement functions with the templated versions
0643     // because the former where giving warnings with clang
0644     template<class T>
0645     T
0646     ZeroElement (T) {
0647         return static_cast<T> (0);
0648     }
0649 
0650     template<class T>
0651     vector<T>
0652     ZeroElement (vector<T>) {
0653         return zero_vector<T> ();
0654     }
0655 
0656     template<class T>
0657     matrix<T>
0658     ZeroElement (matrix<T>) {
0659         return zero_matrix<T> ();
0660     }
0661 
0662     template<class T>
0663     T
0664     OneElement (T) {
0665         return static_cast<T> (1);
0666     }
0667 
0668     template<class T>
0669     matrix<T>
0670     OneElement (matrix<T>) {
0671         return identity_matrix<T> ();
0672     }
0673 
0674 
0675     template<class E1, class E2>
0676     bool
0677     operator == (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
0678         typedef typename promote_traits<typename E1::value_type,
0679                                                     typename E2::value_type>::promote_type value_type;
0680         typedef typename type_traits<value_type>::real_type real_type;
0681         return norm_inf (e1 - e2) == real_type/*zero*/();
0682     }
0683     template<class E1, class E2>
0684     bool
0685     operator == (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
0686         typedef typename promote_traits<typename E1::value_type,
0687                                                     typename E2::value_type>::promote_type value_type;
0688         typedef typename type_traits<value_type>::real_type real_type;
0689         return norm_inf (e1 - e2) == real_type/*zero*/();
0690     }
0691 
0692     template<class T>
0693     struct AdditiveAbelianGroupConcept {
0694         typedef T value_type;
0695 
0696         void constraints () {
0697             bool r;
0698             value_type a = value_type (), b = value_type (), c = value_type ();
0699             r = (a + b) + c == a + (b + c);
0700             r = ZeroElement (value_type ()) + a == a;
0701             r = a + ZeroElement (value_type ()) == a;
0702             r = a + (- a) == ZeroElement (value_type ());
0703             r = (- a) + a == ZeroElement (value_type ());
0704             r = a + b == b + a;
0705             ignore_unused_variable_warning (r);
0706         }
0707     };
0708 
0709     template<class T>
0710     struct MultiplicativeAbelianGroupConcept {
0711         typedef T value_type;
0712 
0713         void constraints () {
0714             bool r;
0715             value_type a = value_type (), b = value_type (), c = value_type ();
0716             r = (a * b) * c == a * (b * c);
0717             r = OneElement (value_type ()) * a == a;
0718             r = a * OneElement (value_type ()) == a;
0719             r = a * (OneElement (value_type ()) / a) == a;
0720             r = (OneElement (value_type ()) / a) * a == a;
0721             r = a * b == b * a;
0722             ignore_unused_variable_warning (r);
0723         }
0724     };
0725 
0726     template<class T>
0727     struct RingWithIdentityConcept {
0728         typedef T value_type;
0729 
0730         void constraints () {
0731             function_requires< AdditiveAbelianGroupConcept<value_type> >();
0732             bool r;
0733             value_type a = value_type (), b = value_type (), c = value_type ();
0734             r = (a * b) * c == a * (b * c);
0735             r = (a + b) * c == a * c + b * c;
0736             r = OneElement (value_type ()) * a == a;
0737             r = a * OneElement (value_type ()) == a;
0738             ignore_unused_variable_warning (r);
0739         }
0740     };
0741 
0742     template<class T>
0743     struct Prod_RingWithIdentityConcept {
0744         typedef T value_type;
0745 
0746         void constraints () {
0747             function_requires< AdditiveAbelianGroupConcept<value_type> >();
0748             bool r;
0749             value_type a = value_type (), b = value_type (), c = value_type ();
0750             r = prod (T (prod (a, b)), c) == prod (a, T (prod (b, c)));
0751             r = prod (a + b, c) == prod (a, c) + prod (b, c);
0752             r = prod (OneElement (value_type ()), a) == a;
0753             r = prod (a, OneElement (value_type ())) == a;
0754             ignore_unused_variable_warning (r);
0755         }
0756     };
0757 
0758     template<class T>
0759     struct CommutativeRingWithIdentityConcept {
0760         typedef T value_type;
0761 
0762         void constraints () {
0763             function_requires< RingWithIdentityConcept<value_type> >();
0764             bool r;
0765             value_type a = value_type (), b = value_type ();
0766             r = a * b == b * a;
0767             ignore_unused_variable_warning (r);
0768         }
0769     };
0770 
0771     template<class T>
0772     struct FieldConcept {
0773         typedef T value_type;
0774 
0775         void constraints () {
0776             function_requires< CommutativeRingWithIdentityConcept<value_type> >();
0777             bool r;
0778             value_type a = value_type ();
0779             r = a == ZeroElement (value_type ()) || a * (OneElement (value_type ()) / a) == a;
0780             r = a == ZeroElement (value_type ()) || (OneElement (value_type ()) / a) * a == a;
0781             ignore_unused_variable_warning (r);
0782         }
0783     };
0784 
0785     template<class T, class V>
0786     struct VectorSpaceConcept {
0787         typedef T value_type;
0788         typedef V vector_type;
0789 
0790         void constraints () {
0791             function_requires< FieldConcept<value_type> >();
0792             function_requires< AdditiveAbelianGroupConcept<vector_type> >();
0793             bool r;
0794             value_type alpha = value_type (), beta = value_type ();
0795             vector_type a = vector_type (), b = vector_type ();
0796             r = alpha * (a + b) == alpha * a + alpha * b;
0797             r = (alpha + beta) * a == alpha * a + beta * a;
0798             r = (alpha * beta) * a == alpha * (beta * a);
0799             r = OneElement (value_type ()) * a == a;
0800             ignore_unused_variable_warning (r);
0801         }
0802     };
0803 
0804     template<class T, class V, class M>
0805     struct LinearOperatorConcept {
0806         typedef T value_type;
0807         typedef V vector_type;
0808         typedef M matrix_type;
0809 
0810         void constraints () {
0811             function_requires< VectorSpaceConcept<value_type, vector_type> >();
0812             bool r;
0813             value_type alpha = value_type (), beta = value_type ();
0814             vector_type a = vector_type (), b = vector_type ();
0815             matrix_type A = matrix_type ();
0816             r = prod (A, alpha * a + beta * b) == alpha * prod (A, a) + beta * prod (A, b);
0817             ignore_unused_variable_warning (r);
0818         }
0819     };
0820 
0821 inline void concept_checks () {
0822 
0823         // Allow tests to be group to keep down compiler storage requirement
0824 #ifdef INTERAL
0825 #define INTERNAL_STORAGE
0826 #define INTERNAL_VECTOR
0827 #define INTERNAL_MATRIX
0828 #define INTERNAL_SPECIAL
0829 #define INTERNAL_SPARSE
0830 #define INTERNAL_EXPRESSION
0831 #endif
0832 
0833         // TODO enable this for development
0834         // #define VIEW_CONCEPTS
0835 
0836         // Element value type for tests
0837         typedef float T;
0838 
0839         // Storage Array
0840 #if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_DENSE)
0841         {
0842             typedef std::vector<T> container_model;
0843             function_requires< Mutable_StorageArrayConcept<container_model> >();
0844             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
0845             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
0846         }
0847 
0848         {
0849             typedef bounded_array<T, 1> container_model;
0850             function_requires< Mutable_StorageArrayConcept<container_model> >();
0851             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
0852             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
0853         }
0854 
0855         {
0856             typedef unbounded_array<T> container_model;
0857             function_requires< Mutable_StorageArrayConcept<container_model> >();
0858             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
0859             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
0860         }
0861 
0862 /* FIXME array_adaptors are in progress
0863         {
0864             typedef array_adaptor<T> container_model;
0865             function_requires< Mutable_StorageArrayConcept<container_model> >();
0866             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
0867             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
0868         }
0869 */
0870 
0871         {
0872             typedef range container_model;
0873             function_requires< IndexSetConcept<range> >();
0874             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
0875         }
0876 
0877         {
0878             typedef slice container_model;
0879             function_requires< IndexSetConcept<range> >();
0880             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
0881         }
0882 
0883         {
0884             typedef indirect_array<> container_model;
0885             function_requires< IndexSetConcept<range> >();
0886             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
0887         }
0888 #endif
0889 
0890         // Storage Sparse
0891 #if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_SPARSE)
0892         {
0893            typedef map_array<std::size_t, T> container_model;
0894            function_requires< Mutable_StorageSparseConcept<container_model> >();
0895            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
0896            function_requires< RandomAccessIteratorConcept<container_model::iterator> >();
0897         }
0898 
0899         {
0900            typedef std::map<std::size_t, T> container_model;
0901            function_requires< Mutable_StorageSparseConcept<container_model > >();
0902            function_requires< BidirectionalIteratorConcept<container_model::const_iterator> >();
0903            function_requires< BidirectionalIteratorConcept<container_model::iterator> >();
0904         }
0905 #endif
0906 
0907 #ifdef VIEW_CONCEPTS
0908         // read only vectors
0909         {
0910            typedef vector_view<T> container_model;
0911            function_requires< RandomAccessContainerConcept<container_model> >();
0912            function_requires< VectorConcept<container_model> >();
0913            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0914            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0915         }
0916 #endif
0917 
0918         // Vector
0919 #if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_DENSE)
0920         {
0921            typedef vector<T> container_model;
0922            function_requires< RandomAccessContainerConcept<container_model> >();
0923            function_requires< Mutable_VectorConcept<container_model> >();
0924            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0925            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
0926            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0927            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
0928         }
0929 
0930         {
0931            typedef zero_vector<T> container_model;
0932            function_requires< VectorConcept<container_model> >();
0933            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
0934            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
0935         }
0936 
0937         {
0938            typedef unit_vector<T> container_model;
0939            function_requires< VectorConcept<container_model> >();
0940            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
0941            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
0942         }
0943 
0944         {
0945            typedef scalar_vector<T> container_model;
0946            function_requires< VectorConcept<container_model> >();
0947            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0948            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0949         }
0950 
0951         {
0952            typedef c_vector<T, 1> container_model;
0953            function_requires< Mutable_VectorConcept<container_model> >();
0954            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0955            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
0956            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0957            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
0958         }
0959 #endif
0960 
0961         // Vector Proxies
0962 #if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_PROXY)
0963         {
0964            typedef vector_range<vector<T> > container_model;
0965            function_requires< Mutable_VectorExpressionConcept<container_model> >();
0966            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0967            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
0968            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0969            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
0970         }
0971 
0972         {
0973            typedef vector_slice<vector<T> > container_model;
0974            function_requires< Mutable_VectorExpressionConcept<container_model> >();
0975            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0976            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
0977            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0978            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
0979         }
0980 
0981         {
0982            typedef vector_indirect<vector<T> > container_model;
0983            function_requires< Mutable_VectorExpressionConcept<container_model> >();
0984            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
0985            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
0986            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
0987            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
0988         }
0989 #endif
0990 
0991         // Sparse Vector
0992 #if defined (INTERNAL_SPARSE) || defined (INTERNAL_VECTOR_SPARSE)
0993         {
0994             typedef mapped_vector<T> container_model;
0995             function_requires< Mutable_SparseVectorConcept<container_model> >();
0996             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
0997             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
0998             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
0999             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1000         }
1001 
1002         {
1003             typedef compressed_vector<T> container_model;
1004             function_requires< Mutable_SparseVectorConcept<container_model> >();
1005             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1006             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
1007             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1008             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1009         }
1010 
1011         {
1012             typedef coordinate_vector<T> container_model;
1013             function_requires< Mutable_SparseVectorConcept<container_model> >();
1014             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
1015             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
1016             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
1017             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
1018         }
1019 #endif
1020 
1021         // Matrix
1022 #if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_DENSE)
1023         {
1024             typedef matrix<T> container_model;
1025             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1026             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1027             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1028             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1029             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1030         }
1031 
1032         {
1033             typedef vector_of_vector<T> container_model;
1034             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1035             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1036             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1037             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1038             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1039         }
1040 
1041         {
1042             typedef zero_matrix<T> container_model;
1043             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1044             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1045             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1046         }
1047 
1048         {
1049             typedef identity_matrix<T> container_model;
1050             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1051             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1052             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1053         }
1054 
1055         {
1056             typedef scalar_matrix<T> container_model;
1057             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1058             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1059             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1060         }
1061 
1062         {
1063             typedef c_matrix<T, 1, 1> container_model;
1064             function_requires< Mutable_MatrixConcept<matrix<T> > >();
1065             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1066             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1067             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1068             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1069         }
1070 #endif
1071 
1072         // Matrix Proxies
1073 #if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_PROXY)
1074         {
1075             typedef matrix_row<matrix<T> > container_model;
1076             function_requires< Mutable_VectorExpressionConcept<container_model> >();
1077             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1078             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1079             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1080             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1081         }
1082 
1083         {
1084             typedef matrix_column<matrix<T> > container_model;
1085             function_requires< Mutable_VectorExpressionConcept<container_model> >();
1086             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1087             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1088             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1089             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1090         }
1091 
1092         {
1093             typedef matrix_vector_range<matrix<T> > container_model;
1094             function_requires< Mutable_VectorExpressionConcept<container_model> >();
1095             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1096             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1097             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1098             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1099         }
1100 
1101         {
1102             typedef matrix_vector_slice<matrix<T> > container_model;
1103             function_requires< Mutable_VectorExpressionConcept<container_model> >();
1104             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1105             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1106             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1107             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1108         }
1109 
1110         {
1111             typedef matrix_vector_indirect<matrix<T> > container_model;
1112             function_requires< Mutable_VectorExpressionConcept<container_model> >();
1113             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
1114             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
1115             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
1116             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
1117         }
1118 
1119         {
1120             typedef matrix_range<matrix<T> > container_model;
1121             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1122             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1123             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1124             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1125             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1126         }
1127 
1128         {
1129             typedef matrix_slice<matrix<T> > container_model;
1130             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1131             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1132             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1133             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1134             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1135         }
1136 
1137         {
1138             typedef matrix_indirect<matrix<T> > container_model;
1139             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1140             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1141             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1142             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1143             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1144         }
1145 #endif
1146 
1147         // Banded Matrix
1148 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_BANDED)
1149         {
1150             typedef banded_matrix<T> container_model;
1151             function_requires< Mutable_MatrixConcept<container_model> >();
1152             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1153             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1154             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1155             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1156         }
1157 
1158         {
1159             typedef banded_adaptor<matrix<T> > container_model;
1160             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1161             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1162             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1163             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1164             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1165         }
1166 #endif
1167 
1168         // Triangular Matrix
1169 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_TRIANGULAR)
1170         {
1171             typedef triangular_matrix<T> container_model;
1172             function_requires< Mutable_MatrixConcept<container_model> >();
1173             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1174             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1175             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1176             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1177         }
1178 
1179         {
1180             typedef triangular_adaptor<matrix<T> > container_model;
1181             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1182             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1183             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1184             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1185             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1186         }
1187 #endif
1188 
1189         // Symmetric Matrix
1190 #if defined (INTERNA_SPECIAL) || defined (INTERNAL_SYMMETRIC)
1191         {
1192             typedef symmetric_matrix<T> container_model;
1193             function_requires< Mutable_MatrixConcept<container_model> >();
1194             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1195             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1196             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1197             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1198         }
1199 
1200         {
1201             typedef banded_adaptor<matrix<T> > container_model;
1202 #ifndef SKIP_BAD
1203            // const_iterator (iterator) constructor is bad
1204             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1205 #endif
1206             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1207             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1208             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1209             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1210         }
1211 #endif
1212 
1213         // Hermitian Matrix
1214 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_HERMITIAN)
1215         {
1216             typedef hermitian_matrix<T> container_model;
1217             function_requires< Mutable_MatrixConcept<container_model> >();
1218             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1219             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1220             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1221             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1222         }
1223         
1224         {
1225             typedef hermitian_adaptor<matrix<T> > container_model;
1226 #ifndef SKIP_BAD
1227            // const_iterator (iterator) constructor is bad
1228             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
1229 #endif
1230             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1231             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1232             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1233             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1234         }
1235 #endif
1236 
1237         // Sparse Matrix
1238 #if defined (INTERNAL_SPARSE) || defined (INTERNAL_MATRIX_SPARSE)
1239         {
1240             typedef mapped_matrix<T> container_model;
1241             function_requires< Mutable_SparseMatrixConcept<container_model> >();
1242             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1243             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1244             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1245             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1246         }
1247         {
1248             typedef mapped_vector_of_mapped_vector<T> container_model;
1249             function_requires< Mutable_SparseMatrixConcept<container_model> >();
1250             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1251             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1252             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1253             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1254         }
1255         {
1256             typedef compressed_matrix<T> container_model;
1257             function_requires< Mutable_SparseMatrixConcept<container_model> >();
1258             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1259             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1260             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1261             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1262         }
1263         {
1264             typedef coordinate_matrix<T> container_model;
1265             function_requires< Mutable_SparseMatrixConcept<container_model> >();
1266             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1267             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1268             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1269             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1270         }
1271         {
1272             typedef generalized_vector_of_vector<T, row_major, vector< coordinate_vector<T> > > container_model;
1273             function_requires< Mutable_SparseMatrixConcept<container_model> >();
1274             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
1275             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
1276             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
1277             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
1278         }
1279 
1280 #endif
1281 
1282         // Scalar Expressions
1283 #if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_VECTOR_EXPRESSION)
1284         function_requires< ScalarExpressionConcept<scalar_value<T> > >();
1285         function_requires< ScalarExpressionConcept<scalar_reference<T> > >();
1286 
1287         // Vector Expressions
1288         {
1289             typedef vector_reference<vector<T> > expression_model;
1290             function_requires< VectorExpressionConcept<expression_model> >();
1291             function_requires< Mutable_VectorExpressionConcept<expression_model> >();
1292             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1293             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::iterator> >();
1294             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1295             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::reverse_iterator> >();
1296         }
1297 
1298         {
1299             typedef vector_unary<vector<T>, scalar_identity<T> > expression_model;
1300             function_requires< VectorExpressionConcept<expression_model> >();
1301             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1302             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1303         }
1304 
1305         {
1306             typedef vector_binary<vector<T>, vector<T>, scalar_plus<T, T> > expression_model;
1307             function_requires< VectorExpressionConcept<expression_model> >();
1308             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1309             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1310         }
1311 
1312         {
1313             typedef vector_binary_scalar1<T, vector<T>, scalar_multiplies<T, T> > expression_model;
1314             function_requires< VectorExpressionConcept<expression_model> >();
1315             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1316             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1317         }
1318 
1319         {
1320             typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1321             function_requires< VectorExpressionConcept<expression_model> >();
1322             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1323             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1324         }
1325 
1326         {
1327             typedef vector_binary_scalar1<scalar_value<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
1328             function_requires< VectorExpressionConcept<expression_model> >();
1329             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1330             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1331         }
1332 
1333         {
1334             typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1335             function_requires< VectorExpressionConcept<expression_model> >();
1336             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1337             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1338         }
1339 
1340         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_sum<vector<T> > > > >();
1341         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_1<vector<T> > > > >();
1342         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_2<vector<T> > > > >();
1343         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_inf<vector<T> > > > >();
1344 
1345         function_requires< ScalarExpressionConcept<vector_scalar_binary<vector<T>, vector<T>, vector_inner_prod<vector<T>, vector<T>, T> > > >();
1346 #endif
1347 
1348         // Matrix Expressions
1349 #if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_MATRIX_EXPRESSION)
1350         {
1351             typedef matrix_reference<matrix<T> > expression_model;
1352             function_requires< MatrixExpressionConcept<expression_model> >();
1353             function_requires< Mutable_MatrixExpressionConcept<expression_model> >();
1354             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1355             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::iterator1, expression_model::iterator2> >();
1356             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1357             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::reverse_iterator1, expression_model::reverse_iterator2> >();
1358         }
1359 
1360         {
1361             typedef vector_matrix_binary<vector<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
1362             function_requires< MatrixExpressionConcept<expression_model> >();
1363             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1364             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1365         }
1366 
1367         {
1368             typedef matrix_unary1<matrix<T>, scalar_identity<T> > expression_model;
1369             function_requires< MatrixExpressionConcept<expression_model> >();
1370             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1371             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1372         }
1373 
1374         {
1375             typedef matrix_unary2<matrix<T>, scalar_identity<T> > expression_model;
1376             function_requires< MatrixExpressionConcept<expression_model> >();
1377             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1378             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1379         }
1380 
1381         {
1382             typedef matrix_binary<matrix<T>, matrix<T>, scalar_plus<T, T> > expression_model;
1383             function_requires< MatrixExpressionConcept<expression_model> >();
1384             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1385             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1386         }
1387 
1388         {
1389             typedef matrix_binary_scalar1<T, matrix<T>, scalar_multiplies<T, T> > expression_model;
1390             function_requires< MatrixExpressionConcept<expression_model> >();
1391             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1392             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1393         }
1394 
1395         {
1396             typedef matrix_binary_scalar2<matrix<T>, T, scalar_multiplies<T, T> > expression_model;
1397             function_requires< MatrixExpressionConcept<expression_model> >();
1398             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1399             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1400         }
1401 
1402         {
1403             typedef matrix_binary_scalar1<scalar_value<T>, matrix<T>, scalar_multiplies<T, T> > expression_model;
1404             function_requires< MatrixExpressionConcept<expression_model> >();
1405             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1406             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1407         }
1408 
1409         {
1410             typedef matrix_binary_scalar2<matrix<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
1411             function_requires< MatrixExpressionConcept<expression_model> >();
1412             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1413             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1414         }
1415 
1416         {
1417             typedef matrix_vector_binary1<matrix<T>, vector<T>, matrix_vector_prod1<matrix<T>, vector<T>, T> > expression_model;
1418             function_requires< VectorExpressionConcept<expression_model> >();
1419             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1420             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1421         }
1422 
1423         {
1424             typedef matrix_vector_binary2<vector<T>, matrix<T>, matrix_vector_prod2<matrix<T>, vector<T>, T > > expression_model;
1425             function_requires< VectorExpressionConcept<expression_model> >();
1426             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
1427             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
1428         }
1429 
1430         {
1431             typedef matrix_matrix_binary<matrix<T>, matrix<T>, matrix_matrix_prod<matrix<T>, matrix<T>, T > > expression_model;
1432             function_requires< MatrixExpressionConcept<expression_model> >();
1433             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
1434             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
1435         }
1436 
1437         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_1<vector<T> > > > >();
1438         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_frobenius<vector<T> > > > >();
1439         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_inf<vector<T> > > > >();
1440 #endif
1441 
1442 #ifdef EXTERNAL
1443         function_requires< AdditiveAbelianGroupConcept<T> >();
1444         function_requires< CommutativeRingWithIdentityConcept<T> >();
1445         function_requires< FieldConcept<T> >();
1446         function_requires< VectorSpaceConcept<T, vector<T> > >();
1447         function_requires< Prod_RingWithIdentityConcept<matrix<T> > >();
1448         function_requires< VectorSpaceConcept<T, matrix<T> > >();
1449         function_requires< LinearOperatorConcept<T, vector<T>, matrix<T> > >();
1450 
1451         function_requires< AdditiveAbelianGroupConcept<std::complex<T> > >();
1452         function_requires< CommutativeRingWithIdentityConcept<std::complex<T> > >();
1453         function_requires< FieldConcept<std::complex<T> > >();
1454         function_requires< VectorSpaceConcept<std::complex<T>, vector<std::complex<T> > > >();
1455         function_requires< Prod_RingWithIdentityConcept<matrix<std::complex<T> > > >();
1456         function_requires< VectorSpaceConcept<std::complex<T>, matrix<std::complex<T> > > >();
1457         function_requires< LinearOperatorConcept<std::complex<T>, vector<std::complex<T> >, matrix<std::complex<T> > > >();
1458 #endif
1459     }
1460 
1461     } // end of anonymous namespace
1462 
1463 }}}
1464 
1465 #endif