forked from boostorg/concept_check
work on archetypes
[SVN r8360]
This commit is contained in:
@@ -20,7 +20,10 @@ namespace boost {
|
||||
}
|
||||
static detail::dummy_constructor dummy_cons;
|
||||
|
||||
// A type that models no concept.
|
||||
// A type that models no concept. The template parameter
|
||||
// is only there so that null_archetype types can be created
|
||||
// that have different type.
|
||||
template <class T = int>
|
||||
class null_archetype {
|
||||
private:
|
||||
null_archetype() { }
|
||||
@@ -28,6 +31,7 @@ namespace boost {
|
||||
null_archetype& operator=(const null_archetype&) { return *this; }
|
||||
public:
|
||||
null_archetype(detail::dummy_constructor) { }
|
||||
template <class TT>
|
||||
friend void dummy_friend(); // just to avoid warnings
|
||||
};
|
||||
|
||||
@@ -57,12 +61,71 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Base = null_archetype>
|
||||
template <class Base = null_archetype<> >
|
||||
class default_constructible_archetype : public Base {
|
||||
public:
|
||||
default_constructible_archetype() : Base(dummy_cons) { }
|
||||
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class assignable_archetype : public Base {
|
||||
assignable_archetype() { }
|
||||
assignable_archetype(const assignable_archetype&) { }
|
||||
public:
|
||||
assignable_archetype& operator=(const assignable_archetype&) {
|
||||
return *this;
|
||||
}
|
||||
assignable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class copy_constructible_archetype : public Base {
|
||||
public:
|
||||
copy_constructible_archetype() : Base(dummy_cons) { }
|
||||
copy_constructible_archetype(const copy_constructible_archetype&)
|
||||
: Base(dummy_cons) { }
|
||||
copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class sgi_assignable_archetype : public Base {
|
||||
public:
|
||||
sgi_assignable_archetype(const sgi_assignable_archetype&)
|
||||
: Base(dummy_cons) { }
|
||||
sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
|
||||
return *this;
|
||||
}
|
||||
sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
|
||||
};
|
||||
|
||||
#if 0
|
||||
// Careful, don't use same type for T and Base. That
|
||||
// results in the conversion operator being invalid.
|
||||
template <class T, class Base = null_archetype<> >
|
||||
class convertible_to_archetype : public Base {
|
||||
public:
|
||||
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
operator const T&() const { return static_object<T>::get(); }
|
||||
};
|
||||
#else
|
||||
|
||||
struct default_archetype_base {
|
||||
default_archetype_base(detail::dummy_constructor x) { }
|
||||
};
|
||||
|
||||
template <class T, class Base = default_archetype_base>
|
||||
class convertible_to_archetype : public Base {
|
||||
private:
|
||||
convertible_to_archetype() { }
|
||||
convertible_to_archetype(const convertible_to_archetype& ) { }
|
||||
convertible_to_archetype& operator=(const convertible_to_archetype&)
|
||||
{ return *this; }
|
||||
public:
|
||||
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
operator const T&() const { return static_object<T>::get(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
class boolean_archetype {
|
||||
public:
|
||||
@@ -74,23 +137,7 @@ namespace boost {
|
||||
boolean_archetype& operator=(const boolean_archetype&) { return *this; }
|
||||
};
|
||||
|
||||
template <class Left, class Base = null_archetype>
|
||||
class left_equality_comparable_archetype : public Base {
|
||||
public:
|
||||
left_equality_comparable_archetype(detail::dummy_constructor x)
|
||||
: Base(x) { }
|
||||
};
|
||||
template <class Left>
|
||||
boolean_archetype
|
||||
operator==(const Left&, const left_equality_comparable_archetype<Left>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Left>
|
||||
boolean_archetype
|
||||
operator!=(const Left&, const left_equality_comparable_archetype<Left>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
template <class Base = null_archetype>
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable_archetype : public Base {
|
||||
public:
|
||||
equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
@@ -107,25 +154,31 @@ namespace boost {
|
||||
{ return boolean_archetype(dummy_cons);; }
|
||||
|
||||
|
||||
template <class XX = null_archetype, class YY = null_archetype>
|
||||
class equality_comparable2_archetype {
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable2_first_archetype : public Base {
|
||||
public:
|
||||
friend boolean_archetype operator==(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator!=(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator==(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator!=(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
equality_comparable2_first_archetype(detail::dummy_constructor x)
|
||||
: Base(x) { }
|
||||
};
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable2_second_archetype : public Base {
|
||||
public:
|
||||
equality_comparable2_second_archetype(detail::dummy_constructor x)
|
||||
: Base(x) { }
|
||||
};
|
||||
template <class Base1, class Base2>
|
||||
boolean_archetype
|
||||
operator==(const equality_comparable2_first_archetype<Base1>&,
|
||||
const equality_comparable2_second_archetype<Base2>&)
|
||||
{ return boolean_archetype(dummy_cons);; }
|
||||
template <class Base1, class Base2>
|
||||
boolean_archetype
|
||||
operator!=(const equality_comparable2_first_archetype<Base1>&,
|
||||
const equality_comparable2_second_archetype<Base2>&)
|
||||
{ return boolean_archetype(dummy_cons);; }
|
||||
|
||||
|
||||
template <class Base = null_archetype>
|
||||
template <class Base = null_archetype<> >
|
||||
class less_than_comparable_archetype : public Base {
|
||||
public:
|
||||
less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
@@ -134,10 +187,11 @@ namespace boost {
|
||||
boolean_archetype
|
||||
operator<(const less_than_comparable_archetype<Base>&,
|
||||
const less_than_comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons);; }
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
template <class Base = null_archetype>
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class comparable_archetype : public Base {
|
||||
public:
|
||||
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
@@ -164,69 +218,79 @@ namespace boost {
|
||||
{ return boolean_archetype(dummy_cons);; }
|
||||
|
||||
|
||||
template <class XX = null_archetype, class YY = null_archetype>
|
||||
class comparable2_archetype {
|
||||
public:
|
||||
friend boolean_archetype operator<(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator<=(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator>(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator>=(const XX& x, const YY& y) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator<(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator<=(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator>(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
friend boolean_archetype operator>=(const YY& y, const XX& x) {
|
||||
return boolean_archetype(dummy_cons);
|
||||
}
|
||||
};
|
||||
#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
|
||||
template <class Base = null_archetype<> > \
|
||||
class NAME##_first_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class Base = null_archetype<> > \
|
||||
class NAME##_second_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class BaseFirst, class BaseSecond> \
|
||||
boolean_archetype \
|
||||
operator OP (const NAME##_first_archetype<BaseFirst>&, \
|
||||
const NAME##_second_archetype<BaseSecond>&) \
|
||||
{ \
|
||||
return boolean_archetype(dummy_cons); \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
|
||||
|
||||
template <class Base = null_archetype>
|
||||
class default_constructible_archetype : public Base {
|
||||
public:
|
||||
default_constructible_archetype() : Base(dummy_cons) { }
|
||||
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
|
||||
template <class Return, class Base = null_archetype<> > \
|
||||
class NAME##_first_archetype : public Base { }; \
|
||||
\
|
||||
template <class Return, class Base = null_archetype<> > \
|
||||
class NAME##_second_archetype : public Base { }; \
|
||||
\
|
||||
template <class Return, class BaseFirst, class BaseSecond> \
|
||||
Return \
|
||||
operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
|
||||
const NAME##_second_archetype<Return, BaseSecond>&) \
|
||||
{ \
|
||||
return Return(dummy_cons); \
|
||||
}
|
||||
|
||||
// The default constructor used in Return() above is bad.
|
||||
|
||||
template <class Base = null_archetype>
|
||||
class copy_constructible_archetype : public Base {
|
||||
public:
|
||||
copy_constructible_archetype() : Base(dummy_cons) { }
|
||||
copy_constructible_archetype(const copy_constructible_archetype&)
|
||||
: Base(dummy_cons) { }
|
||||
copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype>
|
||||
class assignable_archetype : public Base {
|
||||
public:
|
||||
assignable_archetype& operator=(const assignable_archetype&) {
|
||||
return *this;
|
||||
}
|
||||
assignable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
|
||||
|
||||
//===========================================================================
|
||||
// Function Object Archetype Classes
|
||||
|
||||
template <class Return>
|
||||
class generator_archetype {
|
||||
public:
|
||||
const Return& operator()() {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
class void_generator_archetype {
|
||||
public:
|
||||
void operator()() { }
|
||||
};
|
||||
|
||||
template <class Arg, class Return>
|
||||
class unary_function_archetype {
|
||||
private:
|
||||
unary_function_archetype() { }
|
||||
public:
|
||||
unary_function_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
@@ -234,7 +298,10 @@ namespace boost {
|
||||
|
||||
template <class Arg1, class Arg2, class Return>
|
||||
class binary_function_archetype {
|
||||
private:
|
||||
binary_function_archetype() { }
|
||||
public:
|
||||
binary_function_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
@@ -243,7 +310,9 @@ namespace boost {
|
||||
template <class Arg>
|
||||
class unary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
unary_predicate_archetype() { }
|
||||
public:
|
||||
unary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
@@ -252,7 +321,9 @@ namespace boost {
|
||||
template <class Arg1, class Arg2>
|
||||
class binary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
binary_predicate_archetype() { }
|
||||
public:
|
||||
binary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
@@ -261,7 +332,9 @@ namespace boost {
|
||||
template <class Arg1, class Arg2>
|
||||
class const_binary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
const_binary_predicate_archetype() { }
|
||||
public:
|
||||
const_binary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) const {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
@@ -363,26 +436,27 @@ namespace boost {
|
||||
self operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct output_proxy {
|
||||
template <class T>
|
||||
output_proxy& operator=(const T&) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class output_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef output_iterator_archetype self;
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef output_proxy value_type;
|
||||
typedef output_proxy reference;
|
||||
typedef output_proxy<T> value_type;
|
||||
typedef output_proxy<T> reference;
|
||||
typedef void pointer;
|
||||
typedef void difference_type;
|
||||
output_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return output_proxy(); }
|
||||
reference operator*() const { return output_proxy<T>(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
};
|
||||
|
@@ -35,6 +35,15 @@ void function_requires()
|
||||
// The BOOST_CLASS_REQUIRES macros use function pointers as
|
||||
// template parameters, which VC++ does not support.
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_PTR_TEMPLATE_PARAMETERS)
|
||||
|
||||
#define BOOST_CLASS_REQUIRES(type_var, concept)
|
||||
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept)
|
||||
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept)
|
||||
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept)
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CLASS_REQUIRES(type_var, concept) \
|
||||
typedef void (concept <type_var>::* func##type_var##concept)(); \
|
||||
template <func##type_var##concept _Tp1> \
|
||||
@@ -68,6 +77,7 @@ void function_requires()
|
||||
concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U>
|
||||
@@ -135,14 +145,13 @@ struct require_same { typedef T type; };
|
||||
//===========================================================================
|
||||
// Basic Concepts
|
||||
|
||||
template <class X, class Y>
|
||||
struct ConvertibleConcept
|
||||
template <class TT>
|
||||
struct DefaultConstructibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
Y y = x;
|
||||
ignore_unused_variable_warning(y);
|
||||
TT a; // require default constructor
|
||||
ignore_unused_variable_warning(a);
|
||||
}
|
||||
X x;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
@@ -162,32 +171,6 @@ struct require_same { typedef T type; };
|
||||
TT a;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct AssignableSGIConcept
|
||||
{
|
||||
void constraints() {
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = a; // require assignment operator
|
||||
#endif
|
||||
const_constraints(a);
|
||||
}
|
||||
void const_constraints(const TT& b) {
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = b; // const required for argument to assignment
|
||||
#endif
|
||||
}
|
||||
TT a;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct DefaultConstructibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
TT a; // require default constructor
|
||||
ignore_unused_variable_warning(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct CopyConstructibleConcept
|
||||
{
|
||||
@@ -206,6 +189,36 @@ struct require_same { typedef T type; };
|
||||
TT b;
|
||||
};
|
||||
|
||||
// The SGI STL version of Assignable requires copy constructor and operator=
|
||||
template <class TT>
|
||||
struct SGIAssignableConcept
|
||||
{
|
||||
void constraints() {
|
||||
TT b(a);
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = a; // require assignment operator
|
||||
#endif
|
||||
const_constraints(a);
|
||||
}
|
||||
void const_constraints(const TT& b) {
|
||||
TT c(b);
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = b; // const required for argument to assignment
|
||||
#endif
|
||||
}
|
||||
TT a;
|
||||
};
|
||||
|
||||
template <class X, class Y>
|
||||
struct ConvertibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
Y y = x;
|
||||
ignore_unused_variable_warning(y);
|
||||
}
|
||||
X 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
|
||||
@@ -231,19 +244,6 @@ struct require_same { typedef T type; };
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
template <class AA, class BB>
|
||||
struct EqualityComparable2Concept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(a == b);
|
||||
require_boolean_expr(b == a);
|
||||
require_boolean_expr(a != b);
|
||||
require_boolean_expr(b != a);
|
||||
}
|
||||
AA a;
|
||||
BB b;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct LessThanComparableConcept
|
||||
{
|
||||
@@ -253,25 +253,11 @@ struct require_same { typedef T type; };
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
template <class AA, class BB>
|
||||
struct LessThanComparable2Concept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< LessThanComparableConcept<AA> >();
|
||||
function_requires< LessThanComparableConcept<BB> >();
|
||||
require_boolean_expr(a < b);
|
||||
require_boolean_expr(b < a);
|
||||
}
|
||||
AA a;
|
||||
BB b;
|
||||
};
|
||||
|
||||
// This is equivalent to SGI STL's LessThanComparable.
|
||||
template <class TT>
|
||||
struct ComparableConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< EqualityComparableConcept<TT> >();
|
||||
require_boolean_expr(a < b);
|
||||
require_boolean_expr(a > b);
|
||||
require_boolean_expr(a <= b);
|
||||
@@ -280,26 +266,146 @@ struct require_same { typedef T type; };
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
// This is a generalization of SGI STL's LessThanComparable
|
||||
// concept to 2 types.
|
||||
template <class AA, class BB>
|
||||
struct Comparable2Concept
|
||||
#define BOOST_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 BOOST_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; \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
|
||||
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
|
||||
|
||||
//===========================================================================
|
||||
// Function Object Concepts
|
||||
|
||||
template <class Func, class Return>
|
||||
struct GeneratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< EqualityComparable2Concept<AA,BB> >();
|
||||
function_requires< ComparableConcept<AA> >();
|
||||
function_requires< ComparableConcept<BB> >();
|
||||
require_boolean_expr(a < b);
|
||||
require_boolean_expr(b < a);
|
||||
require_boolean_expr(a > b);
|
||||
require_boolean_expr(b > a);
|
||||
require_boolean_expr(a <= b);
|
||||
require_boolean_expr(b <= a);
|
||||
require_boolean_expr(a >= b);
|
||||
require_boolean_expr(b >= a);
|
||||
const Return& r = f(); // require operator() member function
|
||||
}
|
||||
AA a;
|
||||
BB b;
|
||||
Func f;
|
||||
};
|
||||
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func>
|
||||
struct GeneratorConcept<Func,void>
|
||||
{
|
||||
void constraints() {
|
||||
f(); // require operator() member function
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Return, class Arg>
|
||||
struct UnaryFunctionConcept
|
||||
{
|
||||
void constraints() {
|
||||
r = f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
Return r;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func, class Arg>
|
||||
struct UnaryFunctionConcept<Func, void, Arg> {
|
||||
void constraints() {
|
||||
f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
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;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Arg>
|
||||
struct UnaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(arg)); // require operator() returning bool
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
};
|
||||
|
||||
template <class Func, class First, class Second>
|
||||
struct BinaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(a, b)); // require operator() 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
|
||||
require_boolean_expr(fun(a, b));
|
||||
}
|
||||
Func f;
|
||||
First a;
|
||||
Second b;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
@@ -465,149 +571,6 @@ struct require_same { typedef T type; };
|
||||
#endif
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Function Object Concepts
|
||||
|
||||
template <class Func, class Return>
|
||||
struct GeneratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
r = f(); // require operator() member function
|
||||
}
|
||||
Func f;
|
||||
Return r;
|
||||
};
|
||||
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func>
|
||||
struct GeneratorConcept<Func,void>
|
||||
{
|
||||
void constraints() {
|
||||
f(); // require operator() member function
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Return, class Arg>
|
||||
struct UnaryFunctionConcept
|
||||
{
|
||||
void constraints() {
|
||||
r = f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
Return r;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func, class Arg>
|
||||
struct UnaryFunctionConcept<Func, void, Arg> {
|
||||
void constraints() {
|
||||
f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
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;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Arg>
|
||||
struct UnaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(arg)); // require operator() returning bool
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
};
|
||||
|
||||
template <class Func, class First, class Second>
|
||||
struct BinaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(a, b)); // require operator() 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
|
||||
require_boolean_expr(fun(a, b));
|
||||
}
|
||||
Func f;
|
||||
First a;
|
||||
Second b;
|
||||
};
|
||||
|
||||
#define BOOST_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 BOOST_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; \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
|
||||
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
|
||||
|
||||
//===========================================================================
|
||||
// Container Concepts
|
||||
|
||||
|
Reference in New Issue
Block a user