~ubuntu-branches/ubuntu/wily/bombono-dvd/wily

« back to all changes in this revision

Viewing changes to libs/boost-lib/boost/concept_check.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2010-11-04 11:46:25 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20101104114625-8xfdhvhpsm51i0nu
Tags: upstream-0.8.0
ImportĀ upstreamĀ versionĀ 0.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
// See http://www.boost.org/libs/concept_check for documentation.
14
14
 
15
15
#ifndef BOOST_CONCEPT_CHECKS_HPP
16
 
#define BOOST_CONCEPT_CHECKS_HPP
17
 
 
18
 
#include <boost/config.hpp>
19
 
#include <boost/iterator.hpp>
20
 
#include <boost/type_traits/conversion_traits.hpp>
21
 
#include <utility>
22
 
#include <boost/type_traits/conversion_traits.hpp>
23
 
#include <boost/static_assert.hpp>
24
 
#include <boost/mpl/identity.hpp>
25
 
 
26
 
 
27
 
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__BORLANDC__)
28
 
#define BOOST_FPTR
29
 
#else
30
 
#define BOOST_FPTR &
31
 
#endif
32
 
 
33
 
namespace boost {
34
 
 
35
 
/*
36
 
  "inline" is used for ignore_unused_variable_warning()
37
 
   and function_requires() to make sure there is no
38
 
   overhead with g++.
39
 
 */
40
 
 
41
 
template <class T> inline void ignore_unused_variable_warning(const T&) { }
42
 
 
43
 
// the unused, defaulted parameter is a workaround for MSVC and Compaq C++
44
 
template <class Concept>
45
 
inline void function_requires(mpl::identity<Concept>* = 0)
 
16
# define BOOST_CONCEPT_CHECKS_HPP
 
17
 
 
18
# include <boost/concept/assert.hpp>
 
19
 
 
20
# include <boost/iterator.hpp>
 
21
# include <boost/type_traits/conversion_traits.hpp>
 
22
# include <utility>
 
23
# include <boost/type_traits/is_same.hpp>
 
24
# include <boost/type_traits/is_void.hpp>
 
25
# include <boost/mpl/assert.hpp>
 
26
# include <boost/mpl/bool.hpp>
 
27
# include <boost/detail/workaround.hpp>
 
28
# include <boost/detail/iterator.hpp>
 
29
 
 
30
# include <boost/concept/usage.hpp>
 
31
# include <boost/concept/detail/concept_def.hpp>
 
32
 
 
33
namespace boost
46
34
{
47
 
#if !defined(NDEBUG)
48
 
  void (Concept::*x)() = BOOST_FPTR Concept::constraints;
49
 
  ignore_unused_variable_warning(x);
50
 
#endif
51
 
}
52
 
 
53
 
#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
54
 
  typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
55
 
  template <func##type_var##concept Tp1_> \
56
 
  struct concept_checking_##type_var##concept { }; \
57
 
  typedef concept_checking_##type_var##concept< \
58
 
    BOOST_FPTR ns::concept<type_var>::constraints> \
59
 
    concept_checking_typedef_##type_var##concept
60
 
 
61
 
#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
62
 
  typedef void (ns::concept <type_var1,type_var2>::* \
63
 
     func##type_var1##type_var2##concept)(); \
64
 
  template <func##type_var1##type_var2##concept Tp1_> \
65
 
  struct concept_checking_##type_var1##type_var2##concept { }; \
66
 
  typedef concept_checking_##type_var1##type_var2##concept< \
67
 
    BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
68
 
    concept_checking_typedef_##type_var1##type_var2##concept
69
 
 
70
 
#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
71
 
  typedef void (ns::concept <tv1,tv2,tv3>::* \
72
 
     func##tv1##tv2##tv3##concept)(); \
73
 
  template <func##tv1##tv2##tv3##concept Tp1_> \
74
 
  struct concept_checking_##tv1##tv2##tv3##concept { }; \
75
 
  typedef concept_checking_##tv1##tv2##tv3##concept< \
76
 
    BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
77
 
    concept_checking_typedef_##tv1##tv2##tv3##concept
78
 
 
79
 
#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
80
 
  typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
81
 
     func##tv1##tv2##tv3##tv4##concept)(); \
82
 
  template <func##tv1##tv2##tv3##tv4##concept Tp1_> \
83
 
  struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
84
 
  typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
85
 
    BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
86
 
    concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
87
 
 
88
 
// NOTE: The BOOST_CLASS_REQUIRES (with an 'S' at the end) is deprecated.
89
 
 
90
 
// The BOOST_CLASS_REQUIRES macros use function pointers as
91
 
// template parameters, which VC++ does not support.
92
 
 
93
 
#if defined(BOOST_NO_FUNCTION_PTR_TEMPLATE_PARAMETERS)
94
 
 
95
 
#define BOOST_CLASS_REQUIRES(type_var, concept)
96
 
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept)
97
 
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept)
98
 
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept)
99
 
 
100
 
#else
101
 
 
102
 
#define BOOST_CLASS_REQUIRES(type_var, concept) \
103
 
  typedef void (concept <type_var>::* func##type_var##concept)(); \
104
 
  template <func##type_var##concept Tp1_> \
105
 
  struct concept_checking_##type_var##concept { }; \
106
 
  typedef concept_checking_##type_var##concept< \
107
 
    BOOST_FPTR concept <type_var>::constraints> \
108
 
    concept_checking_typedef_##type_var##concept
109
 
 
110
 
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
111
 
  typedef void (concept <type_var1,type_var2>::* func##type_var1##type_var2##concept)(); \
112
 
  template <func##type_var1##type_var2##concept Tp1_> \
113
 
  struct concept_checking_##type_var1##type_var2##concept { }; \
114
 
  typedef concept_checking_##type_var1##type_var2##concept< \
115
 
    BOOST_FPTR concept <type_var1,type_var2>::constraints> \
116
 
    concept_checking_typedef_##type_var1##type_var2##concept
117
 
 
118
 
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
119
 
  typedef void (concept <type_var1,type_var2,type_var3>::* func##type_var1##type_var2##type_var3##concept)(); \
120
 
  template <func##type_var1##type_var2##type_var3##concept Tp1_> \
121
 
  struct concept_checking_##type_var1##type_var2##type_var3##concept { }; \
122
 
  typedef concept_checking_##type_var1##type_var2##type_var3##concept< \
123
 
    BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints>  \
124
 
  concept_checking_typedef_##type_var1##type_var2##type_var3##concept
125
 
 
126
 
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
127
 
  typedef void (concept <type_var1,type_var2,type_var3,type_var4>::* func##type_var1##type_var2##type_var3##type_var4##concept)(); \
128
 
  template <func##type_var1##type_var2##type_var3##type_var4##concept Tp1_> \
129
 
  struct concept_checking_##type_var1##type_var2##type_var3##type_var4##concept { }; \
130
 
  typedef concept_checking_##type_var1##type_var2##type_var3##type_var4##concept< \
131
 
    BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints>  \
132
 
    concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
133
 
 
134
 
 
135
 
#endif
136
 
 
137
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
138
 
template <class T, class U>
139
 
struct require_same { };
140
 
 
141
 
template <class T>
142
 
struct require_same<T,T> { typedef T type; };
143
 
#else
144
 
// This version does not perform checking, but will not do any harm.
145
 
template <class T, class U>
146
 
struct require_same { typedef T type; };
147
 
#endif
148
 
 
149
 
  template <class T>
150
 
  struct IntegerConcept {
151
 
    void constraints() { 
152
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
153
 
      x.error_type_must_be_an_integer_type();
154
 
#endif      
155
 
    }
156
 
    T x;
 
35
 
 
36
  //
 
37
  // Backward compatibility
 
38
  //
 
39
  
 
40
  template <class Model>
 
41
  inline void function_requires(Model* = 0)
 
42
  {
 
43
      BOOST_CONCEPT_ASSERT((Model));
 
44
  }    
 
45
  template <class T> inline void ignore_unused_variable_warning(T const&) {}
 
46
  
 
47
#  define BOOST_CLASS_REQUIRE(type_var, ns, concept)    \
 
48
    BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
 
49
 
 
50
#  define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept)   \
 
51
    BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
 
52
 
 
53
#  define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept)  \
 
54
    BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
 
55
 
 
56
#  define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
 
57
    BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
 
58
 
 
59
  
 
60
  //
 
61
  // Begin concept definitions
 
62
  //
 
63
  BOOST_concept(Integer, (T))
 
64
  {
 
65
      BOOST_CONCEPT_USAGE(Integer)
 
66
        { 
 
67
            x.error_type_must_be_an_integer_type();
 
68
        }
 
69
   private:
 
70
      T x;
157
71
  };
158
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
159
 
  template <> struct IntegerConcept<short> { void constraints() {} };
160
 
  template <> struct IntegerConcept<unsigned short> { void constraints() {} };
161
 
  template <> struct IntegerConcept<int> { void constraints() {} };
162
 
  template <> struct IntegerConcept<unsigned int> { void constraints() {} };
163
 
  template <> struct IntegerConcept<long> { void constraints() {} };
164
 
  template <> struct IntegerConcept<unsigned long> { void constraints() {} };
165
 
  // etc.
166
 
#endif      
167
 
 
168
 
  template <class T>
169
 
  struct SignedIntegerConcept {
170
 
    void constraints() { 
171
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
72
 
 
73
  template <> struct Integer<signed char> {};
 
74
  template <> struct Integer<unsigned char> {};
 
75
  template <> struct Integer<short> {};
 
76
  template <> struct Integer<unsigned short> {};
 
77
  template <> struct Integer<int> {};
 
78
  template <> struct Integer<unsigned int> {};
 
79
  template <> struct Integer<long> {};
 
80
  template <> struct Integer<unsigned long> {};
 
81
# if defined(BOOST_HAS_LONG_LONG)
 
82
  template <> struct Integer< ::boost::long_long_type> {};
 
83
  template <> struct Integer< ::boost::ulong_long_type> {};
 
84
# elif defined(BOOST_HAS_MS_INT64)
 
85
  template <> struct Integer<__int64> {};
 
86
  template <> struct Integer<unsigned __int64> {};
 
87
# endif
 
88
 
 
89
  BOOST_concept(SignedInteger,(T)) {
 
90
    BOOST_CONCEPT_USAGE(SignedInteger) { 
172
91
      x.error_type_must_be_a_signed_integer_type();
173
 
#endif      
174
92
    }
 
93
   private:
175
94
    T x;
176
95
  };
177
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
178
 
  template <> struct SignedIntegerConcept<short> { void constraints() {} };
179
 
  template <> struct SignedIntegerConcept<int> { void constraints() {} };
180
 
  template <> struct SignedIntegerConcept<long> { void constraints() {} };
 
96
  template <> struct SignedInteger<signed char> { };
 
97
  template <> struct SignedInteger<short> {};
 
98
  template <> struct SignedInteger<int> {};
 
99
  template <> struct SignedInteger<long> {};
181
100
# if defined(BOOST_HAS_LONG_LONG)
182
 
  template <> struct SignedIntegerConcept< ::boost::long_long_type> { void constraints() {} };
183
 
# endif
184
 
  // etc.
185
 
#endif      
 
101
  template <> struct SignedInteger< ::boost::long_long_type> {};
 
102
# elif defined(BOOST_HAS_MS_INT64)
 
103
  template <> struct SignedInteger<__int64> {};
 
104
# endif      
186
105
 
187
 
  template <class T>
188
 
  struct UnsignedIntegerConcept {
189
 
    void constraints() { 
190
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
106
  BOOST_concept(UnsignedInteger,(T)) {
 
107
    BOOST_CONCEPT_USAGE(UnsignedInteger) { 
191
108
      x.error_type_must_be_an_unsigned_integer_type();
192
 
#endif      
193
109
    }
 
110
   private:
194
111
    T x;
195
112
  };
196
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
197
 
  template <> struct UnsignedIntegerConcept<unsigned short>
198
 
    { void constraints() {} };
199
 
  template <> struct UnsignedIntegerConcept<unsigned int>
200
 
    { void constraints() {} };
201
 
  template <> struct UnsignedIntegerConcept<unsigned long>
202
 
    { void constraints() {} };
203
 
  // etc.
204
 
#endif      
 
113
  
 
114
  template <> struct UnsignedInteger<unsigned char> {};
 
115
  template <> struct UnsignedInteger<unsigned short> {};
 
116
  template <> struct UnsignedInteger<unsigned int> {};
 
117
  template <> struct UnsignedInteger<unsigned long> {};
 
118
# if defined(BOOST_HAS_LONG_LONG)
 
119
  template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
 
120
# elif defined(BOOST_HAS_MS_INT64)
 
121
  template <> struct UnsignedInteger<unsigned __int64> {};
 
122
# endif
205
123
 
206
124
  //===========================================================================
207
125
  // Basic Concepts
208
126
 
209
 
  template <class TT>
210
 
  struct DefaultConstructibleConcept
 
127
  BOOST_concept(DefaultConstructible,(TT))
211
128
  {
212
 
    void constraints() {
 
129
    BOOST_CONCEPT_USAGE(DefaultConstructible) {
213
130
      TT a;               // require default constructor
214
131
      ignore_unused_variable_warning(a);
215
132
    }
216
133
  };
217
134
 
218
 
  template <class TT>
219
 
  struct AssignableConcept
 
135
  BOOST_concept(Assignable,(TT))
220
136
  {
221
 
    void constraints() {
 
137
    BOOST_CONCEPT_USAGE(Assignable) {
222
138
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
223
 
      a = a;              // require assignment operator
 
139
      a = a;             // require assignment operator
224
140
#endif
225
141
      const_constraints(a);
226
142
    }
 
143
   private:
227
144
    void const_constraints(const TT& b) {
228
145
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
229
146
      a = b;              // const required for argument to assignment
 
147
#else
 
148
      ignore_unused_variable_warning(b);
230
149
#endif
231
150
    }
 
151
   private:
232
152
    TT a;
233
153
  };
234
154
 
235
 
  template <class TT>
236
 
  struct CopyConstructibleConcept
 
155
  
 
156
  BOOST_concept(CopyConstructible,(TT))
237
157
  {
238
 
    void constraints() {
 
158
    BOOST_CONCEPT_USAGE(CopyConstructible) {
239
159
      TT a(b);            // require copy constructor
240
160
      TT* ptr = &a;       // require address of operator
241
161
      const_constraints(a);
242
162
      ignore_unused_variable_warning(ptr);
243
163
    }
 
164
   private:
244
165
    void const_constraints(const TT& a) {
245
166
      TT c(a);            // require const copy constructor
246
167
      const TT* ptr = &a; // require const address of operator
250
171
    TT b;
251
172
  };
252
173
 
 
174
#if (defined _MSC_VER)
 
175
# pragma warning( push )
 
176
# pragma warning( disable : 4510 ) // default constructor could not be generated
 
177
# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
 
178
#endif
253
179
  // The SGI STL version of Assignable requires copy constructor and operator=
254
 
  template <class TT>
255
 
  struct SGIAssignableConcept
 
180
  BOOST_concept(SGIAssignable,(TT))
256
181
  {
257
 
    void constraints() {
 
182
    BOOST_CONCEPT_USAGE(SGIAssignable) {
258
183
      TT b(a);
259
184
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
260
185
      a = a;              // require assignment operator
262
187
      const_constraints(a);
263
188
      ignore_unused_variable_warning(b);
264
189
    }
 
190
   private:
265
191
    void const_constraints(const TT& b) {
266
192
      TT c(b);
267
193
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
271
197
    }
272
198
    TT a;
273
199
  };
 
200
#if (defined _MSC_VER)
 
201
# pragma warning( pop )
 
202
#endif
274
203
 
275
 
  template <class X, class Y>
276
 
  struct ConvertibleConcept
 
204
  BOOST_concept(Convertible,(X)(Y))
277
205
  {
278
 
    void constraints() {
 
206
    BOOST_CONCEPT_USAGE(Convertible) {
279
207
      Y y = x;
280
208
      ignore_unused_variable_warning(y);
281
209
    }
 
210
   private:
282
211
    X x;
283
212
  };
284
213
 
297
226
    ignore_unused_variable_warning(x);
298
227
  }
299
228
 
300
 
  template <class TT>
301
 
  struct EqualityComparableConcept
 
229
  BOOST_concept(EqualityComparable,(TT))
302
230
  {
303
 
    void constraints() {
 
231
    BOOST_CONCEPT_USAGE(EqualityComparable) {
304
232
      require_boolean_expr(a == b);
305
233
      require_boolean_expr(a != b);
306
234
    }
 
235
   private:
307
236
    TT a, b;
308
237
  };
309
238
 
310
 
  template <class TT>
311
 
  struct LessThanComparableConcept
 
239
  BOOST_concept(LessThanComparable,(TT))
312
240
  {
313
 
    void constraints() {
 
241
    BOOST_CONCEPT_USAGE(LessThanComparable) {
314
242
      require_boolean_expr(a < b);
315
243
    }
 
244
   private:
316
245
    TT a, b;
317
246
  };
318
247
 
319
248
  // This is equivalent to SGI STL's LessThanComparable.
320
 
  template <class TT>
321
 
  struct ComparableConcept
 
249
  BOOST_concept(Comparable,(TT))
322
250
  {
323
 
    void constraints() {
 
251
    BOOST_CONCEPT_USAGE(Comparable) {
324
252
      require_boolean_expr(a < b);
325
253
      require_boolean_expr(a > b);
326
254
      require_boolean_expr(a <= b);
327
255
      require_boolean_expr(a >= b);
328
256
    }
 
257
   private:
329
258
    TT a, b;
330
259
  };
331
260
 
332
 
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
333
 
  template <class First, class Second> \
334
 
  struct NAME { \
335
 
    void constraints() { (void)constraints_(); } \
336
 
    bool constraints_() {  \
337
 
      return  a OP b; \
338
 
    } \
339
 
    First a; \
340
 
    Second b; \
341
 
  }
342
 
 
343
 
#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
344
 
  template <class Ret, class First, class Second> \
345
 
  struct NAME { \
346
 
    void constraints() { (void)constraints_(); } \
347
 
    Ret constraints_() {  \
348
 
      return a OP b; \
349
 
    } \
350
 
    First a; \
351
 
    Second b; \
352
 
  }
353
 
 
354
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
355
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
356
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
357
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
358
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
359
 
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
360
 
 
361
 
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
362
 
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
363
 
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
364
 
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
365
 
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
 
261
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME)    \
 
262
  BOOST_concept(NAME, (First)(Second))                          \
 
263
  {                                                             \
 
264
      BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); }                         \
 
265
     private:                                                   \
 
266
        bool constraints_() { return a OP b; }                  \
 
267
        First a;                                                \
 
268
        Second b;                                               \
 
269
  }
 
270
 
 
271
#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME)    \
 
272
  BOOST_concept(NAME, (Ret)(First)(Second))                 \
 
273
  {                                                         \
 
274
      BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); }                     \
 
275
  private:                                                  \
 
276
      Ret constraints_() { return a OP b; }                 \
 
277
      First a;                                              \
 
278
      Second b;                                             \
 
279
  }
 
280
 
 
281
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
 
282
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
 
283
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
 
284
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
 
285
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
 
286
  BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
 
287
 
 
288
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
 
289
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
 
290
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
 
291
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
 
292
  BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
366
293
 
367
294
  //===========================================================================
368
295
  // Function Object Concepts
369
296
 
370
 
  template <class Func, class Return>
371
 
  struct GeneratorConcept
372
 
  {
373
 
    void constraints() {
374
 
      const Return& r = f();   // require operator() member function
375
 
      ignore_unused_variable_warning(r);
376
 
    }
377
 
    Func f;
378
 
  };
379
 
 
380
 
 
381
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
382
 
  template <class Func>
383
 
  struct GeneratorConcept<Func,void>
384
 
  {
385
 
    void constraints() {
386
 
      f();              // require operator() member function
387
 
    }
388
 
    Func f;
389
 
  };
390
 
#endif
391
 
 
392
 
  template <class Func, class Return, class Arg>
393
 
  struct UnaryFunctionConcept
394
 
  {
395
 
    // required in case any of our template args are const-qualified:
396
 
    UnaryFunctionConcept();
397
 
    
398
 
    void constraints() {
399
 
      r = f(arg); // require operator()
400
 
    }
401
 
    Func f;
402
 
    Arg arg;
403
 
    Return r;
404
 
  };
405
 
 
406
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
407
 
  template <class Func, class Arg>
408
 
  struct UnaryFunctionConcept<Func, void, Arg> {
409
 
    void constraints() { 
410
 
      f(arg);                 // require operator()
411
 
    }
412
 
    Func f;
413
 
    Arg arg;
414
 
  };
415
 
#endif
416
 
 
417
 
  template <class Func, class Return, class First, class Second>
418
 
  struct BinaryFunctionConcept
419
 
  {
420
 
    void constraints() { 
421
 
      r = f(first, second); // require operator()
422
 
    }
423
 
    Func f;
424
 
    First first;
425
 
    Second second;
426
 
    Return r;
427
 
  };
428
 
 
429
 
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
430
 
  template <class Func, class First, class Second>
431
 
  struct BinaryFunctionConcept<Func, void, First, Second>
432
 
  {
433
 
    void constraints() {
434
 
      f(first, second); // require operator()
435
 
    }
436
 
    Func f;
437
 
    First first;
438
 
    Second second;
439
 
  };
440
 
#endif
441
 
 
442
 
  template <class Func, class Arg>
443
 
  struct UnaryPredicateConcept
444
 
  {
445
 
    void constraints() {
 
297
  BOOST_concept(Generator,(Func)(Return))
 
298
  {
 
299
      BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
 
300
      
 
301
   private:
 
302
      void test(boost::mpl::false_)
 
303
      {
 
304
          // Do we really want a reference here?
 
305
          const Return& r = f();
 
306
          ignore_unused_variable_warning(r);
 
307
      }
 
308
 
 
309
      void test(boost::mpl::true_)
 
310
      {
 
311
          f();
 
312
      }
 
313
      
 
314
      Func f;
 
315
  };
 
316
 
 
317
  BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
 
318
  {
 
319
      BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
 
320
      
 
321
   private:
 
322
      void test(boost::mpl::false_)
 
323
      {
 
324
          f(arg);               // "priming the pump" this way keeps msvc6 happy (ICE)
 
325
          Return r = f(arg);
 
326
          ignore_unused_variable_warning(r); 
 
327
      }
 
328
      
 
329
      void test(boost::mpl::true_)
 
330
      {
 
331
          f(arg);
 
332
      }
 
333
 
 
334
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
 
335
                      && BOOST_WORKAROUND(__GNUC__, > 3)))
 
336
      // Declare a dummy construktor to make gcc happy.
 
337
      // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
 
338
      // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
 
339
      // in class without a constructor [-Wuninitialized])
 
340
      UnaryFunction();
 
341
#endif
 
342
 
 
343
      Func f;
 
344
      Arg arg;
 
345
  };
 
346
 
 
347
  BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
 
348
  {
 
349
      BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
 
350
   private:
 
351
      void test(boost::mpl::false_)
 
352
      {
 
353
          f(first,second);
 
354
          Return r = f(first, second); // require operator()
 
355
          (void)r;
 
356
      }
 
357
      
 
358
      void test(boost::mpl::true_)
 
359
      {
 
360
          f(first,second);
 
361
      }
 
362
      
 
363
      Func f;
 
364
      First first;
 
365
      Second second;
 
366
  };
 
367
 
 
368
  BOOST_concept(UnaryPredicate,(Func)(Arg))
 
369
  {
 
370
    BOOST_CONCEPT_USAGE(UnaryPredicate) {
446
371
      require_boolean_expr(f(arg)); // require operator() returning bool
447
372
    }
 
373
   private:
448
374
    Func f;
449
375
    Arg arg;
450
376
  };
451
377
 
452
 
  template <class Func, class First, class Second>
453
 
  struct BinaryPredicateConcept
 
378
  BOOST_concept(BinaryPredicate,(Func)(First)(Second))
454
379
  {
455
 
    void constraints() {
 
380
    BOOST_CONCEPT_USAGE(BinaryPredicate) {
456
381
      require_boolean_expr(f(a, b)); // require operator() returning bool
457
382
    }
 
383
   private:
458
384
    Func f;
459
385
    First a;
460
386
    Second b;
461
387
  };
462
388
 
463
389
  // use this when functor is used inside a container class like std::set
464
 
  template <class Func, class First, class Second>
465
 
  struct Const_BinaryPredicateConcept {
466
 
    void constraints() { 
 
390
  BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
 
391
    : BinaryPredicate<Func, First, Second>
 
392
  {
 
393
    BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { 
467
394
      const_constraints(f);
468
395
    }
 
396
   private:
469
397
    void const_constraints(const Func& fun) {
470
 
      function_requires<BinaryPredicateConcept<Func, First, Second> >();
471
398
      // operator() must be a const member function
472
399
      require_boolean_expr(fun(a, b));
473
400
    }
476
403
    Second b;
477
404
  };
478
405
 
479
 
  template <class Func, class Return>
480
 
  struct AdaptableGeneratorConcept
 
406
  BOOST_concept(AdaptableGenerator,(Func)(Return))
 
407
    : Generator<Func, typename Func::result_type>
481
408
  {
482
 
    void constraints() {
483
409
      typedef typename Func::result_type result_type;
484
 
      BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
485
 
      function_requires< GeneratorConcept<Func, result_type> >();
486
 
    }
 
410
      
 
411
      BOOST_CONCEPT_USAGE(AdaptableGenerator)
 
412
      {
 
413
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
 
414
      }
487
415
  };
488
416
 
489
 
  template <class Func, class Return, class Arg>
490
 
  struct AdaptableUnaryFunctionConcept
 
417
  BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
 
418
    : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
491
419
  {
492
 
    void constraints() {
493
420
      typedef typename Func::argument_type argument_type;
494
421
      typedef typename Func::result_type result_type;
495
 
      BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
496
 
      BOOST_STATIC_ASSERT((is_convertible<Arg, argument_type>::value));
497
 
      function_requires< UnaryFunctionConcept<Func, result_type, argument_type> >();
498
 
    }
 
422
 
 
423
      ~AdaptableUnaryFunction()
 
424
      {
 
425
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
 
426
          BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
 
427
      }
499
428
  };
500
429
 
501
 
  template <class Func, class Return, class First, class Second>
502
 
  struct AdaptableBinaryFunctionConcept
 
430
  BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
 
431
    : BinaryFunction<
 
432
          Func
 
433
        , typename Func::result_type
 
434
        , typename Func::first_argument_type
 
435
        , typename Func::second_argument_type
 
436
      >
503
437
  {
504
 
    void constraints() {
505
438
      typedef typename Func::first_argument_type first_argument_type;
506
439
      typedef typename Func::second_argument_type second_argument_type;
507
440
      typedef typename Func::result_type result_type;
508
 
      BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
509
 
      BOOST_STATIC_ASSERT((is_convertible<First, first_argument_type>::value));
510
 
      BOOST_STATIC_ASSERT((is_convertible<Second, second_argument_type>::value));
511
 
      function_requires< BinaryFunctionConcept<Func, result_type, 
512
 
        first_argument_type, second_argument_type> >();
513
 
    }
514
 
  };
515
 
 
516
 
  template <class Func, class Arg>
517
 
  struct AdaptablePredicateConcept
518
 
  {
519
 
    void constraints() {
520
 
      function_requires< UnaryPredicateConcept<Func, Arg> >();
521
 
      function_requires< AdaptableUnaryFunctionConcept<Func, bool, Arg> >();
522
 
    }
523
 
  };
524
 
 
525
 
  template <class Func, class First, class Second>
526
 
  struct AdaptableBinaryPredicateConcept
527
 
  {
528
 
    void constraints() {
529
 
      function_requires< BinaryPredicateConcept<Func, First, Second> >();
530
 
      function_requires< AdaptableBinaryFunctionConcept<Func, bool, First, Second> >();
531
 
    }
 
441
      
 
442
      ~AdaptableBinaryFunction()
 
443
      {
 
444
          BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
 
445
          BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
 
446
          BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
 
447
      }
 
448
  };
 
449
 
 
450
  BOOST_concept(AdaptablePredicate,(Func)(Arg))
 
451
    : UnaryPredicate<Func, Arg>
 
452
    , AdaptableUnaryFunction<Func, bool, Arg>
 
453
  {
 
454
  };
 
455
 
 
456
  BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
 
457
    : BinaryPredicate<Func, First, Second>
 
458
    , AdaptableBinaryFunction<Func, bool, First, Second>
 
459
  {
532
460
  };
533
461
 
534
462
  //===========================================================================
535
463
  // Iterator Concepts
536
464
 
537
 
  template <class TT>
538
 
  struct InputIteratorConcept
 
465
  BOOST_concept(InputIterator,(TT))
 
466
    : Assignable<TT>
 
467
    , EqualityComparable<TT>
539
468
  {
540
 
    void constraints() {
541
 
      function_requires< AssignableConcept<TT> >();
542
 
      function_requires< EqualityComparableConcept<TT> >();
543
 
      TT j(i);
544
 
      (void)*i;           // require dereference operator
545
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
546
 
      // require iterator_traits typedef's
547
 
      typedef typename std::iterator_traits<TT>::difference_type D;
548
 
      // Hmm, the following is a bit fragile
549
 
      //function_requires< SignedIntegerConcept<D> >();
550
 
      typedef typename std::iterator_traits<TT>::reference R;
551
 
      typedef typename std::iterator_traits<TT>::pointer P;
552
 
      typedef typename std::iterator_traits<TT>::iterator_category C;
553
 
      function_requires< ConvertibleConcept<C, std::input_iterator_tag> >();
554
 
#endif
555
 
      ++j;                // require preincrement operator
556
 
      i++;                // require postincrement operator
557
 
    }
 
469
      typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
 
470
      typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
 
471
      typedef typename boost::detail::iterator_traits<TT>::reference reference;
 
472
      typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
 
473
      typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
 
474
 
 
475
      BOOST_CONCEPT_USAGE(InputIterator)
 
476
      {
 
477
        BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
 
478
        BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
 
479
        
 
480
        TT j(i);
 
481
        (void)*i;           // require dereference operator
 
482
        ++j;                // require preincrement operator
 
483
        i++;                // require postincrement operator
 
484
      }
 
485
   private:
558
486
    TT i;
559
487
  };
560
488
 
561
 
  template <class TT, class ValueT>
562
 
  struct OutputIteratorConcept
 
489
  BOOST_concept(OutputIterator,(TT)(ValueT))
 
490
    : Assignable<TT>
563
491
  {
564
 
    void constraints() {
565
 
      function_requires< AssignableConcept<TT> >();
 
492
    BOOST_CONCEPT_USAGE(OutputIterator) {
 
493
      
566
494
      ++i;                // require preincrement operator
567
495
      i++;                // require postincrement operator
568
496
      *i++ = t;           // require postincrement and assignment
569
497
    }
 
498
   private:
570
499
    TT i, j;
571
500
    ValueT t;
572
501
  };
573
502
 
574
 
  template <class TT>
575
 
  struct ForwardIteratorConcept
576
 
  {
577
 
    void constraints() {
578
 
      function_requires< InputIteratorConcept<TT> >();
579
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
580
 
      typedef typename std::iterator_traits<TT>::iterator_category C;
581
 
      function_requires< ConvertibleConcept<C, std::forward_iterator_tag> >();
582
 
      typedef typename std::iterator_traits<TT>::reference reference;
583
 
      reference r = *i;
584
 
      ignore_unused_variable_warning(r);
585
 
#endif
586
 
    }
587
 
    TT i;
588
 
  };
589
 
 
590
 
  template <class TT>
591
 
  struct Mutable_ForwardIteratorConcept
592
 
  {
593
 
    void constraints() {
594
 
      function_requires< ForwardIteratorConcept<TT> >();
595
 
      *i++ = *i;         // require postincrement and assignment
596
 
    }
597
 
    TT i;
598
 
  };
599
 
 
600
 
  template <class TT>
601
 
  struct BidirectionalIteratorConcept
602
 
  {
603
 
    void constraints() {
604
 
      function_requires< ForwardIteratorConcept<TT> >();
605
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
606
 
      typedef typename std::iterator_traits<TT>::iterator_category C;
607
 
      function_requires< ConvertibleConcept<C, 
608
 
        std::bidirectional_iterator_tag> >();
609
 
#endif
610
 
      --i;                // require predecrement operator
611
 
      i--;                // require postdecrement operator
612
 
    }
613
 
    TT i;
614
 
  };
615
 
 
616
 
  template <class TT>
617
 
  struct Mutable_BidirectionalIteratorConcept
618
 
  {
619
 
    void constraints() {
620
 
      function_requires< BidirectionalIteratorConcept<TT> >();
621
 
      function_requires< Mutable_ForwardIteratorConcept<TT> >();
622
 
      *i-- = *i;                  // require postdecrement and assignment
623
 
    }
624
 
    TT i;
625
 
  };
626
 
 
627
 
 
628
 
  template <class TT>
629
 
  struct RandomAccessIteratorConcept
630
 
  {
631
 
    void constraints() {
632
 
      function_requires< BidirectionalIteratorConcept<TT> >();
633
 
      function_requires< ComparableConcept<TT> >();
634
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
635
 
      typedef typename std::iterator_traits<TT>::iterator_category C;
636
 
      function_requires< ConvertibleConcept< C,
637
 
        std::random_access_iterator_tag> >();
638
 
      typedef typename std::iterator_traits<TT>::reference R;
639
 
#endif
640
 
 
641
 
      i += n;             // require assignment addition operator
642
 
      i = i + n; i = n + i; // require addition with difference type
643
 
      i -= n;             // require assignment subtraction operator
644
 
      i = i - n;                  // require subtraction with difference type
645
 
      n = i - j;                  // require difference operator
646
 
      (void)i[n];                 // require element access operator
647
 
    }
 
503
  BOOST_concept(ForwardIterator,(TT))
 
504
    : InputIterator<TT>
 
505
  {
 
506
      BOOST_CONCEPT_USAGE(ForwardIterator)
 
507
      {
 
508
          BOOST_CONCEPT_ASSERT((Convertible<
 
509
              BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
 
510
            , std::forward_iterator_tag
 
511
          >));
 
512
          
 
513
          typename InputIterator<TT>::reference r = *i;
 
514
          ignore_unused_variable_warning(r);
 
515
      }
 
516
      
 
517
   private:
 
518
      TT i;
 
519
  };
 
520
 
 
521
  BOOST_concept(Mutable_ForwardIterator,(TT))
 
522
    : ForwardIterator<TT>
 
523
  {
 
524
      BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
 
525
        *i++ = *i;         // require postincrement and assignment
 
526
      }
 
527
   private:
 
528
      TT i;
 
529
  };
 
530
 
 
531
  BOOST_concept(BidirectionalIterator,(TT))
 
532
    : ForwardIterator<TT>
 
533
  {
 
534
      BOOST_CONCEPT_USAGE(BidirectionalIterator)
 
535
      {
 
536
          BOOST_CONCEPT_ASSERT((Convertible<
 
537
              BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
 
538
            , std::bidirectional_iterator_tag
 
539
          >));
 
540
 
 
541
          --i;                // require predecrement operator
 
542
          i--;                // require postdecrement operator
 
543
      }
 
544
   private:
 
545
      TT i;
 
546
  };
 
547
 
 
548
  BOOST_concept(Mutable_BidirectionalIterator,(TT))
 
549
    : BidirectionalIterator<TT>
 
550
    , Mutable_ForwardIterator<TT>
 
551
  {
 
552
      BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
 
553
      {
 
554
          *i-- = *i;                  // require postdecrement and assignment
 
555
      }
 
556
   private:
 
557
      TT i;
 
558
  };
 
559
 
 
560
  BOOST_concept(RandomAccessIterator,(TT))
 
561
    : BidirectionalIterator<TT>
 
562
    , Comparable<TT>
 
563
  {
 
564
      BOOST_CONCEPT_USAGE(RandomAccessIterator)
 
565
      {
 
566
          BOOST_CONCEPT_ASSERT((Convertible<
 
567
              BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
 
568
            , std::random_access_iterator_tag
 
569
          >));
 
570
 
 
571
          i += n;             // require assignment addition operator
 
572
          i = i + n; i = n + i; // require addition with difference type
 
573
          i -= n;             // require assignment subtraction operator
 
574
          i = i - n;                  // require subtraction with difference type
 
575
          n = i - j;                  // require difference operator
 
576
          (void)i[n];                 // require element access operator
 
577
      }
 
578
      
 
579
   private:
648
580
    TT a, b;
649
581
    TT i, j;
650
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
651
 
    typename std::iterator_traits<TT>::difference_type n;
652
 
#else
653
 
    std::ptrdiff_t n;
654
 
#endif
 
582
      typename boost::detail::iterator_traits<TT>::difference_type n;
655
583
  };
656
584
 
657
 
  template <class TT>
658
 
  struct Mutable_RandomAccessIteratorConcept
 
585
  BOOST_concept(Mutable_RandomAccessIterator,(TT))
 
586
    : RandomAccessIterator<TT>
 
587
    , Mutable_BidirectionalIterator<TT>
659
588
  {
660
 
    void constraints() {
661
 
      function_requires< RandomAccessIteratorConcept<TT> >();
662
 
      function_requires< Mutable_BidirectionalIteratorConcept<TT> >();
663
 
      i[n] = *i;                  // require element access and assignment
664
 
    }
 
589
      BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
 
590
      {
 
591
          i[n] = *i;                  // require element access and assignment
 
592
      }
 
593
   private:
665
594
    TT i;
666
 
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
667
 
    typename std::iterator_traits<TT>::difference_type n;
668
 
#else
669
 
    std::ptrdiff_t n;
670
 
#endif
 
595
    typename boost::detail::iterator_traits<TT>::difference_type n;
671
596
  };
672
597
 
673
598
  //===========================================================================
674
 
  // Container Concepts
675
 
 
676
 
  template <class Container>
677
 
  struct ContainerConcept
678
 
  {
679
 
    typedef typename Container::value_type value_type;
680
 
    typedef typename Container::difference_type difference_type;
681
 
    typedef typename Container::size_type size_type;
682
 
    typedef typename Container::const_reference const_reference;
683
 
    typedef typename Container::const_pointer const_pointer;
684
 
    typedef typename Container::const_iterator const_iterator;
685
 
 
686
 
    void constraints() {
687
 
      function_requires< InputIteratorConcept<const_iterator> >();
688
 
      function_requires< AssignableConcept<Container> >();
689
 
      const_constraints(c);
690
 
    }
691
 
    void const_constraints(const Container& cc) {
692
 
      i = cc.begin();
693
 
      i = cc.end();
694
 
      n = cc.size();
695
 
      n = cc.max_size();
696
 
      b = cc.empty();
697
 
    }
698
 
    Container c;
699
 
    bool b;
700
 
    const_iterator i;
701
 
    size_type n;
702
 
  };
703
 
 
704
 
  template <class Container>
705
 
  struct Mutable_ContainerConcept
706
 
  {
707
 
    typedef typename Container::value_type value_type;
708
 
    typedef typename Container::reference reference;
709
 
    typedef typename Container::iterator iterator;
710
 
    typedef typename Container::pointer pointer;
711
 
    
712
 
    void constraints() {
713
 
      function_requires< ContainerConcept<Container> >();
714
 
      function_requires< AssignableConcept<value_type> >();
715
 
      function_requires< InputIteratorConcept<iterator> >();
716
 
 
717
 
      i = c.begin();
718
 
      i = c.end();
719
 
      c.swap(c2);
720
 
    }
721
 
    iterator i;
722
 
    Container c, c2;
723
 
  };
724
 
 
725
 
  template <class ForwardContainer>
726
 
  struct ForwardContainerConcept
727
 
  {
728
 
    void constraints() {
729
 
      function_requires< ContainerConcept<ForwardContainer> >();
730
 
      typedef typename ForwardContainer::const_iterator const_iterator;
731
 
      function_requires< ForwardIteratorConcept<const_iterator> >();
732
 
    }
733
 
  };  
734
 
 
735
 
  template <class ForwardContainer>
736
 
  struct Mutable_ForwardContainerConcept
737
 
  {
738
 
    void constraints() {
739
 
      function_requires< ForwardContainerConcept<ForwardContainer> >();
740
 
      function_requires< Mutable_ContainerConcept<ForwardContainer> >();
741
 
      typedef typename ForwardContainer::iterator iterator;
742
 
      function_requires< Mutable_ForwardIteratorConcept<iterator> >();
743
 
    }
744
 
  };  
745
 
 
746
 
  template <class ReversibleContainer>
747
 
  struct ReversibleContainerConcept
748
 
  {
749
 
    typedef typename ReversibleContainer::const_iterator const_iterator;
750
 
    typedef typename ReversibleContainer::const_reverse_iterator
751
 
      const_reverse_iterator;
752
 
 
753
 
    void constraints() {
754
 
      function_requires< ForwardContainerConcept<ReversibleContainer> >();
755
 
      function_requires< BidirectionalIteratorConcept<const_iterator> >();
756
 
      function_requires< 
757
 
        BidirectionalIteratorConcept<const_reverse_iterator> >();
758
 
      const_constraints(c);
759
 
    }
760
 
    void const_constraints(const ReversibleContainer& cc) {
761
 
      const_reverse_iterator i = cc.rbegin();
762
 
      i = cc.rend();
763
 
    }
764
 
    ReversibleContainer c;
765
 
  };
766
 
 
767
 
  template <class ReversibleContainer>
768
 
  struct Mutable_ReversibleContainerConcept
769
 
  {
770
 
    typedef typename ReversibleContainer::iterator iterator;
771
 
    typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
772
 
 
773
 
    void constraints() {
774
 
      function_requires< ReversibleContainerConcept<ReversibleContainer> >();
775
 
      function_requires<
776
 
        Mutable_ForwardContainerConcept<ReversibleContainer> >();
777
 
      function_requires< Mutable_BidirectionalIteratorConcept<iterator> >();
778
 
      function_requires<
779
 
        Mutable_BidirectionalIteratorConcept<reverse_iterator> >();
780
 
 
781
 
      reverse_iterator i = c.rbegin();
782
 
      i = c.rend();
783
 
    }
784
 
    ReversibleContainer c;
785
 
  };
786
 
 
787
 
  template <class RandomAccessContainer>
788
 
  struct RandomAccessContainerConcept
789
 
  {
790
 
    typedef typename RandomAccessContainer::size_type size_type;
791
 
    typedef typename RandomAccessContainer::const_reference const_reference;
792
 
    typedef typename RandomAccessContainer::const_iterator const_iterator;
793
 
    typedef typename RandomAccessContainer::const_reverse_iterator
794
 
      const_reverse_iterator;
795
 
 
796
 
    void constraints() {
797
 
      function_requires< ReversibleContainerConcept<RandomAccessContainer> >();
798
 
      function_requires< RandomAccessIteratorConcept<const_iterator> >();
799
 
      function_requires<
800
 
        RandomAccessIteratorConcept<const_reverse_iterator> >();
801
 
 
802
 
      const_constraints(c);
803
 
    }
804
 
    void const_constraints(const RandomAccessContainer& cc) {
805
 
      const_reference r = cc[n];
806
 
      ignore_unused_variable_warning(r);
807
 
    }
808
 
    RandomAccessContainer c;
809
 
    size_type n;
810
 
  };
811
 
 
812
 
  template <class RandomAccessContainer>
813
 
  struct Mutable_RandomAccessContainerConcept
814
 
  {
815
 
    typedef typename RandomAccessContainer::size_type size_type;
816
 
    typedef typename RandomAccessContainer::reference reference;
817
 
    typedef typename RandomAccessContainer::iterator iterator;
818
 
    typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
819
 
 
820
 
    void constraints() {
821
 
      function_requires<
822
 
        RandomAccessContainerConcept<RandomAccessContainer> >();
823
 
      function_requires<
824
 
        Mutable_ReversibleContainerConcept<RandomAccessContainer> >();
825
 
      function_requires< Mutable_RandomAccessIteratorConcept<iterator> >();
826
 
      function_requires<
827
 
        Mutable_RandomAccessIteratorConcept<reverse_iterator> >();
828
 
 
829
 
      reference r = c[i];
830
 
      ignore_unused_variable_warning(r);
831
 
    }
832
 
    size_type i;
833
 
    RandomAccessContainer c;
 
599
  // Container s
 
600
 
 
601
  BOOST_concept(Container,(C))
 
602
    : Assignable<C>
 
603
  {
 
604
    typedef typename C::value_type value_type;
 
605
    typedef typename C::difference_type difference_type;
 
606
    typedef typename C::size_type size_type;
 
607
    typedef typename C::const_reference const_reference;
 
608
    typedef typename C::const_pointer const_pointer;
 
609
    typedef typename C::const_iterator const_iterator;
 
610
 
 
611
      BOOST_CONCEPT_USAGE(Container)
 
612
      {
 
613
          BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
 
614
          const_constraints(c);
 
615
      }
 
616
      
 
617
   private:
 
618
      void const_constraints(const C& cc) {
 
619
          i = cc.begin();
 
620
          i = cc.end();
 
621
          n = cc.size();
 
622
          n = cc.max_size();
 
623
          b = cc.empty();
 
624
      }
 
625
      C c;
 
626
      bool b;
 
627
      const_iterator i;
 
628
      size_type n;
 
629
  };
 
630
 
 
631
  BOOST_concept(Mutable_Container,(C))
 
632
    : Container<C>
 
633
  {
 
634
      typedef typename C::reference reference;
 
635
      typedef typename C::iterator iterator;
 
636
      typedef typename C::pointer pointer;
 
637
    
 
638
      BOOST_CONCEPT_USAGE(Mutable_Container)
 
639
      {
 
640
          BOOST_CONCEPT_ASSERT((
 
641
               Assignable<typename Mutable_Container::value_type>));
 
642
          
 
643
          BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
 
644
          
 
645
          i = c.begin();
 
646
          i = c.end();
 
647
          c.swap(c2);
 
648
      }
 
649
      
 
650
   private:
 
651
      iterator i;
 
652
      C c, c2;
 
653
  };
 
654
 
 
655
  BOOST_concept(ForwardContainer,(C))
 
656
    : Container<C>
 
657
  {
 
658
      BOOST_CONCEPT_USAGE(ForwardContainer)
 
659
      {
 
660
          BOOST_CONCEPT_ASSERT((
 
661
               ForwardIterator<
 
662
                    typename ForwardContainer::const_iterator
 
663
               >));
 
664
      }
 
665
  };  
 
666
 
 
667
  BOOST_concept(Mutable_ForwardContainer,(C))
 
668
    : ForwardContainer<C>
 
669
    , Mutable_Container<C>
 
670
  {
 
671
      BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
 
672
      {
 
673
          BOOST_CONCEPT_ASSERT((
 
674
               Mutable_ForwardIterator<
 
675
                   typename Mutable_ForwardContainer::iterator
 
676
               >));
 
677
      }
 
678
  };  
 
679
 
 
680
  BOOST_concept(ReversibleContainer,(C))
 
681
    : ForwardContainer<C>
 
682
  {
 
683
      typedef typename
 
684
        C::const_reverse_iterator
 
685
      const_reverse_iterator;
 
686
 
 
687
      BOOST_CONCEPT_USAGE(ReversibleContainer)
 
688
      {
 
689
          BOOST_CONCEPT_ASSERT((
 
690
              BidirectionalIterator<
 
691
                  typename ReversibleContainer::const_iterator>));
 
692
          
 
693
          BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
 
694
          
 
695
          const_constraints(c);
 
696
      }
 
697
   private:
 
698
      void const_constraints(const C& cc)
 
699
      {
 
700
          const_reverse_iterator i = cc.rbegin();
 
701
          i = cc.rend();
 
702
      }
 
703
      C c;
 
704
  };
 
705
 
 
706
  BOOST_concept(Mutable_ReversibleContainer,(C))
 
707
    : Mutable_ForwardContainer<C>
 
708
    , ReversibleContainer<C>
 
709
  {
 
710
      typedef typename C::reverse_iterator reverse_iterator;
 
711
      
 
712
      BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
 
713
      {
 
714
          typedef typename Mutable_ForwardContainer<C>::iterator iterator;
 
715
          BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
 
716
          BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
 
717
          
 
718
          reverse_iterator i = c.rbegin();
 
719
          i = c.rend();
 
720
      }
 
721
   private:  
 
722
      C c;
 
723
  };
 
724
 
 
725
  BOOST_concept(RandomAccessContainer,(C))
 
726
    : ReversibleContainer<C>
 
727
  {
 
728
      typedef typename C::size_type size_type;
 
729
      typedef typename C::const_reference const_reference;
 
730
 
 
731
      BOOST_CONCEPT_USAGE(RandomAccessContainer)
 
732
      {
 
733
          BOOST_CONCEPT_ASSERT((
 
734
              RandomAccessIterator<
 
735
                  typename RandomAccessContainer::const_iterator
 
736
              >));
 
737
          
 
738
          const_constraints(c);
 
739
      }
 
740
   private:
 
741
      void const_constraints(const C& cc)
 
742
      {
 
743
          const_reference r = cc[n];
 
744
          ignore_unused_variable_warning(r);
 
745
      }
 
746
    
 
747
      C c;
 
748
      size_type n;
 
749
  };
 
750
 
 
751
  BOOST_concept(Mutable_RandomAccessContainer,(C))
 
752
    : Mutable_ReversibleContainer<C>
 
753
    , RandomAccessContainer<C>
 
754
  {
 
755
   private:
 
756
      typedef Mutable_RandomAccessContainer self;
 
757
   public:
 
758
      BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
 
759
      {
 
760
          BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
 
761
          BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
 
762
          
 
763
          typename self::reference r = c[i];
 
764
          ignore_unused_variable_warning(r);
 
765
      }
 
766
      
 
767
   private:
 
768
      typename Mutable_ReversibleContainer<C>::size_type i;
 
769
      C c;
834
770
  };
835
771
 
836
772
  // A Sequence is inherently mutable
837
 
  template <class Sequence>
838
 
  struct SequenceConcept
839
 
  {
840
 
 
841
 
    typedef typename Sequence::reference reference;
842
 
    typedef typename Sequence::const_reference const_reference;
843
 
 
844
 
    void constraints() {
 
773
  BOOST_concept(Sequence,(S))
 
774
    : Mutable_ForwardContainer<S>
845
775
      // Matt Austern's book puts DefaultConstructible here, the C++
846
 
      // standard places it in Container
847
 
      //    function_requires< DefaultConstructible<Sequence> >();
848
 
      function_requires< Mutable_ForwardContainerConcept<Sequence> >();
849
 
      function_requires< DefaultConstructibleConcept<Sequence> >();
850
 
 
851
 
      Sequence 
852
 
        c(n),
853
 
        c2(n, t),
854
 
        c3(first, last);
855
 
 
856
 
      c.insert(p, t);
857
 
      c.insert(p, n, t);
858
 
      c.insert(p, first, last);
859
 
 
860
 
      c.erase(p);
861
 
      c.erase(p, q);
862
 
 
863
 
      reference r = c.front();
864
 
 
865
 
      ignore_unused_variable_warning(c);
866
 
      ignore_unused_variable_warning(c2);
867
 
      ignore_unused_variable_warning(c3);
868
 
      ignore_unused_variable_warning(r);
869
 
      const_constraints(c);
870
 
    }
871
 
    void const_constraints(const Sequence& c) {
872
 
      const_reference r = c.front();
873
 
      ignore_unused_variable_warning(r);
874
 
    }
875
 
    typename Sequence::value_type t;
876
 
    typename Sequence::size_type n;
877
 
    typename Sequence::value_type* first, *last;
878
 
    typename Sequence::iterator p, q;
879
 
  };
880
 
 
881
 
  template <class FrontInsertionSequence>
882
 
  struct FrontInsertionSequenceConcept
883
 
  {
884
 
    void constraints() {
885
 
      function_requires< SequenceConcept<FrontInsertionSequence> >();
886
 
 
887
 
      c.push_front(t);
888
 
      c.pop_front();
889
 
    }
890
 
    FrontInsertionSequence c;
891
 
    typename FrontInsertionSequence::value_type t;
892
 
  };
893
 
 
894
 
  template <class BackInsertionSequence>
895
 
  struct BackInsertionSequenceConcept
896
 
  {
897
 
    typedef typename BackInsertionSequence::reference reference;
898
 
    typedef typename BackInsertionSequence::const_reference const_reference;
899
 
 
900
 
    void constraints() {
901
 
      function_requires< SequenceConcept<BackInsertionSequence> >();
902
 
 
903
 
      c.push_back(t);
904
 
      c.pop_back();
905
 
      reference r = c.back();
906
 
      ignore_unused_variable_warning(r);
907
 
    }
908
 
    void const_constraints(const BackInsertionSequence& cc) {
909
 
      const_reference r = cc.back();
910
 
      ignore_unused_variable_warning(r);
911
 
    };
912
 
    BackInsertionSequence c;
913
 
    typename BackInsertionSequence::value_type t;
914
 
  };
915
 
 
916
 
  template <class AssociativeContainer>
917
 
  struct AssociativeContainerConcept
918
 
  {
919
 
    void constraints() {
920
 
      function_requires< ForwardContainerConcept<AssociativeContainer> >();
921
 
      function_requires< DefaultConstructibleConcept<AssociativeContainer> >();
922
 
    
923
 
      i = c.find(k);
924
 
      r = c.equal_range(k);
925
 
      c.erase(k);
926
 
      c.erase(i);
927
 
      c.erase(r.first, r.second);
928
 
      const_constraints(c);
929
 
    }
930
 
    void const_constraints(const AssociativeContainer& cc) {
931
 
      ci = cc.find(k);
932
 
      n = cc.count(k);
933
 
      cr = cc.equal_range(k);
934
 
    }
935
 
    typedef typename AssociativeContainer::iterator iterator;
936
 
    typedef typename AssociativeContainer::const_iterator const_iterator;
937
 
 
938
 
    AssociativeContainer c;
939
 
    iterator i;
940
 
    std::pair<iterator,iterator> r;
941
 
    const_iterator ci;
942
 
    std::pair<const_iterator,const_iterator> cr;
943
 
    typename AssociativeContainer::key_type k;
944
 
    typename AssociativeContainer::size_type n;
945
 
  };
946
 
 
947
 
  template <class UniqueAssociativeContainer>
948
 
  struct UniqueAssociativeContainerConcept
949
 
  {
950
 
    void constraints() {
951
 
      function_requires< AssociativeContainerConcept<UniqueAssociativeContainer> >();
952
 
    
953
 
      UniqueAssociativeContainer c(first, last);
954
 
      
955
 
      pos_flag = c.insert(t);
956
 
      c.insert(first, last);
957
 
 
958
 
      ignore_unused_variable_warning(c);
959
 
    }
960
 
    std::pair<typename UniqueAssociativeContainer::iterator, bool> pos_flag;
961
 
    typename UniqueAssociativeContainer::value_type t;
962
 
    typename UniqueAssociativeContainer::value_type* first, *last;
963
 
  };
964
 
 
965
 
  template <class MultipleAssociativeContainer>
966
 
  struct MultipleAssociativeContainerConcept
967
 
  {
968
 
    void constraints() {
969
 
      function_requires< AssociativeContainerConcept<MultipleAssociativeContainer> >();
970
 
 
971
 
      MultipleAssociativeContainer c(first, last);
972
 
      
973
 
      pos = c.insert(t);
974
 
      c.insert(first, last);
975
 
 
976
 
      ignore_unused_variable_warning(c);
977
 
      ignore_unused_variable_warning(pos);
978
 
    }
979
 
    typename MultipleAssociativeContainer::iterator pos;
980
 
    typename MultipleAssociativeContainer::value_type t;
981
 
    typename MultipleAssociativeContainer::value_type* first, *last;
982
 
  };
983
 
 
984
 
  template <class SimpleAssociativeContainer>
985
 
  struct SimpleAssociativeContainerConcept
986
 
  {
987
 
    void constraints() {
988
 
      function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
989
 
      typedef typename SimpleAssociativeContainer::key_type key_type;
990
 
      typedef typename SimpleAssociativeContainer::value_type value_type;
991
 
      typedef typename require_same<key_type, value_type>::type req;
992
 
    }
993
 
  };
994
 
 
995
 
  template <class SimpleAssociativeContainer>
996
 
  struct PairAssociativeContainerConcept
997
 
  {
998
 
    void constraints() {
999
 
      function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
1000
 
      typedef typename SimpleAssociativeContainer::key_type key_type;
1001
 
      typedef typename SimpleAssociativeContainer::value_type value_type;
1002
 
      typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
1003
 
      typedef std::pair<const key_type, mapped_type> required_value_type;
1004
 
      typedef typename require_same<value_type, required_value_type>::type req;
1005
 
    }
1006
 
  };
1007
 
 
1008
 
  template <class SortedAssociativeContainer>
1009
 
  struct SortedAssociativeContainerConcept
1010
 
  {
1011
 
    void constraints() {
1012
 
      function_requires< AssociativeContainerConcept<SortedAssociativeContainer> >();
1013
 
      function_requires< ReversibleContainerConcept<SortedAssociativeContainer> >();
1014
 
 
1015
 
      SortedAssociativeContainer 
1016
 
        c(kc),
1017
 
        c2(first, last),
1018
 
        c3(first, last, kc);
1019
 
 
1020
 
      p = c.upper_bound(k);
1021
 
      p = c.lower_bound(k);
1022
 
      r = c.equal_range(k);
1023
 
      
1024
 
      c.insert(p, t);
1025
 
      
1026
 
      ignore_unused_variable_warning(c);
1027
 
      ignore_unused_variable_warning(c2);
1028
 
      ignore_unused_variable_warning(c3);
1029
 
    }
1030
 
    void const_constraints(const SortedAssociativeContainer& c) {
1031
 
      kc = c.key_comp();
1032
 
      vc = c.value_comp();
1033
 
 
1034
 
      cp = c.upper_bound(k);
1035
 
      cp = c.lower_bound(k);
1036
 
      cr = c.equal_range(k);
1037
 
    }
1038
 
    typename SortedAssociativeContainer::key_compare kc;
1039
 
    typename SortedAssociativeContainer::value_compare vc;
1040
 
    typename SortedAssociativeContainer::value_type t;
1041
 
    typename SortedAssociativeContainer::key_type k;
1042
 
    typedef typename SortedAssociativeContainer::iterator iterator;
1043
 
    typedef typename SortedAssociativeContainer::const_iterator const_iterator;
1044
 
    iterator p;
1045
 
    const_iterator cp;
1046
 
    std::pair<iterator,iterator> r;
1047
 
    std::pair<const_iterator,const_iterator> cr;
1048
 
    typename SortedAssociativeContainer::value_type* first, *last;
 
776
      // standard places it in Container --JGS
 
777
      // ... so why aren't we following the standard?  --DWA
 
778
    , DefaultConstructible<S>
 
779
  {
 
780
      BOOST_CONCEPT_USAGE(Sequence)
 
781
      {
 
782
          S 
 
783
              c(n),
 
784
              c2(n, t),
 
785
              c3(first, last);
 
786
 
 
787
          c.insert(p, t);
 
788
          c.insert(p, n, t);
 
789
          c.insert(p, first, last);
 
790
 
 
791
          c.erase(p);
 
792
          c.erase(p, q);
 
793
 
 
794
          typename Sequence::reference r = c.front();
 
795
 
 
796
          ignore_unused_variable_warning(c);
 
797
          ignore_unused_variable_warning(c2);
 
798
          ignore_unused_variable_warning(c3);
 
799
          ignore_unused_variable_warning(r);
 
800
          const_constraints(c);
 
801
      }
 
802
   private:
 
803
      void const_constraints(const S& c) {
 
804
          typename Sequence::const_reference r = c.front();
 
805
          ignore_unused_variable_warning(r);
 
806
      }
 
807
    
 
808
      typename S::value_type t;
 
809
      typename S::size_type n;
 
810
      typename S::value_type* first, *last;
 
811
      typename S::iterator p, q;
 
812
  };
 
813
 
 
814
  BOOST_concept(FrontInsertionSequence,(S))
 
815
    : Sequence<S>
 
816
  {
 
817
      BOOST_CONCEPT_USAGE(FrontInsertionSequence)
 
818
      {
 
819
          c.push_front(t);
 
820
          c.pop_front();
 
821
      }
 
822
   private:
 
823
      S c;
 
824
      typename S::value_type t;
 
825
  };
 
826
 
 
827
  BOOST_concept(BackInsertionSequence,(S))
 
828
    : Sequence<S>
 
829
  {
 
830
      BOOST_CONCEPT_USAGE(BackInsertionSequence)
 
831
      {
 
832
          c.push_back(t);
 
833
          c.pop_back();
 
834
          typename BackInsertionSequence::reference r = c.back();
 
835
          ignore_unused_variable_warning(r);
 
836
          const_constraints(c);
 
837
      }
 
838
   private:
 
839
      void const_constraints(const S& cc) {
 
840
          typename BackInsertionSequence::const_reference
 
841
              r = cc.back();
 
842
          ignore_unused_variable_warning(r);
 
843
      };
 
844
      S c;
 
845
      typename S::value_type t;
 
846
  };
 
847
 
 
848
  BOOST_concept(AssociativeContainer,(C))
 
849
    : ForwardContainer<C>
 
850
    , DefaultConstructible<C>
 
851
  {
 
852
      typedef typename C::key_type key_type;
 
853
      typedef typename C::key_compare key_compare;
 
854
      typedef typename C::value_compare value_compare;
 
855
      typedef typename C::iterator iterator;
 
856
 
 
857
      BOOST_CONCEPT_USAGE(AssociativeContainer)
 
858
      {
 
859
          i = c.find(k);
 
860
          r = c.equal_range(k);
 
861
          c.erase(k);
 
862
          c.erase(i);
 
863
          c.erase(r.first, r.second);
 
864
          const_constraints(c);
 
865
          BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
 
866
          
 
867
          typedef typename AssociativeContainer::value_type value_type_;
 
868
          BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
 
869
      }
 
870
      
 
871
      // Redundant with the base concept, but it helps below.
 
872
      typedef typename C::const_iterator const_iterator;
 
873
   private:
 
874
      void const_constraints(const C& cc)
 
875
      {
 
876
          ci = cc.find(k);
 
877
          n = cc.count(k);
 
878
          cr = cc.equal_range(k);
 
879
      }
 
880
 
 
881
      C c;
 
882
      iterator i;
 
883
      std::pair<iterator,iterator> r;
 
884
      const_iterator ci;
 
885
      std::pair<const_iterator,const_iterator> cr;
 
886
      typename C::key_type k;
 
887
      typename C::size_type n;
 
888
  };
 
889
 
 
890
  BOOST_concept(UniqueAssociativeContainer,(C))
 
891
    : AssociativeContainer<C>
 
892
  {
 
893
      BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
 
894
      {
 
895
          C c(first, last);
 
896
      
 
897
          pos_flag = c.insert(t);
 
898
          c.insert(first, last);
 
899
 
 
900
          ignore_unused_variable_warning(c);
 
901
      }
 
902
   private:
 
903
      std::pair<typename C::iterator, bool> pos_flag;
 
904
      typename C::value_type t;
 
905
      typename C::value_type* first, *last;
 
906
  };
 
907
 
 
908
  BOOST_concept(MultipleAssociativeContainer,(C))
 
909
    : AssociativeContainer<C>
 
910
  {
 
911
      BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
 
912
      {
 
913
          C c(first, last);
 
914
      
 
915
          pos = c.insert(t);
 
916
          c.insert(first, last);
 
917
 
 
918
          ignore_unused_variable_warning(c);
 
919
          ignore_unused_variable_warning(pos);
 
920
      }
 
921
   private:
 
922
      typename C::iterator pos;
 
923
      typename C::value_type t;
 
924
      typename C::value_type* first, *last;
 
925
  };
 
926
 
 
927
  BOOST_concept(SimpleAssociativeContainer,(C))
 
928
    : AssociativeContainer<C>
 
929
  {
 
930
      BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
 
931
      {
 
932
          typedef typename C::key_type key_type;
 
933
          typedef typename C::value_type value_type;
 
934
          BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
 
935
      }
 
936
  };
 
937
 
 
938
  BOOST_concept(PairAssociativeContainer,(C))
 
939
    : AssociativeContainer<C>
 
940
  {
 
941
      BOOST_CONCEPT_USAGE(PairAssociativeContainer)
 
942
      {
 
943
          typedef typename C::key_type key_type;
 
944
          typedef typename C::value_type value_type;
 
945
          typedef typename C::mapped_type mapped_type;
 
946
          typedef std::pair<const key_type, mapped_type> required_value_type;
 
947
          BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
 
948
      }
 
949
  };
 
950
 
 
951
  BOOST_concept(SortedAssociativeContainer,(C))
 
952
    : AssociativeContainer<C>
 
953
    , ReversibleContainer<C>
 
954
  {
 
955
      BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
 
956
      {
 
957
          C 
 
958
              c(kc),
 
959
              c2(first, last),
 
960
              c3(first, last, kc);
 
961
 
 
962
          p = c.upper_bound(k);
 
963
          p = c.lower_bound(k);
 
964
          r = c.equal_range(k);
 
965
      
 
966
          c.insert(p, t);
 
967
      
 
968
          ignore_unused_variable_warning(c);
 
969
          ignore_unused_variable_warning(c2);
 
970
          ignore_unused_variable_warning(c3);
 
971
          const_constraints(c);
 
972
      }
 
973
      
 
974
      void const_constraints(const C& c)
 
975
      {
 
976
          kc = c.key_comp();
 
977
          vc = c.value_comp();
 
978
 
 
979
          cp = c.upper_bound(k);
 
980
          cp = c.lower_bound(k);
 
981
          cr = c.equal_range(k);
 
982
      }
 
983
      
 
984
   private:
 
985
      typename C::key_compare kc;
 
986
      typename C::value_compare vc;
 
987
      typename C::value_type t;
 
988
      typename C::key_type k;
 
989
      typedef typename C::iterator iterator;
 
990
      typedef typename C::const_iterator const_iterator;
 
991
 
 
992
      typedef SortedAssociativeContainer self;
 
993
      iterator p;
 
994
      const_iterator cp;
 
995
      std::pair<typename self::iterator,typename self::iterator> r;
 
996
      std::pair<typename self::const_iterator,typename self::const_iterator> cr;
 
997
      typename C::value_type* first, *last;
1049
998
  };
1050
999
 
1051
1000
  // HashedAssociativeContainer
1052
1001
 
1053
1002
} // namespace boost
1054
1003
 
 
1004
# include <boost/concept/detail/concept_undef.hpp>
 
1005
 
1055
1006
#endif // BOOST_CONCEPT_CHECKS_HPP
1056
1007