1169691Skan// -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
497403Sobrien//
5132720Skan// This file is part of the GNU ISO C++ Library.  This library is free
6132720Skan// software; you can redistribute it and/or modify it under the
7132720Skan// terms of the GNU General Public License as published by the
8132720Skan// Free Software Foundation; either version 2, or (at your option)
9132720Skan// any later version.
10132720Skan
11132720Skan// This library is distributed in the hope that it will be useful,
12132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14132720Skan// GNU General Public License for more details.
15132720Skan
16132720Skan// You should have received a copy of the GNU General Public License along
17132720Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19132720Skan// USA.
20132720Skan
21132720Skan// As a special exception, you may use this file as part of a free software
22132720Skan// library without restriction.  Specifically, if other files instantiate
23132720Skan// templates or use macros or inline functions from this file, or you compile
24132720Skan// this file and link it with other files to produce an executable, this
25132720Skan// file does not by itself cause the resulting executable to be covered by
26132720Skan// the GNU General Public License.  This exception does not however
27132720Skan// invalidate any other reasons why the executable file might be covered by
28132720Skan// the GNU General Public License.
29132720Skan
3097403Sobrien// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
3197403Sobrien// sell and distribute this software is granted provided this
3297403Sobrien// copyright notice appears in all copies. This software is provided
3397403Sobrien// "as is" without express or implied warranty, and with no claim as
3497403Sobrien// to its suitability for any purpose.
3597403Sobrien//
3697403Sobrien
3797403Sobrien/** @file boost_concept_check.h
3897403Sobrien *  This is an internal header file, included by other library headers.
3997403Sobrien *  You should not attempt to use it directly.
4097403Sobrien */
4197403Sobrien
42169691Skan// GCC Note:  based on version 1.12.0 of the Boost library.
43169691Skan
44132720Skan#ifndef _BOOST_CONCEPT_CHECK_H
45132720Skan#define _BOOST_CONCEPT_CHECK_H 1
4697403Sobrien
4797403Sobrien#pragma GCC system_header
48132720Skan
4997403Sobrien#include <cstddef>                // for ptrdiff_t, used next
5097403Sobrien#include <bits/stl_iterator_base_types.h>    // for traits and tags
5197403Sobrien#include <utility>                           // for pair<>
5297403Sobrien
53169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
5497403Sobrien
5597403Sobrien#define _IsUnused __attribute__ ((__unused__))
5697403Sobrien
5797403Sobrien// When the C-C code is in use, we would like this function to do as little
5897403Sobrien// as possible at runtime, use as few resources as possible, and hopefully
5997403Sobrien// be elided out of existence... hmmm.
6097403Sobrientemplate <class _Concept>
6197403Sobrieninline void __function_requires()
6297403Sobrien{
6397403Sobrien  void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
6497403Sobrien}
6597403Sobrien
66132720Skan// No definition: if this is referenced, there's a problem with
67132720Skan// the instantiating type not being one of the required integer types.
68132720Skan// Unfortunately, this results in a link-time error, not a compile-time error.
69132720Skanvoid __error_type_must_be_an_integer_type();
70132720Skanvoid __error_type_must_be_an_unsigned_integer_type();
71132720Skanvoid __error_type_must_be_a_signed_integer_type();
7297403Sobrien
7397403Sobrien// ??? Should the "concept_checking*" structs begin with more than _ ?
74132720Skan#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
7597403Sobrien  typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
7697403Sobrien  template <_func##_type_var##_concept _Tp1> \
7797403Sobrien  struct _concept_checking##_type_var##_concept { }; \
7897403Sobrien  typedef _concept_checking##_type_var##_concept< \
7997403Sobrien    &_ns::_concept <_type_var>::__constraints> \
8097403Sobrien    _concept_checking_typedef##_type_var##_concept
8197403Sobrien
82132720Skan#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
8397403Sobrien  typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
8497403Sobrien  template <_func##_type_var1##_type_var2##_concept _Tp1> \
8597403Sobrien  struct _concept_checking##_type_var1##_type_var2##_concept { }; \
8697403Sobrien  typedef _concept_checking##_type_var1##_type_var2##_concept< \
8797403Sobrien    &_ns::_concept <_type_var1,_type_var2>::__constraints> \
8897403Sobrien    _concept_checking_typedef##_type_var1##_type_var2##_concept
8997403Sobrien
90132720Skan#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
9197403Sobrien  typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
9297403Sobrien  template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
9397403Sobrien  struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
9497403Sobrien  typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
9597403Sobrien    &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints>  \
9697403Sobrien  _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
9797403Sobrien
98132720Skan#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
9997403Sobrien  typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
10097403Sobrien  template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
10197403Sobrien  struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
10297403Sobrien  typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
10397403Sobrien  &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
10497403Sobrien    _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
10597403Sobrien
10697403Sobrien
10797403Sobrientemplate <class _Tp1, class _Tp2>
10897403Sobrienstruct _Aux_require_same { };
10997403Sobrien
11097403Sobrientemplate <class _Tp>
11197403Sobrienstruct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
11297403Sobrien
11397403Sobrien  template <class _Tp1, class _Tp2>
11497403Sobrien  struct _SameTypeConcept
11597403Sobrien  {
11697403Sobrien    void __constraints() {
11797403Sobrien      typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
11897403Sobrien    }
11997403Sobrien  };
12097403Sobrien
12197403Sobrien  template <class _Tp>
12297403Sobrien  struct _IntegerConcept {
123132720Skan    void __constraints() {
12497403Sobrien      __error_type_must_be_an_integer_type();
12597403Sobrien    }
12697403Sobrien  };
12797403Sobrien  template <> struct _IntegerConcept<short> { void __constraints() {} };
12897403Sobrien  template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
12997403Sobrien  template <> struct _IntegerConcept<int> { void __constraints() {} };
13097403Sobrien  template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
13197403Sobrien  template <> struct _IntegerConcept<long> { void __constraints() {} };
13297403Sobrien  template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
13397403Sobrien  template <> struct _IntegerConcept<long long> { void __constraints() {} };
13497403Sobrien  template <> struct _IntegerConcept<unsigned long long>
13597403Sobrien                                                { void __constraints() {} };
13697403Sobrien
13797403Sobrien  template <class _Tp>
13897403Sobrien  struct _SignedIntegerConcept {
139132720Skan    void __constraints() {
14097403Sobrien      __error_type_must_be_a_signed_integer_type();
14197403Sobrien    }
14297403Sobrien  };
14397403Sobrien  template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
14497403Sobrien  template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
14597403Sobrien  template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
14697403Sobrien  template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
14797403Sobrien
14897403Sobrien  template <class _Tp>
14997403Sobrien  struct _UnsignedIntegerConcept {
150132720Skan    void __constraints() {
15197403Sobrien      __error_type_must_be_an_unsigned_integer_type();
15297403Sobrien    }
15397403Sobrien  };
15497403Sobrien  template <> struct _UnsignedIntegerConcept<unsigned short>
15597403Sobrien    { void __constraints() {} };
15697403Sobrien  template <> struct _UnsignedIntegerConcept<unsigned int>
15797403Sobrien    { void __constraints() {} };
15897403Sobrien  template <> struct _UnsignedIntegerConcept<unsigned long>
15997403Sobrien    { void __constraints() {} };
16097403Sobrien  template <> struct _UnsignedIntegerConcept<unsigned long long>
16197403Sobrien    { void __constraints() {} };
16297403Sobrien
16397403Sobrien  //===========================================================================
16497403Sobrien  // Basic Concepts
16597403Sobrien
16697403Sobrien  template <class _Tp>
16797403Sobrien  struct _DefaultConstructibleConcept
16897403Sobrien  {
16997403Sobrien    void __constraints() {
17097403Sobrien      _Tp __a _IsUnused;                // require default constructor
17197403Sobrien    }
17297403Sobrien  };
17397403Sobrien
17497403Sobrien  template <class _Tp>
17597403Sobrien  struct _AssignableConcept
17697403Sobrien  {
17797403Sobrien    void __constraints() {
17897403Sobrien      __a = __a;                        // require assignment operator
17997403Sobrien      __const_constraints(__a);
18097403Sobrien    }
18197403Sobrien    void __const_constraints(const _Tp& __b) {
18297403Sobrien      __a = __b;                   // const required for argument to assignment
18397403Sobrien    }
18497403Sobrien    _Tp __a;
185117397Skan    // possibly should be "Tp* a;" and then dereference "a" in constraint
186117397Skan    // functions?  present way would require a default ctor, i think...
18797403Sobrien  };
18897403Sobrien
18997403Sobrien  template <class _Tp>
19097403Sobrien  struct _CopyConstructibleConcept
19197403Sobrien  {
19297403Sobrien    void __constraints() {
19397403Sobrien      _Tp __a(__b);                     // require copy constructor
19497403Sobrien      _Tp* __ptr _IsUnused = &__a;      // require address of operator
19597403Sobrien      __const_constraints(__a);
19697403Sobrien    }
19797403Sobrien    void __const_constraints(const _Tp& __a) {
198132720Skan      _Tp __c _IsUnused(__a);           // require const copy constructor
19997403Sobrien      const _Tp* __ptr _IsUnused = &__a; // require const address of operator
20097403Sobrien    }
20197403Sobrien    _Tp __b;
20297403Sobrien  };
20397403Sobrien
20497403Sobrien  // The SGI STL version of Assignable requires copy constructor and operator=
20597403Sobrien  template <class _Tp>
20697403Sobrien  struct _SGIAssignableConcept
20797403Sobrien  {
20897403Sobrien    void __constraints() {
209132720Skan      _Tp __b _IsUnused(__a);
21097403Sobrien      __a = __a;                        // require assignment operator
21197403Sobrien      __const_constraints(__a);
21297403Sobrien    }
21397403Sobrien    void __const_constraints(const _Tp& __b) {
214132720Skan      _Tp __c _IsUnused(__b);
21597403Sobrien      __a = __b;              // const required for argument to assignment
21697403Sobrien    }
21797403Sobrien    _Tp __a;
21897403Sobrien  };
21997403Sobrien
22097403Sobrien  template <class _From, class _To>
22197403Sobrien  struct _ConvertibleConcept
22297403Sobrien  {
22397403Sobrien    void __constraints() {
22497403Sobrien      _To __y _IsUnused = __x;
22597403Sobrien    }
22697403Sobrien    _From __x;
22797403Sobrien  };
22897403Sobrien
22997403Sobrien  // The C++ standard requirements for many concepts talk about return
23097403Sobrien  // types that must be "convertible to bool".  The problem with this
23197403Sobrien  // requirement is that it leaves the door open for evil proxies that
23297403Sobrien  // define things like operator|| with strange return types.  Two
23397403Sobrien  // possible solutions are:
23497403Sobrien  // 1) require the return type to be exactly bool
23597403Sobrien  // 2) stay with convertible to bool, and also
23697403Sobrien  //    specify stuff about all the logical operators.
23797403Sobrien  // For now we just test for convertible to bool.
23897403Sobrien  template <class _Tp>
23997403Sobrien  void __aux_require_boolean_expr(const _Tp& __t) {
24097403Sobrien    bool __x _IsUnused = __t;
24197403Sobrien  }
24297403Sobrien
24397403Sobrien// FIXME
24497403Sobrien  template <class _Tp>
24597403Sobrien  struct _EqualityComparableConcept
24697403Sobrien  {
24797403Sobrien    void __constraints() {
24897403Sobrien      __aux_require_boolean_expr(__a == __b);
24997403Sobrien    }
25097403Sobrien    _Tp __a, __b;
25197403Sobrien  };
25297403Sobrien
25397403Sobrien  template <class _Tp>
25497403Sobrien  struct _LessThanComparableConcept
25597403Sobrien  {
25697403Sobrien    void __constraints() {
25797403Sobrien      __aux_require_boolean_expr(__a < __b);
25897403Sobrien    }
25997403Sobrien    _Tp __a, __b;
26097403Sobrien  };
26197403Sobrien
26297403Sobrien  // This is equivalent to SGI STL's LessThanComparable.
26397403Sobrien  template <class _Tp>
26497403Sobrien  struct _ComparableConcept
26597403Sobrien  {
26697403Sobrien    void __constraints() {
26797403Sobrien      __aux_require_boolean_expr(__a < __b);
26897403Sobrien      __aux_require_boolean_expr(__a > __b);
26997403Sobrien      __aux_require_boolean_expr(__a <= __b);
27097403Sobrien      __aux_require_boolean_expr(__a >= __b);
27197403Sobrien    }
27297403Sobrien    _Tp __a, __b;
27397403Sobrien  };
27497403Sobrien
275132720Skan#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
27697403Sobrien  template <class _First, class _Second> \
27797403Sobrien  struct _NAME { \
27897403Sobrien    void __constraints() { (void)__constraints_(); } \
27997403Sobrien    bool __constraints_() {  \
28097403Sobrien      return  __a _OP __b; \
28197403Sobrien    } \
28297403Sobrien    _First __a; \
28397403Sobrien    _Second __b; \
28497403Sobrien  }
28597403Sobrien
286132720Skan#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
28797403Sobrien  template <class _Ret, class _First, class _Second> \
28897403Sobrien  struct _NAME { \
28997403Sobrien    void __constraints() { (void)__constraints_(); } \
29097403Sobrien    _Ret __constraints_() {  \
29197403Sobrien      return __a _OP __b; \
29297403Sobrien    } \
29397403Sobrien    _First __a; \
29497403Sobrien    _Second __b; \
29597403Sobrien  }
29697403Sobrien
297132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
298132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
299132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
300132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
301132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
302132720Skan  _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
30397403Sobrien
304132720Skan  _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
305132720Skan  _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
306132720Skan  _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
307132720Skan  _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
308132720Skan  _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
30997403Sobrien
310132720Skan#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
311132720Skan#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
31297403Sobrien
31397403Sobrien  //===========================================================================
31497403Sobrien  // Function Object Concepts
31597403Sobrien
31697403Sobrien  template <class _Func, class _Return>
31797403Sobrien  struct _GeneratorConcept
31897403Sobrien  {
31997403Sobrien    void __constraints() {
32097403Sobrien      const _Return& __r _IsUnused = __f();// require operator() member function
32197403Sobrien    }
32297403Sobrien    _Func __f;
32397403Sobrien  };
32497403Sobrien
32597403Sobrien
32697403Sobrien  template <class _Func>
32797403Sobrien  struct _GeneratorConcept<_Func,void>
32897403Sobrien  {
32997403Sobrien    void __constraints() {
33097403Sobrien      __f();                            // require operator() member function
33197403Sobrien    }
33297403Sobrien    _Func __f;
33397403Sobrien  };
33497403Sobrien
33597403Sobrien  template <class _Func, class _Return, class _Arg>
33697403Sobrien  struct _UnaryFunctionConcept
33797403Sobrien  {
33897403Sobrien    void __constraints() {
33997403Sobrien      __r = __f(__arg);                  // require operator()
34097403Sobrien    }
34197403Sobrien    _Func __f;
34297403Sobrien    _Arg __arg;
34397403Sobrien    _Return __r;
34497403Sobrien  };
34597403Sobrien
34697403Sobrien  template <class _Func, class _Arg>
34797403Sobrien  struct _UnaryFunctionConcept<_Func, void, _Arg> {
348132720Skan    void __constraints() {
34997403Sobrien      __f(__arg);                       // require operator()
35097403Sobrien    }
35197403Sobrien    _Func __f;
35297403Sobrien    _Arg __arg;
35397403Sobrien  };
35497403Sobrien
35597403Sobrien  template <class _Func, class _Return, class _First, class _Second>
35697403Sobrien  struct _BinaryFunctionConcept
35797403Sobrien  {
358132720Skan    void __constraints() {
35997403Sobrien      __r = __f(__first, __second);     // require operator()
36097403Sobrien    }
36197403Sobrien    _Func __f;
36297403Sobrien    _First __first;
36397403Sobrien    _Second __second;
36497403Sobrien    _Return __r;
36597403Sobrien  };
36697403Sobrien
36797403Sobrien  template <class _Func, class _First, class _Second>
36897403Sobrien  struct _BinaryFunctionConcept<_Func, void, _First, _Second>
36997403Sobrien  {
37097403Sobrien    void __constraints() {
37197403Sobrien      __f(__first, __second);           // require operator()
37297403Sobrien    }
37397403Sobrien    _Func __f;
37497403Sobrien    _First __first;
37597403Sobrien    _Second __second;
37697403Sobrien  };
37797403Sobrien
37897403Sobrien  template <class _Func, class _Arg>
37997403Sobrien  struct _UnaryPredicateConcept
38097403Sobrien  {
38197403Sobrien    void __constraints() {
38297403Sobrien      __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
38397403Sobrien    }
38497403Sobrien    _Func __f;
38597403Sobrien    _Arg __arg;
38697403Sobrien  };
38797403Sobrien
38897403Sobrien  template <class _Func, class _First, class _Second>
38997403Sobrien  struct _BinaryPredicateConcept
39097403Sobrien  {
39197403Sobrien    void __constraints() {
39297403Sobrien      __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
39397403Sobrien    }
39497403Sobrien    _Func __f;
39597403Sobrien    _First __a;
39697403Sobrien    _Second __b;
39797403Sobrien  };
39897403Sobrien
39997403Sobrien  // use this when functor is used inside a container class like std::set
40097403Sobrien  template <class _Func, class _First, class _Second>
40197403Sobrien  struct _Const_BinaryPredicateConcept {
402132720Skan    void __constraints() {
40397403Sobrien      __const_constraints(__f);
40497403Sobrien    }
40597403Sobrien    void __const_constraints(const _Func& __fun) {
40697403Sobrien      __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
40797403Sobrien      // operator() must be a const member function
40897403Sobrien      __aux_require_boolean_expr(__fun(__a, __b));
40997403Sobrien    }
41097403Sobrien    _Func __f;
41197403Sobrien    _First __a;
41297403Sobrien    _Second __b;
41397403Sobrien  };
41497403Sobrien
41597403Sobrien  //===========================================================================
41697403Sobrien  // Iterator Concepts
41797403Sobrien
41897403Sobrien  template <class _Tp>
41997403Sobrien  struct _TrivialIteratorConcept
42097403Sobrien  {
42197403Sobrien    void __constraints() {
422132720Skan//    __function_requires< _DefaultConstructibleConcept<_Tp> >();
42397403Sobrien      __function_requires< _AssignableConcept<_Tp> >();
42497403Sobrien      __function_requires< _EqualityComparableConcept<_Tp> >();
42597403Sobrien//      typedef typename std::iterator_traits<_Tp>::value_type _V;
42697403Sobrien      (void)*__i;                       // require dereference operator
42797403Sobrien    }
42897403Sobrien    _Tp __i;
42997403Sobrien  };
43097403Sobrien
43197403Sobrien  template <class _Tp>
43297403Sobrien  struct _Mutable_TrivialIteratorConcept
43397403Sobrien  {
43497403Sobrien    void __constraints() {
43597403Sobrien      __function_requires< _TrivialIteratorConcept<_Tp> >();
43697403Sobrien      *__i = *__j;                      // require dereference and assignment
43797403Sobrien    }
43897403Sobrien    _Tp __i, __j;
43997403Sobrien  };
44097403Sobrien
44197403Sobrien  template <class _Tp>
44297403Sobrien  struct _InputIteratorConcept
44397403Sobrien  {
44497403Sobrien    void __constraints() {
44597403Sobrien      __function_requires< _TrivialIteratorConcept<_Tp> >();
44697403Sobrien      // require iterator_traits typedef's
447132720Skan      typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
448132720Skan//      __function_requires< _SignedIntegerConcept<_Diff> >();
449132720Skan      typedef typename std::iterator_traits<_Tp>::reference _Ref;
45097403Sobrien      typedef typename std::iterator_traits<_Tp>::pointer _Pt;
45197403Sobrien      typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
45297403Sobrien      __function_requires< _ConvertibleConcept<
45397403Sobrien        typename std::iterator_traits<_Tp>::iterator_category,
45497403Sobrien        std::input_iterator_tag> >();
45597403Sobrien      ++__i;                            // require preincrement operator
45697403Sobrien      __i++;                            // require postincrement operator
45797403Sobrien    }
45897403Sobrien    _Tp __i;
45997403Sobrien  };
46097403Sobrien
46197403Sobrien  template <class _Tp, class _ValueT>
46297403Sobrien  struct _OutputIteratorConcept
46397403Sobrien  {
46497403Sobrien    void __constraints() {
46597403Sobrien      __function_requires< _AssignableConcept<_Tp> >();
46697403Sobrien      ++__i;                            // require preincrement operator
46797403Sobrien      __i++;                            // require postincrement operator
46897403Sobrien      *__i++ = __t;                     // require postincrement and assignment
46997403Sobrien    }
47097403Sobrien    _Tp __i;
47197403Sobrien    _ValueT __t;
47297403Sobrien  };
47397403Sobrien
47497403Sobrien  template <class _Tp>
47597403Sobrien  struct _ForwardIteratorConcept
47697403Sobrien  {
47797403Sobrien    void __constraints() {
47897403Sobrien      __function_requires< _InputIteratorConcept<_Tp> >();
479132720Skan      __function_requires< _DefaultConstructibleConcept<_Tp> >();
48097403Sobrien      __function_requires< _ConvertibleConcept<
48197403Sobrien        typename std::iterator_traits<_Tp>::iterator_category,
48297403Sobrien        std::forward_iterator_tag> >();
483132720Skan      typedef typename std::iterator_traits<_Tp>::reference _Ref;
484132720Skan      _Ref __r _IsUnused = *__i;
48597403Sobrien    }
48697403Sobrien    _Tp __i;
48797403Sobrien  };
48897403Sobrien
48997403Sobrien  template <class _Tp>
49097403Sobrien  struct _Mutable_ForwardIteratorConcept
49197403Sobrien  {
49297403Sobrien    void __constraints() {
49397403Sobrien      __function_requires< _ForwardIteratorConcept<_Tp> >();
49497403Sobrien      *__i++ = *__i;                    // require postincrement and assignment
49597403Sobrien    }
49697403Sobrien    _Tp __i;
49797403Sobrien  };
49897403Sobrien
49997403Sobrien  template <class _Tp>
50097403Sobrien  struct _BidirectionalIteratorConcept
50197403Sobrien  {
50297403Sobrien    void __constraints() {
50397403Sobrien      __function_requires< _ForwardIteratorConcept<_Tp> >();
50497403Sobrien      __function_requires< _ConvertibleConcept<
50597403Sobrien        typename std::iterator_traits<_Tp>::iterator_category,
50697403Sobrien        std::bidirectional_iterator_tag> >();
50797403Sobrien      --__i;                            // require predecrement operator
50897403Sobrien      __i--;                            // require postdecrement operator
50997403Sobrien    }
51097403Sobrien    _Tp __i;
51197403Sobrien  };
51297403Sobrien
51397403Sobrien  template <class _Tp>
51497403Sobrien  struct _Mutable_BidirectionalIteratorConcept
51597403Sobrien  {
51697403Sobrien    void __constraints() {
51797403Sobrien      __function_requires< _BidirectionalIteratorConcept<_Tp> >();
51897403Sobrien      __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
51997403Sobrien      *__i-- = *__i;                    // require postdecrement and assignment
52097403Sobrien    }
52197403Sobrien    _Tp __i;
52297403Sobrien  };
52397403Sobrien
52497403Sobrien
52597403Sobrien  template <class _Tp>
52697403Sobrien  struct _RandomAccessIteratorConcept
52797403Sobrien  {
52897403Sobrien    void __constraints() {
52997403Sobrien      __function_requires< _BidirectionalIteratorConcept<_Tp> >();
53097403Sobrien      __function_requires< _ComparableConcept<_Tp> >();
53197403Sobrien      __function_requires< _ConvertibleConcept<
53297403Sobrien        typename std::iterator_traits<_Tp>::iterator_category,
53397403Sobrien        std::random_access_iterator_tag> >();
534132720Skan      // ??? We don't use _Ref, are we just checking for "referenceability"?
535132720Skan      typedef typename std::iterator_traits<_Tp>::reference _Ref;
53697403Sobrien
53797403Sobrien      __i += __n;                       // require assignment addition operator
53897403Sobrien      __i = __i + __n; __i = __n + __i; // require addition with difference type
53997403Sobrien      __i -= __n;                       // require assignment subtraction op
54097403Sobrien      __i = __i - __n;                  // require subtraction with
54197403Sobrien                                        //            difference type
54297403Sobrien      __n = __i - __j;                  // require difference operator
54397403Sobrien      (void)__i[__n];                   // require element access operator
54497403Sobrien    }
54597403Sobrien    _Tp __a, __b;
54697403Sobrien    _Tp __i, __j;
54797403Sobrien    typename std::iterator_traits<_Tp>::difference_type __n;
54897403Sobrien  };
54997403Sobrien
55097403Sobrien  template <class _Tp>
55197403Sobrien  struct _Mutable_RandomAccessIteratorConcept
55297403Sobrien  {
55397403Sobrien    void __constraints() {
55497403Sobrien      __function_requires< _RandomAccessIteratorConcept<_Tp> >();
55597403Sobrien      __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
55697403Sobrien      __i[__n] = *__i;                  // require element access and assignment
55797403Sobrien    }
55897403Sobrien    _Tp __i;
55997403Sobrien    typename std::iterator_traits<_Tp>::difference_type __n;
56097403Sobrien  };
56197403Sobrien
56297403Sobrien  //===========================================================================
56397403Sobrien  // Container Concepts
56497403Sobrien
56597403Sobrien  template <class _Container>
56697403Sobrien  struct _ContainerConcept
56797403Sobrien  {
56897403Sobrien    typedef typename _Container::value_type _Value_type;
56997403Sobrien    typedef typename _Container::difference_type _Difference_type;
57097403Sobrien    typedef typename _Container::size_type _Size_type;
57197403Sobrien    typedef typename _Container::const_reference _Const_reference;
57297403Sobrien    typedef typename _Container::const_pointer _Const_pointer;
57397403Sobrien    typedef typename _Container::const_iterator _Const_iterator;
57497403Sobrien
57597403Sobrien    void __constraints() {
57697403Sobrien      __function_requires< _InputIteratorConcept<_Const_iterator> >();
57797403Sobrien      __function_requires< _AssignableConcept<_Container> >();
57897403Sobrien      const _Container __c;
57997403Sobrien      __i = __c.begin();
58097403Sobrien      __i = __c.end();
58197403Sobrien      __n = __c.size();
58297403Sobrien      __n = __c.max_size();
58397403Sobrien      __b = __c.empty();
58497403Sobrien    }
58597403Sobrien    bool __b;
58697403Sobrien    _Const_iterator __i;
58797403Sobrien    _Size_type __n;
58897403Sobrien  };
58997403Sobrien
59097403Sobrien  template <class _Container>
59197403Sobrien  struct _Mutable_ContainerConcept
59297403Sobrien  {
59397403Sobrien    typedef typename _Container::value_type _Value_type;
59497403Sobrien    typedef typename _Container::reference _Reference;
59597403Sobrien    typedef typename _Container::iterator _Iterator;
59697403Sobrien    typedef typename _Container::pointer _Pointer;
597132720Skan
59897403Sobrien    void __constraints() {
59997403Sobrien      __function_requires< _ContainerConcept<_Container> >();
60097403Sobrien      __function_requires< _AssignableConcept<_Value_type> >();
60197403Sobrien      __function_requires< _InputIteratorConcept<_Iterator> >();
60297403Sobrien
60397403Sobrien      __i = __c.begin();
60497403Sobrien      __i = __c.end();
60597403Sobrien      __c.swap(__c2);
60697403Sobrien    }
60797403Sobrien    _Iterator __i;
60897403Sobrien    _Container __c, __c2;
60997403Sobrien  };
61097403Sobrien
61197403Sobrien  template <class _ForwardContainer>
61297403Sobrien  struct _ForwardContainerConcept
61397403Sobrien  {
61497403Sobrien    void __constraints() {
61597403Sobrien      __function_requires< _ContainerConcept<_ForwardContainer> >();
61697403Sobrien      typedef typename _ForwardContainer::const_iterator _Const_iterator;
61797403Sobrien      __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
61897403Sobrien    }
619132720Skan  };
62097403Sobrien
62197403Sobrien  template <class _ForwardContainer>
62297403Sobrien  struct _Mutable_ForwardContainerConcept
62397403Sobrien  {
62497403Sobrien    void __constraints() {
62597403Sobrien      __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
62697403Sobrien      __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
62797403Sobrien      typedef typename _ForwardContainer::iterator _Iterator;
62897403Sobrien      __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
62997403Sobrien    }
630132720Skan  };
63197403Sobrien
63297403Sobrien  template <class _ReversibleContainer>
63397403Sobrien  struct _ReversibleContainerConcept
63497403Sobrien  {
63597403Sobrien    typedef typename _ReversibleContainer::const_iterator _Const_iterator;
63697403Sobrien    typedef typename _ReversibleContainer::const_reverse_iterator
63797403Sobrien      _Const_reverse_iterator;
63897403Sobrien
63997403Sobrien    void __constraints() {
64097403Sobrien      __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
64197403Sobrien      __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
64297403Sobrien      __function_requires<
64397403Sobrien        _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
64497403Sobrien
64597403Sobrien      const _ReversibleContainer __c;
64697403Sobrien      _Const_reverse_iterator __i = __c.rbegin();
64797403Sobrien      __i = __c.rend();
64897403Sobrien    }
64997403Sobrien  };
65097403Sobrien
65197403Sobrien  template <class _ReversibleContainer>
65297403Sobrien  struct _Mutable_ReversibleContainerConcept
65397403Sobrien  {
65497403Sobrien    typedef typename _ReversibleContainer::iterator _Iterator;
65597403Sobrien    typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
65697403Sobrien
65797403Sobrien    void __constraints() {
65897403Sobrien      __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
65997403Sobrien      __function_requires<
66097403Sobrien        _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
66197403Sobrien      __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
66297403Sobrien      __function_requires<
66397403Sobrien        _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
66497403Sobrien
66597403Sobrien      _Reverse_iterator __i = __c.rbegin();
66697403Sobrien      __i = __c.rend();
66797403Sobrien    }
66897403Sobrien    _ReversibleContainer __c;
66997403Sobrien  };
67097403Sobrien
67197403Sobrien  template <class _RandomAccessContainer>
67297403Sobrien  struct _RandomAccessContainerConcept
67397403Sobrien  {
67497403Sobrien    typedef typename _RandomAccessContainer::size_type _Size_type;
67597403Sobrien    typedef typename _RandomAccessContainer::const_reference _Const_reference;
67697403Sobrien    typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
67797403Sobrien    typedef typename _RandomAccessContainer::const_reverse_iterator
67897403Sobrien      _Const_reverse_iterator;
67997403Sobrien
68097403Sobrien    void __constraints() {
68197403Sobrien      __function_requires<
68297403Sobrien        _ReversibleContainerConcept<_RandomAccessContainer> >();
68397403Sobrien      __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
68497403Sobrien      __function_requires<
68597403Sobrien        _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
68697403Sobrien
68797403Sobrien      const _RandomAccessContainer __c;
68897403Sobrien      _Const_reference __r _IsUnused = __c[__n];
68997403Sobrien    }
69097403Sobrien    _Size_type __n;
69197403Sobrien  };
69297403Sobrien
69397403Sobrien  template <class _RandomAccessContainer>
69497403Sobrien  struct _Mutable_RandomAccessContainerConcept
69597403Sobrien  {
69697403Sobrien    typedef typename _RandomAccessContainer::size_type _Size_type;
69797403Sobrien    typedef typename _RandomAccessContainer::reference _Reference;
69897403Sobrien    typedef typename _RandomAccessContainer::iterator _Iterator;
69997403Sobrien    typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
70097403Sobrien
70197403Sobrien    void __constraints() {
70297403Sobrien      __function_requires<
70397403Sobrien        _RandomAccessContainerConcept<_RandomAccessContainer> >();
70497403Sobrien      __function_requires<
70597403Sobrien        _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
70697403Sobrien      __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
70797403Sobrien      __function_requires<
70897403Sobrien        _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
70997403Sobrien
71097403Sobrien      _Reference __r _IsUnused = __c[__i];
71197403Sobrien    }
71297403Sobrien    _Size_type __i;
71397403Sobrien    _RandomAccessContainer __c;
71497403Sobrien  };
71597403Sobrien
71697403Sobrien  // A Sequence is inherently mutable
71797403Sobrien  template <class _Sequence>
71897403Sobrien  struct _SequenceConcept
71997403Sobrien  {
72097403Sobrien    typedef typename _Sequence::reference _Reference;
72197403Sobrien    typedef typename _Sequence::const_reference _Const_reference;
72297403Sobrien
72397403Sobrien    void __constraints() {
72497403Sobrien      // Matt Austern's book puts DefaultConstructible here, the C++
72597403Sobrien      // standard places it in Container
72697403Sobrien      //    function_requires< DefaultConstructible<Sequence> >();
72797403Sobrien      __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
72897403Sobrien      __function_requires< _DefaultConstructibleConcept<_Sequence> >();
72997403Sobrien
730132720Skan      _Sequence
731146897Skan	__c _IsUnused(__n, __t),
732146897Skan        __c2 _IsUnused(__first, __last);
73397403Sobrien
73497403Sobrien      __c.insert(__p, __t);
73597403Sobrien      __c.insert(__p, __n, __t);
73697403Sobrien      __c.insert(__p, __first, __last);
73797403Sobrien
73897403Sobrien      __c.erase(__p);
73997403Sobrien      __c.erase(__p, __q);
74097403Sobrien
74197403Sobrien      _Reference __r _IsUnused = __c.front();
74297403Sobrien
74397403Sobrien      __const_constraints(__c);
74497403Sobrien    }
74597403Sobrien    void __const_constraints(const _Sequence& __c) {
74697403Sobrien      _Const_reference __r _IsUnused = __c.front();
74797403Sobrien    }
74897403Sobrien    typename _Sequence::value_type __t;
74997403Sobrien    typename _Sequence::size_type __n;
75097403Sobrien    typename _Sequence::value_type *__first, *__last;
75197403Sobrien    typename _Sequence::iterator __p, __q;
75297403Sobrien  };
75397403Sobrien
75497403Sobrien  template <class _FrontInsertionSequence>
75597403Sobrien  struct _FrontInsertionSequenceConcept
75697403Sobrien  {
75797403Sobrien    void __constraints() {
75897403Sobrien      __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
75997403Sobrien
76097403Sobrien      __c.push_front(__t);
76197403Sobrien      __c.pop_front();
76297403Sobrien    }
76397403Sobrien    _FrontInsertionSequence __c;
76497403Sobrien    typename _FrontInsertionSequence::value_type __t;
76597403Sobrien  };
76697403Sobrien
76797403Sobrien  template <class _BackInsertionSequence>
76897403Sobrien  struct _BackInsertionSequenceConcept
76997403Sobrien  {
77097403Sobrien    typedef typename _BackInsertionSequence::reference _Reference;
77197403Sobrien    typedef typename _BackInsertionSequence::const_reference _Const_reference;
77297403Sobrien
77397403Sobrien    void __constraints() {
77497403Sobrien      __function_requires< _SequenceConcept<_BackInsertionSequence> >();
77597403Sobrien
77697403Sobrien      __c.push_back(__t);
77797403Sobrien      __c.pop_back();
77897403Sobrien      _Reference __r _IsUnused = __c.back();
77997403Sobrien    }
78097403Sobrien    void __const_constraints(const _BackInsertionSequence& __c) {
78197403Sobrien      _Const_reference __r _IsUnused = __c.back();
78297403Sobrien    };
78397403Sobrien    _BackInsertionSequence __c;
78497403Sobrien    typename _BackInsertionSequence::value_type __t;
78597403Sobrien  };
78697403Sobrien
78797403Sobrien  template <class _AssociativeContainer>
78897403Sobrien  struct _AssociativeContainerConcept
78997403Sobrien  {
79097403Sobrien    void __constraints() {
79197403Sobrien      __function_requires< _ForwardContainerConcept<_AssociativeContainer> >();
79297403Sobrien      __function_requires<
79397403Sobrien        _DefaultConstructibleConcept<_AssociativeContainer> >();
794132720Skan
79597403Sobrien      __i = __c.find(__k);
79697403Sobrien      __r = __c.equal_range(__k);
79797403Sobrien      __c.erase(__k);
79897403Sobrien      __c.erase(__i);
79997403Sobrien      __c.erase(__r.first, __r.second);
80097403Sobrien      __const_constraints(__c);
80197403Sobrien    }
80297403Sobrien    void __const_constraints(const _AssociativeContainer& __c) {
80397403Sobrien      __ci = __c.find(__k);
80497403Sobrien      __n = __c.count(__k);
80597403Sobrien      __cr = __c.equal_range(__k);
80697403Sobrien    }
80797403Sobrien    typedef typename _AssociativeContainer::iterator _Iterator;
80897403Sobrien    typedef typename _AssociativeContainer::const_iterator _Const_iterator;
80997403Sobrien
81097403Sobrien    _AssociativeContainer __c;
81197403Sobrien    _Iterator __i;
81297403Sobrien    std::pair<_Iterator,_Iterator> __r;
81397403Sobrien    _Const_iterator __ci;
81497403Sobrien    std::pair<_Const_iterator,_Const_iterator> __cr;
81597403Sobrien    typename _AssociativeContainer::key_type __k;
81697403Sobrien    typename _AssociativeContainer::size_type __n;
81797403Sobrien  };
81897403Sobrien
81997403Sobrien  template <class _UniqueAssociativeContainer>
82097403Sobrien  struct _UniqueAssociativeContainerConcept
82197403Sobrien  {
82297403Sobrien    void __constraints() {
82397403Sobrien      __function_requires<
82497403Sobrien        _AssociativeContainerConcept<_UniqueAssociativeContainer> >();
825132720Skan
82697403Sobrien      _UniqueAssociativeContainer __c(__first, __last);
827132720Skan
82897403Sobrien      __pos_flag = __c.insert(__t);
82997403Sobrien      __c.insert(__first, __last);
83097403Sobrien    }
83197403Sobrien    std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag;
83297403Sobrien    typename _UniqueAssociativeContainer::value_type __t;
83397403Sobrien    typename _UniqueAssociativeContainer::value_type *__first, *__last;
83497403Sobrien  };
83597403Sobrien
83697403Sobrien  template <class _MultipleAssociativeContainer>
83797403Sobrien  struct _MultipleAssociativeContainerConcept
83897403Sobrien  {
83997403Sobrien    void __constraints() {
84097403Sobrien      __function_requires<
84197403Sobrien        _AssociativeContainerConcept<_MultipleAssociativeContainer> >();
84297403Sobrien
84397403Sobrien      _MultipleAssociativeContainer __c(__first, __last);
844132720Skan
84597403Sobrien      __pos = __c.insert(__t);
84697403Sobrien      __c.insert(__first, __last);
84797403Sobrien
84897403Sobrien    }
849132720Skan    typename _MultipleAssociativeContainer::iterator __pos;
85097403Sobrien    typename _MultipleAssociativeContainer::value_type __t;
85197403Sobrien    typename _MultipleAssociativeContainer::value_type *__first, *__last;
85297403Sobrien  };
85397403Sobrien
85497403Sobrien  template <class _SimpleAssociativeContainer>
85597403Sobrien  struct _SimpleAssociativeContainerConcept
85697403Sobrien  {
85797403Sobrien    void __constraints() {
85897403Sobrien      __function_requires<
85997403Sobrien        _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
86097403Sobrien      typedef typename _SimpleAssociativeContainer::key_type _Key_type;
86197403Sobrien      typedef typename _SimpleAssociativeContainer::value_type _Value_type;
86297403Sobrien      typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type
863132720Skan        _Required;
86497403Sobrien    }
86597403Sobrien  };
86697403Sobrien
86797403Sobrien  template <class _SimpleAssociativeContainer>
86897403Sobrien  struct _PairAssociativeContainerConcept
86997403Sobrien  {
87097403Sobrien    void __constraints() {
87197403Sobrien      __function_requires<
87297403Sobrien        _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
87397403Sobrien      typedef typename _SimpleAssociativeContainer::key_type _Key_type;
87497403Sobrien      typedef typename _SimpleAssociativeContainer::value_type _Value_type;
87597403Sobrien      typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type;
87697403Sobrien      typedef std::pair<const _Key_type, _Mapped_type> _Required_value_type;
87797403Sobrien      typedef typename _Aux_require_same<_Value_type,
87897403Sobrien        _Required_value_type>::_Type _Required;
87997403Sobrien    }
88097403Sobrien  };
88197403Sobrien
88297403Sobrien  template <class _SortedAssociativeContainer>
88397403Sobrien  struct _SortedAssociativeContainerConcept
88497403Sobrien  {
88597403Sobrien    void __constraints() {
88697403Sobrien      __function_requires<
88797403Sobrien        _AssociativeContainerConcept<_SortedAssociativeContainer> >();
88897403Sobrien      __function_requires<
88997403Sobrien        _ReversibleContainerConcept<_SortedAssociativeContainer> >();
89097403Sobrien
891132720Skan      _SortedAssociativeContainer
892132720Skan        __c _IsUnused(__kc),
893132720Skan        __c2 _IsUnused(__first, __last),
894132720Skan        __c3 _IsUnused(__first, __last, __kc);
89597403Sobrien
89697403Sobrien      __p = __c.upper_bound(__k);
89797403Sobrien      __p = __c.lower_bound(__k);
89897403Sobrien      __r = __c.equal_range(__k);
899132720Skan
90097403Sobrien      __c.insert(__p, __t);
90197403Sobrien    }
90297403Sobrien    void __const_constraints(const _SortedAssociativeContainer& __c) {
90397403Sobrien      __kc = __c.key_comp();
90497403Sobrien      __vc = __c.value_comp();
90597403Sobrien
90697403Sobrien      __cp = __c.upper_bound(__k);
90797403Sobrien      __cp = __c.lower_bound(__k);
90897403Sobrien      __cr = __c.equal_range(__k);
90997403Sobrien    }
91097403Sobrien    typename _SortedAssociativeContainer::key_compare __kc;
91197403Sobrien    typename _SortedAssociativeContainer::value_compare __vc;
91297403Sobrien    typename _SortedAssociativeContainer::value_type __t;
91397403Sobrien    typename _SortedAssociativeContainer::key_type __k;
91497403Sobrien    typedef typename _SortedAssociativeContainer::iterator _Iterator;
91597403Sobrien    typedef typename _SortedAssociativeContainer::const_iterator
91697403Sobrien      _Const_iterator;
91797403Sobrien
91897403Sobrien    _Iterator __p;
91997403Sobrien    _Const_iterator __cp;
92097403Sobrien    std::pair<_Iterator,_Iterator> __r;
92197403Sobrien    std::pair<_Const_iterator,_Const_iterator> __cr;
92297403Sobrien    typename _SortedAssociativeContainer::value_type *__first, *__last;
92397403Sobrien  };
92497403Sobrien
92597403Sobrien  // HashedAssociativeContainer
92697403Sobrien
927169691Skan_GLIBCXX_END_NAMESPACE
92897403Sobrien
92997403Sobrien#undef _IsUnused
93097403Sobrien
931132720Skan#endif // _GLIBCXX_BOOST_CONCEPT_CHECK
93297403Sobrien
93397403Sobrien
934