From 24326c9df51d4fcaa0027380b55304cad6173dae Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Apr 2006 20:27:14 +0000 Subject: [PATCH] Fixes for concept checking; use destructors for checking classes, misc cleanup. [SVN r33862] --- Jamfile | 17 +- Jamfile.v2 | 16 +- class_concept_check_test.cpp | 16 +- class_concept_fail_expected.cpp | 13 +- concept_check_fail_expected.cpp | 10 +- function_requires_fail.cpp | 26 + include/boost/concept_check.hpp | 545 ++++++++---------- include/boost/concept_check/Attic/borland.hpp | 25 + include/boost/concept_check/Attic/general.hpp | 82 +++ .../concept_check/Attic/has_constraints.hpp | 31 + include/boost/concept_check/Attic/msvc.hpp | 62 ++ include/boost/concept_check/borland.hpp | 25 + include/boost/concept_check/general.hpp | 82 +++ .../boost/concept_check/has_constraints.hpp | 31 + include/boost/concept_check/msvc.hpp | 62 ++ old_concept_class_fail.cpp | 28 + old_concept_function_fail.cpp | 23 + old_concept_pass.cpp | 34 ++ old_concepts.hpp | 67 +++ 19 files changed, 864 insertions(+), 331 deletions(-) create mode 100755 function_requires_fail.cpp create mode 100755 include/boost/concept_check/Attic/borland.hpp create mode 100755 include/boost/concept_check/Attic/general.hpp create mode 100755 include/boost/concept_check/Attic/has_constraints.hpp create mode 100755 include/boost/concept_check/Attic/msvc.hpp create mode 100755 include/boost/concept_check/borland.hpp create mode 100755 include/boost/concept_check/general.hpp create mode 100755 include/boost/concept_check/has_constraints.hpp create mode 100755 include/boost/concept_check/msvc.hpp create mode 100755 old_concept_class_fail.cpp create mode 100755 old_concept_function_fail.cpp create mode 100755 old_concept_pass.cpp create mode 100755 old_concepts.hpp diff --git a/Jamfile b/Jamfile index 7cd68ec..782ed1a 100644 --- a/Jamfile +++ b/Jamfile @@ -3,9 +3,16 @@ subproject libs/concept_check ; import testing ; test-suite concept_check - : [ compile stl_concept_covering.cpp ] - [ compile concept_check_test.cpp ] - [ compile class_concept_check_test.cpp ] - [ link-fail concept_check_fail_expected.cpp ] - [ link-fail class_concept_fail_expected.cpp ] + : [ run stl_concept_covering.cpp ] + [ run concept_check_test.cpp ] + [ run class_concept_check_test.cpp ] + [ compile-fail concept_check_fail_expected.cpp ] + [ compile-fail class_concept_fail_expected.cpp ] + + # Backward compatibility tests + [ run old_concept_pass.cpp ] + [ compile-fail function_requires_fail.cpp ] + [ compile-fail old_concept_function_fail.cpp ] + [ compile-fail old_concept_class_fail.cpp ] ; + diff --git a/Jamfile.v2 b/Jamfile.v2 index 84bbb6d..a37786a 100644 --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -2,9 +2,15 @@ import testing ; test-suite concept_check - : [ compile stl_concept_covering.cpp ] - [ compile concept_check_test.cpp ] - [ compile class_concept_check_test.cpp ] - [ link-fail concept_check_fail_expected.cpp ] - [ link-fail class_concept_fail_expected.cpp ] + : [ run stl_concept_covering.cpp ] + [ run concept_check_test.cpp ] + [ run class_concept_check_test.cpp ] + [ compile-fail concept_check_fail_expected.cpp ] + [ compile-fail class_concept_fail_expected.cpp ] + + # Backward compatibility tests + [ run old_concept_pass.cpp ] + [ compile-fail function_requires_fail.cpp ] + [ compile-fail old_concept_function_fail.cpp ] + [ compile-fail old_concept_class_fail.cpp ] ; diff --git a/class_concept_check_test.cpp b/class_concept_check_test.cpp index e941682..d99845c 100644 --- a/class_concept_check_test.cpp +++ b/class_concept_check_test.cpp @@ -18,17 +18,17 @@ struct bar { bool operator()(int, char) { return true; } }; class class_requires_test { - BOOST_CLASS_REQUIRE(int, boost, EqualityComparableConcept); - typedef int* int_ptr; typedef const int* const_int_ptr; - BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, boost, EqualOpConcept); - BOOST_CLASS_REQUIRE3(foo, bool, int, boost, UnaryFunctionConcept); - BOOST_CLASS_REQUIRE4(bar, bool, int, char, boost, BinaryFunctionConcept); + BOOST_CONCEPT_ASSERT((boost::EqualityComparableConcept)); + typedef int* int_ptr; typedef const int* const_int_ptr; + BOOST_CONCEPT_ASSERT((boost::EqualOpConcept)); + BOOST_CONCEPT_ASSERT((boost::UnaryFunctionConcept)); +// BOOST_CONCEPT_ASSERT((boost::BinaryFunctionConcept)); }; int main() { - class_requires_test x; - boost::ignore_unused_variable_warning(x); - return 0; + class_requires_test x; + boost::ignore_unused_variable_warning(x); + return 0; } diff --git a/class_concept_fail_expected.cpp b/class_concept_fail_expected.cpp index 11f7f52..6cafbd4 100644 --- a/class_concept_fail_expected.cpp +++ b/class_concept_fail_expected.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2000. +// (C) Copyright Jeremy Siek, David Abrahams 2000-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) @@ -11,21 +11,22 @@ /* This file verifies that class_requires of the Boost Concept Checking - Library catches errors when it is suppose to. + Library catches errors when it is supposed to. */ struct foo { }; +template class class_requires_test { - BOOST_CLASS_REQUIRE(foo, boost, EqualityComparableConcept); + BOOST_CONCEPT_ASSERT((boost::EqualityComparableConcept)); }; int main() { - class_requires_test x; - (void)x; // suppress unused variable warning - return 0; + class_requires_test x; + (void)x; // suppress unused variable warning + return 0; } diff --git a/concept_check_fail_expected.cpp b/concept_check_fail_expected.cpp index 789bdf4..f213ab5 100644 --- a/concept_check_fail_expected.cpp +++ b/concept_check_fail_expected.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2000. +// (C) Copyright Jeremy Siek, David Abrahams 2000-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) @@ -11,8 +11,8 @@ /* - This file verifies that function_requires() of the Boost Concept - Checking Library catches errors when it is suppose to. + This file verifies that BOOST_CONCEPT_ASSERT catches errors in + function context. */ @@ -21,6 +21,6 @@ struct foo { }; int main() { - boost::function_requires< boost::EqualityComparableConcept >(); - return 0; + BOOST_CONCEPT_ASSERT((boost::EqualityComparableConcept)); + return 0; } diff --git a/function_requires_fail.cpp b/function_requires_fail.cpp new file mode 100755 index 0000000..5c9a4f3 --- /dev/null +++ b/function_requires_fail.cpp @@ -0,0 +1,26 @@ +// (C) Copyright Jeremy Siek 2000. +// 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) + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include + +/* + + This file verifies that function_requires() of the Boost Concept + Checking Library catches errors when it is suppose to. + +*/ + +struct foo { }; + +int +main() +{ + boost::function_requires< boost::EqualityComparableConcept >(); + return 0; +} diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp index eaa4ba0..c8aef71 100644 --- a/include/boost/concept_check.hpp +++ b/include/boost/concept_check.hpp @@ -20,6 +20,7 @@ # include # include # include +# include # include # include # include @@ -28,79 +29,28 @@ # 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_SFINAE) && !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) +# define BOOST_OLD_CONCEPT_SUPPORT +# endif + +# ifdef BOOST_MSVC +# include +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +# else +# include +# endif + namespace boost { -/* - "inline" is used for ignore_unused_variable_warning() - and function_requires() to make sure there is no - overhead with g++. - */ - -# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ - && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x543)) - namespace concept_checking - { - template - void* failed(BOOST_EXPLICIT_TEMPLATE_TYPE(Model)) - { return new ((void*)0) Model; } - - template struct instantiate; - } - - template - struct concept_check - { - typedef typename boost::parameter::aux::unaryfunptr_arg_type::type model; - typedef concept_checking::instantiate > type; - - enum { instantiate = 1 }; - }; - -# else - namespace concept_checking - { - template - struct test - { - static void inline failed() { new ((void*)0) T; } - }; - - template inline void instantiate(T const&) {} - } - - template - struct concept_check - { - typedef typename boost::parameter::aux::unaryfunptr_arg_type::type model; - -# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) - // This occasionally causes ICE with vc6, and in-class checks - // don't work with that compiler anyway, and if you want the - // in-function checks to work you have to use - // function_requires<>, so disabling it does no harm. - virtual void failed() { new ((void*)0) model; } -# endif - - enum { instantiate = 1 }; - }; -# endif - - // Usage, in class or function context: - // - // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); - // - // This macro works everywhere except vc-6.0 and Borland. On those - // compilers it will be innocuous but will never cause a compilation - // error. Concept checks at class level seem to be impossible on - // those compilers. If you want to see errors at function level, - // you have to use the old boost_function_requires idiom, which - // works everywhere. -# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ - typedef int BOOST_PP_CAT(boost_concept_check,__LINE__)[ \ - ::boost::concept_check< void(*)ModelInParens >::instantiate \ - ] - // // Backward compatibility // @@ -108,14 +58,8 @@ namespace boost template inline void function_requires(BOOST_EXPLICIT_TEMPLATE_TYPE(Model)) { -# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ - || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x543)) - concept_checking::instantiate(&concept_checking::test::failed); -# else BOOST_CONCEPT_ASSERT((Model)); -# endif } - template inline void ignore_unused_variable_warning(T const&) {} # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ @@ -130,65 +74,59 @@ namespace boost # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ BOOST_CONCEPT_ASSERT((ns::concept)) + + // + // Begin concept definitions + // template struct IntegerConcept { - IntegerConcept() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + ~IntegerConcept() { x.error_type_must_be_an_integer_type(); -#endif } private: - static T x; + T x; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template <> struct IntegerConcept { IntegerConcept() {} }; - template <> struct IntegerConcept { IntegerConcept() {} }; - template <> struct IntegerConcept { IntegerConcept() {} }; - template <> struct IntegerConcept { IntegerConcept() {} }; - template <> struct IntegerConcept { IntegerConcept() {} }; - template <> struct IntegerConcept { IntegerConcept() {} }; + + template <> struct IntegerConcept { ~IntegerConcept() {} }; + template <> struct IntegerConcept { ~IntegerConcept() {} }; + template <> struct IntegerConcept { ~IntegerConcept() {} }; + template <> struct IntegerConcept { ~IntegerConcept() {} }; + template <> struct IntegerConcept { ~IntegerConcept() {} }; + template <> struct IntegerConcept { ~IntegerConcept() {} }; // etc. -#endif template struct SignedIntegerConcept { - SignedIntegerConcept() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + ~SignedIntegerConcept() { x.error_type_must_be_a_signed_integer_type(); -#endif } private: - static T x; + T x; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template <> struct SignedIntegerConcept { SignedIntegerConcept() {} }; - template <> struct SignedIntegerConcept { SignedIntegerConcept() {} }; - template <> struct SignedIntegerConcept { SignedIntegerConcept() {} }; + template <> struct SignedIntegerConcept { ~SignedIntegerConcept() {} }; + template <> struct SignedIntegerConcept { ~SignedIntegerConcept() {} }; + template <> struct SignedIntegerConcept { ~SignedIntegerConcept() {} }; # if defined(BOOST_HAS_LONG_LONG) - template <> struct SignedIntegerConcept< ::boost::long_long_type> { SignedIntegerConcept() {} }; -# endif + template <> struct SignedIntegerConcept< ::boost::long_long_type> { ~SignedIntegerConcept() {} }; // etc. #endif template struct UnsignedIntegerConcept { - UnsignedIntegerConcept() { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + ~UnsignedIntegerConcept() { x.error_type_must_be_an_unsigned_integer_type(); -#endif } private: - static T x; + T x; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template <> struct UnsignedIntegerConcept - { UnsignedIntegerConcept() {} }; + { ~UnsignedIntegerConcept() {} }; template <> struct UnsignedIntegerConcept - { UnsignedIntegerConcept() {} }; + { ~UnsignedIntegerConcept() {} }; template <> struct UnsignedIntegerConcept - { UnsignedIntegerConcept() {} }; + { ~UnsignedIntegerConcept() {} }; // etc. -#endif //=========================================================================== // Basic Concepts @@ -196,7 +134,7 @@ namespace boost template struct DefaultConstructibleConcept { - DefaultConstructibleConcept() { + ~DefaultConstructibleConcept() { TT a; // require default constructor ignore_unused_variable_warning(a); } @@ -205,7 +143,7 @@ namespace boost template struct AssignableConcept { - AssignableConcept() { + ~AssignableConcept() { #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL a = a; // require assignment operator #endif @@ -218,13 +156,13 @@ namespace boost #endif } private: - static TT a; + TT a; }; template struct CopyConstructibleConcept { - CopyConstructibleConcept() { + ~CopyConstructibleConcept() { TT a(b); // require copy constructor TT* ptr = &a; // require address of operator const_constraints(a); @@ -237,14 +175,14 @@ namespace boost ignore_unused_variable_warning(c); ignore_unused_variable_warning(ptr); } - static TT b; + TT b; }; // The SGI STL version of Assignable requires copy constructor and operator= template struct SGIAssignableConcept { - SGIAssignableConcept() { + ~SGIAssignableConcept() { TT b(a); #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL a = a; // require assignment operator @@ -260,18 +198,18 @@ namespace boost #endif ignore_unused_variable_warning(c); } - static TT a; + TT a; }; template struct ConvertibleConcept { - ConvertibleConcept() { + ~ConvertibleConcept() { Y y = x; ignore_unused_variable_warning(y); } private: - static X x; + X x; }; // The C++ standard requirements for many concepts talk about return @@ -292,60 +230,60 @@ namespace boost template struct EqualityComparableConcept { - EqualityComparableConcept() { + ~EqualityComparableConcept() { require_boolean_expr(a == b); require_boolean_expr(a != b); } private: - static TT a, b; + TT a, b; }; template struct LessThanComparableConcept { - LessThanComparableConcept() { + ~LessThanComparableConcept() { require_boolean_expr(a < b); } private: - static TT a, b; + TT a, b; }; // This is equivalent to SGI STL's LessThanComparable. template struct ComparableConcept { - ComparableConcept() { + ~ComparableConcept() { require_boolean_expr(a < b); require_boolean_expr(a > b); require_boolean_expr(a <= b); require_boolean_expr(a >= b); } private: - static TT a, b; + TT a, b; }; #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ template \ struct NAME { \ - NAME() { (void)constraints_(); } \ + ~NAME() { (void)constraints_(); } \ private: \ bool constraints_() { \ return a OP b; \ } \ - static First a; \ - static Second b; \ + First a; \ + Second b; \ } #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ template \ struct NAME { \ - NAME() { (void)constraints_(); } \ + ~NAME() { (void)constraints_(); } \ private: \ Ret constraints_() { \ return a OP b; \ } \ - static First a; \ - static Second b; \ + First a; \ + Second b; \ } BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept); @@ -367,99 +305,91 @@ namespace boost template struct GeneratorConcept { - GeneratorConcept() { - const Return& r = f(); // require operator() member function - ignore_unused_variable_warning(r); - } + ~GeneratorConcept() { test(is_void()); } + private: - static Func f; + 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 - { - GeneratorConcept() { - f(); // require operator() member function - } - private: - static Func f; - }; -#endif - template struct UnaryFunctionConcept { - UnaryFunctionConcept() { - r = f(arg); // require operator() - } + ~UnaryFunctionConcept() { test(is_void()); } + private: - static Func f; - static Arg arg; - static Return r; + 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 { - UnaryFunctionConcept() { - f(arg); // require operator() - } - private: - static Func f; - static Arg arg; - }; -#endif - template struct BinaryFunctionConcept { - BinaryFunctionConcept() { - r = f(first, second); // require operator() - } + ~BinaryFunctionConcept() { test(is_void()); } private: - static Func f; - static First first; - static Second second; - static Return r; + 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; + Return r; }; -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct BinaryFunctionConcept - { - BinaryFunctionConcept() { - f(first, second); // require operator() - } - private: - static Func f; - static First first; - static Second second; - }; -#endif - template struct UnaryPredicateConcept { - UnaryPredicateConcept() { + ~UnaryPredicateConcept() { require_boolean_expr(f(arg)); // require operator() returning bool } private: - static Func f; - static Arg arg; + Func f; + Arg arg; }; template struct BinaryPredicateConcept { - BinaryPredicateConcept() { + ~BinaryPredicateConcept() { require_boolean_expr(f(a, b)); // require operator() returning bool } private: - static Func f; - static First a; - static Second b; + Func f; + First a; + Second b; }; // use this when functor is used inside a container class like std::set @@ -467,7 +397,7 @@ namespace boost struct Const_BinaryPredicateConcept : BinaryPredicateConcept { - Const_BinaryPredicateConcept() { + ~Const_BinaryPredicateConcept() { const_constraints(f); } private: @@ -475,9 +405,9 @@ namespace boost // operator() must be a const member function require_boolean_expr(fun(a, b)); } - static Func f; - static First a; - static Second b; + Func f; + First a; + Second b; }; template @@ -486,7 +416,7 @@ namespace boost { typedef typename Func::result_type result_type; - AdaptableGeneratorConcept() + ~AdaptableGeneratorConcept() { BOOST_MPL_ASSERT((is_convertible)); } @@ -499,7 +429,7 @@ namespace boost typedef typename Func::argument_type argument_type; typedef typename Func::result_type result_type; - AdaptableUnaryFunctionConcept() + ~AdaptableUnaryFunctionConcept() { BOOST_MPL_ASSERT((is_convertible)); BOOST_MPL_ASSERT((is_convertible)); @@ -519,7 +449,7 @@ namespace boost typedef typename Func::second_argument_type second_argument_type; typedef typename Func::result_type result_type; - AdaptableBinaryFunctionConcept() + ~AdaptableBinaryFunctionConcept() { BOOST_MPL_ASSERT((is_convertible)); BOOST_MPL_ASSERT((is_convertible)); @@ -554,10 +484,10 @@ namespace boost typedef typename boost::detail::iterator_traits::pointer pointer; typedef typename boost::detail::iterator_traits::iterator_category iterator_category; - InputIteratorConcept() + ~InputIteratorConcept() { - SignedIntegerConcept(); - ConvertibleConcept(); + BOOST_CONCEPT_ASSERT((SignedIntegerConcept)); + BOOST_CONCEPT_ASSERT((ConvertibleConcept)); TT j(i); (void)*i; // require dereference operator @@ -565,70 +495,70 @@ namespace boost i++; // require postincrement operator } private: - static TT i; + TT i; }; template struct OutputIteratorConcept : AssignableConcept { - OutputIteratorConcept() { + ~OutputIteratorConcept() { ++i; // require preincrement operator i++; // require postincrement operator *i++ = t; // require postincrement and assignment } private: - static TT i, j; - static ValueT t; + TT i, j; + ValueT t; }; template struct ForwardIteratorConcept : InputIteratorConcept { - ForwardIteratorConcept() + ~ForwardIteratorConcept() { - ConvertibleConcept< + BOOST_CONCEPT_ASSERT((ConvertibleConcept< BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::iterator_category , std::forward_iterator_tag - >(); + >)); typename InputIteratorConcept::reference r = *i; ignore_unused_variable_warning(r); } private: - static TT i; + TT i; }; template struct Mutable_ForwardIteratorConcept : ForwardIteratorConcept { - Mutable_ForwardIteratorConcept() { + ~Mutable_ForwardIteratorConcept() { *i++ = *i; // require postincrement and assignment } private: - static TT i; + TT i; }; template struct BidirectionalIteratorConcept : ForwardIteratorConcept { - BidirectionalIteratorConcept() + ~BidirectionalIteratorConcept() { - ConvertibleConcept< + BOOST_CONCEPT_ASSERT((ConvertibleConcept< BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::iterator_category , std::bidirectional_iterator_tag - >(); + >)); --i; // require predecrement operator i--; // require postdecrement operator } private: - static TT i; + TT i; }; template @@ -636,12 +566,12 @@ namespace boost : BidirectionalIteratorConcept , Mutable_ForwardIteratorConcept { - Mutable_BidirectionalIteratorConcept() + ~Mutable_BidirectionalIteratorConcept() { *i-- = *i; // require postdecrement and assignment } private: - static TT i; + TT i; }; @@ -650,12 +580,12 @@ namespace boost : BidirectionalIteratorConcept , ComparableConcept { - RandomAccessIteratorConcept() + ~RandomAccessIteratorConcept() { - ConvertibleConcept< + BOOST_CONCEPT_ASSERT((ConvertibleConcept< BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::iterator_category , std::random_access_iterator_tag - >(); + >)); i += n; // require assignment addition operator i = i + n; i = n + i; // require addition with difference type @@ -666,8 +596,8 @@ namespace boost } private: - static TT a, b; - static TT i, j; + TT a, b; + TT i, j; typename boost::detail::iterator_traits::difference_type n; }; @@ -676,11 +606,11 @@ namespace boost : RandomAccessIteratorConcept , Mutable_BidirectionalIteratorConcept { - Mutable_RandomAccessIteratorConcept() { + ~Mutable_RandomAccessIteratorConcept() { i[n] = *i; // require element access and assignment } private: - static TT i; + TT i; typename boost::detail::iterator_traits::difference_type n; }; @@ -698,9 +628,9 @@ namespace boost typedef typename Container::const_pointer const_pointer; typedef typename Container::const_iterator const_iterator; - ContainerConcept() + ~ContainerConcept() { - InputIteratorConcept(); + BOOST_CONCEPT_ASSERT((InputIteratorConcept)); const_constraints(c); } @@ -712,10 +642,10 @@ namespace boost n = cc.max_size(); b = cc.empty(); } - static Container c; - static bool b; - static const_iterator i; - static size_type n; + Container c; + bool b; + const_iterator i; + size_type n; }; template @@ -726,10 +656,12 @@ namespace boost typedef typename Container::iterator iterator; typedef typename Container::pointer pointer; - Mutable_ContainerConcept() + ~Mutable_ContainerConcept() { - AssignableConcept(); - InputIteratorConcept(); + BOOST_CONCEPT_ASSERT(( + AssignableConcept)); + + BOOST_CONCEPT_ASSERT((InputIteratorConcept)); i = c.begin(); i = c.end(); @@ -737,17 +669,20 @@ namespace boost } private: - static iterator i; - static Container c, c2; + iterator i; + Container c, c2; }; template struct ForwardContainerConcept : ContainerConcept { - ForwardContainerConcept() + ~ForwardContainerConcept() { - ForwardIteratorConcept(); + BOOST_CONCEPT_ASSERT(( + ForwardIteratorConcept< + typename ForwardContainerConcept::const_iterator + >)); } }; @@ -756,11 +691,12 @@ namespace boost : ForwardContainerConcept , Mutable_ContainerConcept { - Mutable_ForwardContainerConcept() + ~Mutable_ForwardContainerConcept() { - Mutable_ForwardIteratorConcept< - typename Mutable_ForwardContainerConcept::iterator - >(); + BOOST_CONCEPT_ASSERT(( + Mutable_ForwardIteratorConcept< + typename Mutable_ForwardContainerConcept::iterator + >)); } }; @@ -772,10 +708,14 @@ namespace boost ReversibleContainer::const_reverse_iterator const_reverse_iterator; - ReversibleContainerConcept() + ~ReversibleContainerConcept() { - BidirectionalIteratorConcept(); - BidirectionalIteratorConcept(); + BOOST_CONCEPT_ASSERT(( + BidirectionalIteratorConcept< + typename ReversibleContainerConcept::const_iterator>)); + + BOOST_CONCEPT_ASSERT((BidirectionalIteratorConcept)); + const_constraints(c); } private: @@ -784,7 +724,7 @@ namespace boost const_reverse_iterator i = cc.rbegin(); i = cc.rend(); } - static ReversibleContainer c; + ReversibleContainer c; }; template @@ -795,15 +735,15 @@ namespace boost typedef typename ReversibleContainer::iterator iterator; typedef typename ReversibleContainer::reverse_iterator reverse_iterator; - Mutable_ReversibleContainerConcept() + ~Mutable_ReversibleContainerConcept() { - Mutable_BidirectionalIteratorConcept(); - Mutable_BidirectionalIteratorConcept(); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIteratorConcept)); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIteratorConcept)); reverse_iterator i = c.rbegin(); i = c.rend(); } private: - static ReversibleContainer c; + ReversibleContainer c; }; template @@ -813,11 +753,12 @@ namespace boost typedef typename RandomAccessContainer::size_type size_type; typedef typename RandomAccessContainer::const_reference const_reference; - RandomAccessContainerConcept() + ~RandomAccessContainerConcept() { - RandomAccessIteratorConcept< - typename RandomAccessContainerConcept::const_iterator - >(); + BOOST_CONCEPT_ASSERT(( + RandomAccessIteratorConcept< + typename RandomAccessContainerConcept::const_iterator + >)); const_constraints(c); } @@ -828,8 +769,8 @@ namespace boost ignore_unused_variable_warning(r); } - static RandomAccessContainer c; - static size_type n; + RandomAccessContainer c; + size_type n; }; template @@ -840,18 +781,18 @@ namespace boost private: typedef Mutable_RandomAccessContainerConcept self; public: - Mutable_RandomAccessContainerConcept() + ~Mutable_RandomAccessContainerConcept() { - Mutable_RandomAccessIteratorConcept(); - Mutable_RandomAccessIteratorConcept(); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIteratorConcept)); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIteratorConcept)); typename self::reference r = c[i]; ignore_unused_variable_warning(r); } private: - static typename Mutable_ReversibleContainerConcept::size_type i; - static RandomAccessContainer c; + typename Mutable_ReversibleContainerConcept::size_type i; + RandomAccessContainer c; }; // A Sequence is inherently mutable @@ -863,7 +804,7 @@ namespace boost // ... so why aren't we following the standard? --DWA , DefaultConstructibleConcept { - SequenceConcept() + ~SequenceConcept() { Sequence c(n), @@ -891,31 +832,31 @@ namespace boost ignore_unused_variable_warning(r); } - static typename Sequence::value_type t; - static typename Sequence::size_type n; - static typename Sequence::value_type* first, *last; - static typename Sequence::iterator p, q; + typename Sequence::value_type t; + typename Sequence::size_type n; + typename Sequence::value_type* first, *last; + typename Sequence::iterator p, q; }; template struct FrontInsertionSequenceConcept : SequenceConcept { - FrontInsertionSequenceConcept() + ~FrontInsertionSequenceConcept() { c.push_front(t); c.pop_front(); } private: - static FrontInsertionSequence c; - static typename FrontInsertionSequence::value_type t; + FrontInsertionSequence c; + typename FrontInsertionSequence::value_type t; }; template struct BackInsertionSequenceConcept : SequenceConcept { - BackInsertionSequenceConcept() + ~BackInsertionSequenceConcept() { c.push_back(t); c.pop_back(); @@ -929,8 +870,8 @@ namespace boost r = cc.back(); ignore_unused_variable_warning(r); }; - static BackInsertionSequence c; - static typename BackInsertionSequence::value_type t; + BackInsertionSequence c; + typename BackInsertionSequence::value_type t; }; template @@ -943,7 +884,7 @@ namespace boost typedef typename AssociativeContainer::value_compare value_compare; typedef typename AssociativeContainer::iterator iterator; - AssociativeContainerConcept() + ~AssociativeContainerConcept() { i = c.find(k); r = c.equal_range(k); @@ -951,10 +892,10 @@ namespace boost c.erase(i); c.erase(r.first, r.second); const_constraints(c); - BinaryPredicateConcept(); + BOOST_CONCEPT_ASSERT((BinaryPredicateConcept)); - typedef typename AssociativeContainerConcept::value_type value_type; - BinaryPredicateConcept(); + typedef typename AssociativeContainerConcept::value_type value_type_; + BOOST_CONCEPT_ASSERT((BinaryPredicateConcept)); } // Redundant with the base concept, but it helps below. @@ -967,20 +908,20 @@ namespace boost cr = cc.equal_range(k); } - static AssociativeContainer c; - static iterator i; - static std::pair r; - static const_iterator ci; - static std::pair cr; - static typename AssociativeContainer::key_type k; - static typename AssociativeContainer::size_type n; + AssociativeContainer c; + iterator i; + std::pair r; + const_iterator ci; + std::pair cr; + typename AssociativeContainer::key_type k; + typename AssociativeContainer::size_type n; }; template struct UniqueAssociativeContainerConcept : AssociativeContainerConcept { - UniqueAssociativeContainerConcept() + ~UniqueAssociativeContainerConcept() { UniqueAssociativeContainer c(first, last); @@ -990,16 +931,16 @@ namespace boost ignore_unused_variable_warning(c); } private: - static std::pair pos_flag; - static typename UniqueAssociativeContainer::value_type t; - static typename UniqueAssociativeContainer::value_type* first, *last; + std::pair pos_flag; + typename UniqueAssociativeContainer::value_type t; + typename UniqueAssociativeContainer::value_type* first, *last; }; template struct MultipleAssociativeContainerConcept : AssociativeContainerConcept { - MultipleAssociativeContainerConcept() + ~MultipleAssociativeContainerConcept() { MultipleAssociativeContainer c(first, last); @@ -1010,16 +951,16 @@ namespace boost ignore_unused_variable_warning(pos); } private: - static typename MultipleAssociativeContainer::iterator pos; - static typename MultipleAssociativeContainer::value_type t; - static typename MultipleAssociativeContainer::value_type* first, *last; + typename MultipleAssociativeContainer::iterator pos; + typename MultipleAssociativeContainer::value_type t; + typename MultipleAssociativeContainer::value_type* first, *last; }; template struct SimpleAssociativeContainerConcept : AssociativeContainerConcept { - SimpleAssociativeContainerConcept() + ~SimpleAssociativeContainerConcept() { typedef typename SimpleAssociativeContainer::key_type key_type; typedef typename SimpleAssociativeContainer::value_type value_type; @@ -1031,7 +972,7 @@ namespace boost struct PairAssociativeContainerConcept : AssociativeContainerConcept { - PairAssociativeContainerConcept() + ~PairAssociativeContainerConcept() { typedef typename SimpleAssociativeContainer::key_type key_type; typedef typename SimpleAssociativeContainer::value_type value_type; @@ -1046,7 +987,7 @@ namespace boost : AssociativeContainerConcept , ReversibleContainerConcept { - SortedAssociativeContainerConcept() + ~SortedAssociativeContainerConcept() { SortedAssociativeContainer c(kc), @@ -1076,19 +1017,19 @@ namespace boost } private: - static typename SortedAssociativeContainer::key_compare kc; - static typename SortedAssociativeContainer::value_compare vc; - static typename SortedAssociativeContainer::value_type t; - static typename SortedAssociativeContainer::key_type 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; typedef SortedAssociativeContainerConcept self; - static iterator p; - static const_iterator cp; - static std::pair r; - static std::pair cr; - static typename SortedAssociativeContainer::value_type* first, *last; + iterator p; + const_iterator cp; + std::pair r; + std::pair cr; + typename SortedAssociativeContainer::value_type* first, *last; }; // HashedAssociativeContainer diff --git a/include/boost/concept_check/Attic/borland.hpp b/include/boost/concept_check/Attic/borland.hpp new file mode 100755 index 0000000..107926b --- /dev/null +++ b/include/boost/concept_check/Attic/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/Attic/general.hpp b/include/boost/concept_check/Attic/general.hpp new file mode 100755 index 0000000..cd09fb0 --- /dev/null +++ b/include/boost/concept_check/Attic/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/Attic/has_constraints.hpp b/include/boost/concept_check/Attic/has_constraints.hpp new file mode 100755 index 0000000..e19f664 --- /dev/null +++ b/include/boost/concept_check/Attic/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/Attic/msvc.hpp b/include/boost/concept_check/Attic/msvc.hpp new file mode 100755 index 0000000..102cc07 --- /dev/null +++ b/include/boost/concept_check/Attic/msvc.hpp @@ -0,0 +1,62 @@ +// 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 +{ + template + struct concept_check + { + virtual void failed(Model* x) + { + x->~Model(); + } + + int test; + }; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + template + struct constraint_check + { + virtual void failed(Model* x) + { + x->constraints(); + } + + int test; + }; + + template + typename mpl::if_c< + concept_checking::has_constraints::value + , constraint_check + , concept_check + >::type concept_check_(void(*)(Model)); + +# else + + template + concept_check concept_check_(void(*)(Model)); + +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(boost::concept_check_((void(*) ModelInParens)0).test) \ + } +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_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..102cc07 --- /dev/null +++ b/include/boost/concept_check/msvc.hpp @@ -0,0 +1,62 @@ +// 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 +{ + template + struct concept_check + { + virtual void failed(Model* x) + { + x->~Model(); + } + + int test; + }; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + template + struct constraint_check + { + virtual void failed(Model* x) + { + x->constraints(); + } + + int test; + }; + + template + typename mpl::if_c< + concept_checking::has_constraints::value + , constraint_check + , concept_check + >::type concept_check_(void(*)(Model)); + +# else + + template + concept_check concept_check_(void(*)(Model)); + +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(boost::concept_check_((void(*) ModelInParens)0).test) \ + } +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/old_concept_class_fail.cpp b/old_concept_class_fail.cpp new file mode 100755 index 0000000..be41037 --- /dev/null +++ b/old_concept_class_fail.cpp @@ -0,0 +1,28 @@ +// (C) Copyright Jeremy Siek, David Abrahams 2000-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) +// +// Change Log: +// 20 Jan 2001 - Added warning suppression (David Abrahams) + +#include "old_concepts.hpp" + +// This file verifies that concepts written the old way still catch +// errors in class context. This is not expected to work on compilers +// without SFINAE support. + +struct foo { }; + +class class_requires_test +{ + BOOST_CLASS_REQUIRE(foo, old, EqualityComparableConcept); +}; + +int +main() +{ + class_requires_test x; + (void)x; // suppress unused variable warning + return 0; +} diff --git a/old_concept_function_fail.cpp b/old_concept_function_fail.cpp new file mode 100755 index 0000000..6b7bf30 --- /dev/null +++ b/old_concept_function_fail.cpp @@ -0,0 +1,23 @@ +// (C) Copyright Jeremy Siek 2000. +// 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) + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include "old_concepts.hpp" + +// This file verifies that concepts written the old way still catch +// errors in function context. This is not expected to work on +// compilers without SFINAE support. + +struct foo { }; + +int +main() +{ + boost::function_requires< old::EqualityComparableConcept >(); + return 0; +} diff --git a/old_concept_pass.cpp b/old_concept_pass.cpp new file mode 100755 index 0000000..e9601fc --- /dev/null +++ b/old_concept_pass.cpp @@ -0,0 +1,34 @@ +// (C) Copyright Jeremy Siek, David Abrahams 2000-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) + +#include +#include "old_concepts.hpp" + +// This test verifies that use of the old-style concept checking +// classes still compiles (but not that it detects constraint +// violations). We check them with the old-style macros just for +// completeness, since those macros stranslate into +// BOOST_CONCEPT_ASSERTs. + +struct foo { bool operator()(int) { return true; } }; +struct bar { bool operator()(int, char) { return true; } }; + + +class class_requires_test +{ + BOOST_CLASS_REQUIRE(int, old, EqualityComparableConcept); + typedef int* int_ptr; typedef const int* const_int_ptr; + BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, old, EqualOpConcept); + BOOST_CLASS_REQUIRE3(foo, bool, int, old, UnaryFunctionConcept); + BOOST_CLASS_REQUIRE4(bar, bool, int, char, old, BinaryFunctionConcept); +}; + +int +main() +{ + class_requires_test x; + boost::ignore_unused_variable_warning(x); + return 0; +} diff --git a/old_concepts.hpp b/old_concepts.hpp new file mode 100755 index 0000000..76fad3c --- /dev/null +++ b/old_concepts.hpp @@ -0,0 +1,67 @@ +// Copyright Jeremy Siek, David Abrahams 2000-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_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP +# define BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP + +#include + +namespace old +{ + template + void require_boolean_expr(const TT& t) { + bool x = t; + boost::ignore_unused_variable_warning(x); + } + + template + struct EqualityComparableConcept + { + void constraints() { + boost::require_boolean_expr(a == b); + boost::require_boolean_expr(a != b); + } + TT a, b; + }; + + 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; + }; + + template + struct BinaryFunctionConcept + { + void constraints() { + r = f(first, second); // require operator() + } + Func f; + First first; + Second second; + Return r; + }; + +#define 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_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept); +} + +#endif // BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP