mirror of
https://github.com/boostorg/concept_check.git
synced 2025-07-30 04:27:33 +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 concept_check_fail_expected.cpp ]
|
||||||
[ compile-fail class_concept_fail_expected.cpp ]
|
[ compile-fail class_concept_fail_expected.cpp ]
|
||||||
|
|
||||||
|
[ run where.cpp ]
|
||||||
|
[ compile-fail where_fail.cpp ]
|
||||||
|
|
||||||
# Backward compatibility tests
|
# Backward compatibility tests
|
||||||
[ run old_concept_pass.cpp ]
|
[ run old_concept_pass.cpp ]
|
||||||
[ compile-fail function_requires_fail.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
|
#ifndef BOOST_CONCEPT_CHECKS_HPP
|
||||||
# define 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/iterator.hpp>
|
||||||
# include <boost/type_traits/conversion_traits.hpp>
|
# include <boost/type_traits/conversion_traits.hpp>
|
||||||
# include <utility>
|
# include <utility>
|
||||||
# include <boost/type_traits/is_same.hpp>
|
# include <boost/type_traits/is_same.hpp>
|
||||||
# include <boost/type_traits/is_void.hpp>
|
# include <boost/type_traits/is_void.hpp>
|
||||||
# include <boost/mpl/assert.hpp>
|
# include <boost/mpl/assert.hpp>
|
||||||
# include <boost/mpl/identity.hpp>
|
|
||||||
# include <boost/detail/workaround.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>
|
# 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
|
namespace boost
|
||||||
{
|
{
|
||||||
|
@ -4,9 +4,11 @@
|
|||||||
#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
|
#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
|
||||||
# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
|
# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
|
||||||
|
|
||||||
|
# include <boost/preprocessor/cat.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template <class ModelFn>
|
template <class ModelFnPtr>
|
||||||
struct concept_check;
|
struct concept_check;
|
||||||
|
|
||||||
template <class Model>
|
template <class Model>
|
||||||
@ -15,9 +17,11 @@ struct concept_check<void(*)(Model)>
|
|||||||
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
|
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
|
||||||
};
|
};
|
||||||
|
|
||||||
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
|
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||||
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
enum \
|
||||||
boost::concept_check<void(*)ModelInParens>::instantiate \
|
{ \
|
||||||
|
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||||
|
boost::concept_check<ModelFnPtr>::instantiate \
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace boost::concept_checking
|
} // namespace boost::concept_checking
|
||||||
|
@ -4,52 +4,38 @@
|
|||||||
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||||
# define 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
|
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||||
# include <boost/concept_check/has_constraints.hpp>
|
# include <boost/concept_check/has_constraints.hpp>
|
||||||
# include <boost/mpl/if.hpp>
|
# include <boost/mpl/if.hpp>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
// This implementation works on Comeau and GCC, all the way back to
|
||||||
// This implementation works on GCC and Comeau, but has actually been
|
// 2.95
|
||||||
// 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 boost
|
||||||
{
|
{
|
||||||
namespace concept_checking
|
template <class ModelFnPtr>
|
||||||
|
struct concept_check_;
|
||||||
|
|
||||||
|
namespace concept_checking
|
||||||
{
|
{
|
||||||
template <void(*)()> struct instantiate {};
|
template <void(*)()> struct instantiate {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ModelFn> struct concept_check_;
|
|
||||||
|
|
||||||
template <class Model>
|
|
||||||
void concept_check_failed()
|
|
||||||
{
|
|
||||||
((Model*)0)->~Model();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Model>
|
template <class Model>
|
||||||
struct concept_check
|
struct concept_check
|
||||||
{
|
{
|
||||||
concept_checking::instantiate<concept_check_failed<Model> > x;
|
static void failed() { ((Model*)0)->~Model(); }
|
||||||
enum { instantiate = 1 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||||
|
|
||||||
template <class Model>
|
|
||||||
void constraint_check_failed()
|
|
||||||
{
|
|
||||||
((Model*)0)->constraints();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Model>
|
template <class Model>
|
||||||
struct constraint_check
|
struct constraint_check
|
||||||
{
|
{
|
||||||
concept_checking::instantiate<constraint_check_failed<Model> > x;
|
static void failed() { ((Model*)0)->constraints(); }
|
||||||
enum { instantiate = 1 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Model>
|
template <class Model>
|
||||||
@ -69,14 +55,12 @@ namespace boost
|
|||||||
{};
|
{};
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// Usage, in class or function context:
|
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||||
//
|
typedef boost::concept_checking::instantiate< \
|
||||||
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
|
&boost::concept_check_<ModelFnPtr>::failed> \
|
||||||
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
|
BOOST_PP_CAT(boost_concept_check,__LINE__)
|
||||||
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
|
||||||
::boost::concept_check_<void(*) ModelInParens>::instantiate \
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||||
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
|
||||||
|
|
||||||
|
# include <boost/preprocessor/cat.hpp>
|
||||||
|
|
||||||
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
# ifdef BOOST_OLD_CONCEPT_SUPPORT
|
||||||
# include <boost/concept_check/has_constraints.hpp>
|
# include <boost/concept_check/has_constraints.hpp>
|
||||||
# include <boost/mpl/if.hpp>
|
# include <boost/mpl/if.hpp>
|
||||||
@ -17,6 +19,7 @@ namespace boost
|
|||||||
template <class Model>
|
template <class Model>
|
||||||
struct concept_check_
|
struct concept_check_
|
||||||
{
|
{
|
||||||
|
~concept_check_();
|
||||||
virtual void failed(Model* x)
|
virtual void failed(Model* x)
|
||||||
{
|
{
|
||||||
x->~Model();
|
x->~Model();
|
||||||
@ -52,7 +55,9 @@ namespace boost
|
|||||||
template <class Model>
|
template <class Model>
|
||||||
struct concept_check
|
struct concept_check
|
||||||
: concept_checking::concept_check_<Model>
|
: concept_checking::concept_check_<Model>
|
||||||
{};
|
{
|
||||||
|
~concept_check();
|
||||||
|
};
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -68,9 +73,11 @@ namespace boost
|
|||||||
: concept_check<Model>
|
: concept_check<Model>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
|
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||||
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
enum \
|
||||||
sizeof(::boost::concept_check<void(*) ModelInParens>) \
|
{ \
|
||||||
|
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||||
|
sizeof(::boost::concept_check<ModelFnPtr>) \
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
@ -79,9 +86,11 @@ namespace boost
|
|||||||
concept_check<Model>
|
concept_check<Model>
|
||||||
concept_check_(void(*)(Model));
|
concept_check_(void(*)(Model));
|
||||||
|
|
||||||
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
|
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
|
||||||
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
enum \
|
||||||
sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \
|
{ \
|
||||||
|
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
|
||||||
|
sizeof(::boost::concept_check_((ModelFnPtr)0)) \
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
# 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