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