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