//
-// (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.
+// (C) Copyright Jeremy Siek 2000.
+// Copyright 2002 The Trustees of Indiana University.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
//
// Revision History:
// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
// See http://www.boost.org/libs/concept_check for documentation.
#ifndef BOOST_CONCEPT_CHECKS_HPP
-#define BOOST_CONCEPT_CHECKS_HPP
+# define BOOST_CONCEPT_CHECKS_HPP
-#include <boost/config.hpp>
-#include <boost/iterator.hpp>
-#include <boost/type_traits/conversion_traits.hpp>
-#include <utility>
-#include <boost/type_traits/conversion_traits.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type.hpp>
+# include <boost/concept/assert.hpp>
+# include <boost/iterator.hpp>
+# include <boost/type_traits/conversion_traits.hpp>
+# include <utility>
+# include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_void.hpp>
+# include <boost/mpl/assert.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/detail/workaround.hpp>
+# include <boost/detail/iterator.hpp>
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__BORLANDC__)
-#define BOOST_FPTR
-#else
-#define BOOST_FPTR &
-#endif
+# include <boost/concept/usage.hpp>
+# include <boost/concept/detail/concept_def.hpp>
-namespace boost {
+namespace boost
+{
-/*
- "inline" is used for ignore_unused_variable_warning()
- and function_requires() to make sure there is no
- overhead with g++.
- */
+ //
+ // Backward compatibility
+ //
-template <class T> inline void ignore_unused_variable_warning(const T&) { }
+ template <class Model>
+ inline void function_requires(Model* = 0)
+ {
+ BOOST_CONCEPT_ASSERT((Model));
+ }
+ template <class T> inline void ignore_unused_variable_warning(T const&) {}
-// the unused, defaulted parameter is a workaround for MSVC and Compaq C++
-template <class Concept>
-inline void function_requires(type<Concept>* = 0)
-{
-#if !defined(NDEBUG)
- void (Concept::*x)() = BOOST_FPTR Concept::constraints;
- ignore_unused_variable_warning(x);
-#endif
-}
-
-#define BOOST_CLASS_REQUIRE(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< \
- BOOST_FPTR ns::concept<type_var>::constraints> \
- concept_checking_typedef_##type_var##concept
-
-#define BOOST_CLASS_REQUIRE2(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< \
- BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
- concept_checking_typedef_##type_var1##type_var2##concept
-
-#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
- typedef void (ns::concept <tv1,tv2,tv3>::* \
- func##tv1##tv2##tv3##concept)(); \
- template <func##tv1##tv2##tv3##concept _Tp1> \
- struct concept_checking_##tv1##tv2##tv3##concept { }; \
- typedef concept_checking_##tv1##tv2##tv3##concept< \
- BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
- concept_checking_typedef_##tv1##tv2##tv3##concept
-
-#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
- typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
- func##tv1##tv2##tv3##tv4##concept)(); \
- template <func##tv1##tv2##tv3##tv4##concept _Tp1> \
- struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
- typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
- BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
- concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
-
-// NOTE: The BOOST_CLASS_REQUIRES (with an 'S' at the end) is deprecated.
-
-// 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)
+# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
-#else
+# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
-#define BOOST_CLASS_REQUIRES(type_var, concept) \
- typedef void (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< \
- BOOST_FPTR concept <type_var>::constraints> \
- concept_checking_typedef_##type_var##concept
-
-#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
- typedef void (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< \
- BOOST_FPTR concept <type_var1,type_var2>::constraints> \
- concept_checking_typedef_##type_var1##type_var2##concept
-
-#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
- typedef void (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< \
- BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints> \
- concept_checking_typedef_##type_var1##type_var2##type_var3##concept
-
-#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
- typedef void (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< \
- BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints> \
- concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
+# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
+# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
-#endif
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-template <class T, class U>
-struct require_same { };
+ //
+ // Begin concept definitions
+ //
+ BOOST_concept(Integer, (T))
+ {
+ BOOST_CONCEPT_USAGE(Integer)
+ {
+ x.error_type_must_be_an_integer_type();
+ }
+ private:
+ T x;
+ };
-template <class T>
-struct require_same<T,T> { typedef T type; };
-#else
-// This version does not perform checking, but will not do any harm.
-template <class T, class U>
-struct require_same { typedef T type; };
-#endif
+ template <> struct Integer<char> {};
+ template <> struct Integer<signed char> {};
+ template <> struct Integer<unsigned char> {};
+ template <> struct Integer<short> {};
+ template <> struct Integer<unsigned short> {};
+ template <> struct Integer<int> {};
+ template <> struct Integer<unsigned int> {};
+ template <> struct Integer<long> {};
+ template <> struct Integer<unsigned long> {};
+# if defined(BOOST_HAS_LONG_LONG)
+ template <> struct Integer< ::boost::long_long_type> {};
+ template <> struct Integer< ::boost::ulong_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct Integer<__int64> {};
+ template <> struct Integer<unsigned __int64> {};
+# endif
- template <class T>
- struct IntegerConcept {
- void constraints() {
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- x.error_type_must_be_an_integer_type();
-#endif
- }
- T x;
- };
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- 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() {} };
- // etc.
-#endif
-
- template <class T>
- struct SignedIntegerConcept {
- void constraints() {
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ BOOST_concept(SignedInteger,(T)) {
+ BOOST_CONCEPT_USAGE(SignedInteger) {
x.error_type_must_be_a_signed_integer_type();
-#endif
}
+ private:
T x;
};
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template <> struct SignedIntegerConcept<short> { void constraints() {} };
- template <> struct SignedIntegerConcept<int> { void constraints() {} };
- template <> struct SignedIntegerConcept<long> { void constraints() {} };
+ template <> struct SignedInteger<signed char> { };
+ template <> struct SignedInteger<short> {};
+ template <> struct SignedInteger<int> {};
+ template <> struct SignedInteger<long> {};
# if defined(BOOST_HAS_LONG_LONG)
- template <> struct SignedIntegerConcept<long long> { void constraints() {} };
+ template <> struct SignedInteger< ::boost::long_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct SignedInteger<__int64> {};
# endif
- // etc.
-#endif
- template <class T>
- struct UnsignedIntegerConcept {
- void constraints() {
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ BOOST_concept(UnsignedInteger,(T)) {
+ BOOST_CONCEPT_USAGE(UnsignedInteger) {
x.error_type_must_be_an_unsigned_integer_type();
-#endif
}
+ private:
T x;
};
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template <> struct UnsignedIntegerConcept<unsigned short>
- { void constraints() {} };
- template <> struct UnsignedIntegerConcept<unsigned int>
- { void constraints() {} };
- template <> struct UnsignedIntegerConcept<unsigned long>
- { void constraints() {} };
- // etc.
-#endif
+
+ template <> struct UnsignedInteger<unsigned char> {};
+ template <> struct UnsignedInteger<unsigned short> {};
+ template <> struct UnsignedInteger<unsigned int> {};
+ template <> struct UnsignedInteger<unsigned long> {};
+# if defined(BOOST_HAS_LONG_LONG)
+ template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct UnsignedInteger<unsigned __int64> {};
+# endif
//===========================================================================
// Basic Concepts
- template <class TT>
- struct DefaultConstructibleConcept
+ BOOST_concept(DefaultConstructible,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(DefaultConstructible) {
TT a; // require default constructor
ignore_unused_variable_warning(a);
}
};
- template <class TT>
- struct AssignableConcept
+ BOOST_concept(Assignable,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(Assignable) {
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
- a = a; // require assignment operator
+ a = b; // require assignment operator
#endif
- const_constraints(a);
+ const_constraints(b);
}
- void const_constraints(const TT& b) {
+ private:
+ void const_constraints(const TT& x) {
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
- a = b; // const required for argument to assignment
+ a = x; // const required for argument to assignment
+#else
+ ignore_unused_variable_warning(x);
#endif
}
+ private:
TT a;
+ TT b;
};
- template <class TT>
- struct CopyConstructibleConcept
+
+ BOOST_concept(CopyConstructible,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(CopyConstructible) {
TT a(b); // require copy constructor
TT* ptr = &a; // require address of operator
const_constraints(a);
ignore_unused_variable_warning(ptr);
}
+ private:
void const_constraints(const TT& a) {
TT c(a); // require const copy constructor
const TT* ptr = &a; // require const address of operator
TT b;
};
+#if (defined _MSC_VER)
+# pragma warning( push )
+# pragma warning( disable : 4510 ) // default constructor could not be generated
+# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
+#endif
// The SGI STL version of Assignable requires copy constructor and operator=
- template <class TT>
- struct SGIAssignableConcept
+ BOOST_concept(SGIAssignable,(TT))
{
- void constraints() {
- TT b(a);
+ BOOST_CONCEPT_USAGE(SGIAssignable) {
+ TT c(a);
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
- a = a; // require assignment operator
+ a = b; // require assignment operator
#endif
- const_constraints(a);
- ignore_unused_variable_warning(b);
+ const_constraints(b);
+ ignore_unused_variable_warning(c);
}
- void const_constraints(const TT& b) {
- TT c(b);
+ private:
+ void const_constraints(const TT& x) {
+ TT c(x);
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
- a = b; // const required for argument to assignment
+ a = x; // const required for argument to assignment
#endif
ignore_unused_variable_warning(c);
}
TT a;
+ TT b;
};
+#if (defined _MSC_VER)
+# pragma warning( pop )
+#endif
- template <class X, class Y>
- struct ConvertibleConcept
+ BOOST_concept(Convertible,(X)(Y))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(Convertible) {
Y y = x;
ignore_unused_variable_warning(y);
}
+ private:
X x;
};
ignore_unused_variable_warning(x);
}
- template <class TT>
- struct EqualityComparableConcept
+ BOOST_concept(EqualityComparable,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(EqualityComparable) {
require_boolean_expr(a == b);
require_boolean_expr(a != b);
}
+ private:
TT a, b;
};
- template <class TT>
- struct LessThanComparableConcept
+ BOOST_concept(LessThanComparable,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(LessThanComparable) {
require_boolean_expr(a < b);
}
+ private:
TT a, b;
};
// This is equivalent to SGI STL's LessThanComparable.
- template <class TT>
- struct ComparableConcept
+ BOOST_concept(Comparable,(TT))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(Comparable) {
require_boolean_expr(a < b);
require_boolean_expr(a > b);
require_boolean_expr(a <= b);
require_boolean_expr(a >= b);
}
+ private:
TT a, 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_PREDICATE_OP_CONSTRAINT(OP,NAME) \
+ BOOST_concept(NAME, (First)(Second)) \
+ { \
+ BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
+ private: \
+ 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; \
+#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
+ BOOST_concept(NAME, (Ret)(First)(Second)) \
+ { \
+ BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
+ private: \
+ 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_PREDICATE_OP_CONSTRAINT(==, EqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
- 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);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
//===========================================================================
// Function Object Concepts
- template <class Func, class Return>
- struct GeneratorConcept
+ BOOST_concept(Generator,(Func)(Return))
{
- void constraints() {
- const Return& r = f(); // require operator() member function
- ignore_unused_variable_warning(r);
- }
- Func f;
+ BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
+
+ private:
+ void test(boost::mpl::false_)
+ {
+ // Do we really want a reference here?
+ const Return& r = f();
+ ignore_unused_variable_warning(r);
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f();
+ }
+
+ Func f;
};
-
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template <class Func>
- struct GeneratorConcept<Func,void>
+ BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
{
- void constraints() {
- f(); // require operator() member function
- }
- Func f;
- };
+ BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
+
+ private:
+ void test(boost::mpl::false_)
+ {
+ f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
+ Return r = f(arg);
+ ignore_unused_variable_warning(r);
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f(arg);
+ }
+
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy construktor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ UnaryFunction();
#endif
- template <class Func, class Return, class Arg>
- struct UnaryFunctionConcept
- {
- // required in case any of our template args are const-qualified:
- UnaryFunctionConcept();
-
- void constraints() {
- r = f(arg); // require operator()
- }
- Func f;
- Arg arg;
- Return r;
+ Func f;
+ Arg arg;
};
-#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;
- Arg arg;
- };
+ BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
+ {
+ BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
+ private:
+ void test(boost::mpl::false_)
+ {
+ f(first,second);
+ Return r = f(first, second); // require operator()
+ (void)r;
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f(first,second);
+ }
+
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::BinaryFunction<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ BinaryFunction();
#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;
+ Func f;
+ First first;
+ Second second;
};
-#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template <class Func, class First, class Second>
- struct BinaryFunctionConcept<Func, void, First, Second>
+ BOOST_concept(UnaryPredicate,(Func)(Arg))
{
- void constraints() {
- f(first, second); // require operator()
+ BOOST_CONCEPT_USAGE(UnaryPredicate) {
+ require_boolean_expr(f(arg)); // require operator() returning bool
}
- Func f;
- First first;
- Second second;
- };
+ private:
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::UnaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ UnaryPredicate();
#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
+ BOOST_concept(BinaryPredicate,(Func)(First)(Second))
{
- void constraints() {
+ BOOST_CONCEPT_USAGE(BinaryPredicate) {
require_boolean_expr(f(a, b)); // require operator() returning bool
}
+ private:
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::BinaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ BinaryPredicate();
+#endif
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() {
+ BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
+ : BinaryPredicate<Func, First, Second>
+ {
+ BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
const_constraints(f);
}
+ private:
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));
}
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::Const_BinaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ Const_BinaryPredicate();
+#endif
+
Func f;
First a;
Second b;
};
- template <class Func, class Return>
- struct AdaptableGeneratorConcept
+ BOOST_concept(AdaptableGenerator,(Func)(Return))
+ : Generator<Func, typename Func::result_type>
{
- void constraints() {
typedef typename Func::result_type result_type;
- BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
- function_requires< GeneratorConcept<Func, result_type> >();
- }
+
+ BOOST_CONCEPT_USAGE(AdaptableGenerator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ }
};
- template <class Func, class Return, class Arg>
- struct AdaptableUnaryFunctionConcept
+ BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
+ : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
{
- void constraints() {
typedef typename Func::argument_type argument_type;
typedef typename Func::result_type result_type;
- BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
- BOOST_STATIC_ASSERT((is_convertible<Arg, argument_type>::value));
- function_requires< UnaryFunctionConcept<Func, result_type, argument_type> >();
- }
+
+ ~AdaptableUnaryFunction()
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
+ }
};
- template <class Func, class Return, class First, class Second>
- struct AdaptableBinaryFunctionConcept
+ BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
+ : BinaryFunction<
+ Func
+ , typename Func::result_type
+ , typename Func::first_argument_type
+ , typename Func::second_argument_type
+ >
{
- void constraints() {
typedef typename Func::first_argument_type first_argument_type;
typedef typename Func::second_argument_type second_argument_type;
typedef typename Func::result_type result_type;
- BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
- BOOST_STATIC_ASSERT((is_convertible<First, first_argument_type>::value));
- BOOST_STATIC_ASSERT((is_convertible<Second, second_argument_type>::value));
- function_requires< BinaryFunctionConcept<Func, result_type,
- first_argument_type, second_argument_type> >();
- }
+
+ ~AdaptableBinaryFunction()
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
+ BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
+ }
};
- template <class Func, class Arg>
- struct AdaptablePredicateConcept
+ BOOST_concept(AdaptablePredicate,(Func)(Arg))
+ : UnaryPredicate<Func, Arg>
+ , AdaptableUnaryFunction<Func, bool, Arg>
{
- void constraints() {
- function_requires< UnaryPredicateConcept<Func, Arg> >();
- function_requires< AdaptableUnaryFunctionConcept<Func, bool, Arg> >();
- }
};
- template <class Func, class First, class Second>
- struct AdaptableBinaryPredicateConcept
+ BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
+ : BinaryPredicate<Func, First, Second>
+ , AdaptableBinaryFunction<Func, bool, First, Second>
{
- void constraints() {
- function_requires< BinaryPredicateConcept<Func, First, Second> >();
- function_requires< AdaptableBinaryFunctionConcept<Func, bool, First, Second> >();
- }
};
//===========================================================================
// Iterator Concepts
- template <class TT>
- struct TrivialIteratorConcept
+ BOOST_concept(InputIterator,(TT))
+ : Assignable<TT>
+ , EqualityComparable<TT>
{
- void constraints() {
- function_requires< AssignableConcept<TT> >();
- function_requires< DefaultConstructibleConcept<TT> >();
- function_requires< EqualityComparableConcept<TT> >();
- (void)*i; // require dereference operator
- }
+ typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
+ typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
+ typedef typename boost::detail::iterator_traits<TT>::reference reference;
+ typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
+ typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
+
+ BOOST_CONCEPT_USAGE(InputIterator)
+ {
+ BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
+ BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
+
+ TT j(i);
+ (void)*i; // require dereference operator
+ ++j; // require preincrement operator
+ i++; // require postincrement operator
+ }
+ private:
TT i;
};
- template <class TT>
- struct Mutable_TrivialIteratorConcept
- {
- void constraints() {
- function_requires< TrivialIteratorConcept<TT> >();
- *i = *j; // require dereference and assignment
- }
- TT i, j;
- };
-
- template <class TT>
- struct InputIteratorConcept
+ BOOST_concept(OutputIterator,(TT)(ValueT))
+ : Assignable<TT>
{
- void constraints() {
- function_requires< TrivialIteratorConcept<TT> >();
- // require iterator_traits typedef's
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typedef typename std::iterator_traits<TT>::difference_type D;
- // Hmm, the following is a bit fragile
- //function_requires< SignedIntegerConcept<D> >();
- typedef typename std::iterator_traits<TT>::reference R;
- typedef typename std::iterator_traits<TT>::pointer P;
- typedef typename std::iterator_traits<TT>::iterator_category C;
- function_requires< ConvertibleConcept<C, std::input_iterator_tag> >();
-#endif
- ++i; // require preincrement operator
- i++; // require postincrement operator
- }
- TT i;
- };
+ BOOST_CONCEPT_USAGE(OutputIterator) {
- template <class TT, class ValueT>
- struct OutputIteratorConcept
- {
- void constraints() {
- function_requires< AssignableConcept<TT> >();
++i; // require preincrement operator
i++; // require postincrement operator
*i++ = t; // require postincrement and assignment
}
+ private:
TT i, j;
ValueT t;
};
- template <class TT>
- struct ForwardIteratorConcept
+ BOOST_concept(ForwardIterator,(TT))
+ : InputIterator<TT>
{
- void constraints() {
- function_requires< InputIteratorConcept<TT> >();
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typedef typename std::iterator_traits<TT>::iterator_category C;
- function_requires< ConvertibleConcept<C, std::forward_iterator_tag> >();
- typedef typename std::iterator_traits<TT>::reference reference;
- reference r = *i;
- ignore_unused_variable_warning(r);
-#endif
- }
- TT i;
+ BOOST_CONCEPT_USAGE(ForwardIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
+ , std::forward_iterator_tag
+ >));
+
+ typename InputIterator<TT>::reference r = *i;
+ ignore_unused_variable_warning(r);
+ }
+
+ private:
+ TT i;
};
- template <class TT>
- struct Mutable_ForwardIteratorConcept
+ BOOST_concept(Mutable_ForwardIterator,(TT))
+ : ForwardIterator<TT>
{
- void constraints() {
- function_requires< ForwardIteratorConcept<TT> >();
- *i++ = *i; // require postincrement and assignment
- }
- TT i;
+ BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
+ *i++ = *i; // require postincrement and assignment
+ }
+ private:
+ TT i;
};
- template <class TT>
- struct BidirectionalIteratorConcept
+ BOOST_concept(BidirectionalIterator,(TT))
+ : ForwardIterator<TT>
{
- void constraints() {
- function_requires< ForwardIteratorConcept<TT> >();
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typedef typename std::iterator_traits<TT>::iterator_category C;
- function_requires< ConvertibleConcept<C,
- std::bidirectional_iterator_tag> >();
-#endif
- --i; // require predecrement operator
- i--; // require postdecrement operator
- }
- TT i;
+ BOOST_CONCEPT_USAGE(BidirectionalIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
+ , std::bidirectional_iterator_tag
+ >));
+
+ --i; // require predecrement operator
+ i--; // require postdecrement operator
+ }
+ private:
+ TT i;
};
- template <class TT>
- struct Mutable_BidirectionalIteratorConcept
+ BOOST_concept(Mutable_BidirectionalIterator,(TT))
+ : BidirectionalIterator<TT>
+ , Mutable_ForwardIterator<TT>
{
- void constraints() {
- function_requires< BidirectionalIteratorConcept<TT> >();
- function_requires< Mutable_ForwardIteratorConcept<TT> >();
- *i-- = *i; // require postdecrement and assignment
- }
- TT i;
+ BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
+ {
+ *i-- = *i; // require postdecrement and assignment
+ }
+ private:
+ TT i;
};
-
- template <class TT>
- struct RandomAccessIteratorConcept
+ BOOST_concept(RandomAccessIterator,(TT))
+ : BidirectionalIterator<TT>
+ , Comparable<TT>
{
- void constraints() {
- function_requires< BidirectionalIteratorConcept<TT> >();
- function_requires< ComparableConcept<TT> >();
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typedef typename std::iterator_traits<TT>::iterator_category C;
- function_requires< ConvertibleConcept< C,
- std::random_access_iterator_tag> >();
- typedef typename std::iterator_traits<TT>::reference R;
-#endif
-
- i += n; // require assignment addition operator
- i = i + n; i = n + i; // require addition with difference type
- i -= n; // require assignment subtraction operator
- i = i - n; // require subtraction with difference type
- n = i - j; // require difference operator
- (void)i[n]; // require element access operator
- }
+ BOOST_CONCEPT_USAGE(RandomAccessIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
+ , std::random_access_iterator_tag
+ >));
+
+ i += n; // require assignment addition operator
+ i = i + n; i = n + i; // require addition with difference type
+ i -= n; // require assignment subtraction operator
+ i = i - n; // require subtraction with difference type
+ n = i - j; // require difference operator
+ (void)i[n]; // require element access operator
+ }
+
+ private:
TT a, b;
TT i, j;
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typename std::iterator_traits<TT>::difference_type n;
-#else
- std::ptrdiff_t n;
-#endif
+ typename boost::detail::iterator_traits<TT>::difference_type n;
};
- template <class TT>
- struct Mutable_RandomAccessIteratorConcept
+ BOOST_concept(Mutable_RandomAccessIterator,(TT))
+ : RandomAccessIterator<TT>
+ , Mutable_BidirectionalIterator<TT>
{
- void constraints() {
- function_requires< RandomAccessIteratorConcept<TT> >();
- function_requires< Mutable_BidirectionalIteratorConcept<TT> >();
- i[n] = *i; // require element access and assignment
- }
+ BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
+ {
+ i[n] = *i; // require element access and assignment
+ }
+ private:
TT i;
-#ifndef BOOST_NO_STD_ITERATOR_TRAITS
- typename std::iterator_traits<TT>::difference_type n;
-#else
- std::ptrdiff_t n;
-#endif
+ typename boost::detail::iterator_traits<TT>::difference_type n;
};
//===========================================================================
- // Container Concepts
+ // Container s
- template <class Container>
- struct ContainerConcept
+ BOOST_concept(Container,(C))
+ : Assignable<C>
{
- typedef typename Container::value_type value_type;
- typedef typename Container::difference_type difference_type;
- typedef typename Container::size_type size_type;
- typedef typename Container::const_reference const_reference;
- typedef typename Container::const_pointer const_pointer;
- typedef typename Container::const_iterator const_iterator;
-
- void constraints() {
- function_requires< InputIteratorConcept<const_iterator> >();
- function_requires< AssignableConcept<Container> >();
- const_constraints(c);
- }
- void const_constraints(const Container& c) {
- i = c.begin();
- i = c.end();
- n = c.size();
- n = c.max_size();
- b = c.empty();
- }
- Container c;
- bool b;
- const_iterator i;
- size_type n;
+ typedef typename C::value_type value_type;
+ typedef typename C::difference_type difference_type;
+ typedef typename C::size_type size_type;
+ typedef typename C::const_reference const_reference;
+ typedef typename C::const_pointer const_pointer;
+ typedef typename C::const_iterator const_iterator;
+
+ BOOST_CONCEPT_USAGE(Container)
+ {
+ BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
+ const_constraints(c);
+ }
+
+ private:
+ void const_constraints(const C& cc) {
+ i = cc.begin();
+ i = cc.end();
+ n = cc.size();
+ n = cc.max_size();
+ b = cc.empty();
+ }
+ C c;
+ bool b;
+ const_iterator i;
+ size_type n;
};
- template <class Container>
- struct Mutable_ContainerConcept
+ BOOST_concept(Mutable_Container,(C))
+ : Container<C>
{
- typedef typename Container::value_type value_type;
- typedef typename Container::reference reference;
- typedef typename Container::iterator iterator;
- typedef typename Container::pointer pointer;
-
- void constraints() {
- function_requires< ContainerConcept<Container> >();
- function_requires< AssignableConcept<value_type> >();
- function_requires< InputIteratorConcept<iterator> >();
-
- i = c.begin();
- i = c.end();
- c.swap(c2);
- }
- iterator i;
- Container c, c2;
+ typedef typename C::reference reference;
+ typedef typename C::iterator iterator;
+ typedef typename C::pointer pointer;
+
+ BOOST_CONCEPT_USAGE(Mutable_Container)
+ {
+ BOOST_CONCEPT_ASSERT((
+ Assignable<typename Mutable_Container::value_type>));
+
+ BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
+
+ i = c.begin();
+ i = c.end();
+ c.swap(c2);
+ }
+
+ private:
+ iterator i;
+ C c, c2;
};
- template <class ForwardContainer>
- struct ForwardContainerConcept
+ BOOST_concept(ForwardContainer,(C))
+ : Container<C>
{
- void constraints() {
- function_requires< ContainerConcept<ForwardContainer> >();
- typedef typename ForwardContainer::const_iterator const_iterator;
- function_requires< ForwardIteratorConcept<const_iterator> >();
- }
- };
+ BOOST_CONCEPT_USAGE(ForwardContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ ForwardIterator<
+ typename ForwardContainer::const_iterator
+ >));
+ }
+ };
- template <class ForwardContainer>
- struct Mutable_ForwardContainerConcept
+ BOOST_concept(Mutable_ForwardContainer,(C))
+ : ForwardContainer<C>
+ , Mutable_Container<C>
{
- void constraints() {
- function_requires< ForwardContainerConcept<ForwardContainer> >();
- function_requires< Mutable_ContainerConcept<ForwardContainer> >();
- typedef typename ForwardContainer::iterator iterator;
- function_requires< Mutable_ForwardIteratorConcept<iterator> >();
- }
- };
+ BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ Mutable_ForwardIterator<
+ typename Mutable_ForwardContainer::iterator
+ >));
+ }
+ };
- template <class ReversibleContainer>
- struct ReversibleContainerConcept
+ BOOST_concept(ReversibleContainer,(C))
+ : ForwardContainer<C>
{
- typedef typename ReversibleContainer::const_iterator const_iterator;
- typedef typename ReversibleContainer::const_reverse_iterator
+ typedef typename
+ C::const_reverse_iterator
const_reverse_iterator;
- void constraints() {
- function_requires< ForwardContainerConcept<ReversibleContainer> >();
- function_requires< BidirectionalIteratorConcept<const_iterator> >();
- function_requires<
- BidirectionalIteratorConcept<const_reverse_iterator> >();
- const_constraints(c);
- }
- void const_constraints(const ReversibleContainer& c) {
- const_reverse_iterator i = c.rbegin();
- i = c.rend();
- }
- ReversibleContainer c;
+ BOOST_CONCEPT_USAGE(ReversibleContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ BidirectionalIterator<
+ typename ReversibleContainer::const_iterator>));
+
+ BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
+
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const C& cc)
+ {
+ const_reverse_iterator i = cc.rbegin();
+ i = cc.rend();
+ }
+ C c;
};
- template <class ReversibleContainer>
- struct Mutable_ReversibleContainerConcept
+ BOOST_concept(Mutable_ReversibleContainer,(C))
+ : Mutable_ForwardContainer<C>
+ , ReversibleContainer<C>
{
- typedef typename ReversibleContainer::iterator iterator;
- typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
-
- void constraints() {
- function_requires< ReversibleContainerConcept<ReversibleContainer> >();
- function_requires<
- Mutable_ForwardContainerConcept<ReversibleContainer> >();
- function_requires< Mutable_BidirectionalIteratorConcept<iterator> >();
- function_requires<
- Mutable_BidirectionalIteratorConcept<reverse_iterator> >();
-
- reverse_iterator i = c.rbegin();
- i = c.rend();
- }
- ReversibleContainer c;
+ typedef typename C::reverse_iterator reverse_iterator;
+
+ BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
+ {
+ typedef typename Mutable_ForwardContainer<C>::iterator iterator;
+ BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
+ BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
+
+ reverse_iterator i = c.rbegin();
+ i = c.rend();
+ }
+ private:
+ C c;
};
- template <class RandomAccessContainer>
- struct RandomAccessContainerConcept
+ BOOST_concept(RandomAccessContainer,(C))
+ : ReversibleContainer<C>
{
- typedef typename RandomAccessContainer::size_type size_type;
- typedef typename RandomAccessContainer::const_reference const_reference;
- typedef typename RandomAccessContainer::const_iterator const_iterator;
- typedef typename RandomAccessContainer::const_reverse_iterator
- const_reverse_iterator;
-
- void constraints() {
- function_requires< ReversibleContainerConcept<RandomAccessContainer> >();
- function_requires< RandomAccessIteratorConcept<const_iterator> >();
- function_requires<
- RandomAccessIteratorConcept<const_reverse_iterator> >();
-
- const_constraints(c);
- }
- void const_constraints(const RandomAccessContainer& c) {
- const_reference r = c[n];
- ignore_unused_variable_warning(r);
- }
- RandomAccessContainer c;
- size_type n;
+ typedef typename C::size_type size_type;
+ typedef typename C::const_reference const_reference;
+
+ BOOST_CONCEPT_USAGE(RandomAccessContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ RandomAccessIterator<
+ typename RandomAccessContainer::const_iterator
+ >));
+
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const C& cc)
+ {
+ const_reference r = cc[n];
+ ignore_unused_variable_warning(r);
+ }
+
+ C c;
+ size_type n;
};
- template <class RandomAccessContainer>
- struct Mutable_RandomAccessContainerConcept
+ BOOST_concept(Mutable_RandomAccessContainer,(C))
+ : Mutable_ReversibleContainer<C>
+ , RandomAccessContainer<C>
{
- typedef typename RandomAccessContainer::size_type size_type;
- typedef typename RandomAccessContainer::reference reference;
- typedef typename RandomAccessContainer::iterator iterator;
- typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
-
- void constraints() {
- function_requires<
- RandomAccessContainerConcept<RandomAccessContainer> >();
- function_requires<
- Mutable_ReversibleContainerConcept<RandomAccessContainer> >();
- function_requires< Mutable_RandomAccessIteratorConcept<iterator> >();
- function_requires<
- Mutable_RandomAccessIteratorConcept<reverse_iterator> >();
-
- reference r = c[i];
- ignore_unused_variable_warning(r);
- }
- size_type i;
- RandomAccessContainer c;
+ private:
+ typedef Mutable_RandomAccessContainer self;
+ public:
+ BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
+ {
+ BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
+ BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
+
+ typename self::reference r = c[i];
+ ignore_unused_variable_warning(r);
+ }
+
+ private:
+ typename Mutable_ReversibleContainer<C>::size_type i;
+ C c;
};
// A Sequence is inherently mutable
- template <class Sequence>
- struct SequenceConcept
- {
-
- typedef typename Sequence::reference reference;
- typedef typename Sequence::const_reference const_reference;
-
- void constraints() {
+ BOOST_concept(Sequence,(S))
+ : Mutable_ForwardContainer<S>
// Matt Austern's book puts DefaultConstructible here, the C++
- // standard places it in Container
- // function_requires< DefaultConstructible<Sequence> >();
- function_requires< Mutable_ForwardContainerConcept<Sequence> >();
- function_requires< DefaultConstructibleConcept<Sequence> >();
-
- Sequence
- c(n),
- c2(n, t),
- c3(first, last);
-
- c.insert(p, t);
- c.insert(p, n, t);
- c.insert(p, first, last);
-
- c.erase(p);
- c.erase(p, q);
-
- reference r = c.front();
-
- ignore_unused_variable_warning(c);
- ignore_unused_variable_warning(c2);
- ignore_unused_variable_warning(c3);
- ignore_unused_variable_warning(r);
- const_constraints(c);
- }
- void const_constraints(const Sequence& c) {
- const_reference r = c.front();
- ignore_unused_variable_warning(r);
- }
- typename Sequence::value_type t;
- typename Sequence::size_type n;
- typename Sequence::value_type* first, *last;
- typename Sequence::iterator p, q;
+ // standard places it in Container --JGS
+ // ... so why aren't we following the standard? --DWA
+ , DefaultConstructible<S>
+ {
+ BOOST_CONCEPT_USAGE(Sequence)
+ {
+ S
+ c(n),
+ c2(n, t),
+ c3(first, last);
+
+ c.insert(p, t);
+ c.insert(p, n, t);
+ c.insert(p, first, last);
+
+ c.erase(p);
+ c.erase(p, q);
+
+ typename Sequence::reference r = c.front();
+
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(c2);
+ ignore_unused_variable_warning(c3);
+ ignore_unused_variable_warning(r);
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const S& c) {
+ typename Sequence::const_reference r = c.front();
+ ignore_unused_variable_warning(r);
+ }
+
+ typename S::value_type t;
+ typename S::size_type n;
+ typename S::value_type* first, *last;
+ typename S::iterator p, q;
};
- template <class FrontInsertionSequence>
- struct FrontInsertionSequenceConcept
+ BOOST_concept(FrontInsertionSequence,(S))
+ : Sequence<S>
{
- void constraints() {
- function_requires< SequenceConcept<FrontInsertionSequence> >();
-
- c.push_front(t);
- c.pop_front();
- }
- FrontInsertionSequence c;
- typename FrontInsertionSequence::value_type t;
+ BOOST_CONCEPT_USAGE(FrontInsertionSequence)
+ {
+ c.push_front(t);
+ c.pop_front();
+ }
+ private:
+ S c;
+ typename S::value_type t;
};
- template <class BackInsertionSequence>
- struct BackInsertionSequenceConcept
+ BOOST_concept(BackInsertionSequence,(S))
+ : Sequence<S>
{
- typedef typename BackInsertionSequence::reference reference;
- typedef typename BackInsertionSequence::const_reference const_reference;
-
- void constraints() {
- function_requires< SequenceConcept<BackInsertionSequence> >();
-
- c.push_back(t);
- c.pop_back();
- reference r = c.back();
- ignore_unused_variable_warning(r);
- }
- void const_constraints(const BackInsertionSequence& c) {
- const_reference r = c.back();
- ignore_unused_variable_warning(r);
- };
- BackInsertionSequence c;
- typename BackInsertionSequence::value_type t;
+ BOOST_CONCEPT_USAGE(BackInsertionSequence)
+ {
+ c.push_back(t);
+ c.pop_back();
+ typename BackInsertionSequence::reference r = c.back();
+ ignore_unused_variable_warning(r);
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const S& cc) {
+ typename BackInsertionSequence::const_reference
+ r = cc.back();
+ ignore_unused_variable_warning(r);
+ };
+ S c;
+ typename S::value_type t;
};
- template <class AssociativeContainer>
- struct AssociativeContainerConcept
+ BOOST_concept(AssociativeContainer,(C))
+ : ForwardContainer<C>
+ , DefaultConstructible<C>
{
- void constraints() {
- function_requires< ForwardContainerConcept<AssociativeContainer> >();
- function_requires< DefaultConstructibleConcept<AssociativeContainer> >();
-
- i = c.find(k);
- r = c.equal_range(k);
- c.erase(k);
- c.erase(i);
- c.erase(r.first, r.second);
- const_constraints(c);
- }
- void const_constraints(const AssociativeContainer& c) {
- ci = c.find(k);
- n = c.count(k);
- cr = c.equal_range(k);
- }
- typedef typename AssociativeContainer::iterator iterator;
- typedef typename AssociativeContainer::const_iterator const_iterator;
-
- AssociativeContainer c;
- iterator i;
- std::pair<iterator,iterator> r;
- const_iterator ci;
- std::pair<const_iterator,const_iterator> cr;
- typename AssociativeContainer::key_type k;
- typename AssociativeContainer::size_type n;
+ typedef typename C::key_type key_type;
+ typedef typename C::key_compare key_compare;
+ typedef typename C::value_compare value_compare;
+ typedef typename C::iterator iterator;
+
+ BOOST_CONCEPT_USAGE(AssociativeContainer)
+ {
+ i = c.find(k);
+ r = c.equal_range(k);
+ c.erase(k);
+ c.erase(i);
+ c.erase(r.first, r.second);
+ const_constraints(c);
+ BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
+
+ typedef typename AssociativeContainer::value_type value_type_;
+ BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
+ }
+
+ // Redundant with the base concept, but it helps below.
+ typedef typename C::const_iterator const_iterator;
+ private:
+ void const_constraints(const C& cc)
+ {
+ ci = cc.find(k);
+ n = cc.count(k);
+ cr = cc.equal_range(k);
+ }
+
+ C c;
+ iterator i;
+ std::pair<iterator,iterator> r;
+ const_iterator ci;
+ std::pair<const_iterator,const_iterator> cr;
+ typename C::key_type k;
+ typename C::size_type n;
};
- template <class UniqueAssociativeContainer>
- struct UniqueAssociativeContainerConcept
+ BOOST_concept(UniqueAssociativeContainer,(C))
+ : AssociativeContainer<C>
{
- void constraints() {
- function_requires< AssociativeContainerConcept<UniqueAssociativeContainer> >();
-
- UniqueAssociativeContainer c(first, last);
-
- pos_flag = c.insert(t);
- c.insert(first, last);
-
- ignore_unused_variable_warning(c);
- }
- std::pair<typename UniqueAssociativeContainer::iterator, bool> pos_flag;
- typename UniqueAssociativeContainer::value_type t;
- typename UniqueAssociativeContainer::value_type* first, *last;
+ BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
+ {
+ C c(first, last);
+
+ pos_flag = c.insert(t);
+ c.insert(first, last);
+
+ ignore_unused_variable_warning(c);
+ }
+ private:
+ std::pair<typename C::iterator, bool> pos_flag;
+ typename C::value_type t;
+ typename C::value_type* first, *last;
};
- template <class MultipleAssociativeContainer>
- struct MultipleAssociativeContainerConcept
+ BOOST_concept(MultipleAssociativeContainer,(C))
+ : AssociativeContainer<C>
{
- void constraints() {
- function_requires< AssociativeContainerConcept<MultipleAssociativeContainer> >();
-
- MultipleAssociativeContainer c(first, last);
-
- pos = c.insert(t);
- c.insert(first, last);
-
- ignore_unused_variable_warning(c);
- ignore_unused_variable_warning(pos);
- }
- typename MultipleAssociativeContainer::iterator pos;
- typename MultipleAssociativeContainer::value_type t;
- typename MultipleAssociativeContainer::value_type* first, *last;
+ BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
+ {
+ C c(first, last);
+
+ pos = c.insert(t);
+ c.insert(first, last);
+
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(pos);
+ }
+ private:
+ typename C::iterator pos;
+ typename C::value_type t;
+ typename C::value_type* first, *last;
};
- template <class SimpleAssociativeContainer>
- struct SimpleAssociativeContainerConcept
+ BOOST_concept(SimpleAssociativeContainer,(C))
+ : AssociativeContainer<C>
{
- void constraints() {
- function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
- typedef typename SimpleAssociativeContainer::key_type key_type;
- typedef typename SimpleAssociativeContainer::value_type value_type;
- typedef typename require_same<key_type, value_type>::type req;
- }
+ BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
+ {
+ typedef typename C::key_type key_type;
+ typedef typename C::value_type value_type;
+ BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
+ }
};
- template <class SimpleAssociativeContainer>
- struct PairAssociativeContainerConcept
+ BOOST_concept(PairAssociativeContainer,(C))
+ : AssociativeContainer<C>
{
- void constraints() {
- function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
- typedef typename SimpleAssociativeContainer::key_type key_type;
- typedef typename SimpleAssociativeContainer::value_type value_type;
- typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
- typedef std::pair<const key_type, mapped_type> required_value_type;
- typedef typename require_same<value_type, required_value_type>::type req;
- }
+ BOOST_CONCEPT_USAGE(PairAssociativeContainer)
+ {
+ typedef typename C::key_type key_type;
+ typedef typename C::value_type value_type;
+ typedef typename C::mapped_type mapped_type;
+ typedef std::pair<const key_type, mapped_type> required_value_type;
+ BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
+ }
};
- template <class SortedAssociativeContainer>
- struct SortedAssociativeContainerConcept
+ BOOST_concept(SortedAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ , ReversibleContainer<C>
{
- void constraints() {
- function_requires< AssociativeContainerConcept<SortedAssociativeContainer> >();
- function_requires< ReversibleContainerConcept<SortedAssociativeContainer> >();
-
- SortedAssociativeContainer
- c(kc),
- c2(first, last),
- c3(first, last, kc);
-
- p = c.upper_bound(k);
- p = c.lower_bound(k);
- r = c.equal_range(k);
-
- c.insert(p, t);
-
- ignore_unused_variable_warning(c);
- ignore_unused_variable_warning(c2);
- ignore_unused_variable_warning(c3);
- }
- void const_constraints(const SortedAssociativeContainer& c) {
- kc = c.key_comp();
- vc = c.value_comp();
-
- cp = c.upper_bound(k);
- cp = c.lower_bound(k);
- cr = c.equal_range(k);
- }
- typename SortedAssociativeContainer::key_compare kc;
- typename SortedAssociativeContainer::value_compare vc;
- typename SortedAssociativeContainer::value_type t;
- typename SortedAssociativeContainer::key_type k;
- typedef typename SortedAssociativeContainer::iterator iterator;
- typedef typename SortedAssociativeContainer::const_iterator const_iterator;
- iterator p;
- const_iterator cp;
- std::pair<iterator,iterator> r;
- std::pair<const_iterator,const_iterator> cr;
- typename SortedAssociativeContainer::value_type* first, *last;
+ BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
+ {
+ C
+ c(kc),
+ c2(first, last),
+ c3(first, last, kc);
+
+ p = c.upper_bound(k);
+ p = c.lower_bound(k);
+ r = c.equal_range(k);
+
+ c.insert(p, t);
+
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(c2);
+ ignore_unused_variable_warning(c3);
+ const_constraints(c);
+ }
+
+ void const_constraints(const C& c)
+ {
+ kc = c.key_comp();
+ vc = c.value_comp();
+
+ cp = c.upper_bound(k);
+ cp = c.lower_bound(k);
+ cr = c.equal_range(k);
+ }
+
+ private:
+ typename C::key_compare kc;
+ typename C::value_compare vc;
+ typename C::value_type t;
+ typename C::key_type k;
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+
+ typedef SortedAssociativeContainer self;
+ iterator p;
+ const_iterator cp;
+ std::pair<typename self::iterator,typename self::iterator> r;
+ std::pair<typename self::const_iterator,typename self::const_iterator> cr;
+ typename C::value_type* first, *last;
};
// HashedAssociativeContainer
+ BOOST_concept(Collection,(C))
+ {
+ BOOST_CONCEPT_USAGE(Collection)
+ {
+ boost::function_requires<boost::InputIteratorConcept<iterator> >();
+ boost::function_requires<boost::InputIteratorConcept<const_iterator> >();
+ boost::function_requires<boost::CopyConstructibleConcept<value_type> >();
+ const_constraints(c);
+ i = c.begin();
+ i = c.end();
+ c.swap(c);
+ }
+
+ void const_constraints(const C& c) {
+ ci = c.begin();
+ ci = c.end();
+ n = c.size();
+ b = c.empty();
+ }
+
+ private:
+ typedef typename C::value_type value_type;
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename C::reference reference;
+ typedef typename C::const_reference const_reference;
+ // typedef typename C::pointer pointer;
+ typedef typename C::difference_type difference_type;
+ typedef typename C::size_type size_type;
+
+ C c;
+ bool b;
+ iterator i;
+ const_iterator ci;
+ size_type n;
+ };
} // namespace boost
+# include <boost/concept/detail/concept_undef.hpp>
+
#endif // BOOST_CONCEPT_CHECKS_HPP