work on archetypes

[SVN r8360]
This commit is contained in:
Jeremy Siek
2000-11-30 02:54:39 +00:00
parent 92306b4a19
commit 35852aace9
2 changed files with 347 additions and 310 deletions

View File

@@ -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; }
};

View File

@@ -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