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