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