Fixes for concept checking; use destructors for checking classes, misc cleanup.

[SVN r33862]
This commit is contained in:
Dave Abrahams
2006-04-29 20:27:14 +00:00
parent d4ecb93adb
commit 24326c9df5
19 changed files with 864 additions and 331 deletions

17
Jamfile
View File

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

View File

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

View File

@@ -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<int>));
typedef int* int_ptr; typedef const int* const_int_ptr;
BOOST_CONCEPT_ASSERT((boost::EqualOpConcept<int_ptr,const_int_ptr>));
BOOST_CONCEPT_ASSERT((boost::UnaryFunctionConcept<foo,bool,int>));
// BOOST_CONCEPT_ASSERT((boost::BinaryFunctionConcept<bar,bool,int,char>));
};
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;
}

View File

@@ -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 T>
class class_requires_test
{
BOOST_CLASS_REQUIRE(foo, boost, EqualityComparableConcept);
BOOST_CONCEPT_ASSERT((boost::EqualityComparableConcept<foo>));
};
int
main()
{
class_requires_test x;
(void)x; // suppress unused variable warning
return 0;
class_requires_test<int> x;
(void)x; // suppress unused variable warning
return 0;
}

View File

@@ -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<foo> >();
return 0;
BOOST_CONCEPT_ASSERT((boost::EqualityComparableConcept<foo>));
return 0;
}

26
function_requires_fail.cpp Executable file
View File

@@ -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 <boost/concept_check.hpp>
/*
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<foo> >();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <class ModelFn>
struct concept_check;
template <class Model>
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 \
}
} // namespace boost::concept_checking
#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP

View File

@@ -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 <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.
namespace boost
{
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 };
};
# 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 };
};
template <class Model>
struct concept_check_<void(*)(Model)>
: mpl::if_c<
concept_checking::has_constraints<Model>::value
, constraint_check<Model>
, concept_check<Model>
>::type
{};
# else
template <class Model>
struct concept_check_<void(*)(Model)>
: concept_check<Model>
{};
# 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 \
}
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -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 <class Model, void (Model::*)()>
struct wrap_constraints {};
template <class Model>
inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
inline no has_constraints_(...);
template <class Model>
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

View File

@@ -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 <boost/concept_check/has_constraints.hpp>
# include <boost/mpl/if.hpp>
# endif
namespace boost
{
template <class Model>
struct concept_check
{
virtual void failed(Model* x)
{
x->~Model();
}
int test;
};
# ifdef BOOST_OLD_CONCEPT_SUPPORT
template <class Model>
struct constraint_check
{
virtual void failed(Model* x)
{
x->constraints();
}
int test;
};
template <class Model>
typename mpl::if_c<
concept_checking::has_constraints<Model>::value
, constraint_check<Model>
, concept_check<Model>
>::type concept_check_(void(*)(Model));
# else
template <class Model>
concept_check<Model> concept_check_(void(*)(Model));
# 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__) = \
sizeof(boost::concept_check_((void(*) ModelInParens)0).test) \
}
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -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 <class ModelFn>
struct concept_check;
template <class Model>
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 \
}
} // namespace boost::concept_checking
#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP

View File

@@ -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 <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.
namespace boost
{
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 };
};
# 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 };
};
template <class Model>
struct concept_check_<void(*)(Model)>
: mpl::if_c<
concept_checking::has_constraints<Model>::value
, constraint_check<Model>
, concept_check<Model>
>::type
{};
# else
template <class Model>
struct concept_check_<void(*)(Model)>
: concept_check<Model>
{};
# 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 \
}
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -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 <class Model, void (Model::*)()>
struct wrap_constraints {};
template <class Model>
inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
inline no has_constraints_(...);
template <class Model>
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

View File

@@ -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 <boost/concept_check/has_constraints.hpp>
# include <boost/mpl/if.hpp>
# endif
namespace boost
{
template <class Model>
struct concept_check
{
virtual void failed(Model* x)
{
x->~Model();
}
int test;
};
# ifdef BOOST_OLD_CONCEPT_SUPPORT
template <class Model>
struct constraint_check
{
virtual void failed(Model* x)
{
x->constraints();
}
int test;
};
template <class Model>
typename mpl::if_c<
concept_checking::has_constraints<Model>::value
, constraint_check<Model>
, concept_check<Model>
>::type concept_check_(void(*)(Model));
# else
template <class Model>
concept_check<Model> concept_check_(void(*)(Model));
# 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__) = \
sizeof(boost::concept_check_((void(*) ModelInParens)0).test) \
}
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

28
old_concept_class_fail.cpp Executable file
View File

@@ -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;
}

23
old_concept_function_fail.cpp Executable file
View File

@@ -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<foo> >();
return 0;
}

34
old_concept_pass.cpp Executable file
View File

@@ -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 <boost/concept_check.hpp>
#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;
}

67
old_concepts.hpp Executable file
View File

@@ -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 <boost/concept_check.hpp>
namespace old
{
template <class TT>
void require_boolean_expr(const TT& t) {
bool x = t;
boost::ignore_unused_variable_warning(x);
}
template <class TT>
struct EqualityComparableConcept
{
void constraints() {
boost::require_boolean_expr(a == b);
boost::require_boolean_expr(a != b);
}
TT a, b;
};
template <class Func, class Return, class Arg>
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 <class Func, class Return, class First, class Second>
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 <class First, class Second> \
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