1//
2// Copyright (c) 2000-2002
3// Joerg Walter, Mathias Koch
4//
5// Distributed under the Boost Software License, Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// The authors gratefully acknowledge the support of
10// GeNeSys mbH & Co. KG in producing this work.
11//
12
13#ifndef _BOOST_UBLAS_CONCEPTS_
14#define _BOOST_UBLAS_CONCEPTS_
15
16#include <boost/concept_check.hpp>
17
18// Concept checks based on ideas of Jeremy Siek
19
20namespace boost { namespace numeric { namespace ublas {
21
22
23 template<class I>
24 struct Indexed1DIteratorConcept {
25 typedef I iterator_type;
26
27 void constraints () {
28 iterator_type it = iterator_type ();
29 // Index
30 it.index ();
31 }
32 };
33
34 template<class I>
35 struct IndexedBidirectional1DIteratorConcept {
36 typedef I iterator_type;
37
38 void constraints () {
39 function_requires< BidirectionalIteratorConcept<iterator_type> >();
40 function_requires< Indexed1DIteratorConcept<iterator_type> >();
41 }
42 };
43
44 template<class I>
45 struct Mutable_IndexedBidirectional1DIteratorConcept {
46 typedef I iterator_type;
47
48 void constraints () {
49 function_requires< Mutable_BidirectionalIteratorConcept<iterator_type> >();
50 function_requires< Indexed1DIteratorConcept<iterator_type> >();
51 }
52 };
53
54 template<class I>
55 struct IndexedRandomAccess1DIteratorConcept {
56 typedef I iterator_type;
57
58 void constraints () {
59 function_requires< RandomAccessIteratorConcept<iterator_type> >();
60 function_requires< Indexed1DIteratorConcept<iterator_type> >();
61 }
62 };
63
64 template<class I>
65 struct Mutable_IndexedRandomAccess1DIteratorConcept {
66 typedef I iterator_type;
67
68 void constraints () {
69 function_requires< Mutable_RandomAccessIteratorConcept<iterator_type> >();
70 function_requires< Indexed1DIteratorConcept<iterator_type> >();
71 }
72 };
73
74 template<class I>
75 struct Indexed2DIteratorConcept {
76 typedef I iterator_type;
77 typedef typename I::dual_iterator_type dual_iterator_type;
78 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
79
80 void constraints () {
81 iterator_type it = iterator_type ();
82 // Indices
83 it.index1 ();
84 it.index2 ();
85 // Iterator begin/end
86 dual_iterator_type it_begin (it.begin ());
87 dual_iterator_type it_end (it.end ());
88 // Reverse iterator begin/end
89 dual_reverse_iterator_type it_rbegin (it.rbegin ());
90 dual_reverse_iterator_type it_rend (it.rend ());
91 ignore_unused_variable_warning (it_begin);
92 ignore_unused_variable_warning (it_end);
93 ignore_unused_variable_warning (it_rbegin);
94 ignore_unused_variable_warning (it_rend);
95 }
96 };
97
98 template<class I1, class I2>
99 struct IndexedBidirectional2DIteratorConcept {
100 typedef I1 subiterator1_type;
101 typedef I2 subiterator2_type;
102
103 void constraints () {
104 function_requires< BidirectionalIteratorConcept<subiterator1_type> >();
105 function_requires< BidirectionalIteratorConcept<subiterator2_type> >();
106 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
107 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
108 }
109 };
110
111 template<class I1, class I2>
112 struct Mutable_IndexedBidirectional2DIteratorConcept {
113 typedef I1 subiterator1_type;
114 typedef I2 subiterator2_type;
115
116 void constraints () {
117 function_requires< Mutable_BidirectionalIteratorConcept<subiterator1_type> >();
118 function_requires< Mutable_BidirectionalIteratorConcept<subiterator2_type> >();
119 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
120 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
121 }
122 };
123
124 template<class I1, class I2>
125 struct IndexedRandomAccess2DIteratorConcept {
126 typedef I1 subiterator1_type;
127 typedef I2 subiterator2_type;
128
129 void constraints () {
130 function_requires< RandomAccessIteratorConcept<subiterator1_type> >();
131 function_requires< RandomAccessIteratorConcept<subiterator2_type> >();
132 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
133 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
134 }
135 };
136
137 template<class I1, class I2>
138 struct Mutable_IndexedRandomAccess2DIteratorConcept {
139 typedef I1 subiterator1_type;
140 typedef I2 subiterator2_type;
141
142 void constraints () {
143 function_requires< Mutable_RandomAccessIteratorConcept<subiterator1_type> >();
144 function_requires< Mutable_RandomAccessIteratorConcept<subiterator2_type> >();
145 function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
146 function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
147 }
148 };
149
150 template<class C>
151 struct StorageArrayConcept {
152 typedef C container_type;
153 typedef typename C::size_type size_type;
154 typedef typename C::value_type value_type;
155
156 void constraints () {
157 function_requires< RandomAccessContainerConcept<container_type> >();
158 size_type n (0);
159 // Sizing constructor
160 container_type c = container_type (n);
161 // Initialised sizing constructor
162 container_type (n, value_type (5));
163 ignore_unused_variable_warning (c);
164 }
165 };
166
167 template<class C>
168 struct Mutable_StorageArrayConcept {
169 typedef C container_type;
170 typedef typename C::size_type size_type;
171 typedef typename C::value_type value_type;
172 typedef typename C::iterator iterator_type;
173
174 void constraints () {
175 function_requires< Mutable_RandomAccessContainerConcept<container_type> > ();
176 size_type n (0);
177 // Sizing constructor
178 container_type c = container_type (n);
179 // Initialised sizing constructor
180 c = container_type (n, value_type (3));
181 // Resize
182 c.resize (n, value_type (5));
183 // Resize - none preserving
184 c.resize (n);
185 }
186 };
187
188 template<class C>
189 struct StorageSparseConcept {
190 typedef C container_type;
191 typedef typename C::size_type size_type;
192
193 void constraints () {
194 function_requires< ReversibleContainerConcept<container_type> > ();
195 }
196 };
197
198 template<class C>
199 struct Mutable_StorageSparseConcept {
200 typedef C container_type;
201 typedef typename C::size_type size_type;
202 typedef typename C::value_type value_type;
203 typedef typename C::iterator iterator_type;
204
205 void constraints () {
206 // NOTE - Not Mutable_ReversibleContainerConcept
207 function_requires< ReversibleContainerConcept<container_type> >();
208 container_type c = container_type ();
209 value_type t = value_type ();
210 iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type ();
211 // Insert
212 c.insert (it, t);
213 // Erase
214 c.erase (it);
215 // Range erase
216 c.erase (it1, it2);
217 // Clear
218 c.clear ();
219 }
220 };
221
222 template<class G>
223 struct IndexSetConcept {
224 typedef G generator_type;
225 typedef typename G::size_type size_type;
226 typedef typename G::value_type value_type;
227
228 void constraints () {
229 function_requires< AssignableConcept<generator_type> >();
230 function_requires< ReversibleContainerConcept<generator_type> >();
231 generator_type g = generator_type ();
232 size_type n (0);
233 value_type t;
234 // Element access
235 t = g (n);
236 ignore_unused_variable_warning (t);
237 }
238 };
239
240 /** \brief Scalar expression concept.
241 *
242 * requirements
243 * \li \c SE::value_type is the type of the scalar expression
244 * \li \c SE must be convertable to \c SE::value_type
245 * \li the constant \c SE::complexity must exist
246 *
247 * \param SE the type of the scalar expression
248 */
249 template<class SE>
250 struct ScalarExpressionConcept {
251 typedef SE scalar_expression_type;
252 typedef typename SE::value_type value_type;
253
254 static const unsigned complexity = SE::complexity;
255
256 void constraints () {
257 scalar_expression_type *sp;
258 scalar_expression_type s = *sp;
259 value_type t;
260 // Conversion
261 t = s;
262 ignore_unused_variable_warning (t);
263 }
264 };
265
266 /** \brief Vector expression concept.
267 *
268 * requirements
269 * \li \c VE::value_type is the type of the elements
270 * \li \c VE::const_reference The return type when accessing an element of a constant vector
271 * expression. Must be convertable to a \c value_type.
272 * \li \c VE::size_type is the (unsigned) type of the indices
273 * \li \c VE::difference_type is the (signed) type of distances between indices
274 * \li \c VE::category
275 *
276 * \li the constant \c SE::complexity must exist
277 *
278 * \param SE the type of the scalar expression
279 */
280 template<class VE>
281 struct VectorExpressionConcept {
282 typedef VE vector_expression_type;
283 typedef typename VE::type_category type_category;
284 typedef typename VE::size_type size_type;
285 typedef typename VE::difference_type difference_type;
286 typedef typename VE::value_type value_type;
287 typedef typename VE::const_reference const_reference;
288 typedef typename VE::const_iterator const_iterator_type;
289 typedef typename VE::const_reverse_iterator const_reverse_iterator_type;
290
291 void constraints () {
292 vector_expression_type *vp;
293 const vector_expression_type *cvp;
294 vector_expression_type v = *vp;
295 const vector_expression_type cv = *cvp;
296 size_type n (0), i (0);
297 value_type t;
298 // Find (internal?)
299 const_iterator_type cit (v.find (i));
300 // Beginning of range
301 const_iterator_type cit_begin (v.begin ());
302 // End of range
303 const_iterator_type cit_end (v.end ());
304 // Size
305 n = v.size ();
306 // Beginning of reverse range
307 const_reverse_iterator_type crit_begin (cv.rbegin ());
308 // End of reverse range
309 const_reverse_iterator_type crit_end (cv.rend ());
310 // Element access
311 t = v (i);
312 ignore_unused_variable_warning (n);
313 ignore_unused_variable_warning (cit);
314 ignore_unused_variable_warning (cit_begin);
315 ignore_unused_variable_warning (cit_end);
316 ignore_unused_variable_warning (crit_begin);
317 ignore_unused_variable_warning (crit_end);
318 ignore_unused_variable_warning (t);
319 }
320 };
321
322 template<class VE>
323 struct Mutable_VectorExpressionConcept {
324 typedef VE vector_expression_type;
325 typedef typename VE::size_type size_type;
326 typedef typename VE::value_type value_type;
327 typedef typename VE::iterator iterator_type;
328 typedef typename VE::reverse_iterator reverse_iterator_type;
329
330 void constraints () {
331 function_requires< AssignableConcept<vector_expression_type> >();
332 function_requires< VectorExpressionConcept<vector_expression_type> >();
333 vector_expression_type *vp;
334 vector_expression_type v = *vp, v1 = *vp, v2 = *vp;
335 size_type i (0);
336 value_type t = value_type ();
337 // Find (internal?)
338 iterator_type it (v.find (i));
339 // Beginning of range
340 iterator_type it_begin (v.begin ());
341 // End of range
342 iterator_type it_end (v.end ());
343 // Swap
344 v1.swap (v2);
345 // Beginning of reverse range
346 reverse_iterator_type rit_begin (v.rbegin ());
347 // End of reverse range
348 reverse_iterator_type rit_end (v.rend ());
349 // Assignments
350 v2 = v1;
351 v2.assign (v1);
352 v2 += v1;
353 v2.plus_assign (v1);
354 v2 -= v1;
355 v2.minus_assign (v1);
356 v *= t;
357 ignore_unused_variable_warning (it);
358 ignore_unused_variable_warning (it_begin);
359 ignore_unused_variable_warning (it_end);
360 ignore_unused_variable_warning (rit_begin);
361 ignore_unused_variable_warning (rit_end);
362 }
363 };
364
365 template<class ME>
366 struct MatrixExpressionConcept {
367 typedef ME matrix_expression_type;
368 typedef typename ME::type_category type_category;
369 typedef typename ME::size_type size_type;
370 typedef typename ME::value_type value_type;
371 typedef typename ME::const_iterator1 const_subiterator1_type;
372 typedef typename ME::const_iterator2 const_subiterator2_type;
373 typedef typename ME::const_reverse_iterator1 const_reverse_subiterator1_type;
374 typedef typename ME::const_reverse_iterator2 const_reverse_subiterator2_type;
375
376 void constraints () {
377 matrix_expression_type *mp;
378 const matrix_expression_type *cmp;
379 matrix_expression_type m = *mp;
380 const matrix_expression_type cm = *cmp;
381 size_type n (0), i (0), j (0);
382 value_type t;
383 // Find (internal?)
384 const_subiterator1_type cit1 (m.find1 (0, i, j));
385 const_subiterator2_type cit2 (m.find2 (0, i, j));
386 // Beginning of range
387 const_subiterator1_type cit1_begin (m.begin1 ());
388 const_subiterator2_type cit2_begin (m.begin2 ());
389 // End of range
390 const_subiterator1_type cit1_end (m.end1 ());
391 const_subiterator2_type cit2_end (m.end2 ());
392 // Size
393 n = m.size1 ();
394 n = m.size2 ();
395 // Beginning of reverse range
396 const_reverse_subiterator1_type crit1_begin (cm.rbegin1 ());
397 const_reverse_subiterator2_type crit2_begin (cm.rbegin2 ());
398 // End of reverse range
399 const_reverse_subiterator1_type crit1_end (cm.rend1 ());
400 const_reverse_subiterator2_type crit2_end (cm.rend2 ());
401 // Element access
402 t = m (i, j);
403 ignore_unused_variable_warning (n);
404 ignore_unused_variable_warning (cit1);
405 ignore_unused_variable_warning (cit2);
406 ignore_unused_variable_warning (cit1_begin);
407 ignore_unused_variable_warning (cit2_begin);
408 ignore_unused_variable_warning (cit1_end);
409 ignore_unused_variable_warning (cit2_end);
410 ignore_unused_variable_warning (crit1_begin);
411 ignore_unused_variable_warning (crit2_begin);
412 ignore_unused_variable_warning (crit1_end);
413 ignore_unused_variable_warning (crit2_end);
414 ignore_unused_variable_warning (t);
415 }
416 };
417
418 template<class ME>
419 struct Mutable_MatrixExpressionConcept {
420 typedef ME matrix_expression_type;
421 typedef typename ME::size_type size_type;
422 typedef typename ME::value_type value_type;
423 typedef typename ME::iterator1 subiterator1_type;
424 typedef typename ME::iterator2 subiterator2_type;
425 typedef typename ME::reverse_iterator1 reverse_subiterator1_type;
426 typedef typename ME::reverse_iterator2 reverse_subiterator2_type;
427
428 void constraints () {
429 function_requires< AssignableConcept<matrix_expression_type> >();
430 function_requires< MatrixExpressionConcept<matrix_expression_type> >();
431 matrix_expression_type *mp;
432 matrix_expression_type m = *mp, m1 = *mp, m2 = *mp;
433 size_type i (0), j (0);
434 value_type t = value_type ();
435 // Find (internal?)
436 subiterator1_type it1 (m.find1 (0, i, j));
437 subiterator2_type it2 (m.find2 (0, i, j));
438 // Beginning of range
439 subiterator1_type it1_begin (m.begin1 ());
440 subiterator2_type it2_begin (m.begin2 ());
441 // End of range
442 subiterator1_type it1_end (m.end1 ());
443 subiterator2_type it2_end (m.end2 ());
444 // Swap
445 m1.swap (m2);
446 // Beginning of reverse range
447 reverse_subiterator1_type rit1_begin (m.rbegin1 ());
448 reverse_subiterator2_type rit2_begin (m.rbegin2 ());
449 // End of reverse range
450 reverse_subiterator1_type rit1_end (m.rend1 ());
451 reverse_subiterator2_type rit2_end (m.rend2 ());
452 // Assignments
453 m2 = m1;
454 m2.assign (m1);
455 m2 += m1;
456 m2.plus_assign (m1);
457 m2 -= m1;
458 m2.minus_assign (m1);
459 m *= t;
460 ignore_unused_variable_warning (it1);
461 ignore_unused_variable_warning (it2);
462 ignore_unused_variable_warning (it1_begin);
463 ignore_unused_variable_warning (it2_begin);
464 ignore_unused_variable_warning (it1_end);
465 ignore_unused_variable_warning (it2_end);
466 ignore_unused_variable_warning (rit1_begin);
467 ignore_unused_variable_warning (rit2_begin);
468 ignore_unused_variable_warning (rit1_end);
469 ignore_unused_variable_warning (rit2_end);
470 }
471 };
472
473 template<class V>
474 struct VectorConcept {
475 typedef V vector_type;
476 typedef typename V::size_type size_type;
477 typedef typename V::value_type value_type;
478 typedef const value_type *const_pointer;
479
480 void constraints () {
481 function_requires< VectorExpressionConcept<vector_type> >();
482 size_type n (0);
483 size_type i (0);
484 // Sizing constructor
485 vector_type v (n);
486 // Element support
487 const_pointer p = v.find_element (i);
488
489 ignore_unused_variable_warning (p);
490 }
491 };
492
493 template<class V>
494 struct Mutable_VectorConcept {
495 typedef V vector_type;
496 typedef typename V::size_type size_type;
497 typedef typename V::value_type value_type;
498 typedef value_type *pointer;
499
500 void constraints () {
501 function_requires< VectorConcept<vector_type> >();
502 function_requires< DefaultConstructible<vector_type> >();
503 function_requires< Mutable_VectorExpressionConcept<vector_type> >();
504 size_type n (0);
505 value_type t = value_type ();
506 size_type i (0);
507 vector_type v;
508 // Element support
509 pointer p = v.find_element (i);
510 // Element assignment
511 value_type r = v.insert_element (i, t);
512 v.insert_element (i, t) = r;
513 // Zeroing
514 v.clear ();
515 // Resize
516 v.resize (n);
517
518 ignore_unused_variable_warning (p);
519 ignore_unused_variable_warning (r);
520 }
521 };
522
523 template<class V>
524 struct SparseVectorConcept {
525 typedef V vector_type;
526 typedef typename V::size_type size_type;
527
528 void constraints () {
529 function_requires< VectorConcept<vector_type> >();
530 }
531 };
532
533 template<class V>
534 struct Mutable_SparseVectorConcept {
535 typedef V vector_type;
536 typedef typename V::size_type size_type;
537 typedef typename V::value_type value_type;
538
539 void constraints () {
540 function_requires< SparseVectorConcept<vector_type> >();
541 function_requires< Mutable_VectorConcept<vector_type> >();
542 size_type i (0);
543 vector_type v;
544 // Element erasure
545 v.erase_element (i);
546 }
547 };
548
549 template<class M>
550 struct MatrixConcept {
551 typedef M matrix_type;
552 typedef typename M::size_type size_type;
553 typedef typename M::value_type value_type;
554 typedef const value_type *const_pointer;
555
556 void constraints () {
557 function_requires< MatrixExpressionConcept<matrix_type> >();
558 size_type n (0);
559 size_type i (0), j (0);
560 // Sizing constructor
561 matrix_type m (n, n);
562 // Element support
563#ifndef SKIP_BAD
564 const_pointer p = m.find_element (i, j);
565#else
566 const_pointer p;
567 ignore_unused_variable_warning (i);
568 ignore_unused_variable_warning (j);
569#endif
570 ignore_unused_variable_warning (p);
571 }
572 };
573
574 template<class M>
575 struct Mutable_MatrixConcept {
576 typedef M matrix_type;
577 typedef typename M::size_type size_type;
578 typedef typename M::value_type value_type;
579 typedef value_type *pointer;
580
581 void constraints () {
582 function_requires< MatrixConcept<matrix_type> >();
583 function_requires< DefaultConstructible<matrix_type> >();
584 function_requires< Mutable_MatrixExpressionConcept<matrix_type> >();
585 size_type n (0);
586 value_type t = value_type ();
587 size_type i (0), j (0);
588 matrix_type m;
589 // Element support
590#ifndef SKIP_BAD
591 pointer p = m.find_element (i, j);
592 ignore_unused_variable_warning (i);
593 ignore_unused_variable_warning (j);
594#else
595 pointer p;
596#endif
597 // Element assigment
598 value_type r = m.insert_element (i, j, t);
599 m.insert_element (i, j, t) = r;
600 // Zeroing
601 m.clear ();
602 // Resize
603 m.resize (n, n);
604 m.resize (n, n, false);
605
606 ignore_unused_variable_warning (p);
607 ignore_unused_variable_warning (r);
608 }
609 };
610
611 template<class M>
612 struct SparseMatrixConcept {
613 typedef M matrix_type;
614 typedef typename M::size_type size_type;
615
616 void constraints () {
617 function_requires< MatrixConcept<matrix_type> >();
618 }
619 };
620
621 template<class M>
622 struct Mutable_SparseMatrixConcept {
623 typedef M matrix_type;
624 typedef typename M::size_type size_type;
625 typedef typename M::value_type value_type;
626
627 void constraints () {
628 function_requires< SparseMatrixConcept<matrix_type> >();
629 function_requires< Mutable_MatrixConcept<matrix_type> >();
630 size_type i (0), j (0);
631 matrix_type m;
632 // Elemnent erasure
633 m.erase_element (i, j);
634 }
635 };
636
637 /** introduce anonymous namespace to make following functions
638 * local to the current compilation unit.
639 */
640 namespace {
641
642 // Replaced the ZeroElement and OneElement functions with the templated versions
643 // because the former where giving warnings with clang
644 template<class T>
645 T
646 ZeroElement (T) {
647 return static_cast<T> (0);
648 }
649
650 template<class T>
651 vector<T>
652 ZeroElement (vector<T>) {
653 return zero_vector<T> ();
654 }
655
656 template<class T>
657 matrix<T>
658 ZeroElement (matrix<T>) {
659 return zero_matrix<T> ();
660 }
661
662 template<class T>
663 T
664 OneElement (T) {
665 return static_cast<T> (1);
666 }
667
668 template<class T>
669 matrix<T>
670 OneElement (matrix<T>) {
671 return identity_matrix<T> ();
672 }
673
674
675 template<class E1, class E2>
676 bool
677 operator == (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
678 typedef typename promote_traits<typename E1::value_type,
679 typename E2::value_type>::promote_type value_type;
680 typedef typename type_traits<value_type>::real_type real_type;
681 return norm_inf (e1 - e2) == real_type/*zero*/();
682 }
683 template<class E1, class E2>
684 bool
685 operator == (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
686 typedef typename promote_traits<typename E1::value_type,
687 typename E2::value_type>::promote_type value_type;
688 typedef typename type_traits<value_type>::real_type real_type;
689 return norm_inf (e1 - e2) == real_type/*zero*/();
690 }
691
692 template<class T>
693 struct AdditiveAbelianGroupConcept {
694 typedef T value_type;
695
696 void constraints () {
697 bool r;
698 value_type a = value_type (), b = value_type (), c = value_type ();
699 r = (a + b) + c == a + (b + c);
700 r = ZeroElement (value_type ()) + a == a;
701 r = a + ZeroElement (value_type ()) == a;
702 r = a + (- a) == ZeroElement (value_type ());
703 r = (- a) + a == ZeroElement (value_type ());
704 r = a + b == b + a;
705 ignore_unused_variable_warning (r);
706 }
707 };
708
709 template<class T>
710 struct MultiplicativeAbelianGroupConcept {
711 typedef T value_type;
712
713 void constraints () {
714 bool r;
715 value_type a = value_type (), b = value_type (), c = value_type ();
716 r = (a * b) * c == a * (b * c);
717 r = OneElement (value_type ()) * a == a;
718 r = a * OneElement (value_type ()) == a;
719 r = a * (OneElement (value_type ()) / a) == a;
720 r = (OneElement (value_type ()) / a) * a == a;
721 r = a * b == b * a;
722 ignore_unused_variable_warning (r);
723 }
724 };
725
726 template<class T>
727 struct RingWithIdentityConcept {
728 typedef T value_type;
729
730 void constraints () {
731 function_requires< AdditiveAbelianGroupConcept<value_type> >();
732 bool r;
733 value_type a = value_type (), b = value_type (), c = value_type ();
734 r = (a * b) * c == a * (b * c);
735 r = (a + b) * c == a * c + b * c;
736 r = OneElement (value_type ()) * a == a;
737 r = a * OneElement (value_type ()) == a;
738 ignore_unused_variable_warning (r);
739 }
740 };
741
742 template<class T>
743 struct Prod_RingWithIdentityConcept {
744 typedef T value_type;
745
746 void constraints () {
747 function_requires< AdditiveAbelianGroupConcept<value_type> >();
748 bool r;
749 value_type a = value_type (), b = value_type (), c = value_type ();
750 r = prod (T (prod (a, b)), c) == prod (a, T (prod (b, c)));
751 r = prod (a + b, c) == prod (a, c) + prod (b, c);
752 r = prod (OneElement (value_type ()), a) == a;
753 r = prod (a, OneElement (value_type ())) == a;
754 ignore_unused_variable_warning (r);
755 }
756 };
757
758 template<class T>
759 struct CommutativeRingWithIdentityConcept {
760 typedef T value_type;
761
762 void constraints () {
763 function_requires< RingWithIdentityConcept<value_type> >();
764 bool r;
765 value_type a = value_type (), b = value_type ();
766 r = a * b == b * a;
767 ignore_unused_variable_warning (r);
768 }
769 };
770
771 template<class T>
772 struct FieldConcept {
773 typedef T value_type;
774
775 void constraints () {
776 function_requires< CommutativeRingWithIdentityConcept<value_type> >();
777 bool r;
778 value_type a = value_type ();
779 r = a == ZeroElement (value_type ()) || a * (OneElement (value_type ()) / a) == a;
780 r = a == ZeroElement (value_type ()) || (OneElement (value_type ()) / a) * a == a;
781 ignore_unused_variable_warning (r);
782 }
783 };
784
785 template<class T, class V>
786 struct VectorSpaceConcept {
787 typedef T value_type;
788 typedef V vector_type;
789
790 void constraints () {
791 function_requires< FieldConcept<value_type> >();
792 function_requires< AdditiveAbelianGroupConcept<vector_type> >();
793 bool r;
794 value_type alpha = value_type (), beta = value_type ();
795 vector_type a = vector_type (), b = vector_type ();
796 r = alpha * (a + b) == alpha * a + alpha * b;
797 r = (alpha + beta) * a == alpha * a + beta * a;
798 r = (alpha * beta) * a == alpha * (beta * a);
799 r = OneElement (value_type ()) * a == a;
800 ignore_unused_variable_warning (r);
801 }
802 };
803
804 template<class T, class V, class M>
805 struct LinearOperatorConcept {
806 typedef T value_type;
807 typedef V vector_type;
808 typedef M matrix_type;
809
810 void constraints () {
811 function_requires< VectorSpaceConcept<value_type, vector_type> >();
812 bool r;
813 value_type alpha = value_type (), beta = value_type ();
814 vector_type a = vector_type (), b = vector_type ();
815 matrix_type A = matrix_type ();
816 r = prod (A, alpha * a + beta * b) == alpha * prod (A, a) + beta * prod (A, b);
817 ignore_unused_variable_warning (r);
818 }
819 };
820
821inline void concept_checks () {
822
823 // Allow tests to be group to keep down compiler storage requirement
824#ifdef INTERAL
825#define INTERNAL_STORAGE
826#define INTERNAL_VECTOR
827#define INTERNAL_MATRIX
828#define INTERNAL_SPECIAL
829#define INTERNAL_SPARSE
830#define INTERNAL_EXPRESSION
831#endif
832
833 // TODO enable this for development
834 // #define VIEW_CONCEPTS
835
836 // Element value type for tests
837 typedef float T;
838
839 // Storage Array
840#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_DENSE)
841 {
842 typedef std::vector<T> container_model;
843 function_requires< Mutable_StorageArrayConcept<container_model> >();
844 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
845 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
846 }
847
848 {
849 typedef bounded_array<T, 1> container_model;
850 function_requires< Mutable_StorageArrayConcept<container_model> >();
851 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
852 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
853 }
854
855 {
856 typedef unbounded_array<T> container_model;
857 function_requires< Mutable_StorageArrayConcept<container_model> >();
858 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
859 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
860 }
861
862/* FIXME array_adaptors are in progress
863 {
864 typedef array_adaptor<T> container_model;
865 function_requires< Mutable_StorageArrayConcept<container_model> >();
866 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
867 function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
868 }
869*/
870
871 {
872 typedef range container_model;
873 function_requires< IndexSetConcept<range> >();
874 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
875 }
876
877 {
878 typedef slice container_model;
879 function_requires< IndexSetConcept<range> >();
880 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
881 }
882
883 {
884 typedef indirect_array<> container_model;
885 function_requires< IndexSetConcept<range> >();
886 function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
887 }
888#endif
889
890 // Storage Sparse
891#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_SPARSE)
892 {
893 typedef map_array<std::size_t, T> container_model;
894 function_requires< Mutable_StorageSparseConcept<container_model> >();
895 function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
896 function_requires< RandomAccessIteratorConcept<container_model::iterator> >();
897 }
898
899 {
900 typedef std::map<std::size_t, T> container_model;
901 function_requires< Mutable_StorageSparseConcept<container_model > >();
902 function_requires< BidirectionalIteratorConcept<container_model::const_iterator> >();
903 function_requires< BidirectionalIteratorConcept<container_model::iterator> >();
904 }
905#endif
906
907#ifdef VIEW_CONCEPTS
908 // read only vectors
909 {
910 typedef vector_view<T> container_model;
911 function_requires< RandomAccessContainerConcept<container_model> >();
912 function_requires< VectorConcept<container_model> >();
913 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
914 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
915 }
916#endif
917
918 // Vector
919#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_DENSE)
920 {
921 typedef vector<T> container_model;
922 function_requires< RandomAccessContainerConcept<container_model> >();
923 function_requires< Mutable_VectorConcept<container_model> >();
924 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
925 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
926 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
927 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
928 }
929
930 {
931 typedef zero_vector<T> container_model;
932 function_requires< VectorConcept<container_model> >();
933 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
934 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
935 }
936
937 {
938 typedef unit_vector<T> container_model;
939 function_requires< VectorConcept<container_model> >();
940 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
941 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
942 }
943
944 {
945 typedef scalar_vector<T> container_model;
946 function_requires< VectorConcept<container_model> >();
947 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
948 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
949 }
950
951 {
952 typedef c_vector<T, 1> container_model;
953 function_requires< Mutable_VectorConcept<container_model> >();
954 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
955 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
956 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
957 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
958 }
959#endif
960
961 // Vector Proxies
962#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_PROXY)
963 {
964 typedef vector_range<vector<T> > container_model;
965 function_requires< Mutable_VectorExpressionConcept<container_model> >();
966 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
967 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
968 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
969 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
970 }
971
972 {
973 typedef vector_slice<vector<T> > container_model;
974 function_requires< Mutable_VectorExpressionConcept<container_model> >();
975 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
976 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
977 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
978 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
979 }
980
981 {
982 typedef vector_indirect<vector<T> > container_model;
983 function_requires< Mutable_VectorExpressionConcept<container_model> >();
984 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
985 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
986 function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
987 function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
988 }
989#endif
990
991 // Sparse Vector
992#if defined (INTERNAL_SPARSE) || defined (INTERNAL_VECTOR_SPARSE)
993 {
994 typedef mapped_vector<T> container_model;
995 function_requires< Mutable_SparseVectorConcept<container_model> >();
996 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
997 function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
998 function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
999 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
1466

source code of boost/libs/numeric/ublas/include/boost/numeric/ublas/detail/concepts.hpp