PageRenderTime 81ms CodeModel.GetById 18ms app.highlight 56ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/concept_check.hpp

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