📄 boost_concept_check.h
字号:
//// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,// sell and distribute this software is granted provided this// copyright notice appears in all copies. This software is provided// "as is" without express or implied warranty, and with no claim as// to its suitability for any purpose.//// GCC Note: based on version 1.12.0 of the Boost library./** @file boost_concept_check.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */#ifndef _GLIBCPP_BOOST_CONCEPT_CHECK#define _GLIBCPP_BOOST_CONCEPT_CHECK 1#pragma GCC system_header#include <cstddef> // for ptrdiff_t, used next#include <bits/stl_iterator_base_types.h> // for traits and tags#include <utility> // for pair<>namespace __gnu_cxx{#define _IsUnused __attribute__ ((__unused__))// When the C-C code is in use, we would like this function to do as little// as possible at runtime, use as few resources as possible, and hopefully// be elided out of existence... hmmm.template <class _Concept>inline void __function_requires(){ void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;}// ??? Should the "concept_checking*" structs begin with more than _ ?#define _GLIBCPP_CLASS_REQUIRES(_type_var, _ns, _concept) \ typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ template <_func##_type_var##_concept _Tp1> \ struct _concept_checking##_type_var##_concept { }; \ typedef _concept_checking##_type_var##_concept< \ &_ns::_concept <_type_var>::__constraints> \ _concept_checking_typedef##_type_var##_concept#define _GLIBCPP_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ template <_func##_type_var1##_type_var2##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_concept< \ &_ns::_concept <_type_var1,_type_var2>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_concept#define _GLIBCPP_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept#define _GLIBCPP_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concepttemplate <class _Tp1, class _Tp2>struct _Aux_require_same { };template <class _Tp>struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Tp1, class _Tp2> struct _SameTypeConcept { void __constraints() { typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; } }; template <class _Tp> struct _IntegerConcept { void __constraints() { __error_type_must_be_an_integer_type(); } }; template <> struct _IntegerConcept<short> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned short> { void __constraints(){} }; template <> struct _IntegerConcept<int> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned int> { void __constraints() {} }; template <> struct _IntegerConcept<long> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned long> { void __constraints() {} }; template <> struct _IntegerConcept<long long> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned long long> { void __constraints() {} }; template <class _Tp> struct _SignedIntegerConcept { void __constraints() { __error_type_must_be_a_signed_integer_type(); } }; template <> struct _SignedIntegerConcept<short> { void __constraints() {} }; template <> struct _SignedIntegerConcept<int> { void __constraints() {} }; template <> struct _SignedIntegerConcept<long> { void __constraints() {} }; template <> struct _SignedIntegerConcept<long long> { void __constraints(){}}; template <class _Tp> struct _UnsignedIntegerConcept { void __constraints() { __error_type_must_be_an_unsigned_integer_type(); } }; template <> struct _UnsignedIntegerConcept<unsigned short> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned int> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned long> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned long long> { void __constraints() {} }; //=========================================================================== // Basic Concepts template <class _Tp> struct _DefaultConstructibleConcept { void __constraints() { _Tp __a _IsUnused; // require default constructor } }; template <class _Tp> struct _AssignableConcept { void __constraints() { __a = __a; // require assignment operator __const_constraints(__a); } void __const_constraints(const _Tp& __b) { __a = __b; // const required for argument to assignment } _Tp __a; // possibly should be "Tp* a;" and then dereference "a" in constraint // functions? present way would require a default ctor, i think... }; template <class _Tp> struct _CopyConstructibleConcept { void __constraints() { _Tp __a(__b); // require copy constructor _Tp* __ptr _IsUnused = &__a; // require address of operator __const_constraints(__a); } void __const_constraints(const _Tp& __a) { _Tp __c(__a) _IsUnused; // require const copy constructor const _Tp* __ptr _IsUnused = &__a; // require const address of operator } _Tp __b; }; // The SGI STL version of Assignable requires copy constructor and operator= template <class _Tp> struct _SGIAssignableConcept { void __constraints() { _Tp __b(__a) _IsUnused; __a = __a; // require assignment operator __const_constraints(__a); } void __const_constraints(const _Tp& __b) { _Tp __c(__b) _IsUnused; __a = __b; // const required for argument to assignment } _Tp __a; }; template <class _From, class _To> struct _ConvertibleConcept { void __constraints() { _To __y _IsUnused = __x; } _From __x; }; // The C++ standard requirements for many concepts talk about return // types that must be "convertible to bool". The problem with this // requirement is that it leaves the door open for evil proxies that // define things like operator|| with strange return types. Two // possible solutions are: // 1) require the return type to be exactly bool // 2) stay with convertible to bool, and also // specify stuff about all the logical operators. // For now we just test for convertible to bool. template <class _Tp> void __aux_require_boolean_expr(const _Tp& __t) { bool __x _IsUnused = __t; }// FIXME template <class _Tp> struct _EqualityComparableConcept { void __constraints() { __aux_require_boolean_expr(__a == __b); __aux_require_boolean_expr(__a != __b); } _Tp __a, __b; }; template <class _Tp> struct _LessThanComparableConcept { void __constraints() { __aux_require_boolean_expr(__a < __b); } _Tp __a, __b; }; // This is equivalent to SGI STL's LessThanComparable. template <class _Tp> struct _ComparableConcept { void __constraints() { __aux_require_boolean_expr(__a < __b); __aux_require_boolean_expr(__a > __b); __aux_require_boolean_expr(__a <= __b); __aux_require_boolean_expr(__a >= __b); } _Tp __a, __b; };#define _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ template <class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ bool __constraints_() { \ return __a _OP __b; \ } \ _First __a; \ _Second __b; \ }#define _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ template <class _Ret, class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ _Ret __constraints_() { \ return __a _OP __b; \ } \ _First __a; \ _Second __b; \ } _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);#undef _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT#undef _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT //=========================================================================== // Function Object Concepts template <class _Func, class _Return> struct _GeneratorConcept { void __constraints() { const _Return& __r _IsUnused = __f();// require operator() member function } _Func __f; }; template <class _Func> struct _GeneratorConcept<_Func,void> { void __constraints() { __f(); // require operator() member function } _Func __f; }; template <class _Func, class _Return, class _Arg> struct _UnaryFunctionConcept { void __constraints() { __r = __f(__arg); // require operator() } _Func __f; _Arg __arg; _Return __r; }; template <class _Func, class _Arg> struct _UnaryFunctionConcept<_Func, void, _Arg> { void __constraints() { __f(__arg); // require operator() } _Func __f; _Arg __arg; }; template <class _Func, class _Return, class _First, class _Second> struct _BinaryFunctionConcept { void __constraints() { __r = __f(__first, __second); // require operator() } _Func __f; _First __first; _Second __second; _Return __r; }; template <class _Func, class _First, class _Second> struct _BinaryFunctionConcept<_Func, void, _First, _Second> { void __constraints() { __f(__first, __second); // require operator() } _Func __f; _First __first; _Second __second; }; template <class _Func, class _Arg> struct _UnaryPredicateConcept { void __constraints() { __aux_require_boolean_expr(__f(__arg)); // require op() returning bool } _Func __f; _Arg __arg; }; template <class _Func, class _First, class _Second> struct _BinaryPredicateConcept { void __constraints() { __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool } _Func __f; _First __a; _Second __b; }; // use this when functor is used inside a container class like std::set template <class _Func, class _First, class _Second> struct _Const_BinaryPredicateConcept { void __constraints() { __const_constraints(__f); } void __const_constraints(const _Func& __fun) { __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); // operator() must be a const member function __aux_require_boolean_expr(__fun(__a, __b)); } _Func __f; _First __a; _Second __b; }; //=========================================================================== // Iterator Concepts template <class _Tp> struct _TrivialIteratorConcept { void __constraints() { __function_requires< _DefaultConstructibleConcept<_Tp> >(); __function_requires< _AssignableConcept<_Tp> >(); __function_requires< _EqualityComparableConcept<_Tp> >();// typedef typename std::iterator_traits<_Tp>::value_type _V; (void)*__i; // require dereference operator } _Tp __i; }; template <class _Tp> struct _Mutable_TrivialIteratorConcept { void __constraints() { __function_requires< _TrivialIteratorConcept<_Tp> >(); *__i = *__j; // require dereference and assignment } _Tp __i, __j; }; template <class _Tp> struct _InputIteratorConcept { void __constraints() { __function_requires< _TrivialIteratorConcept<_Tp> >(); // require iterator_traits typedef's typedef typename std::iterator_traits<_Tp>::difference_type _D;// __function_requires< _SignedIntegerConcept<_D> >(); typedef typename std::iterator_traits<_Tp>::reference _R; typedef typename std::iterator_traits<_Tp>::pointer _Pt; typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::input_iterator_tag> >(); ++__i; // require preincrement operator __i++; // require postincrement operator } _Tp __i; }; template <class _Tp, class _ValueT> struct _OutputIteratorConcept { void __constraints() { __function_requires< _AssignableConcept<_Tp> >(); ++__i; // require preincrement operator __i++; // require postincrement operator *__i++ = __t; // require postincrement and assignment } _Tp __i; _ValueT __t; }; template <class _Tp> struct _ForwardIteratorConcept { void __constraints() { __function_requires< _InputIteratorConcept<_Tp> >(); __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::forward_iterator_tag> >(); typedef typename std::iterator_traits<_Tp>::reference _R; _R __r _IsUnused = *__i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -