diff --git a/include/boost/concept/assert.hpp b/include/boost/concept/assert.hpp new file mode 100755 index 0000000..80eca81 --- /dev/null +++ b/include/boost/concept/assert.hpp @@ -0,0 +1,46 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP +# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP + +# include +# include + +// The old protocol used a constraints() member function in concept +// checking classes. If the compiler supports SFINAE, we can detect +// that function and seamlessly support the old concept checking +// classes. In this release, backward compatibility with the old +// concept checking classes is enabled by default, where available. +// The old protocol is deprecated, though, and backward compatibility +// will no longer be the default in the next release. + +# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \ + && !defined(BOOST_NO_SFINAE) \ + \ + && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) \ + && !(BOOST_WORKAROUND(__GNUC__, == 2)) + +// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to +// check for the presence of particularmember functions. + +# define BOOST_OLD_CONCEPT_SUPPORT + +# endif + +# ifdef BOOST_MSVC +# include +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +# else +# include +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); + // +# define BOOST_CONCEPT_ASSERT(ModelInParens) \ + BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens) + +#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP diff --git a/include/boost/concept/detail/borland.hpp b/include/boost/concept/detail/borland.hpp new file mode 100755 index 0000000..59fec55 --- /dev/null +++ b/include/boost/concept/detail/borland.hpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP + +# include + +namespace boost { namespace concept { + +template +struct require; + +template +struct require +{ + enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concept::require::instantiate \ + } + +}} // namespace boost::concept + +#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP diff --git a/include/boost/concept/detail/concept_def.hpp b/include/boost/concept/detail/concept_def.hpp new file mode 100755 index 0000000..79f628e --- /dev/null +++ b/include/boost/concept/detail/concept_def.hpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# include +# include +# include +# include +#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP + +// BOOST_concept(SomeName, (p1)(p2)...(pN)) +// +// Expands to "template struct SomeName" +// +// Also defines an equivalent SomeNameConcept for backward compatibility. +// Maybe in the next release we can kill off the "Concept" suffix for good. +#if BOOST_WORKAROUND(__GNUC__, <= 3) +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + /* at least 2.96 and 3.4.3 both need this */ \ + BOOST_PP_CAT(name,Concept)(); \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name +#else +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name +#endif + +// Helper for BOOST_concept, above. +# define BOOST_CONCEPT_typename(r, ignored, index, t) \ + BOOST_PP_COMMA_IF(index) typename t + diff --git a/include/boost/concept/detail/concept_undef.hpp b/include/boost/concept/detail/concept_undef.hpp new file mode 100755 index 0000000..713db89 --- /dev/null +++ b/include/boost/concept/detail/concept_undef.hpp @@ -0,0 +1,5 @@ +// Copyright David Abrahams 2006. 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) +# undef BOOST_concept_typename +# undef BOOST_concept diff --git a/include/boost/concept/detail/general.hpp b/include/boost/concept/detail/general.hpp new file mode 100755 index 0000000..f36f9c4 --- /dev/null +++ b/include/boost/concept/detail/general.hpp @@ -0,0 +1,66 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP + +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + +// This implementation works on Comeau and GCC, all the way back to +// 2.95 +namespace boost { namespace concept { + +template +struct requirement_; + +namespace detail +{ + template struct instantiate {}; +} + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +template +struct constraint +{ + static void failed() { ((Model*)0)->constraints(); } +}; + +template +struct requirement_ + : mpl::if_< + concept::not_satisfied + , constraint + , requirement + >::type +{}; + +# else + +// For GCC-2.x, these can't have exactly the same name +template +struct requirement_ + : requirement +{}; + +# endif + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + typedef ::boost::concept::detail::instantiate< \ + &::boost::concept::requirement_::failed> \ + BOOST_PP_CAT(boost_concept_check,__LINE__) + +}} + +#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP diff --git a/include/boost/concept/detail/has_constraints.hpp b/include/boost/concept/detail/has_constraints.hpp new file mode 100755 index 0000000..3112b55 --- /dev/null +++ b/include/boost/concept/detail/has_constraints.hpp @@ -0,0 +1,48 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP + +# include +# include +namespace boost { namespace concept { + +namespace detail +{ + +// Here we implement the metafunction that detects whether a +// constraints metafunction exists + typedef char yes; + typedef char (&no)[2]; + + template + struct wrap_constraints {}; + +#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) + // Work around the following bogus error in Sun Studio 11, by + // turning off the has_constraints function entirely: + // Error: complex expression not allowed in dependent template + // argument expression + inline no has_constraints_(...); +#else + template + inline yes has_constraints_(Model*, wrap_constraints* = 0); + inline no has_constraints_(...); +#endif +} + +// This would be called "detail::has_constraints," but it has a strong +// tendency to show up in error messages. +template +struct not_satisfied +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) ); + typedef mpl::bool_ type; +}; + +}} // namespace boost::concept::detail + +#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/include/boost/concept/detail/msvc.hpp b/include/boost/concept/detail/msvc.hpp new file mode 100755 index 0000000..3aadb79 --- /dev/null +++ b/include/boost/concept/detail/msvc.hpp @@ -0,0 +1,92 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +namespace boost { namespace concept { + +template +struct check +{ + virtual void failed(Model* x) + { + x->~Model(); + } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +namespace detail +{ + // No need for a virtual function here, since evaluating + // not_satisfied below will have already instantiated the + // constraints() member. + struct constraint {}; +} + +template +struct require + : mpl::if_c< + not_satisfied::value + , detail::constraint + , check + >::type +{}; + +# else + +template +struct require + : check +{}; + +# endif + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + +// +// The iterator library sees some really strange errors unless we +// do things this way. +// +template +struct require +{ + virtual void failed(Model*) + { + require(); + } +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept::require) \ +} + +# else // Not vc-7.1 + +template +require +require_(void(*)(Model)); + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept::require_((ModelFnPtr)0)) \ +} + +# endif +}} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/include/boost/concept/requires.hpp b/include/boost/concept/requires.hpp new file mode 100755 index 0000000..5570b64 --- /dev/null +++ b/include/boost/concept/requires.hpp @@ -0,0 +1,74 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP +# define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP + +# include +# include +# include + +namespace boost { + +// Template for use in handwritten assertions +template +struct requires_ : More +{ +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename More::type type; +# endif + BOOST_CONCEPT_ASSERT((Model)); +}; + +// Template for use by macros, where models must be wrapped in parens. +// This isn't in namespace detail to keep extra cruft out of resulting +// error messages. +template +struct _requires_ +{ + enum { value = 0 }; + BOOST_CONCEPT_ASSERT_FN(ModelFn); +}; + +template +struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type +{ +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename ::boost::parameter::aux::unaryfunptr_arg_type::type type; +# endif +}; + + +#define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_::value) + +#if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +# define BOOST_CONCEPT_REQUIRES(models, result) \ + typename ::boost::parameter::aux::unaryfunptr_arg_type::type + +#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +// Same thing as below without the initial typename +# define BOOST_CONCEPT_REQUIRES(models, result) \ + ::boost::Requires_< \ + (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ + ::boost::parameter::aux::unaryfunptr_arg_type \ + >::type + +#else + +// This just ICEs on MSVC6 :( +# define BOOST_CONCEPT_REQUIRES(models, result) \ + typename ::boost::Requires_< \ + (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ + void(*)result \ + >::type + +#endif + +// C++0x proposed syntax changed. This supports an older usage +#define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result) + +} // namespace boost::concept_check + +#endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP diff --git a/include/boost/concept/usage.hpp b/include/boost/concept/usage.hpp new file mode 100755 index 0000000..9af8ca3 --- /dev/null +++ b/include/boost/concept/usage.hpp @@ -0,0 +1,43 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP +# define BOOST_CONCEPT_USAGE_DWA2006919_HPP + +# include +# include + +namespace boost { namespace concept { + +# if BOOST_WORKAROUND(__GNUC__, == 2) + +# define BOOST_CONCEPT_USAGE(model) ~model() + +# else + +template +struct usage_requirements +{ + ~usage_requirements() { ((Model*)0)->~Model(); } +}; + +# if BOOST_WORKAROUND(__GNUC__, <= 3) + +# define BOOST_CONCEPT_USAGE(model) \ + model(); /* at least 2.96 and 3.4.3 both need this :( */ \ + BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \ + ~model() + +# else + +# define BOOST_CONCEPT_USAGE(model) \ + BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \ + ~model() + +# endif + +# endif + +}} // namespace boost::concept + +#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp index 8b090d0..4e9fddf 100644 --- a/include/boost/concept_check.hpp +++ b/include/boost/concept_check.hpp @@ -13,234 +13,153 @@ // 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 -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__BORLANDC__) -#define BOOST_FPTR -#else -#define BOOST_FPTR & -#endif +# include +# include -namespace boost { - -/* - "inline" is used for ignore_unused_variable_warning() - and function_requires() to make sure there is no - overhead with g++. - */ - -template inline void ignore_unused_variable_warning(const T&) { } - -// the unused, defaulted parameter is a workaround for MSVC and Compaq C++ -template -inline void function_requires(mpl::identity* = 0) +namespace boost { -#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 ::* func##type_var##concept)(); \ - template \ - struct concept_checking_##type_var##concept { }; \ - typedef concept_checking_##type_var##concept< \ - BOOST_FPTR ns::concept::constraints> \ - concept_checking_typedef_##type_var##concept + // + // Backward compatibility + // + + template + inline void function_requires(Model* = 0) + { + BOOST_CONCEPT_ASSERT((Model)); + } + template inline void ignore_unused_variable_warning(T const&) {} + +# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) -#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ - typedef void (ns::concept ::* \ - func##type_var1##type_var2##concept)(); \ - template \ - struct concept_checking_##type_var1##type_var2##concept { }; \ - typedef concept_checking_##type_var1##type_var2##concept< \ - BOOST_FPTR ns::concept::constraints> \ - concept_checking_typedef_##type_var1##type_var2##concept +# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) -#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ - typedef void (ns::concept ::* \ - func##tv1##tv2##tv3##concept)(); \ - template \ - struct concept_checking_##tv1##tv2##tv3##concept { }; \ - typedef concept_checking_##tv1##tv2##tv3##concept< \ - BOOST_FPTR ns::concept::constraints> \ - concept_checking_typedef_##tv1##tv2##tv3##concept +# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) -#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ - typedef void (ns::concept ::* \ - func##tv1##tv2##tv3##tv4##concept)(); \ - template \ - struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \ - typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \ - BOOST_FPTR ns::concept::constraints> \ - concept_checking_typedef_##tv1##tv2##tv3##tv4##concept +# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::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) - -#else - -#define BOOST_CLASS_REQUIRES(type_var, concept) \ - typedef void (concept ::* func##type_var##concept)(); \ - template \ - struct concept_checking_##type_var##concept { }; \ - typedef concept_checking_##type_var##concept< \ - BOOST_FPTR concept ::constraints> \ - concept_checking_typedef_##type_var##concept - -#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \ - typedef void (concept ::* func##type_var1##type_var2##concept)(); \ - template \ - struct concept_checking_##type_var1##type_var2##concept { }; \ - typedef concept_checking_##type_var1##type_var2##concept< \ - BOOST_FPTR concept ::constraints> \ - concept_checking_typedef_##type_var1##type_var2##concept - -#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \ - typedef void (concept ::* func##type_var1##type_var2##type_var3##concept)(); \ - template \ - struct concept_checking_##type_var1##type_var2##type_var3##concept { }; \ - typedef concept_checking_##type_var1##type_var2##type_var3##concept< \ - BOOST_FPTR concept ::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 ::* func##type_var1##type_var2##type_var3##type_var4##concept)(); \ - template \ - 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 ::constraints> \ - concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept - - -#endif - -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct require_same { }; - -template -struct require_same { typedef T type; }; -#else -// This version does not perform checking, but will not do any harm. -template -struct require_same { typedef T type; }; -#endif - - template - struct IntegerConcept { - void constraints() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - x.error_type_must_be_an_integer_type(); -#endif - } - T x; + + // + // Begin concept definitions + // + BOOST_concept(Integer, (T)) + { + BOOST_CONCEPT_USAGE(Integer) + { + x.error_type_must_be_an_integer_type(); + } + private: + T x; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template <> struct IntegerConcept { void constraints() {} }; - template <> struct IntegerConcept { void constraints() {} }; - template <> struct IntegerConcept { void constraints() {} }; - template <> struct IntegerConcept { void constraints() {} }; - template <> struct IntegerConcept { void constraints() {} }; - template <> struct IntegerConcept { void constraints() {} }; - // etc. -#endif - template - struct SignedIntegerConcept { - void constraints() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - x.error_type_must_be_a_signed_integer_type(); -#endif - } - T x; - }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template <> struct SignedIntegerConcept { void constraints() {} }; - template <> struct SignedIntegerConcept { void constraints() {} }; - template <> struct SignedIntegerConcept { void constraints() {} }; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; # if defined(BOOST_HAS_LONG_LONG) - template <> struct SignedIntegerConcept< ::boost::long_long_type> { void constraints() {} }; + 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 {}; # endif - // etc. -#endif - template - struct UnsignedIntegerConcept { - void constraints() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - x.error_type_must_be_an_unsigned_integer_type(); -#endif + BOOST_concept(SignedInteger,(T)) { + BOOST_CONCEPT_USAGE(SignedInteger) { + x.error_type_must_be_a_signed_integer_type(); } + private: T x; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template <> struct UnsignedIntegerConcept - { void constraints() {} }; - template <> struct UnsignedIntegerConcept - { void constraints() {} }; - template <> struct UnsignedIntegerConcept - { void constraints() {} }; - // etc. -#endif + template <> struct SignedInteger { }; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct SignedInteger< ::boost::long_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct SignedInteger<__int64> {}; +# endif + + BOOST_concept(UnsignedInteger,(T)) { + BOOST_CONCEPT_USAGE(UnsignedInteger) { + x.error_type_must_be_an_unsigned_integer_type(); + } + private: + T x; + }; + + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct UnsignedInteger {}; +# endif //=========================================================================== // Basic Concepts - template - struct DefaultConstructibleConcept + BOOST_concept(DefaultConstructible,(TT)) { - void constraints() { + BOOST_CONCEPT_USAGE(DefaultConstructible) { TT a; // require default constructor ignore_unused_variable_warning(a); } }; - template - 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 = a; // require assignment operator #endif const_constraints(a); } + private: 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 } + private: TT a; }; - template - 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 @@ -251,10 +170,9 @@ struct require_same { typedef T type; }; }; // The SGI STL version of Assignable requires copy constructor and operator= - template - struct SGIAssignableConcept + BOOST_concept(SGIAssignable,(TT)) { - void constraints() { + BOOST_CONCEPT_USAGE(SGIAssignable) { TT b(a); #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL a = a; // require assignment operator @@ -262,6 +180,7 @@ struct require_same { typedef T type; }; const_constraints(a); ignore_unused_variable_warning(b); } + private: void const_constraints(const TT& b) { TT c(b); #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL @@ -272,13 +191,13 @@ struct require_same { typedef T type; }; TT a; }; - template - struct ConvertibleConcept + BOOST_concept(Convertible,(X)(Y)) { - void constraints() { + BOOST_CONCEPT_USAGE(Convertible) { Y y = x; ignore_unused_variable_warning(y); } + private: X x; }; @@ -297,177 +216,166 @@ struct require_same { typedef T type; }; ignore_unused_variable_warning(x); } - template - 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 - 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 - 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 \ - 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 \ - 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 - 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()); } + + 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 - struct GeneratorConcept + BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) { - void constraints() { - f(); // require operator() member function - } - Func f; - }; -#endif - - template - 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; + BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } + + 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); + } + + Func f; + Arg arg; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct UnaryFunctionConcept { - void constraints() { - f(arg); // require operator() - } - Func f; - Arg arg; - }; -#endif - - template - struct BinaryFunctionConcept + BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) { - void constraints() { - r = f(first, second); // require operator() - } - Func f; - First first; - Second second; - Return r; + BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void()); } + 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); + } + + Func f; + First first; + Second second; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct BinaryFunctionConcept + BOOST_concept(UnaryPredicate,(Func)(Arg)) { - void constraints() { - f(first, second); // require operator() - } - Func f; - First first; - Second second; - }; -#endif - - template - struct UnaryPredicateConcept - { - void constraints() { + BOOST_CONCEPT_USAGE(UnaryPredicate) { require_boolean_expr(f(arg)); // require operator() returning bool } + private: Func f; Arg arg; }; - template - 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: Func f; First a; Second b; }; // use this when functor is used inside a container class like std::set - template - struct Const_BinaryPredicateConcept { - void constraints() { + BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + { + BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { const_constraints(f); } + private: void const_constraints(const Func& fun) { - function_requires >(); // operator() must be a const member function require_boolean_expr(fun(a, b)); } @@ -476,581 +384,605 @@ struct require_same { typedef T type; }; Second b; }; - template - struct AdaptableGeneratorConcept + BOOST_concept(AdaptableGenerator,(Func)(Return)) + : Generator { - void constraints() { typedef typename Func::result_type result_type; - BOOST_STATIC_ASSERT((is_convertible::value)); - function_requires< GeneratorConcept >(); - } + + BOOST_CONCEPT_USAGE(AdaptableGenerator) + { + BOOST_CONCEPT_ASSERT((Convertible)); + } }; - template - struct AdaptableUnaryFunctionConcept + BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) + : UnaryFunction { - void constraints() { typedef typename Func::argument_type argument_type; typedef typename Func::result_type result_type; - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_convertible::value)); - function_requires< UnaryFunctionConcept >(); - } + + ~AdaptableUnaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } }; - template - 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::value)); - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_convertible::value)); - function_requires< BinaryFunctionConcept >(); - } + + ~AdaptableBinaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } }; - template - struct AdaptablePredicateConcept + BOOST_concept(AdaptablePredicate,(Func)(Arg)) + : UnaryPredicate + , AdaptableUnaryFunction { - void constraints() { - function_requires< UnaryPredicateConcept >(); - function_requires< AdaptableUnaryFunctionConcept >(); - } }; - template - struct AdaptableBinaryPredicateConcept + BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + , AdaptableBinaryFunction { - void constraints() { - function_requires< BinaryPredicateConcept >(); - function_requires< AdaptableBinaryFunctionConcept >(); - } }; //=========================================================================== // Iterator Concepts - template - struct InputIteratorConcept + BOOST_concept(InputIterator,(TT)) + : Assignable + , EqualityComparable { - void constraints() { - function_requires< AssignableConcept >(); - function_requires< EqualityComparableConcept >(); - TT j(i); - (void)*i; // require dereference operator -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - // require iterator_traits typedef's - typedef typename std::iterator_traits::difference_type D; - // Hmm, the following is a bit fragile - //function_requires< SignedIntegerConcept >(); - typedef typename std::iterator_traits::reference R; - typedef typename std::iterator_traits::pointer P; - typedef typename std::iterator_traits::iterator_category C; - function_requires< ConvertibleConcept >(); -#endif - ++j; // require preincrement operator - i++; // require postincrement operator - } + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::difference_type difference_type; + typedef typename boost::detail::iterator_traits::reference reference; + typedef typename boost::detail::iterator_traits::pointer pointer; + typedef typename boost::detail::iterator_traits::iterator_category iterator_category; + + BOOST_CONCEPT_USAGE(InputIterator) + { + BOOST_CONCEPT_ASSERT((SignedInteger)); + BOOST_CONCEPT_ASSERT((Convertible)); + + TT j(i); + (void)*i; // require dereference operator + ++j; // require preincrement operator + i++; // require postincrement operator + } + private: TT i; }; - template - struct OutputIteratorConcept + BOOST_concept(OutputIterator,(TT)(ValueT)) + : Assignable { - void constraints() { - function_requires< AssignableConcept >(); + BOOST_CONCEPT_USAGE(OutputIterator) { + ++i; // require preincrement operator i++; // require postincrement operator *i++ = t; // require postincrement and assignment } + private: TT i, j; ValueT t; }; - template - struct ForwardIteratorConcept + BOOST_concept(ForwardIterator,(TT)) + : InputIterator { - void constraints() { - function_requires< InputIteratorConcept >(); -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - typedef typename std::iterator_traits::iterator_category C; - function_requires< ConvertibleConcept >(); - typedef typename std::iterator_traits::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::reference r = *i; + ignore_unused_variable_warning(r); + } + + private: + TT i; }; - template - struct Mutable_ForwardIteratorConcept + BOOST_concept(Mutable_ForwardIterator,(TT)) + : ForwardIterator { - void constraints() { - function_requires< ForwardIteratorConcept >(); - *i++ = *i; // require postincrement and assignment - } - TT i; + BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { + *i++ = *i; // require postincrement and assignment + } + private: + TT i; }; - template - struct BidirectionalIteratorConcept + BOOST_concept(BidirectionalIterator,(TT)) + : ForwardIterator { - void constraints() { - function_requires< ForwardIteratorConcept >(); -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - typedef typename std::iterator_traits::iterator_category C; - function_requires< ConvertibleConcept >(); -#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 - struct Mutable_BidirectionalIteratorConcept + BOOST_concept(Mutable_BidirectionalIterator,(TT)) + : BidirectionalIterator + , Mutable_ForwardIterator { - void constraints() { - function_requires< BidirectionalIteratorConcept >(); - function_requires< Mutable_ForwardIteratorConcept >(); - *i-- = *i; // require postdecrement and assignment - } - TT i; + BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) + { + *i-- = *i; // require postdecrement and assignment + } + private: + TT i; }; - - template - struct RandomAccessIteratorConcept + BOOST_concept(RandomAccessIterator,(TT)) + : BidirectionalIterator + , Comparable { - void constraints() { - function_requires< BidirectionalIteratorConcept >(); - function_requires< ComparableConcept >(); -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - typedef typename std::iterator_traits::iterator_category C; - function_requires< ConvertibleConcept< C, - std::random_access_iterator_tag> >(); - typedef typename std::iterator_traits::reference R; -#endif + BOOST_CONCEPT_USAGE(RandomAccessIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::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 - } + 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::difference_type n; -#else - std::ptrdiff_t n; -#endif + typename boost::detail::iterator_traits::difference_type n; }; - template - struct Mutable_RandomAccessIteratorConcept + BOOST_concept(Mutable_RandomAccessIterator,(TT)) + : RandomAccessIterator + , Mutable_BidirectionalIterator { - void constraints() { - function_requires< RandomAccessIteratorConcept >(); - function_requires< Mutable_BidirectionalIteratorConcept >(); - 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::difference_type n; -#else - std::ptrdiff_t n; -#endif + typename boost::detail::iterator_traits::difference_type n; }; //=========================================================================== - // Container Concepts + // Container s - template - struct ContainerConcept + BOOST_concept(Container,(C)) + : Assignable { - 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; + 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; - void constraints() { - function_requires< InputIteratorConcept >(); - function_requires< AssignableConcept >(); - const_constraints(c); - } - void const_constraints(const Container& cc) { - i = cc.begin(); - i = cc.end(); - n = cc.size(); - n = cc.max_size(); - b = cc.empty(); - } - Container c; - bool b; - const_iterator i; - size_type n; + BOOST_CONCEPT_USAGE(Container) + { + BOOST_CONCEPT_ASSERT((InputIterator)); + 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 - struct Mutable_ContainerConcept + BOOST_concept(Mutable_Container,(C)) + : Container { - typedef typename Container::value_type value_type; - typedef typename Container::reference reference; - typedef typename Container::iterator iterator; - typedef typename Container::pointer pointer; + typedef typename C::reference reference; + typedef typename C::iterator iterator; + typedef typename C::pointer pointer; - void constraints() { - function_requires< ContainerConcept >(); - function_requires< AssignableConcept >(); - function_requires< InputIteratorConcept >(); - - i = c.begin(); - i = c.end(); - c.swap(c2); - } - iterator i; - Container c, c2; + BOOST_CONCEPT_USAGE(Mutable_Container) + { + BOOST_CONCEPT_ASSERT(( + Assignable)); + + BOOST_CONCEPT_ASSERT((InputIterator)); + + i = c.begin(); + i = c.end(); + c.swap(c2); + } + + private: + iterator i; + C c, c2; }; - template - struct ForwardContainerConcept + BOOST_concept(ForwardContainer,(C)) + : Container { - void constraints() { - function_requires< ContainerConcept >(); - typedef typename ForwardContainer::const_iterator const_iterator; - function_requires< ForwardIteratorConcept >(); - } + BOOST_CONCEPT_USAGE(ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + ForwardIterator< + typename ForwardContainer::const_iterator + >)); + } }; - template - struct Mutable_ForwardContainerConcept + BOOST_concept(Mutable_ForwardContainer,(C)) + : ForwardContainer + , Mutable_Container { - void constraints() { - function_requires< ForwardContainerConcept >(); - function_requires< Mutable_ContainerConcept >(); - typedef typename ForwardContainer::iterator iterator; - function_requires< Mutable_ForwardIteratorConcept >(); - } + BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + Mutable_ForwardIterator< + typename Mutable_ForwardContainer::iterator + >)); + } }; - template - struct ReversibleContainerConcept + BOOST_concept(ReversibleContainer,(C)) + : ForwardContainer { - 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 >(); - function_requires< BidirectionalIteratorConcept >(); - function_requires< - BidirectionalIteratorConcept >(); - const_constraints(c); - } - void const_constraints(const ReversibleContainer& cc) { - const_reverse_iterator i = cc.rbegin(); - i = cc.rend(); - } - ReversibleContainer c; + BOOST_CONCEPT_USAGE(ReversibleContainer) + { + BOOST_CONCEPT_ASSERT(( + BidirectionalIterator< + typename ReversibleContainer::const_iterator>)); + + BOOST_CONCEPT_ASSERT((BidirectionalIterator)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reverse_iterator i = cc.rbegin(); + i = cc.rend(); + } + C c; }; - template - struct Mutable_ReversibleContainerConcept + BOOST_concept(Mutable_ReversibleContainer,(C)) + : Mutable_ForwardContainer + , ReversibleContainer { - typedef typename ReversibleContainer::iterator iterator; - typedef typename ReversibleContainer::reverse_iterator reverse_iterator; - - void constraints() { - function_requires< ReversibleContainerConcept >(); - function_requires< - Mutable_ForwardContainerConcept >(); - function_requires< Mutable_BidirectionalIteratorConcept >(); - function_requires< - Mutable_BidirectionalIteratorConcept >(); - - 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::iterator iterator; + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + + reverse_iterator i = c.rbegin(); + i = c.rend(); + } + private: + C c; }; - template - struct RandomAccessContainerConcept + BOOST_concept(RandomAccessContainer,(C)) + : ReversibleContainer { - 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; + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; - void constraints() { - function_requires< ReversibleContainerConcept >(); - function_requires< RandomAccessIteratorConcept >(); - function_requires< - RandomAccessIteratorConcept >(); - - const_constraints(c); - } - void const_constraints(const RandomAccessContainer& cc) { - const_reference r = cc[n]; - ignore_unused_variable_warning(r); - } - RandomAccessContainer c; - size_type n; + 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 - struct Mutable_RandomAccessContainerConcept + BOOST_concept(Mutable_RandomAccessContainer,(C)) + : Mutable_ReversibleContainer + , RandomAccessContainer { - 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 >(); - function_requires< - Mutable_ReversibleContainerConcept >(); - function_requires< Mutable_RandomAccessIteratorConcept >(); - function_requires< - Mutable_RandomAccessIteratorConcept >(); - - 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)); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + + typename self::reference r = c[i]; + ignore_unused_variable_warning(r); + } + + private: + typename Mutable_ReversibleContainer::size_type i; + C c; }; // A Sequence is inherently mutable - template - struct SequenceConcept - { - - typedef typename Sequence::reference reference; - typedef typename Sequence::const_reference const_reference; - - void constraints() { + BOOST_concept(Sequence,(S)) + : Mutable_ForwardContainer // Matt Austern's book puts DefaultConstructible here, the C++ - // standard places it in Container - // function_requires< DefaultConstructible >(); - function_requires< Mutable_ForwardContainerConcept >(); - function_requires< DefaultConstructibleConcept >(); - - 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; - }; - - template - struct FrontInsertionSequenceConcept + // standard places it in Container --JGS + // ... so why aren't we following the standard? --DWA + , DefaultConstructible { - void constraints() { - function_requires< SequenceConcept >(); + BOOST_CONCEPT_USAGE(Sequence) + { + S + c(n), + c2(n, t), + c3(first, last); - c.push_front(t); - c.pop_front(); - } - FrontInsertionSequence c; - typename FrontInsertionSequence::value_type t; - }; + c.insert(p, t); + c.insert(p, n, t); + c.insert(p, first, last); - template - struct BackInsertionSequenceConcept - { - typedef typename BackInsertionSequence::reference reference; - typedef typename BackInsertionSequence::const_reference const_reference; + c.erase(p); + c.erase(p, q); - void constraints() { - function_requires< SequenceConcept >(); + typename Sequence::reference r = c.front(); - c.push_back(t); - c.pop_back(); - reference r = c.back(); - ignore_unused_variable_warning(r); - } - void const_constraints(const BackInsertionSequence& cc) { - const_reference r = cc.back(); - ignore_unused_variable_warning(r); - }; - BackInsertionSequence c; - typename BackInsertionSequence::value_type t; - }; - - template - struct AssociativeContainerConcept - { - void constraints() { - function_requires< ForwardContainerConcept >(); - function_requires< DefaultConstructibleConcept >(); + 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); + } - 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& cc) { - ci = cc.find(k); - n = cc.count(k); - cr = cc.equal_range(k); - } - typedef typename AssociativeContainer::iterator iterator; - typedef typename AssociativeContainer::const_iterator const_iterator; - - AssociativeContainer c; - iterator i; - std::pair r; - const_iterator ci; - std::pair cr; - typename AssociativeContainer::key_type k; - typename AssociativeContainer::size_type n; + typename S::value_type t; + typename S::size_type n; + typename S::value_type* first, *last; + typename S::iterator p, q; }; - template - struct UniqueAssociativeContainerConcept + BOOST_concept(FrontInsertionSequence,(S)) + : Sequence { - void constraints() { - function_requires< AssociativeContainerConcept >(); - - UniqueAssociativeContainer c(first, last); + BOOST_CONCEPT_USAGE(FrontInsertionSequence) + { + c.push_front(t); + c.pop_front(); + } + private: + S c; + typename S::value_type t; + }; + + BOOST_concept(BackInsertionSequence,(S)) + : Sequence + { + 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; + }; + + BOOST_concept(AssociativeContainer,(C)) + : ForwardContainer + , DefaultConstructible + { + 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)); + + typedef typename AssociativeContainer::value_type value_type_; + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + } - pos_flag = c.insert(t); - c.insert(first, last); + // 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); + } - ignore_unused_variable_warning(c); - } - std::pair pos_flag; - typename UniqueAssociativeContainer::value_type t; - typename UniqueAssociativeContainer::value_type* first, *last; + C c; + iterator i; + std::pair r; + const_iterator ci; + std::pair cr; + typename C::key_type k; + typename C::size_type n; }; - template - struct MultipleAssociativeContainerConcept + BOOST_concept(UniqueAssociativeContainer,(C)) + : AssociativeContainer { - void constraints() { - function_requires< AssociativeContainerConcept >(); - - MultipleAssociativeContainer c(first, last); + BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) + { + C c(first, last); - pos = c.insert(t); - c.insert(first, last); + pos_flag = 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; + ignore_unused_variable_warning(c); + } + private: + std::pair pos_flag; + typename C::value_type t; + typename C::value_type* first, *last; }; - template - struct SimpleAssociativeContainerConcept + BOOST_concept(MultipleAssociativeContainer,(C)) + : AssociativeContainer { - void constraints() { - function_requires< AssociativeContainerConcept >(); - typedef typename SimpleAssociativeContainer::key_type key_type; - typedef typename SimpleAssociativeContainer::value_type value_type; - typedef typename require_same::type req; - } - }; - - template - struct PairAssociativeContainerConcept - { - void constraints() { - function_requires< AssociativeContainerConcept >(); - typedef typename SimpleAssociativeContainer::key_type key_type; - typedef typename SimpleAssociativeContainer::value_type value_type; - typedef typename SimpleAssociativeContainer::mapped_type mapped_type; - typedef std::pair required_value_type; - typedef typename require_same::type req; - } - }; - - template - struct SortedAssociativeContainerConcept - { - void constraints() { - function_requires< AssociativeContainerConcept >(); - function_requires< ReversibleContainerConcept >(); - - 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); + BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) + { + C c(first, last); - 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(); + pos = c.insert(t); + c.insert(first, last); - 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 r; - std::pair cr; - typename SortedAssociativeContainer::value_type* 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; + }; + + BOOST_concept(SimpleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(PairAssociativeContainer,(C)) + : AssociativeContainer + { + 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 required_value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(SortedAssociativeContainer,(C)) + : AssociativeContainer + , ReversibleContainer + { + 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 r; + std::pair cr; + typename C::value_type* first, *last; }; // HashedAssociativeContainer } // namespace boost +# include + #endif // BOOST_CONCEPT_CHECKS_HPP diff --git a/include/boost/concept_check/borland.hpp b/include/boost/concept_check/borland.hpp new file mode 100755 index 0000000..107926b --- /dev/null +++ b/include/boost/concept_check/borland.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP + +namespace boost { + +template +struct concept_check; + +template +struct concept_check +{ + enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; +}; + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concept_check::instantiate \ + } + +} // namespace boost::concept_checking + +#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP diff --git a/include/boost/concept_check/general.hpp b/include/boost/concept_check/general.hpp new file mode 100755 index 0000000..cd09fb0 --- /dev/null +++ b/include/boost/concept_check/general.hpp @@ -0,0 +1,82 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +// This implementation works on GCC and Comeau, but has actually been +// fairly carefully tuned to work on GCC versions starting with +// gcc-2.95.x. If you're trying to get an additional compiler to pass +// the tests you might consider breaking out a separate gcc.hpp and +// starting over on the general case. +namespace boost +{ + namespace concept_checking + { + template struct instantiate {}; + } + + template struct concept_check_; + + template + void concept_check_failed() + { + ((Model*)0)->~Model(); + } + + template + struct concept_check + { + concept_checking::instantiate > x; + enum { instantiate = 1 }; + }; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + template + void constraint_check_failed() + { + ((Model*)0)->constraints(); + } + + template + struct constraint_check + { + concept_checking::instantiate > x; + enum { instantiate = 1 }; + }; + + template + struct concept_check_ + : mpl::if_c< + concept_checking::has_constraints::value + , constraint_check + , concept_check + >::type + {}; + +# else + + template + struct concept_check_ + : concept_check + {}; + +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + ::boost::concept_check_::instantiate \ + } +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/include/boost/concept_check/has_constraints.hpp b/include/boost/concept_check/has_constraints.hpp new file mode 100755 index 0000000..e19f664 --- /dev/null +++ b/include/boost/concept_check/has_constraints.hpp @@ -0,0 +1,31 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP + +namespace boost { namespace concept_checking { + +// Here we implement the "metafunction" that detects whether a +// constraints metafunction exists +typedef char yes; +typedef char (&no)[2]; + +template +struct wrap_constraints {}; + +template +inline yes has_constraints_(Model*, wrap_constraints* = 0); +inline no has_constraints_(...); + +template +struct has_constraints +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( concept_checking::has_constraints_((Model*)0) ) == 1 ); +}; + +}} // namespace boost::concept_checking + +#endif // BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/include/boost/concept_check/msvc.hpp b/include/boost/concept_check/msvc.hpp new file mode 100755 index 0000000..3968469 --- /dev/null +++ b/include/boost/concept_check/msvc.hpp @@ -0,0 +1,90 @@ +// Copyright David Abrahams 2006. 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) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +namespace boost +{ + namespace concept_checking + { + template + struct concept_check_ + { + virtual void failed(Model* x) + { + x->~Model(); + } + }; + } + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + namespace concept_checking + { + template + struct constraint_check + { + virtual void failed(Model* x) + { + x->constraints(); + } + }; + } + + template + struct concept_check + : mpl::if_c< + concept_checking::has_constraints::value + , concept_checking::constraint_check + , concept_checking::concept_check_ + >::type + {}; + +# else + + template + struct concept_check + : concept_checking::concept_check_ + {}; + +# endif + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + + // + // The iterator library sees some really strange errors unless we + // use partial specialization to extract the model type with + // msvc-7.1 + // + template + struct concept_check + : concept_check + { }; + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check) \ + } + +# else + + template + concept_check + concept_check_(void(*)(Model)); + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \ + } + +# endif +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP