| [12] | 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 |  | 
|---|