]> git.lyx.org Git - lyx.git/blob - boost/boost/concept_check.hpp
attempt to make LyX linkable without NLS, assuming dummy available() should return...
[lyx.git] / boost / boost / concept_check.hpp
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 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
335                       && BOOST_WORKAROUND(__GNUC__, > 3)))
336       // Declare a dummy construktor to make gcc happy.
337       // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
338       // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
339       // in class without a constructor [-Wuninitialized])
340       UnaryFunction();
341 #endif
342
343       Func f;
344       Arg arg;
345   };
346
347   BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
348   {
349       BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
350    private:
351       void test(boost::mpl::false_)
352       {
353           f(first,second);
354           Return r = f(first, second); // require operator()
355           (void)r;
356       }
357       
358       void test(boost::mpl::true_)
359       {
360           f(first,second);
361       }
362       
363       Func f;
364       First first;
365       Second second;
366   };
367
368   BOOST_concept(UnaryPredicate,(Func)(Arg))
369   {
370     BOOST_CONCEPT_USAGE(UnaryPredicate) {
371       require_boolean_expr(f(arg)); // require operator() returning bool
372     }
373    private:
374     Func f;
375     Arg arg;
376   };
377
378   BOOST_concept(BinaryPredicate,(Func)(First)(Second))
379   {
380     BOOST_CONCEPT_USAGE(BinaryPredicate) {
381       require_boolean_expr(f(a, b)); // require operator() returning bool
382     }
383    private:
384     Func f;
385     First a;
386     Second b;
387   };
388
389   // use this when functor is used inside a container class like std::set
390   BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
391     : BinaryPredicate<Func, First, Second>
392   {
393     BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { 
394       const_constraints(f);
395     }
396    private:
397     void const_constraints(const Func& fun) {
398       // operator() must be a const member function
399       require_boolean_expr(fun(a, b));
400     }
401     Func f;
402     First a;
403     Second b;
404   };
405
406   BOOST_concept(AdaptableGenerator,(Func)(Return))
407     : Generator<Func, typename Func::result_type>
408   {
409       typedef typename Func::result_type result_type;
410       
411       BOOST_CONCEPT_USAGE(AdaptableGenerator)
412       {
413           BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
414       }
415   };
416
417   BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
418     : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
419   {
420       typedef typename Func::argument_type argument_type;
421       typedef typename Func::result_type result_type;
422
423       ~AdaptableUnaryFunction()
424       {
425           BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
426           BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
427       }
428   };
429
430   BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
431     : BinaryFunction<
432           Func
433         , typename Func::result_type
434         , typename Func::first_argument_type
435         , typename Func::second_argument_type
436       >
437   {
438       typedef typename Func::first_argument_type first_argument_type;
439       typedef typename Func::second_argument_type second_argument_type;
440       typedef typename Func::result_type result_type;
441       
442       ~AdaptableBinaryFunction()
443       {
444           BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
445           BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
446           BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
447       }
448   };
449
450   BOOST_concept(AdaptablePredicate,(Func)(Arg))
451     : UnaryPredicate<Func, Arg>
452     , AdaptableUnaryFunction<Func, bool, Arg>
453   {
454   };
455
456   BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
457     : BinaryPredicate<Func, First, Second>
458     , AdaptableBinaryFunction<Func, bool, First, Second>
459   {
460   };
461
462   //===========================================================================
463   // Iterator Concepts
464
465   BOOST_concept(InputIterator,(TT))
466     : Assignable<TT>
467     , EqualityComparable<TT>
468   {
469       typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
470       typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
471       typedef typename boost::detail::iterator_traits<TT>::reference reference;
472       typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
473       typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
474
475       BOOST_CONCEPT_USAGE(InputIterator)
476       {
477         BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
478         BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
479         
480         TT j(i);
481         (void)*i;           // require dereference operator
482         ++j;                // require preincrement operator
483         i++;                // require postincrement operator
484       }
485    private:
486     TT i;
487   };
488
489   BOOST_concept(OutputIterator,(TT)(ValueT))
490     : Assignable<TT>
491   {
492     BOOST_CONCEPT_USAGE(OutputIterator) {
493       
494       ++i;                // require preincrement operator
495       i++;                // require postincrement operator
496       *i++ = t;           // require postincrement and assignment
497     }
498    private:
499     TT i, j;
500     ValueT t;
501   };
502
503   BOOST_concept(ForwardIterator,(TT))
504     : InputIterator<TT>
505   {
506       BOOST_CONCEPT_USAGE(ForwardIterator)
507       {
508           BOOST_CONCEPT_ASSERT((Convertible<
509               BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
510             , std::forward_iterator_tag
511           >));
512           
513           typename InputIterator<TT>::reference r = *i;
514           ignore_unused_variable_warning(r);
515       }
516       
517    private:
518       TT i;
519   };
520
521   BOOST_concept(Mutable_ForwardIterator,(TT))
522     : ForwardIterator<TT>
523   {
524       BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
525         *i++ = *i;         // require postincrement and assignment
526       }
527    private:
528       TT i;
529   };
530
531   BOOST_concept(BidirectionalIterator,(TT))
532     : ForwardIterator<TT>
533   {
534       BOOST_CONCEPT_USAGE(BidirectionalIterator)
535       {
536           BOOST_CONCEPT_ASSERT((Convertible<
537               BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
538             , std::bidirectional_iterator_tag
539           >));
540
541           --i;                // require predecrement operator
542           i--;                // require postdecrement operator
543       }
544    private:
545       TT i;
546   };
547
548   BOOST_concept(Mutable_BidirectionalIterator,(TT))
549     : BidirectionalIterator<TT>
550     , Mutable_ForwardIterator<TT>
551   {
552       BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
553       {
554           *i-- = *i;                  // require postdecrement and assignment
555       }
556    private:
557       TT i;
558   };
559
560   BOOST_concept(RandomAccessIterator,(TT))
561     : BidirectionalIterator<TT>
562     , Comparable<TT>
563   {
564       BOOST_CONCEPT_USAGE(RandomAccessIterator)
565       {
566           BOOST_CONCEPT_ASSERT((Convertible<
567               BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
568             , std::random_access_iterator_tag
569           >));
570
571           i += n;             // require assignment addition operator
572           i = i + n; i = n + i; // require addition with difference type
573           i -= n;             // require assignment subtraction operator
574           i = i - n;                  // require subtraction with difference type
575           n = i - j;                  // require difference operator
576           (void)i[n];                 // require element access operator
577       }
578       
579    private:
580     TT a, b;
581     TT i, j;
582       typename boost::detail::iterator_traits<TT>::difference_type n;
583   };
584
585   BOOST_concept(Mutable_RandomAccessIterator,(TT))
586     : RandomAccessIterator<TT>
587     , Mutable_BidirectionalIterator<TT>
588   {
589       BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
590       {
591           i[n] = *i;                  // require element access and assignment
592       }
593    private:
594     TT i;
595     typename boost::detail::iterator_traits<TT>::difference_type n;
596   };
597
598   //===========================================================================
599   // Container s
600
601   BOOST_concept(Container,(C))
602     : Assignable<C>
603   {
604     typedef typename C::value_type value_type;
605     typedef typename C::difference_type difference_type;
606     typedef typename C::size_type size_type;
607     typedef typename C::const_reference const_reference;
608     typedef typename C::const_pointer const_pointer;
609     typedef typename C::const_iterator const_iterator;
610
611       BOOST_CONCEPT_USAGE(Container)
612       {
613           BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
614           const_constraints(c);
615       }
616       
617    private:
618       void const_constraints(const C& cc) {
619           i = cc.begin();
620           i = cc.end();
621           n = cc.size();
622           n = cc.max_size();
623           b = cc.empty();
624       }
625       C c;
626       bool b;
627       const_iterator i;
628       size_type n;
629   };
630
631   BOOST_concept(Mutable_Container,(C))
632     : Container<C>
633   {
634       typedef typename C::reference reference;
635       typedef typename C::iterator iterator;
636       typedef typename C::pointer pointer;
637     
638       BOOST_CONCEPT_USAGE(Mutable_Container)
639       {
640           BOOST_CONCEPT_ASSERT((
641                Assignable<typename Mutable_Container::value_type>));
642           
643           BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
644           
645           i = c.begin();
646           i = c.end();
647           c.swap(c2);
648       }
649       
650    private:
651       iterator i;
652       C c, c2;
653   };
654
655   BOOST_concept(ForwardContainer,(C))
656     : Container<C>
657   {
658       BOOST_CONCEPT_USAGE(ForwardContainer)
659       {
660           BOOST_CONCEPT_ASSERT((
661                ForwardIterator<
662                     typename ForwardContainer::const_iterator
663                >));
664       }
665   };  
666
667   BOOST_concept(Mutable_ForwardContainer,(C))
668     : ForwardContainer<C>
669     , Mutable_Container<C>
670   {
671       BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
672       {
673           BOOST_CONCEPT_ASSERT((
674                Mutable_ForwardIterator<
675                    typename Mutable_ForwardContainer::iterator
676                >));
677       }
678   };  
679
680   BOOST_concept(ReversibleContainer,(C))
681     : ForwardContainer<C>
682   {
683       typedef typename
684         C::const_reverse_iterator
685       const_reverse_iterator;
686
687       BOOST_CONCEPT_USAGE(ReversibleContainer)
688       {
689           BOOST_CONCEPT_ASSERT((
690               BidirectionalIterator<
691                   typename ReversibleContainer::const_iterator>));
692           
693           BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
694           
695           const_constraints(c);
696       }
697    private:
698       void const_constraints(const C& cc)
699       {
700           const_reverse_iterator i = cc.rbegin();
701           i = cc.rend();
702       }
703       C c;
704   };
705
706   BOOST_concept(Mutable_ReversibleContainer,(C))
707     : Mutable_ForwardContainer<C>
708     , ReversibleContainer<C>
709   {
710       typedef typename C::reverse_iterator reverse_iterator;
711       
712       BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
713       {
714           typedef typename Mutable_ForwardContainer<C>::iterator iterator;
715           BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
716           BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
717           
718           reverse_iterator i = c.rbegin();
719           i = c.rend();
720       }
721    private:  
722       C c;
723   };
724
725   BOOST_concept(RandomAccessContainer,(C))
726     : ReversibleContainer<C>
727   {
728       typedef typename C::size_type size_type;
729       typedef typename C::const_reference const_reference;
730
731       BOOST_CONCEPT_USAGE(RandomAccessContainer)
732       {
733           BOOST_CONCEPT_ASSERT((
734               RandomAccessIterator<
735                   typename RandomAccessContainer::const_iterator
736               >));
737           
738           const_constraints(c);
739       }
740    private:
741       void const_constraints(const C& cc)
742       {
743           const_reference r = cc[n];
744           ignore_unused_variable_warning(r);
745       }
746     
747       C c;
748       size_type n;
749   };
750
751   BOOST_concept(Mutable_RandomAccessContainer,(C))
752     : Mutable_ReversibleContainer<C>
753     , RandomAccessContainer<C>
754   {
755    private:
756       typedef Mutable_RandomAccessContainer self;
757    public:
758       BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
759       {
760           BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
761           BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
762           
763           typename self::reference r = c[i];
764           ignore_unused_variable_warning(r);
765       }
766       
767    private:
768       typename Mutable_ReversibleContainer<C>::size_type i;
769       C c;
770   };
771
772   // A Sequence is inherently mutable
773   BOOST_concept(Sequence,(S))
774     : Mutable_ForwardContainer<S>
775       // Matt Austern's book puts DefaultConstructible here, the C++
776       // standard places it in Container --JGS
777       // ... so why aren't we following the standard?  --DWA
778     , DefaultConstructible<S>
779   {
780       BOOST_CONCEPT_USAGE(Sequence)
781       {
782           S 
783               c(n),
784               c2(n, t),
785               c3(first, last);
786
787           c.insert(p, t);
788           c.insert(p, n, t);
789           c.insert(p, first, last);
790
791           c.erase(p);
792           c.erase(p, q);
793
794           typename Sequence::reference r = c.front();
795
796           ignore_unused_variable_warning(c);
797           ignore_unused_variable_warning(c2);
798           ignore_unused_variable_warning(c3);
799           ignore_unused_variable_warning(r);
800           const_constraints(c);
801       }
802    private:
803       void const_constraints(const S& c) {
804           typename Sequence::const_reference r = c.front();
805           ignore_unused_variable_warning(r);
806       }
807     
808       typename S::value_type t;
809       typename S::size_type n;
810       typename S::value_type* first, *last;
811       typename S::iterator p, q;
812   };
813
814   BOOST_concept(FrontInsertionSequence,(S))
815     : Sequence<S>
816   {
817       BOOST_CONCEPT_USAGE(FrontInsertionSequence)
818       {
819           c.push_front(t);
820           c.pop_front();
821       }
822    private:
823       S c;
824       typename S::value_type t;
825   };
826
827   BOOST_concept(BackInsertionSequence,(S))
828     : Sequence<S>
829   {
830       BOOST_CONCEPT_USAGE(BackInsertionSequence)
831       {
832           c.push_back(t);
833           c.pop_back();
834           typename BackInsertionSequence::reference r = c.back();
835           ignore_unused_variable_warning(r);
836           const_constraints(c);
837       }
838    private:
839       void const_constraints(const S& cc) {
840           typename BackInsertionSequence::const_reference
841               r = cc.back();
842           ignore_unused_variable_warning(r);
843       };
844       S c;
845       typename S::value_type t;
846   };
847
848   BOOST_concept(AssociativeContainer,(C))
849     : ForwardContainer<C>
850     , DefaultConstructible<C>
851   {
852       typedef typename C::key_type key_type;
853       typedef typename C::key_compare key_compare;
854       typedef typename C::value_compare value_compare;
855       typedef typename C::iterator iterator;
856
857       BOOST_CONCEPT_USAGE(AssociativeContainer)
858       {
859           i = c.find(k);
860           r = c.equal_range(k);
861           c.erase(k);
862           c.erase(i);
863           c.erase(r.first, r.second);
864           const_constraints(c);
865           BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
866           
867           typedef typename AssociativeContainer::value_type value_type_;
868           BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
869       }
870       
871       // Redundant with the base concept, but it helps below.
872       typedef typename C::const_iterator const_iterator;
873    private:
874       void const_constraints(const C& cc)
875       {
876           ci = cc.find(k);
877           n = cc.count(k);
878           cr = cc.equal_range(k);
879       }
880
881       C c;
882       iterator i;
883       std::pair<iterator,iterator> r;
884       const_iterator ci;
885       std::pair<const_iterator,const_iterator> cr;
886       typename C::key_type k;
887       typename C::size_type n;
888   };
889
890   BOOST_concept(UniqueAssociativeContainer,(C))
891     : AssociativeContainer<C>
892   {
893       BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
894       {
895           C c(first, last);
896       
897           pos_flag = c.insert(t);
898           c.insert(first, last);
899
900           ignore_unused_variable_warning(c);
901       }
902    private:
903       std::pair<typename C::iterator, bool> pos_flag;
904       typename C::value_type t;
905       typename C::value_type* first, *last;
906   };
907
908   BOOST_concept(MultipleAssociativeContainer,(C))
909     : AssociativeContainer<C>
910   {
911       BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
912       {
913           C c(first, last);
914       
915           pos = c.insert(t);
916           c.insert(first, last);
917
918           ignore_unused_variable_warning(c);
919           ignore_unused_variable_warning(pos);
920       }
921    private:
922       typename C::iterator pos;
923       typename C::value_type t;
924       typename C::value_type* first, *last;
925   };
926
927   BOOST_concept(SimpleAssociativeContainer,(C))
928     : AssociativeContainer<C>
929   {
930       BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
931       {
932           typedef typename C::key_type key_type;
933           typedef typename C::value_type value_type;
934           BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
935       }
936   };
937
938   BOOST_concept(PairAssociativeContainer,(C))
939     : AssociativeContainer<C>
940   {
941       BOOST_CONCEPT_USAGE(PairAssociativeContainer)
942       {
943           typedef typename C::key_type key_type;
944           typedef typename C::value_type value_type;
945           typedef typename C::mapped_type mapped_type;
946           typedef std::pair<const key_type, mapped_type> required_value_type;
947           BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
948       }
949   };
950
951   BOOST_concept(SortedAssociativeContainer,(C))
952     : AssociativeContainer<C>
953     , ReversibleContainer<C>
954   {
955       BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
956       {
957           C 
958               c(kc),
959               c2(first, last),
960               c3(first, last, kc);
961
962           p = c.upper_bound(k);
963           p = c.lower_bound(k);
964           r = c.equal_range(k);
965       
966           c.insert(p, t);
967       
968           ignore_unused_variable_warning(c);
969           ignore_unused_variable_warning(c2);
970           ignore_unused_variable_warning(c3);
971           const_constraints(c);
972       }
973       
974       void const_constraints(const C& c)
975       {
976           kc = c.key_comp();
977           vc = c.value_comp();
978
979           cp = c.upper_bound(k);
980           cp = c.lower_bound(k);
981           cr = c.equal_range(k);
982       }
983       
984    private:
985       typename C::key_compare kc;
986       typename C::value_compare vc;
987       typename C::value_type t;
988       typename C::key_type k;
989       typedef typename C::iterator iterator;
990       typedef typename C::const_iterator const_iterator;
991
992       typedef SortedAssociativeContainer self;
993       iterator p;
994       const_iterator cp;
995       std::pair<typename self::iterator,typename self::iterator> r;
996       std::pair<typename self::const_iterator,typename self::const_iterator> cr;
997       typename C::value_type* first, *last;
998   };
999
1000   // HashedAssociativeContainer
1001
1002 } // namespace boost
1003
1004 # include <boost/concept/detail/concept_undef.hpp>
1005
1006 #endif // BOOST_CONCEPT_CHECKS_HPP
1007