From bfb64284174df22f56e85dda5b001ecbc3d62bbf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 1 May 2006 12:50:48 +0000 Subject: [PATCH] Factored out BOOST_CONCEPT_ASSERT into concept_check/assert.hpp Fixed the implementation for GCC 3.3.x and comeau Added BOOST_CONCEPT_WHERE, and tests [SVN r33887] --- Jamfile.v2 | 3 ++ fake_sort.hpp | 22 ++++++++ include/boost/concept_check.hpp | 25 +--------- include/boost/concept_check/Attic/borland.hpp | 12 +++-- include/boost/concept_check/Attic/general.hpp | 50 +++++++------------ include/boost/concept_check/Attic/msvc.hpp | 23 ++++++--- include/boost/concept_check/assert.hpp | 42 ++++++++++++++++ include/boost/concept_check/where.hpp | 50 +++++++++++++++++++ where.cpp | 13 +++++ where_fail.cpp | 13 +++++ 10 files changed, 186 insertions(+), 67 deletions(-) create mode 100755 fake_sort.hpp create mode 100755 include/boost/concept_check/assert.hpp create mode 100755 include/boost/concept_check/where.hpp create mode 100755 where.cpp create mode 100755 where_fail.cpp diff --git a/Jamfile.v2 b/Jamfile.v2 index a37786a..02efb76 100644 --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -8,6 +8,9 @@ test-suite concept_check [ compile-fail concept_check_fail_expected.cpp ] [ compile-fail class_concept_fail_expected.cpp ] + [ run where.cpp ] + [ compile-fail where_fail.cpp ] + # Backward compatibility tests [ run old_concept_pass.cpp ] [ compile-fail function_requires_fail.cpp ] diff --git a/fake_sort.hpp b/fake_sort.hpp new file mode 100755 index 0000000..e96504f --- /dev/null +++ b/fake_sort.hpp @@ -0,0 +1,22 @@ +// 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_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP +# define BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP + +# include +# include +# include + +template +BOOST_CONCEPT_WHERE( + ((boost::Mutable_RandomAccessIteratorConcept)) + ((boost::LessThanComparableConcept::value_type>)) + + , (void)) +fake_sort(RanIter,RanIter) +{ + +} + +#endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp index 23780cf..37f435e 100644 --- a/include/boost/concept_check.hpp +++ b/include/boost/concept_check.hpp @@ -15,38 +15,17 @@ #ifndef BOOST_CONCEPT_CHECKS_HPP # define BOOST_CONCEPT_CHECKS_HPP -# include +# include + # include # include # include # include # include # include -# include # include -# include -# include -# 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 { diff --git a/include/boost/concept_check/Attic/borland.hpp b/include/boost/concept_check/Attic/borland.hpp index 107926b..f82c1c8 100755 --- a/include/boost/concept_check/Attic/borland.hpp +++ b/include/boost/concept_check/Attic/borland.hpp @@ -4,9 +4,11 @@ #ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP # define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP +# include + namespace boost { -template +template struct concept_check; template @@ -15,9 +17,11 @@ 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 \ +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concept_check::instantiate \ } } // namespace boost::concept_checking diff --git a/include/boost/concept_check/Attic/general.hpp b/include/boost/concept_check/Attic/general.hpp index cd09fb0..f9e0274 100755 --- a/include/boost/concept_check/Attic/general.hpp +++ b/include/boost/concept_check/Attic/general.hpp @@ -4,52 +4,38 @@ #ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# include +# include + # 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. +// This implementation works on Comeau and GCC, all the way back to +// 2.95 namespace boost { - namespace concept_checking + template + struct concept_check_; + + 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 }; + static void failed() { ((Model*)0)->~Model(); } }; # ifdef BOOST_OLD_CONCEPT_SUPPORT - - template - void constraint_check_failed() - { - ((Model*)0)->constraints(); - } template struct constraint_check { - concept_checking::instantiate > x; - enum { instantiate = 1 }; + static void failed() { ((Model*)0)->constraints(); } }; template @@ -69,14 +55,12 @@ namespace boost {}; # 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 \ - } + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + typedef boost::concept_checking::instantiate< \ + &boost::concept_check_::failed> \ + BOOST_PP_CAT(boost_concept_check,__LINE__) + } #endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/include/boost/concept_check/Attic/msvc.hpp b/include/boost/concept_check/Attic/msvc.hpp index 3968469..2edcd28 100755 --- a/include/boost/concept_check/Attic/msvc.hpp +++ b/include/boost/concept_check/Attic/msvc.hpp @@ -4,6 +4,8 @@ #ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# include + # ifdef BOOST_OLD_CONCEPT_SUPPORT # include # include @@ -17,6 +19,7 @@ namespace boost template struct concept_check_ { + ~concept_check_(); virtual void failed(Model* x) { x->~Model(); @@ -52,7 +55,9 @@ namespace boost template struct concept_check : concept_checking::concept_check_ - {}; + { + ~concept_check(); + }; # endif @@ -68,9 +73,11 @@ namespace boost : concept_check { }; -# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ - enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ - sizeof(::boost::concept_check) \ +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check) \ } # else @@ -79,9 +86,11 @@ namespace boost 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)) \ +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check_((ModelFnPtr)0)) \ } # endif diff --git a/include/boost/concept_check/assert.hpp b/include/boost/concept_check/assert.hpp new file mode 100755 index 0000000..81bcc51 --- /dev/null +++ b/include/boost/concept_check/assert.hpp @@ -0,0 +1,42 @@ +// 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_ASSERT_DWA2006430_HPP +# define BOOST_CONCEPT_CHECK_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)) + +// Note: gcc-3.3.x had no member function pointer SFINAE +# 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_CHECK_ASSERT_DWA2006430_HPP diff --git a/include/boost/concept_check/where.hpp b/include/boost/concept_check/where.hpp new file mode 100755 index 0000000..c6a6248 --- /dev/null +++ b/include/boost/concept_check/where.hpp @@ -0,0 +1,50 @@ +// 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_WHERE_DWA2006430_HPP +# define BOOST_CONCEPT_CHECK_WHERE_DWA2006430_HPP + +# include +# include +# include + +namespace boost { + +template +struct where : More +{ +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename More::type type; +# endif + BOOST_CONCEPT_ASSERT_FN(ModelFn); +}; + +#define BOOST_CONCEPT_WHERE_OPEN(r,data,t) ::boost::where + +#if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +# define BOOST_CONCEPT_WHERE(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_WHERE(models, result) \ + BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_WHERE_OPEN, ~, models) \ + ::boost::parameter::aux::unaryfunptr_arg_type \ + BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_WHERE_CLOSE, ~, models)::type + +#else + +// This just ICEs on MSVC6 :( +# define BOOST_CONCEPT_WHERE(models, result) \ + typename BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_WHERE_OPEN, ~, models) \ + ::boost::parameter::aux::unaryfunptr_arg_type \ + BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_WHERE_CLOSE, ~, models)::type + +#endif + +} // namespace boost::concept_check + +#endif // BOOST_CONCEPT_CHECK_WHERE_DWA2006430_HPP diff --git a/where.cpp b/where.cpp new file mode 100755 index 0000000..a8d1b8e --- /dev/null +++ b/where.cpp @@ -0,0 +1,13 @@ +// 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) +#include +#undef NDEBUG +#include "fake_sort.hpp" + +int main() +{ + std::vector v; + fake_sort(v.begin(), v.end()); + return 0; +} diff --git a/where_fail.cpp b/where_fail.cpp new file mode 100755 index 0000000..6c10862 --- /dev/null +++ b/where_fail.cpp @@ -0,0 +1,13 @@ +// 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) +#include +#undef NDEBUG +#include "fake_sort.hpp" + +int main() +{ + std::list v; + fake_sort(v.begin(), v.end()); + return 0; +}