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;
|
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 {
|
class null_archetype {
|
||||||
private:
|
private:
|
||||||
null_archetype() { }
|
null_archetype() { }
|
||||||
@@ -28,6 +31,7 @@ namespace boost {
|
|||||||
null_archetype& operator=(const null_archetype&) { return *this; }
|
null_archetype& operator=(const null_archetype&) { return *this; }
|
||||||
public:
|
public:
|
||||||
null_archetype(detail::dummy_constructor) { }
|
null_archetype(detail::dummy_constructor) { }
|
||||||
|
template <class TT>
|
||||||
friend void dummy_friend(); // just to avoid warnings
|
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 {
|
class convertible_to_archetype : public Base {
|
||||||
public:
|
public:
|
||||||
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
|
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||||
operator const T&() const { return static_object<T>::get(); }
|
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 {
|
class boolean_archetype {
|
||||||
public:
|
public:
|
||||||
@@ -74,23 +137,7 @@ namespace boost {
|
|||||||
boolean_archetype& operator=(const boolean_archetype&) { return *this; }
|
boolean_archetype& operator=(const boolean_archetype&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Left, class Base = null_archetype>
|
template <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>
|
|
||||||
class equality_comparable_archetype : public Base {
|
class equality_comparable_archetype : public Base {
|
||||||
public:
|
public:
|
||||||
equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||||
@@ -107,25 +154,31 @@ namespace boost {
|
|||||||
{ return boolean_archetype(dummy_cons);; }
|
{ return boolean_archetype(dummy_cons);; }
|
||||||
|
|
||||||
|
|
||||||
template <class XX = null_archetype, class YY = null_archetype>
|
template <class Base = null_archetype<> >
|
||||||
class equality_comparable2_archetype {
|
class equality_comparable2_first_archetype : public Base {
|
||||||
public:
|
public:
|
||||||
friend boolean_archetype operator==(const XX& x, const YY& y) {
|
equality_comparable2_first_archetype(detail::dummy_constructor x)
|
||||||
return boolean_archetype(dummy_cons);
|
: Base(x) { }
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
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 {
|
class less_than_comparable_archetype : public Base {
|
||||||
public:
|
public:
|
||||||
less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||||
@@ -134,10 +187,11 @@ namespace boost {
|
|||||||
boolean_archetype
|
boolean_archetype
|
||||||
operator<(const less_than_comparable_archetype<Base>&,
|
operator<(const less_than_comparable_archetype<Base>&,
|
||||||
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 {
|
class comparable_archetype : public Base {
|
||||||
public:
|
public:
|
||||||
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||||
@@ -164,69 +218,79 @@ namespace boost {
|
|||||||
{ return boolean_archetype(dummy_cons);; }
|
{ return boolean_archetype(dummy_cons);; }
|
||||||
|
|
||||||
|
|
||||||
template <class XX = null_archetype, class YY = null_archetype>
|
#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
|
||||||
class comparable2_archetype {
|
template <class Base = null_archetype<> > \
|
||||||
public:
|
class NAME##_first_archetype : public Base { \
|
||||||
friend boolean_archetype operator<(const XX& x, const YY& y) {
|
public: \
|
||||||
return boolean_archetype(dummy_cons);
|
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); \
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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>
|
#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
|
||||||
class default_constructible_archetype : public Base {
|
template <class Return, class Base = null_archetype<> > \
|
||||||
public:
|
class NAME##_first_archetype : public Base { }; \
|
||||||
default_constructible_archetype() : Base(dummy_cons) { }
|
\
|
||||||
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
template <class Return, class Base = null_archetype<> > \
|
||||||
};
|
class NAME##_second_archetype : public Base { }; \
|
||||||
|
\
|
||||||
|
template <class Return, class BaseFirst, class BaseSecond> \
|
||||||
template <class Base = null_archetype>
|
Return \
|
||||||
class copy_constructible_archetype : public Base {
|
operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
|
||||||
public:
|
const NAME##_second_archetype<Return, BaseSecond>&) \
|
||||||
copy_constructible_archetype() : Base(dummy_cons) { }
|
{ \
|
||||||
copy_constructible_archetype(const copy_constructible_archetype&)
|
return Return(dummy_cons); \
|
||||||
: 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) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// The default constructor used in Return() above is bad.
|
||||||
|
|
||||||
|
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
|
// 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>
|
template <class Arg, class Return>
|
||||||
class unary_function_archetype {
|
class unary_function_archetype {
|
||||||
|
private:
|
||||||
|
unary_function_archetype() { }
|
||||||
public:
|
public:
|
||||||
|
unary_function_archetype(detail::dummy_constructor) { }
|
||||||
const Return& operator()(const Arg&) {
|
const Return& operator()(const Arg&) {
|
||||||
return static_object<Return>::get();
|
return static_object<Return>::get();
|
||||||
}
|
}
|
||||||
@@ -234,7 +298,10 @@ namespace boost {
|
|||||||
|
|
||||||
template <class Arg1, class Arg2, class Return>
|
template <class Arg1, class Arg2, class Return>
|
||||||
class binary_function_archetype {
|
class binary_function_archetype {
|
||||||
|
private:
|
||||||
|
binary_function_archetype() { }
|
||||||
public:
|
public:
|
||||||
|
binary_function_archetype(detail::dummy_constructor) { }
|
||||||
const Return& operator()(const Arg1&, const Arg2&) {
|
const Return& operator()(const Arg1&, const Arg2&) {
|
||||||
return static_object<Return>::get();
|
return static_object<Return>::get();
|
||||||
}
|
}
|
||||||
@@ -243,7 +310,9 @@ namespace boost {
|
|||||||
template <class Arg>
|
template <class Arg>
|
||||||
class unary_predicate_archetype {
|
class unary_predicate_archetype {
|
||||||
typedef boolean_archetype Return;
|
typedef boolean_archetype Return;
|
||||||
|
unary_predicate_archetype() { }
|
||||||
public:
|
public:
|
||||||
|
unary_predicate_archetype(detail::dummy_constructor) { }
|
||||||
const Return& operator()(const Arg&) {
|
const Return& operator()(const Arg&) {
|
||||||
return static_object<Return>::get();
|
return static_object<Return>::get();
|
||||||
}
|
}
|
||||||
@@ -252,7 +321,9 @@ namespace boost {
|
|||||||
template <class Arg1, class Arg2>
|
template <class Arg1, class Arg2>
|
||||||
class binary_predicate_archetype {
|
class binary_predicate_archetype {
|
||||||
typedef boolean_archetype Return;
|
typedef boolean_archetype Return;
|
||||||
|
binary_predicate_archetype() { }
|
||||||
public:
|
public:
|
||||||
|
binary_predicate_archetype(detail::dummy_constructor) { }
|
||||||
const Return& operator()(const Arg1&, const Arg2&) {
|
const Return& operator()(const Arg1&, const Arg2&) {
|
||||||
return static_object<Return>::get();
|
return static_object<Return>::get();
|
||||||
}
|
}
|
||||||
@@ -261,7 +332,9 @@ namespace boost {
|
|||||||
template <class Arg1, class Arg2>
|
template <class Arg1, class Arg2>
|
||||||
class const_binary_predicate_archetype {
|
class const_binary_predicate_archetype {
|
||||||
typedef boolean_archetype Return;
|
typedef boolean_archetype Return;
|
||||||
|
const_binary_predicate_archetype() { }
|
||||||
public:
|
public:
|
||||||
|
const_binary_predicate_archetype(detail::dummy_constructor) { }
|
||||||
const Return& operator()(const Arg1&, const Arg2&) const {
|
const Return& operator()(const Arg1&, const Arg2&) const {
|
||||||
return static_object<Return>::get();
|
return static_object<Return>::get();
|
||||||
}
|
}
|
||||||
@@ -363,26 +436,27 @@ namespace boost {
|
|||||||
self operator++(int) { return *this; }
|
self operator++(int) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct output_proxy {
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
struct output_proxy {
|
||||||
output_proxy& operator=(const T&) { return *this; }
|
output_proxy& operator=(const T&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
class output_iterator_archetype
|
class output_iterator_archetype
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef output_iterator_archetype self;
|
typedef output_iterator_archetype self;
|
||||||
public:
|
public:
|
||||||
typedef std::output_iterator_tag iterator_category;
|
typedef std::output_iterator_tag iterator_category;
|
||||||
typedef output_proxy value_type;
|
typedef output_proxy<T> value_type;
|
||||||
typedef output_proxy reference;
|
typedef output_proxy<T> reference;
|
||||||
typedef void pointer;
|
typedef void pointer;
|
||||||
typedef void difference_type;
|
typedef void difference_type;
|
||||||
output_iterator_archetype() { }
|
output_iterator_archetype() { }
|
||||||
self& operator=(const self&) { return *this; }
|
self& operator=(const self&) { return *this; }
|
||||||
bool operator==(const self&) const { return true; }
|
bool operator==(const self&) const { return true; }
|
||||||
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++() { return *this; }
|
||||||
self operator++(int) { return *this; }
|
self operator++(int) { return *this; }
|
||||||
};
|
};
|
||||||
|
@@ -35,6 +35,15 @@ void function_requires()
|
|||||||
// The BOOST_CLASS_REQUIRES macros use function pointers as
|
// The BOOST_CLASS_REQUIRES macros use function pointers as
|
||||||
// template parameters, which VC++ does not support.
|
// 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) \
|
#define BOOST_CLASS_REQUIRES(type_var, concept) \
|
||||||
typedef void (concept <type_var>::* func##type_var##concept)(); \
|
typedef void (concept <type_var>::* func##type_var##concept)(); \
|
||||||
template <func##type_var##concept _Tp1> \
|
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
|
concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
@@ -135,14 +145,13 @@ struct require_same { typedef T type; };
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Basic Concepts
|
// Basic Concepts
|
||||||
|
|
||||||
template <class X, class Y>
|
template <class TT>
|
||||||
struct ConvertibleConcept
|
struct DefaultConstructibleConcept
|
||||||
{
|
{
|
||||||
void constraints() {
|
void constraints() {
|
||||||
Y y = x;
|
TT a; // require default constructor
|
||||||
ignore_unused_variable_warning(y);
|
ignore_unused_variable_warning(a);
|
||||||
}
|
}
|
||||||
X x;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class TT>
|
template <class TT>
|
||||||
@@ -162,32 +171,6 @@ struct require_same { typedef T type; };
|
|||||||
TT a;
|
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>
|
template <class TT>
|
||||||
struct CopyConstructibleConcept
|
struct CopyConstructibleConcept
|
||||||
{
|
{
|
||||||
@@ -206,6 +189,36 @@ struct require_same { typedef T type; };
|
|||||||
TT b;
|
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
|
// The C++ standard requirements for many concepts talk about return
|
||||||
// types that must be "convertible to bool". The problem with this
|
// types that must be "convertible to bool". The problem with this
|
||||||
// requirement is that it leaves the door open for evil proxies that
|
// 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;
|
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>
|
template <class TT>
|
||||||
struct LessThanComparableConcept
|
struct LessThanComparableConcept
|
||||||
{
|
{
|
||||||
@@ -253,25 +253,11 @@ struct require_same { typedef T type; };
|
|||||||
TT a, b;
|
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.
|
// This is equivalent to SGI STL's LessThanComparable.
|
||||||
template <class TT>
|
template <class TT>
|
||||||
struct ComparableConcept
|
struct ComparableConcept
|
||||||
{
|
{
|
||||||
void constraints() {
|
void constraints() {
|
||||||
function_requires< EqualityComparableConcept<TT> >();
|
|
||||||
require_boolean_expr(a < b);
|
require_boolean_expr(a < b);
|
||||||
require_boolean_expr(a > b);
|
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;
|
TT a, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a generalization of SGI STL's LessThanComparable
|
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
|
||||||
// concept to 2 types.
|
template <class First, class Second> \
|
||||||
template <class AA, class BB>
|
struct NAME { \
|
||||||
struct Comparable2Concept
|
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() {
|
void constraints() {
|
||||||
function_requires< EqualityComparable2Concept<AA,BB> >();
|
const Return& r = f(); // require operator() member function
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
AA a;
|
Func f;
|
||||||
BB b;
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
#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
|
// Container Concepts
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user