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]
This commit is contained in:
Dave Abrahams
2006-05-01 12:50:48 +00:00
parent 80cbd76189
commit bfb6428417
10 changed files with 186 additions and 67 deletions

View File

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

22
fake_sort.hpp Executable file
View File

@ -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 <boost/detail/iterator.hpp>
# include <boost/concept_check/where.hpp>
# include <boost/concept_check.hpp>
template<typename RanIter>
BOOST_CONCEPT_WHERE(
((boost::Mutable_RandomAccessIteratorConcept<RanIter>))
((boost::LessThanComparableConcept<typename boost::detail::iterator_traits<RanIter>::value_type>))
, (void))
fake_sort(RanIter,RanIter)
{
}
#endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP

View File

@ -15,38 +15,17 @@
#ifndef BOOST_CONCEPT_CHECKS_HPP
# define BOOST_CONCEPT_CHECKS_HPP
# include <boost/config.hpp>
# include <boost/concept_check/assert.hpp>
# include <boost/iterator.hpp>
# include <boost/type_traits/conversion_traits.hpp>
# include <utility>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_void.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/detail/workaround.hpp>
# include <new>
# include <boost/parameter/aux_/parenthesized_type.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/detail/iterator.hpp>
// 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 <boost/concept_check/msvc.hpp>
# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/concept_check/borland.hpp>
# else
# include <boost/concept_check/general.hpp>
# endif
namespace boost
{

View File

@ -4,9 +4,11 @@
#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
# include <boost/preprocessor/cat.hpp>
namespace boost {
template <class ModelFn>
template <class ModelFnPtr>
struct concept_check;
template <class Model>
@ -15,9 +17,11 @@ struct concept_check<void(*)(Model)>
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
};
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
boost::concept_check<void(*)ModelInParens>::instantiate \
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
enum \
{ \
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
boost::concept_check<ModelFnPtr>::instantiate \
}
} // namespace boost::concept_checking

View File

@ -4,52 +4,38 @@
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# include <boost/preprocessor/cat.hpp>
# include <boost/parameter/aux_/parenthesized_type.hpp>
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept_check/has_constraints.hpp>
# include <boost/mpl/if.hpp>
# 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 <class ModelFnPtr>
struct concept_check_;
namespace concept_checking
{
template <void(*)()> struct instantiate {};
}
template <class ModelFn> struct concept_check_;
template <class Model>
void concept_check_failed()
{
((Model*)0)->~Model();
}
template <class Model>
struct concept_check
{
concept_checking::instantiate<concept_check_failed<Model> > x;
enum { instantiate = 1 };
static void failed() { ((Model*)0)->~Model(); }
};
# ifdef BOOST_OLD_CONCEPT_SUPPORT
template <class Model>
void constraint_check_failed()
{
((Model*)0)->constraints();
}
template <class Model>
struct constraint_check
{
concept_checking::instantiate<constraint_check_failed<Model> > x;
enum { instantiate = 1 };
static void failed() { ((Model*)0)->constraints(); }
};
template <class Model>
@ -69,14 +55,12 @@ namespace boost
{};
# endif
// Usage, in class or function context:
//
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
::boost::concept_check_<void(*) ModelInParens>::instantiate \
}
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
typedef boost::concept_checking::instantiate< \
&boost::concept_check_<ModelFnPtr>::failed> \
BOOST_PP_CAT(boost_concept_check,__LINE__)
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@ -4,6 +4,8 @@
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# include <boost/preprocessor/cat.hpp>
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept_check/has_constraints.hpp>
# include <boost/mpl/if.hpp>
@ -17,6 +19,7 @@ namespace boost
template <class Model>
struct concept_check_
{
~concept_check_();
virtual void failed(Model* x)
{
x->~Model();
@ -52,7 +55,9 @@ namespace boost
template <class Model>
struct concept_check
: concept_checking::concept_check_<Model>
{};
{
~concept_check();
};
# endif
@ -68,9 +73,11 @@ namespace boost
: concept_check<Model>
{ };
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concept_check<void(*) ModelInParens>) \
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
enum \
{ \
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concept_check<ModelFnPtr>) \
}
# else
@ -79,9 +86,11 @@ namespace boost
concept_check<Model>
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

View File

@ -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 <boost/config.hpp>
# include <boost/detail/workaround.hpp>
// 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 <boost/concept_check/msvc.hpp>
# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/concept_check/borland.hpp>
# else
# include <boost/concept_check/general.hpp>
# endif
// Usage, in class or function context:
//
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
//
# define BOOST_CONCEPT_ASSERT(ModelInParens) \
BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
#endif // BOOST_CONCEPT_CHECK_ASSERT_DWA2006430_HPP

View File

@ -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 <boost/parameter/aux_/parenthesized_type.hpp>
# include <boost/concept_check/assert.hpp>
# include <boost/preprocessor/seq/for_each.hpp>
namespace boost {
template <class ModelFn, class More>
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<void(*)t,
#define BOOST_CONCEPT_WHERE_CLOSE(r,data,t) >
#if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# define BOOST_CONCEPT_WHERE(models, result) \
typename ::boost::parameter::aux::unaryfunptr_arg_type<void(*)result>::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<void(*)result> \
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<void(*)result> \
BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_WHERE_CLOSE, ~, models)::type
#endif
} // namespace boost::concept_check
#endif // BOOST_CONCEPT_CHECK_WHERE_DWA2006430_HPP

13
where.cpp Executable file
View File

@ -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 <vector>
#undef NDEBUG
#include "fake_sort.hpp"
int main()
{
std::vector<int> v;
fake_sort(v.begin(), v.end());
return 0;
}

13
where_fail.cpp Executable file
View File

@ -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 <list>
#undef NDEBUG
#include "fake_sort.hpp"
int main()
{
std::list<int> v;
fake_sort(v.begin(), v.end());
return 0;
}