mirror of
https://github.com/boostorg/concept_check.git
synced 2025-07-29 20:17:36 +02:00
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:
@ -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
22
fake_sort.hpp
Executable 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
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
42
include/boost/concept_check/assert.hpp
Executable file
42
include/boost/concept_check/assert.hpp
Executable 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
|
50
include/boost/concept_check/where.hpp
Executable file
50
include/boost/concept_check/where.hpp
Executable 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
13
where.cpp
Executable 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
13
where_fail.cpp
Executable 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;
|
||||
}
|
Reference in New Issue
Block a user