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