2
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
3
// sell and distribute this software is granted provided this
4
// copyright notice appears in all copies. This software is provided
5
// "as is" without express or implied warranty, and with no claim as
6
// to its suitability for any purpose.
9
// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
10
// 02 April 2001: Removed limits header altogether. (Jeremy Siek)
11
// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
14
// See http://www.boost.org/libs/concept_check for documentation.
16
#ifndef BOOST_CONCEPT_CHECKS_HPP
17
#define BOOST_CONCEPT_CHECKS_HPP
19
#include <boost/config.hpp>
20
#include <boost/iterator.hpp>
21
#include <boost/type_traits/conversion_traits.hpp>
23
#include <boost/type_traits/conversion_traits.hpp>
24
#include <boost/static_assert.hpp>
25
#include <boost/type.hpp>
28
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__BORLANDC__)
37
"inline" is used for ignore_unused_variable_warning()
38
and function_requires() to make sure there is no
42
template <class T> inline void ignore_unused_variable_warning(const T&) { }
44
// the unused, defaulted parameter is a workaround for MSVC and Compaq C++
45
template <class Concept>
46
inline void function_requires(type<Concept>* = 0)
49
void (Concept::*x)() = BOOST_FPTR Concept::constraints;
50
ignore_unused_variable_warning(x);
54
#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
55
typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
56
template <func##type_var##concept _Tp1> \
57
struct concept_checking_##type_var##concept { }; \
58
typedef concept_checking_##type_var##concept< \
59
BOOST_FPTR ns::concept<type_var>::constraints> \
60
concept_checking_typedef_##type_var##concept
62
#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
63
typedef void (ns::concept <type_var1,type_var2>::* \
64
func##type_var1##type_var2##concept)(); \
65
template <func##type_var1##type_var2##concept _Tp1> \
66
struct concept_checking_##type_var1##type_var2##concept { }; \
67
typedef concept_checking_##type_var1##type_var2##concept< \
68
BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
69
concept_checking_typedef_##type_var1##type_var2##concept
71
#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
72
typedef void (ns::concept <tv1,tv2,tv3>::* \
73
func##tv1##tv2##tv3##concept)(); \
74
template <func##tv1##tv2##tv3##concept _Tp1> \
75
struct concept_checking_##tv1##tv2##tv3##concept { }; \
76
typedef concept_checking_##tv1##tv2##tv3##concept< \
77
BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
78
concept_checking_typedef_##tv1##tv2##tv3##concept
80
#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
81
typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
82
func##tv1##tv2##tv3##tv4##concept)(); \
83
template <func##tv1##tv2##tv3##tv4##concept _Tp1> \
84
struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
85
typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
86
BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
87
concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
89
// NOTE: The BOOST_CLASS_REQUIRES (with an 'S' at the end) is deprecated.
91
// The BOOST_CLASS_REQUIRES macros use function pointers as
92
// template parameters, which VC++ does not support.
94
#if defined(BOOST_NO_FUNCTION_PTR_TEMPLATE_PARAMETERS)
96
#define BOOST_CLASS_REQUIRES(type_var, concept)
97
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept)
98
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept)
99
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept)
103
#define BOOST_CLASS_REQUIRES(type_var, concept) \
104
typedef void (concept <type_var>::* func##type_var##concept)(); \
105
template <func##type_var##concept _Tp1> \
106
struct concept_checking_##type_var##concept { }; \
107
typedef concept_checking_##type_var##concept< \
108
BOOST_FPTR concept <type_var>::constraints> \
109
concept_checking_typedef_##type_var##concept
111
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
112
typedef void (concept <type_var1,type_var2>::* func##type_var1##type_var2##concept)(); \
113
template <func##type_var1##type_var2##concept _Tp1> \
114
struct concept_checking_##type_var1##type_var2##concept { }; \
115
typedef concept_checking_##type_var1##type_var2##concept< \
116
BOOST_FPTR concept <type_var1,type_var2>::constraints> \
117
concept_checking_typedef_##type_var1##type_var2##concept
119
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
120
typedef void (concept <type_var1,type_var2,type_var3>::* func##type_var1##type_var2##type_var3##concept)(); \
121
template <func##type_var1##type_var2##type_var3##concept _Tp1> \
122
struct concept_checking_##type_var1##type_var2##type_var3##concept { }; \
123
typedef concept_checking_##type_var1##type_var2##type_var3##concept< \
124
BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints> \
125
concept_checking_typedef_##type_var1##type_var2##type_var3##concept
127
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
128
typedef void (concept <type_var1,type_var2,type_var3,type_var4>::* func##type_var1##type_var2##type_var3##type_var4##concept)(); \
129
template <func##type_var1##type_var2##type_var3##type_var4##concept _Tp1> \
130
struct concept_checking_##type_var1##type_var2##type_var3##type_var4##concept { }; \
131
typedef concept_checking_##type_var1##type_var2##type_var3##type_var4##concept< \
132
BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints> \
133
concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
138
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
139
template <class T, class U>
140
struct require_same { };
143
struct require_same<T,T> { typedef T type; };
145
// This version does not perform checking, but will not do any harm.
146
template <class T, class U>
147
struct require_same { typedef T type; };
151
struct IntegerConcept {
153
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
154
x.error_type_must_be_an_integer_type();
159
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
160
template <> struct IntegerConcept<short> { void constraints() {} };
161
template <> struct IntegerConcept<unsigned short> { void constraints() {} };
162
template <> struct IntegerConcept<int> { void constraints() {} };
163
template <> struct IntegerConcept<unsigned int> { void constraints() {} };
164
template <> struct IntegerConcept<long> { void constraints() {} };
165
template <> struct IntegerConcept<unsigned long> { void constraints() {} };
170
struct SignedIntegerConcept {
172
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
173
x.error_type_must_be_a_signed_integer_type();
178
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
179
template <> struct SignedIntegerConcept<short> { void constraints() {} };
180
template <> struct SignedIntegerConcept<int> { void constraints() {} };
181
template <> struct SignedIntegerConcept<long> { void constraints() {} };
182
# if defined(BOOST_HAS_LONG_LONG)
183
template <> struct SignedIntegerConcept<long long> { void constraints() {} };
189
struct UnsignedIntegerConcept {
191
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
192
x.error_type_must_be_an_unsigned_integer_type();
197
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
198
template <> struct UnsignedIntegerConcept<unsigned short>
199
{ void constraints() {} };
200
template <> struct UnsignedIntegerConcept<unsigned int>
201
{ void constraints() {} };
202
template <> struct UnsignedIntegerConcept<unsigned long>
203
{ void constraints() {} };
207
//===========================================================================
211
struct DefaultConstructibleConcept
214
TT a; // require default constructor
215
ignore_unused_variable_warning(a);
220
struct AssignableConcept
223
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
224
a = a; // require assignment operator
226
const_constraints(a);
228
void const_constraints(const TT& b) {
229
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
230
a = b; // const required for argument to assignment
237
struct CopyConstructibleConcept
240
TT a(b); // require copy constructor
241
TT* ptr = &a; // require address of operator
242
const_constraints(a);
243
ignore_unused_variable_warning(ptr);
245
void const_constraints(const TT& a) {
246
TT c(a); // require const copy constructor
247
const TT* ptr = &a; // require const address of operator
248
ignore_unused_variable_warning(c);
249
ignore_unused_variable_warning(ptr);
254
// The SGI STL version of Assignable requires copy constructor and operator=
256
struct SGIAssignableConcept
260
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
261
a = a; // require assignment operator
263
const_constraints(a);
264
ignore_unused_variable_warning(b);
266
void const_constraints(const TT& b) {
268
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
269
a = b; // const required for argument to assignment
271
ignore_unused_variable_warning(c);
276
template <class X, class Y>
277
struct ConvertibleConcept
281
ignore_unused_variable_warning(y);
286
// The C++ standard requirements for many concepts talk about return
287
// types that must be "convertible to bool". The problem with this
288
// requirement is that it leaves the door open for evil proxies that
289
// define things like operator|| with strange return types. Two
290
// possible solutions are:
291
// 1) require the return type to be exactly bool
292
// 2) stay with convertible to bool, and also
293
// specify stuff about all the logical operators.
294
// For now we just test for convertible to bool.
296
void require_boolean_expr(const TT& t) {
298
ignore_unused_variable_warning(x);
302
struct EqualityComparableConcept
305
require_boolean_expr(a == b);
306
require_boolean_expr(a != b);
312
struct LessThanComparableConcept
315
require_boolean_expr(a < b);
320
// This is equivalent to SGI STL's LessThanComparable.
322
struct ComparableConcept
325
require_boolean_expr(a < b);
326
require_boolean_expr(a > b);
327
require_boolean_expr(a <= b);
328
require_boolean_expr(a >= b);
333
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
334
template <class First, class Second> \
336
void constraints() { (void)constraints_(); } \
337
bool constraints_() { \
344
#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
345
template <class Ret, class First, class Second> \
347
void constraints() { (void)constraints_(); } \
348
Ret constraints_() { \
355
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
356
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
357
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
358
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
359
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
360
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
362
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
363
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
364
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
365
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
366
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
368
//===========================================================================
369
// Function Object Concepts
371
template <class Func, class Return>
372
struct GeneratorConcept
375
const Return& r = f(); // require operator() member function
376
ignore_unused_variable_warning(r);
382
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
383
template <class Func>
384
struct GeneratorConcept<Func,void>
387
f(); // require operator() member function
393
template <class Func, class Return, class Arg>
394
struct UnaryFunctionConcept
396
// required in case any of our template args are const-qualified:
397
UnaryFunctionConcept();
400
r = f(arg); // require operator()
407
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
408
template <class Func, class Arg>
409
struct UnaryFunctionConcept<Func, void, Arg> {
411
f(arg); // require operator()
418
template <class Func, class Return, class First, class Second>
419
struct BinaryFunctionConcept
422
r = f(first, second); // require operator()
430
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
431
template <class Func, class First, class Second>
432
struct BinaryFunctionConcept<Func, void, First, Second>
435
f(first, second); // require operator()
443
template <class Func, class Arg>
444
struct UnaryPredicateConcept
447
require_boolean_expr(f(arg)); // require operator() returning bool
453
template <class Func, class First, class Second>
454
struct BinaryPredicateConcept
457
require_boolean_expr(f(a, b)); // require operator() returning bool
464
// use this when functor is used inside a container class like std::set
465
template <class Func, class First, class Second>
466
struct Const_BinaryPredicateConcept {
468
const_constraints(f);
470
void const_constraints(const Func& fun) {
471
function_requires<BinaryPredicateConcept<Func, First, Second> >();
472
// operator() must be a const member function
473
require_boolean_expr(fun(a, b));
480
template <class Func, class Return>
481
struct AdaptableGeneratorConcept
484
typedef typename Func::result_type result_type;
485
BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
486
function_requires< GeneratorConcept<Func, result_type> >();
490
template <class Func, class Return, class Arg>
491
struct AdaptableUnaryFunctionConcept
494
typedef typename Func::argument_type argument_type;
495
typedef typename Func::result_type result_type;
496
BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
497
BOOST_STATIC_ASSERT((is_convertible<Arg, argument_type>::value));
498
function_requires< UnaryFunctionConcept<Func, result_type, argument_type> >();
502
template <class Func, class Return, class First, class Second>
503
struct AdaptableBinaryFunctionConcept
506
typedef typename Func::first_argument_type first_argument_type;
507
typedef typename Func::second_argument_type second_argument_type;
508
typedef typename Func::result_type result_type;
509
BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
510
BOOST_STATIC_ASSERT((is_convertible<First, first_argument_type>::value));
511
BOOST_STATIC_ASSERT((is_convertible<Second, second_argument_type>::value));
512
function_requires< BinaryFunctionConcept<Func, result_type,
513
first_argument_type, second_argument_type> >();
517
template <class Func, class Arg>
518
struct AdaptablePredicateConcept
521
function_requires< UnaryPredicateConcept<Func, Arg> >();
522
function_requires< AdaptableUnaryFunctionConcept<Func, bool, Arg> >();
526
template <class Func, class First, class Second>
527
struct AdaptableBinaryPredicateConcept
530
function_requires< BinaryPredicateConcept<Func, First, Second> >();
531
function_requires< AdaptableBinaryFunctionConcept<Func, bool, First, Second> >();
535
//===========================================================================
539
struct TrivialIteratorConcept
542
function_requires< AssignableConcept<TT> >();
543
function_requires< DefaultConstructibleConcept<TT> >();
544
function_requires< EqualityComparableConcept<TT> >();
545
(void)*i; // require dereference operator
551
struct Mutable_TrivialIteratorConcept
554
function_requires< TrivialIteratorConcept<TT> >();
555
*i = *j; // require dereference and assignment
561
struct InputIteratorConcept
564
function_requires< TrivialIteratorConcept<TT> >();
565
// require iterator_traits typedef's
566
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
567
typedef typename std::iterator_traits<TT>::difference_type D;
568
// Hmm, the following is a bit fragile
569
//function_requires< SignedIntegerConcept<D> >();
570
typedef typename std::iterator_traits<TT>::reference R;
571
typedef typename std::iterator_traits<TT>::pointer P;
572
typedef typename std::iterator_traits<TT>::iterator_category C;
573
function_requires< ConvertibleConcept<C, std::input_iterator_tag> >();
575
++i; // require preincrement operator
576
i++; // require postincrement operator
581
template <class TT, class ValueT>
582
struct OutputIteratorConcept
585
function_requires< AssignableConcept<TT> >();
586
++i; // require preincrement operator
587
i++; // require postincrement operator
588
*i++ = t; // require postincrement and assignment
595
struct ForwardIteratorConcept
598
function_requires< InputIteratorConcept<TT> >();
599
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
600
typedef typename std::iterator_traits<TT>::iterator_category C;
601
function_requires< ConvertibleConcept<C, std::forward_iterator_tag> >();
602
typedef typename std::iterator_traits<TT>::reference reference;
604
ignore_unused_variable_warning(r);
611
struct Mutable_ForwardIteratorConcept
614
function_requires< ForwardIteratorConcept<TT> >();
615
*i++ = *i; // require postincrement and assignment
621
struct BidirectionalIteratorConcept
624
function_requires< ForwardIteratorConcept<TT> >();
625
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
626
typedef typename std::iterator_traits<TT>::iterator_category C;
627
function_requires< ConvertibleConcept<C,
628
std::bidirectional_iterator_tag> >();
630
--i; // require predecrement operator
631
i--; // require postdecrement operator
637
struct Mutable_BidirectionalIteratorConcept
640
function_requires< BidirectionalIteratorConcept<TT> >();
641
function_requires< Mutable_ForwardIteratorConcept<TT> >();
642
*i-- = *i; // require postdecrement and assignment
649
struct RandomAccessIteratorConcept
652
function_requires< BidirectionalIteratorConcept<TT> >();
653
function_requires< ComparableConcept<TT> >();
654
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
655
typedef typename std::iterator_traits<TT>::iterator_category C;
656
function_requires< ConvertibleConcept< C,
657
std::random_access_iterator_tag> >();
658
typedef typename std::iterator_traits<TT>::reference R;
661
i += n; // require assignment addition operator
662
i = i + n; i = n + i; // require addition with difference type
663
i -= n; // require assignment subtraction operator
664
i = i - n; // require subtraction with difference type
665
n = i - j; // require difference operator
666
(void)i[n]; // require element access operator
670
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
671
typename std::iterator_traits<TT>::difference_type n;
678
struct Mutable_RandomAccessIteratorConcept
681
function_requires< RandomAccessIteratorConcept<TT> >();
682
function_requires< Mutable_BidirectionalIteratorConcept<TT> >();
683
i[n] = *i; // require element access and assignment
686
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
687
typename std::iterator_traits<TT>::difference_type n;
693
//===========================================================================
694
// Container Concepts
696
template <class Container>
697
struct ContainerConcept
699
typedef typename Container::value_type value_type;
700
typedef typename Container::difference_type difference_type;
701
typedef typename Container::size_type size_type;
702
typedef typename Container::const_reference const_reference;
703
typedef typename Container::const_pointer const_pointer;
704
typedef typename Container::const_iterator const_iterator;
707
function_requires< InputIteratorConcept<const_iterator> >();
708
function_requires< AssignableConcept<Container> >();
709
const_constraints(c);
711
void const_constraints(const Container& c) {
724
template <class Container>
725
struct Mutable_ContainerConcept
727
typedef typename Container::value_type value_type;
728
typedef typename Container::reference reference;
729
typedef typename Container::iterator iterator;
730
typedef typename Container::pointer pointer;
733
function_requires< ContainerConcept<Container> >();
734
function_requires< AssignableConcept<value_type> >();
735
function_requires< InputIteratorConcept<iterator> >();
745
template <class ForwardContainer>
746
struct ForwardContainerConcept
749
function_requires< ContainerConcept<ForwardContainer> >();
750
typedef typename ForwardContainer::const_iterator const_iterator;
751
function_requires< ForwardIteratorConcept<const_iterator> >();
755
template <class ForwardContainer>
756
struct Mutable_ForwardContainerConcept
759
function_requires< ForwardContainerConcept<ForwardContainer> >();
760
function_requires< Mutable_ContainerConcept<ForwardContainer> >();
761
typedef typename ForwardContainer::iterator iterator;
762
function_requires< Mutable_ForwardIteratorConcept<iterator> >();
766
template <class ReversibleContainer>
767
struct ReversibleContainerConcept
769
typedef typename ReversibleContainer::const_iterator const_iterator;
770
typedef typename ReversibleContainer::const_reverse_iterator
771
const_reverse_iterator;
774
function_requires< ForwardContainerConcept<ReversibleContainer> >();
775
function_requires< BidirectionalIteratorConcept<const_iterator> >();
777
BidirectionalIteratorConcept<const_reverse_iterator> >();
778
const_constraints(c);
780
void const_constraints(const ReversibleContainer& c) {
781
const_reverse_iterator i = c.rbegin();
784
ReversibleContainer c;
787
template <class ReversibleContainer>
788
struct Mutable_ReversibleContainerConcept
790
typedef typename ReversibleContainer::iterator iterator;
791
typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
794
function_requires< ReversibleContainerConcept<ReversibleContainer> >();
796
Mutable_ForwardContainerConcept<ReversibleContainer> >();
797
function_requires< Mutable_BidirectionalIteratorConcept<iterator> >();
799
Mutable_BidirectionalIteratorConcept<reverse_iterator> >();
801
reverse_iterator i = c.rbegin();
804
ReversibleContainer c;
807
template <class RandomAccessContainer>
808
struct RandomAccessContainerConcept
810
typedef typename RandomAccessContainer::size_type size_type;
811
typedef typename RandomAccessContainer::const_reference const_reference;
812
typedef typename RandomAccessContainer::const_iterator const_iterator;
813
typedef typename RandomAccessContainer::const_reverse_iterator
814
const_reverse_iterator;
817
function_requires< ReversibleContainerConcept<RandomAccessContainer> >();
818
function_requires< RandomAccessIteratorConcept<const_iterator> >();
820
RandomAccessIteratorConcept<const_reverse_iterator> >();
822
const_constraints(c);
824
void const_constraints(const RandomAccessContainer& c) {
825
const_reference r = c[n];
826
ignore_unused_variable_warning(r);
828
RandomAccessContainer c;
832
template <class RandomAccessContainer>
833
struct Mutable_RandomAccessContainerConcept
835
typedef typename RandomAccessContainer::size_type size_type;
836
typedef typename RandomAccessContainer::reference reference;
837
typedef typename RandomAccessContainer::iterator iterator;
838
typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
842
RandomAccessContainerConcept<RandomAccessContainer> >();
844
Mutable_ReversibleContainerConcept<RandomAccessContainer> >();
845
function_requires< Mutable_RandomAccessIteratorConcept<iterator> >();
847
Mutable_RandomAccessIteratorConcept<reverse_iterator> >();
850
ignore_unused_variable_warning(r);
853
RandomAccessContainer c;
856
// A Sequence is inherently mutable
857
template <class Sequence>
858
struct SequenceConcept
861
typedef typename Sequence::reference reference;
862
typedef typename Sequence::const_reference const_reference;
865
// Matt Austern's book puts DefaultConstructible here, the C++
866
// standard places it in Container
867
// function_requires< DefaultConstructible<Sequence> >();
868
function_requires< Mutable_ForwardContainerConcept<Sequence> >();
869
function_requires< DefaultConstructibleConcept<Sequence> >();
878
c.insert(p, first, last);
883
reference r = c.front();
885
ignore_unused_variable_warning(c);
886
ignore_unused_variable_warning(c2);
887
ignore_unused_variable_warning(c3);
888
ignore_unused_variable_warning(r);
889
const_constraints(c);
891
void const_constraints(const Sequence& c) {
892
const_reference r = c.front();
893
ignore_unused_variable_warning(r);
895
typename Sequence::value_type t;
896
typename Sequence::size_type n;
897
typename Sequence::value_type* first, *last;
898
typename Sequence::iterator p, q;
901
template <class FrontInsertionSequence>
902
struct FrontInsertionSequenceConcept
905
function_requires< SequenceConcept<FrontInsertionSequence> >();
910
FrontInsertionSequence c;
911
typename FrontInsertionSequence::value_type t;
914
template <class BackInsertionSequence>
915
struct BackInsertionSequenceConcept
917
typedef typename BackInsertionSequence::reference reference;
918
typedef typename BackInsertionSequence::const_reference const_reference;
921
function_requires< SequenceConcept<BackInsertionSequence> >();
925
reference r = c.back();
926
ignore_unused_variable_warning(r);
928
void const_constraints(const BackInsertionSequence& c) {
929
const_reference r = c.back();
930
ignore_unused_variable_warning(r);
932
BackInsertionSequence c;
933
typename BackInsertionSequence::value_type t;
936
template <class AssociativeContainer>
937
struct AssociativeContainerConcept
940
function_requires< ForwardContainerConcept<AssociativeContainer> >();
941
function_requires< DefaultConstructibleConcept<AssociativeContainer> >();
944
r = c.equal_range(k);
947
c.erase(r.first, r.second);
948
const_constraints(c);
950
void const_constraints(const AssociativeContainer& c) {
953
cr = c.equal_range(k);
955
typedef typename AssociativeContainer::iterator iterator;
956
typedef typename AssociativeContainer::const_iterator const_iterator;
958
AssociativeContainer c;
960
std::pair<iterator,iterator> r;
962
std::pair<const_iterator,const_iterator> cr;
963
typename AssociativeContainer::key_type k;
964
typename AssociativeContainer::size_type n;
967
template <class UniqueAssociativeContainer>
968
struct UniqueAssociativeContainerConcept
971
function_requires< AssociativeContainerConcept<UniqueAssociativeContainer> >();
973
UniqueAssociativeContainer c(first, last);
975
pos_flag = c.insert(t);
976
c.insert(first, last);
978
ignore_unused_variable_warning(c);
980
std::pair<typename UniqueAssociativeContainer::iterator, bool> pos_flag;
981
typename UniqueAssociativeContainer::value_type t;
982
typename UniqueAssociativeContainer::value_type* first, *last;
985
template <class MultipleAssociativeContainer>
986
struct MultipleAssociativeContainerConcept
989
function_requires< AssociativeContainerConcept<MultipleAssociativeContainer> >();
991
MultipleAssociativeContainer c(first, last);
994
c.insert(first, last);
996
ignore_unused_variable_warning(c);
997
ignore_unused_variable_warning(pos);
999
typename MultipleAssociativeContainer::iterator pos;
1000
typename MultipleAssociativeContainer::value_type t;
1001
typename MultipleAssociativeContainer::value_type* first, *last;
1004
template <class SimpleAssociativeContainer>
1005
struct SimpleAssociativeContainerConcept
1007
void constraints() {
1008
function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
1009
typedef typename SimpleAssociativeContainer::key_type key_type;
1010
typedef typename SimpleAssociativeContainer::value_type value_type;
1011
typedef typename require_same<key_type, value_type>::type req;
1015
template <class SimpleAssociativeContainer>
1016
struct PairAssociativeContainerConcept
1018
void constraints() {
1019
function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
1020
typedef typename SimpleAssociativeContainer::key_type key_type;
1021
typedef typename SimpleAssociativeContainer::value_type value_type;
1022
typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
1023
typedef std::pair<const key_type, mapped_type> required_value_type;
1024
typedef typename require_same<value_type, required_value_type>::type req;
1028
template <class SortedAssociativeContainer>
1029
struct SortedAssociativeContainerConcept
1031
void constraints() {
1032
function_requires< AssociativeContainerConcept<SortedAssociativeContainer> >();
1033
function_requires< ReversibleContainerConcept<SortedAssociativeContainer> >();
1035
SortedAssociativeContainer
1038
c3(first, last, kc);
1040
p = c.upper_bound(k);
1041
p = c.lower_bound(k);
1042
r = c.equal_range(k);
1046
ignore_unused_variable_warning(c);
1047
ignore_unused_variable_warning(c2);
1048
ignore_unused_variable_warning(c3);
1050
void const_constraints(const SortedAssociativeContainer& c) {
1052
vc = c.value_comp();
1054
cp = c.upper_bound(k);
1055
cp = c.lower_bound(k);
1056
cr = c.equal_range(k);
1058
typename SortedAssociativeContainer::key_compare kc;
1059
typename SortedAssociativeContainer::value_compare vc;
1060
typename SortedAssociativeContainer::value_type t;
1061
typename SortedAssociativeContainer::key_type k;
1062
typedef typename SortedAssociativeContainer::iterator iterator;
1063
typedef typename SortedAssociativeContainer::const_iterator const_iterator;
1066
std::pair<iterator,iterator> r;
1067
std::pair<const_iterator,const_iterator> cr;
1068
typename SortedAssociativeContainer::value_type* first, *last;
1071
// HashedAssociativeContainer
1073
} // namespace boost
1075
#endif // BOOST_CONCEPT_CHECKS_HPP