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