Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/numeric/ublas/detail/concepts.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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