📄 boost_concept_check.h
字号:
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
// (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 _BOOST_CONCEPT_CHECK_H
#define _BOOST_CONCEPT_CHECK_H 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;
}
// No definition: if this is referenced, there's a problem with
// the instantiating type not being one of the required integer types.
// Unfortunately, this results in a link-time error, not a compile-time error.
void __error_type_must_be_an_integer_type();
void __error_type_must_be_an_unsigned_integer_type();
void __error_type_must_be_a_signed_integer_type();
// ??? Should the "concept_checking*" structs begin with more than _ ?
#define _GLIBCXX_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 _GLIBCXX_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 _GLIBCXX_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 _GLIBCXX_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##_concept
template <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 _IsUnused(__a); // 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 _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__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);
}
_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 _GLIBCXX_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 _GLIBCXX_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; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -