mirror of
https://github.com/boostorg/contract.git
synced 2026-01-26 18:32:55 +00:00
reorganized aux_/ code in subdirs/namespaces
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_BASE_FUNCTION_HPP_
|
||||
#define BOOST_CONTRACT_AUX_BASE_FUNCTION_HPP_
|
||||
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <boost/contract/aux_/exception.hpp>
|
||||
#include <boost/contract/aux_/none.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/member_function_pointer.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/back.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
|
||||
template<class DerivedFunction, class Intro, typename Func>
|
||||
class base_function {
|
||||
typedef typename boost::function_types::result_type<Func>::type
|
||||
result_type;
|
||||
typedef typename boost::mpl::pop_front<typename boost::function_types::
|
||||
parameter_types<Func>::type>::type arg_types;
|
||||
typedef typename boost::mpl::eval_if<boost::is_same<typename
|
||||
boost::mpl::back<arg_types>::type, boost::contract::virtual_body>,
|
||||
boost::mpl::identity<arg_types>
|
||||
,
|
||||
boost::mpl::push_back<arg_types, boost::contract::virtual_body>
|
||||
>::type virtual_arg_types;
|
||||
|
||||
public:
|
||||
base_function() : virt_(boost::contract::virtual_body::user_call) {}
|
||||
|
||||
void derived_function(DerivedFunction* derived_func) {
|
||||
derived_func_ = derived_func;
|
||||
}
|
||||
|
||||
base_function& action(boost::contract::virtual_body const virt) {
|
||||
virt_ = virt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Base>
|
||||
void operator()(Base*) {
|
||||
call<Base>(boost::mpl::bool_<Intro::template has_member_function<
|
||||
Base, result_type, virtual_arg_types>::value>());
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Base> void call(boost::mpl::false_ const&) {}
|
||||
template<class Base> void call(boost::mpl::true_ const&) {
|
||||
typedef typename boost::mpl::push_front<
|
||||
typename boost::mpl::push_front<virtual_arg_types, Base*>::type,
|
||||
result_type
|
||||
>::type base_virtual_func_types;
|
||||
typedef typename boost::function_types::member_function_pointer<
|
||||
base_virtual_func_types>::type base_virtual_func_ptr;
|
||||
base_virtual_func_ptr base_virtual_func = Intro::template
|
||||
member_function_address<Base, base_virtual_func_ptr>();
|
||||
BOOST_CONTRACT_AUX_DEBUG(base_virtual_func);
|
||||
|
||||
BOOST_CONTRACT_AUX_DEBUG(derived_func_);
|
||||
Base* const base = derived_func_->obj_;
|
||||
BOOST_CONTRACT_AUX_DEBUG(base);
|
||||
|
||||
try {
|
||||
(base->*base_virtual_func)(derived_func_->arg0_, virt_);
|
||||
} catch(boost::contract::aux::no_error const&) {
|
||||
if(virt_.action == boost::contract::virtual_body::check_pre_only) {
|
||||
throw; // Pre logic-or: Stop at 1st no_error (throw to caller).
|
||||
}
|
||||
} catch(...) {
|
||||
if(virt_.action == boost::contract::virtual_body::check_pre_only) {
|
||||
// Pre logic-or: Ignore errors, possibly checking up to caller.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DerivedFunction* derived_func_;
|
||||
boost::contract::virtual_body virt_;
|
||||
};
|
||||
|
||||
template<class DerivedFunction>
|
||||
struct base_function<DerivedFunction, boost::contract::aux::none,
|
||||
boost::contract::aux::none> { // Dummy implementation that does nothing.
|
||||
base_function() {}
|
||||
|
||||
void derived_function(DerivedFunction*) {}
|
||||
base_function& action(boost::contract::virtual_body const) { return *this; }
|
||||
|
||||
template<class Base> // Should never actually be called at runtime.
|
||||
void operator()(Base*) { BOOST_CONTRACT_AUX_DEBUG(false); }
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_BASES_HPP_
|
||||
#define BOOST_CONTRACT_AUX_BASES_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/aux_/tti.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_TYPE(has_bases,
|
||||
BOOST_CONTRACT_CONFIG_BASE_TYPES)
|
||||
|
||||
template< class C >
|
||||
struct bases_of { typedef typename C::BOOST_CONTRACT_CONFIG_BASE_TYPES type; };
|
||||
|
||||
} } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_BASIC_FUNCTION_HPP_
|
||||
#define BOOST_CONTRACT_AUX_BASIC_FUNCTION_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/aux_/base_function.hpp>
|
||||
#include <boost/contract/aux_/bases.hpp>
|
||||
#include <boost/contract/aux_/invariant.hpp>
|
||||
#include <boost/contract/aux_/exception.hpp>
|
||||
#include <boost/contract/aux_/none.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
// TODO: Modelling after Clang message for assert() failure:
|
||||
// assertion "(Key != boost::contract::aux::constructor)" failed: file "..\include/boost/contract/aux_/function.hpp", line 156
|
||||
// This library should say:
|
||||
// precondition/postcondition/invariant/... "..." failed: file "...", line ...
|
||||
// for exception classes precondition/postcondition/..._failure (inheriting from
|
||||
// assertion_failure base exception to be thrown by CONTRACT_ASSERT) and failure
|
||||
// handlers [set_]precondition_failed.
|
||||
|
||||
// TODO: Consider splitting this class into aux_/constructor, aux_/destructor,
|
||||
// etc. bases on Key while keeping all check_... functions in a
|
||||
// aux_/basic_function base class (or even in contract::type directly). The code
|
||||
// might be more clear without all the switch on Key.
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
|
||||
template<
|
||||
class Class = boost::contract::aux::none,
|
||||
class Intro = boost::contract::aux::none,
|
||||
typename Func = boost::contract::aux::none,
|
||||
typename Arg0 = boost::contract::aux::none
|
||||
> class basic_function : public boost::contract::type,
|
||||
private boost::noncopyable {
|
||||
friend class boost::contract::aux::base_function<
|
||||
basic_function, Intro, Func>;
|
||||
|
||||
// Base types as pointers because mpl::for_each will construct them.
|
||||
typedef typename boost::mpl::transform<
|
||||
typename boost::mpl::eval_if<boost::contract::aux::has_bases<Class>,
|
||||
boost::contract::aux::bases_of<Class>
|
||||
,
|
||||
boost::mpl::identity<boost::mpl::vector<> >
|
||||
>::type,
|
||||
boost::add_pointer<boost::mpl::placeholders::_1>
|
||||
>::type base_ptrs;
|
||||
|
||||
#if !BOOST_CONTRACT_CONFIG_PERMISSIVE
|
||||
// TODO: Fix those.
|
||||
//BOOST_STATIC_ASSERT_MSG(!boost::contract::aux::has_mutable_invariant<
|
||||
// Class>::value, "class invariant function must be const");
|
||||
//BOOST_STATIC_ASSERT_MSG(
|
||||
// (!boost::mpl::and_<
|
||||
// boost::contract::aux::has_bases<Class>,
|
||||
// boost::mpl::or_<
|
||||
// boost::is_same<Intro, boost::contract::aux::none>,
|
||||
// boost::is_same<Func, boost::contract::aux::none>
|
||||
// >
|
||||
// >::value),
|
||||
// "must specify introspection type, function type, and function "
|
||||
// "arguments for member contract of class with bases"
|
||||
//);
|
||||
// TODO: static_assert(Func == none || class<Func>::type == Class)
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit basic_function(Class* const obj, Arg0 arg0) : base_func_(),
|
||||
obj_(obj), arg0_(arg0) {
|
||||
BOOST_CONTRACT_AUX_DEBUG(obj_);
|
||||
base_func_.derived_function(this);
|
||||
}
|
||||
|
||||
explicit basic_function(Class* const obj) : base_func_(), obj_(obj) {
|
||||
BOOST_CONTRACT_AUX_DEBUG(obj_);
|
||||
base_func_.derived_function(this);
|
||||
}
|
||||
|
||||
explicit basic_function() : base_func_(), obj_(0) {
|
||||
base_func_.derived_function(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
void check_subcontracted_inv(bool const static_inv_only = false) {
|
||||
if(!boost::mpl::empty<base_ptrs>::value && obj_) {
|
||||
boost::mpl::for_each<base_ptrs>(base_func_.action(
|
||||
static_inv_only ?
|
||||
boost::contract::virtual_body::check_static_inv_only
|
||||
:
|
||||
boost::contract::virtual_body::check_inv_only
|
||||
));
|
||||
}
|
||||
check_inv(static_inv_only);
|
||||
}
|
||||
|
||||
void check_inv(bool const static_inv_only = false) {
|
||||
check_static_inv(boost::mpl::bool_<boost::contract::aux::
|
||||
has_static_invariant<Class>::value>());
|
||||
if(!static_inv_only && obj_) {
|
||||
check_cv_inv(boost::mpl::bool_<boost::contract::aux::
|
||||
has_const_invariant<Class>::value>());
|
||||
}
|
||||
}
|
||||
|
||||
void check_subcontracted_pre() {
|
||||
try {
|
||||
if(!boost::mpl::empty<base_ptrs>::value && obj_) {
|
||||
boost::mpl::for_each<base_ptrs>(base_func_.action(
|
||||
boost::contract::virtual_body::check_pre_only));
|
||||
}
|
||||
check_pre(); // Pre logic-or: Last check, error if also throws.
|
||||
} catch(boost::contract::aux::no_error const&) {
|
||||
// Pre logic-or: Stop at 1st no_error (thrown by callee).
|
||||
}
|
||||
}
|
||||
|
||||
void check_pre() { if(pre_) pre_(); }
|
||||
|
||||
void check_subcontracted_post() {
|
||||
if(!boost::mpl::empty<base_ptrs>::value && obj_) {
|
||||
boost::mpl::for_each<base_ptrs>(base_func_.action(
|
||||
boost::contract::virtual_body::check_post_only));
|
||||
}
|
||||
check_post();
|
||||
}
|
||||
|
||||
void check_post() { if(post_) post_(); }
|
||||
|
||||
private:
|
||||
void check_static_inv(boost::mpl::false_ const&) {}
|
||||
void check_static_inv(boost::mpl::true_ const&) {
|
||||
Class::BOOST_CONTRACT_CONFIG_STATIC_INVARIANT();
|
||||
}
|
||||
|
||||
void check_cv_inv(boost::mpl::false_ const&) {}
|
||||
void check_cv_inv(boost::mpl::true_ const&) {
|
||||
typename boost::add_const<Class>::type* const const_obj = obj_;
|
||||
BOOST_CONTRACT_AUX_DEBUG(const_obj);
|
||||
const_obj->BOOST_CONTRACT_CONFIG_INVARIANT();
|
||||
}
|
||||
|
||||
boost::contract::aux::base_function<basic_function, Intro, Func> base_func_;
|
||||
Class* const obj_;
|
||||
// TODO: add_reference/perfect fwd to all these Arg-i types.
|
||||
// TODO: Support 0-to-n args.
|
||||
Arg0 arg0_;
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
22
include/boost/contract/aux_/check/pre_post.hpp
Normal file
22
include/boost/contract/aux_/check/pre_post.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_CHECK_PRE_POST_HPP_
|
||||
#define BOOST_CONTRACT_AUX_CHECK_PRE_POST_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
|
||||
// TODO: Consider moving this to an aux_/check/ dir and namespace.
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace check {
|
||||
|
||||
// TODO: check_pre/post should probably just be made protected members of
|
||||
// class containing pre_/post_ so those can be made private data members.
|
||||
class pre_post : public boost::contract::type {
|
||||
protected:
|
||||
void check_pre() { if(pre_) pre_(); }
|
||||
void check_post() { if(post_) post_(); }
|
||||
};
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
51
include/boost/contract/aux_/check/pre_post_inv.hpp
Normal file
51
include/boost/contract/aux_/check/pre_post_inv.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_CHECK_PRE_POST_INV_HPP_
|
||||
#define BOOST_CONTRACT_AUX_CHECK_PRE_POST_INV_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/aux_/check/pre_post.hpp>
|
||||
#include <boost/contract/aux_/type_traits/invariant.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace check {
|
||||
|
||||
template<class Class>
|
||||
class pre_post_inv : public boost::contract::aux::check::pre_post {
|
||||
public:
|
||||
// Allow object to be 0 (i.e., no object), for static members.
|
||||
explicit pre_post_inv(Class* const obj = 0) : obj_(obj) {}
|
||||
|
||||
protected:
|
||||
void check_inv(bool const static_inv_only = false) {
|
||||
check_static_inv(boost::mpl::bool_<boost::contract::aux::type_traits::
|
||||
has_static_invariant<Class>::value>());
|
||||
if(!static_inv_only) {
|
||||
check_cv_inv(boost::mpl::bool_<boost::contract::aux::type_traits::
|
||||
has_const_invariant<Class>::value>());
|
||||
}
|
||||
}
|
||||
|
||||
// Could return null pointer (for static members).
|
||||
Class* const object() const { return obj_; }
|
||||
|
||||
private:
|
||||
void check_static_inv(boost::mpl::false_ const&) {}
|
||||
void check_static_inv(boost::mpl::true_ const&) {
|
||||
Class::BOOST_CONTRACT_CONFIG_STATIC_INVARIANT();
|
||||
}
|
||||
|
||||
void check_cv_inv(boost::mpl::false_ const&) {}
|
||||
void check_cv_inv(boost::mpl::true_ const&) {
|
||||
typename boost::add_const<Class>::type* const const_obj = obj_;
|
||||
BOOST_CONTRACT_AUX_DEBUG(const_obj);
|
||||
const_obj->BOOST_CONTRACT_CONFIG_INVARIANT();
|
||||
}
|
||||
|
||||
Class* const obj_;
|
||||
};
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
189
include/boost/contract/aux_/check/subcontracted_pre_post_inv.hpp
Normal file
189
include/boost/contract/aux_/check/subcontracted_pre_post_inv.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_CHECK_SUBCONTRACTED_PRE_POST_INV_HPP_
|
||||
#define BOOST_CONTRACT_AUX_CHECK_SUBCONTRACTED_PRE_POST_INV_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <boost/contract/aux_/check/pre_post_inv.hpp>
|
||||
#include <boost/contract/aux_/type_traits/bases.hpp>
|
||||
#include <boost/contract/aux_/exception.hpp>
|
||||
#include <boost/contract/aux_/none.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/member_function_pointer.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/back.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
// TODO: Modelling after Clang message for assert() failure:
|
||||
// assertion "(Key != boost::contract::aux::constructor)" failed: file "..\include/boost/contract/aux_/function.hpp", line 156
|
||||
// This library should say:
|
||||
// precondition/postcondition/invariant/... "..." failed: file "...", line ...
|
||||
// for exception classes precondition/postcondition/..._failure (inheriting from
|
||||
// assertion_failure base exception to be thrown by CONTRACT_ASSERT) and failure
|
||||
// handlers [set_]precondition_failed.
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace check {
|
||||
|
||||
template<
|
||||
class Class,
|
||||
class Intro = boost::contract::aux::none,
|
||||
typename Func = boost::contract::aux::none,
|
||||
typename Arg0 = boost::contract::aux::none
|
||||
> class subcontracted_pre_post_inv :
|
||||
public boost::contract::aux::check::pre_post_inv<Class>,
|
||||
private boost::noncopyable // Avoid copying captured function arguments.
|
||||
{
|
||||
// Base types as pointers because mpl::for_each will construct them.
|
||||
typedef typename boost::mpl::transform<
|
||||
typename boost::mpl::eval_if<boost::contract::aux::type_traits::
|
||||
has_bases<Class>,
|
||||
boost::contract::aux::type_traits::bases_of<Class>
|
||||
,
|
||||
boost::mpl::identity<boost::mpl::vector<> >
|
||||
>::type,
|
||||
boost::add_pointer<boost::mpl::placeholders::_1>
|
||||
>::type base_ptrs;
|
||||
|
||||
#if !BOOST_CONTRACT_CONFIG_PERMISSIVE
|
||||
// TODO: Fix those.
|
||||
//BOOST_STATIC_ASSERT_MSG(!boost::contract::aux::has_mutable_invariant<
|
||||
// Class>::value, "class invariant function must be const");
|
||||
//BOOST_STATIC_ASSERT_MSG(
|
||||
// (!boost::mpl::and_<
|
||||
// boost::contract::aux::has_bases<Class>,
|
||||
// boost::mpl::or_<
|
||||
// boost::is_same<Intro, boost::contract::aux::none>,
|
||||
// boost::is_same<Func, boost::contract::aux::none>
|
||||
// >
|
||||
// >::value),
|
||||
// "must specify introspection type, function type, and function "
|
||||
// "arguments for member contract of class with bases"
|
||||
//);
|
||||
// TODO: static_assert(Func == none || class<Func>::type == Class)
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit subcontracted_pre_post_inv(Class* const obj, Arg0 arg0) :
|
||||
boost::contract::aux::check::pre_post_inv<Class>(obj),
|
||||
arg0_(arg0)
|
||||
{}
|
||||
|
||||
explicit subcontracted_pre_post_inv(Class* const obj) : boost::contract::
|
||||
aux::check::pre_post_inv<Class>(obj) {
|
||||
}
|
||||
|
||||
protected:
|
||||
void check_subcontracted_inv(bool const static_inv_only = false) {
|
||||
boost::mpl::for_each<base_ptrs>(check_base(*this,
|
||||
static_inv_only ?
|
||||
boost::contract::virtual_body::check_static_inv_only
|
||||
:
|
||||
boost::contract::virtual_body::check_inv_only
|
||||
));
|
||||
this->check_inv(static_inv_only);
|
||||
}
|
||||
|
||||
void check_subcontracted_pre() {
|
||||
try {
|
||||
boost::mpl::for_each<base_ptrs>(check_base(*this,
|
||||
boost::contract::virtual_body::check_pre_only));
|
||||
this->check_pre(); // Pre logic-or: Last check, error also throws.
|
||||
} catch(boost::contract::aux::no_error const&) {
|
||||
// Pre logic-or: Stop at 1st no_error (thrown by callee).
|
||||
}
|
||||
}
|
||||
|
||||
void check_subcontracted_post() {
|
||||
boost::mpl::for_each<base_ptrs>(check_base(*this,
|
||||
boost::contract::virtual_body::check_post_only));
|
||||
this->check_post();
|
||||
}
|
||||
|
||||
class check_base {
|
||||
public:
|
||||
explicit check_base(subcontracted_pre_post_inv& outer,
|
||||
boost::contract::virtual_body const virt) :
|
||||
outer_(outer), virt_(virt)
|
||||
{}
|
||||
|
||||
template<class Base>
|
||||
void operator()(Base*) {
|
||||
typedef typename boost::function_types::result_type<Func>::type
|
||||
result_type;
|
||||
typedef typename boost::mpl::pop_front<
|
||||
typename boost::function_types::parameter_types<Func>::type
|
||||
>::type arg_types;
|
||||
typedef typename boost::mpl::eval_if<boost::is_same<typename boost::
|
||||
mpl::back<arg_types>::type, boost::contract::virtual_body>,
|
||||
boost::mpl::identity<arg_types>
|
||||
,
|
||||
boost::mpl::push_back<arg_types, boost::contract::virtual_body>
|
||||
>::type virtual_arg_types;
|
||||
|
||||
call_base_function<Base, result_type, virtual_arg_types>(
|
||||
boost::mpl::bool_<Intro::template has_member_function<Base,
|
||||
result_type, virtual_arg_types>::value>()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Base, typename ResultType, class VirtualArgTypes>
|
||||
void call_base_function(boost::mpl::false_ const&) {}
|
||||
template<class Base, typename ResultType, class VirtualArgTypes>
|
||||
void call_base_function(boost::mpl::true_ const&) {
|
||||
typedef typename boost::mpl::push_front<
|
||||
typename boost::mpl::push_front<VirtualArgTypes, Base*>::type,
|
||||
ResultType
|
||||
>::type base_virtual_func_types;
|
||||
typedef typename boost::function_types::member_function_pointer<
|
||||
base_virtual_func_types>::type base_virtual_func_ptr;
|
||||
|
||||
base_virtual_func_ptr base_virtual_func = Intro::template
|
||||
member_function_address<Base, base_virtual_func_ptr>();
|
||||
BOOST_CONTRACT_AUX_DEBUG(base_virtual_func);
|
||||
|
||||
Base* const base = outer_.object();
|
||||
BOOST_CONTRACT_AUX_DEBUG(base);
|
||||
|
||||
try {
|
||||
(base->*base_virtual_func)(outer_.arg0_, virt_);
|
||||
} catch(boost::contract::aux::no_error const&) {
|
||||
if(virt_.action == boost::contract::virtual_body::
|
||||
check_pre_only) {
|
||||
throw; // Pre logic-or: 1st no_err stops (throw to caller).
|
||||
}
|
||||
} catch(...) {
|
||||
if(virt_.action == boost::contract::virtual_body::
|
||||
check_pre_only) {
|
||||
// Pre logic-or: Ignore err, possibly checks up to caller.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subcontracted_pre_post_inv& outer_;
|
||||
boost::contract::virtual_body virt_;
|
||||
};
|
||||
|
||||
// TODO: add_reference/perfect fwd to all these Arg-i types.
|
||||
// TODO: Support 0-to-n args.
|
||||
Arg0 arg0_;
|
||||
};
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_CONSTRUCTOR_HPP_
|
||||
#define BOOST_CONTRACT_AUX_CONSTRUCTOR_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_CONSTRUCTOR_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_CONSTRUCTOR_HPP_
|
||||
|
||||
#include <boost/contract/aux_/basic_function.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/contract/aux_/check/pre_post_inv.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
template<class Class>
|
||||
class constructor : public boost::contract::aux::basic_function<Class> {
|
||||
class constructor : public boost::contract::aux::check::pre_post_inv<Class> {
|
||||
public:
|
||||
explicit constructor(Class* const obj) :
|
||||
boost::contract::aux::basic_function<Class>(obj) {
|
||||
BOOST_CONTRACT_AUX_DEBUG(obj);
|
||||
boost::contract::aux::check::pre_post_inv<Class>(obj) {
|
||||
entry();
|
||||
}
|
||||
|
||||
@@ -41,7 +39,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_DESTRUCTOR_HPP_
|
||||
#define BOOST_CONTRACT_AUX_DESTRUCTOR_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_DESTRUCTOR_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_DESTRUCTOR_HPP_
|
||||
|
||||
#include <boost/contract/aux_/basic_function.hpp>
|
||||
#include <boost/contract/aux_/check/pre_post_inv.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
template<class Class>
|
||||
class destructor : public boost::contract::aux::basic_function<Class> {
|
||||
class destructor : public boost::contract::aux::check::pre_post_inv<Class> {
|
||||
public:
|
||||
explicit destructor(Class* const obj) :
|
||||
boost::contract::aux::basic_function<Class>(obj) {
|
||||
BOOST_CONTRACT_AUX_DEBUG(obj);
|
||||
boost::contract::aux::check::pre_post_inv<Class>(obj) {
|
||||
entry();
|
||||
}
|
||||
|
||||
@@ -47,7 +46,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_FREE_FUNCTION_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FREE_FUNCTION_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_FREE_FUNCTION_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_FREE_FUNCTION_HPP_
|
||||
|
||||
#include <boost/contract/aux_/basic_function.hpp>
|
||||
#include <boost/contract/aux_/check/pre_post.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
class free_function : public boost::contract::aux::basic_function<> {
|
||||
class free_function : public boost::contract::aux::check::pre_post {
|
||||
public:
|
||||
explicit free_function() { entry(); }
|
||||
|
||||
@@ -18,7 +18,7 @@ private:
|
||||
void entry() {}
|
||||
|
||||
// Check pre (as soon as related functor set).
|
||||
void pre_available() { this->check_pre(); }
|
||||
void pre_available() { check_pre(); }
|
||||
|
||||
// Post always checked after body, at exit (see below).
|
||||
void post_available() {}
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
18
include/boost/contract/aux_/function/private_member.hpp
Normal file
18
include/boost/contract/aux_/function/private_member.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_PRIVATE_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_PRIVATE_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/function/free_function.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
// Not public members (i.e., private members) are allowed to fail class
|
||||
// invariants (so no inv) and they do not participate in virtual function
|
||||
// polymorphism according to substitution principle (so no subcontracting).
|
||||
// Therefore, their contracts behave like contracts of free functions.
|
||||
typedef boost::contract::aux::function::free_function private_member;
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
18
include/boost/contract/aux_/function/protected_member.hpp
Normal file
18
include/boost/contract/aux_/function/protected_member.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_PROTECTED_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_PROTECTED_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/function/free_function.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
// Not public members (i.e., protected members) are allowed to fail class
|
||||
// invariants (so no inv) and they do not participate in virtual function
|
||||
// polymorphism according to substitution principle (so no subcontracting).
|
||||
// Therefore, their contracts behave like contracts of free functions.
|
||||
typedef boost::contract::aux::function::free_function protected_member;
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_PUBLIC_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_PUBLIC_MEMBER_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_PUBLIC_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_PUBLIC_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/basic_function.hpp>
|
||||
#include <boost/contract/aux_/check/subcontracted_pre_post_inv.hpp>
|
||||
#include <boost/contract/aux_/exception.hpp>
|
||||
#include <boost/contract/aux_/none.hpp>
|
||||
#include <boost/contract/aux_/debug.hpp>
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
template<
|
||||
class Class,
|
||||
class Intro = boost::contract::aux::none,
|
||||
typename Func = boost::contract::aux::none,
|
||||
typename Arg0 = boost::contract::aux::none
|
||||
> class public_member : public boost::contract::aux::basic_function<
|
||||
Class, Intro, Func, Arg0> {
|
||||
> class public_member : public boost::contract::aux::check::
|
||||
subcontracted_pre_post_inv<Class, Intro, Func, Arg0> {
|
||||
public:
|
||||
// Must be used when bases and virtual body (but can also always be used).
|
||||
explicit public_member(
|
||||
boost::contract::virtual_body const virt,
|
||||
Class* const obj,
|
||||
Arg0 arg0
|
||||
) :
|
||||
boost::contract::aux::basic_function<Class, Intro, Func, Arg0>(obj,
|
||||
arg0),
|
||||
explicit public_member(boost::contract::virtual_body const virt,
|
||||
Class* const obj, Arg0 arg0) :
|
||||
boost::contract::aux::check::subcontracted_pre_post_inv<Class, Intro,
|
||||
Func, Arg0>(obj, arg0),
|
||||
virt_(virt)
|
||||
{
|
||||
BOOST_CONTRACT_AUX_DEBUG((!boost::is_same<Intro,
|
||||
@@ -37,12 +34,9 @@ public:
|
||||
}
|
||||
|
||||
// Can be used when bases and no virtual body.
|
||||
explicit public_member(
|
||||
Class* const obj,
|
||||
Arg0 arg0
|
||||
) :
|
||||
boost::contract::aux::basic_function<Class, Intro, Func, Arg0>(obj,
|
||||
arg0),
|
||||
explicit public_member(Class* const obj, Arg0 arg0) :
|
||||
boost::contract::aux::check::subcontracted_pre_post_inv<Class, Intro,
|
||||
Func, Arg0>(obj, arg0),
|
||||
virt_(boost::contract::virtual_body::user_call)
|
||||
{
|
||||
BOOST_CONTRACT_AUX_DEBUG((!boost::is_same<Intro,
|
||||
@@ -53,11 +47,10 @@ public:
|
||||
}
|
||||
|
||||
// Can be used when no bases and virtual body.
|
||||
explicit public_member(
|
||||
boost::contract::virtual_body const virt,
|
||||
Class* const obj
|
||||
) :
|
||||
boost::contract::aux::basic_function<Class, Intro, Func, Arg0>(obj),
|
||||
explicit public_member(boost::contract::virtual_body const virt,
|
||||
Class* const obj) :
|
||||
boost::contract::aux::check::subcontracted_pre_post_inv<Class, Intro,
|
||||
Func, Arg0>(obj),
|
||||
virt_(virt)
|
||||
{
|
||||
BOOST_CONTRACT_AUX_DEBUG((boost::is_same<Intro,
|
||||
@@ -68,22 +61,9 @@ public:
|
||||
}
|
||||
|
||||
// Can be used when no bases and no virtual body.
|
||||
explicit public_member(
|
||||
Class* const obj
|
||||
) :
|
||||
boost::contract::aux::basic_function<Class, Intro, Func, Arg0>(obj),
|
||||
virt_(boost::contract::virtual_body::user_call)
|
||||
{
|
||||
BOOST_CONTRACT_AUX_DEBUG((boost::is_same<Intro,
|
||||
boost::contract::aux::none>::value));
|
||||
BOOST_CONTRACT_AUX_DEBUG((boost::is_same<Func,
|
||||
boost::contract::aux::none>::value));
|
||||
entry();
|
||||
}
|
||||
|
||||
// Must be used for static members.
|
||||
explicit public_member() :
|
||||
boost::contract::aux::basic_function<Class, Intro, Func, Arg0>(),
|
||||
explicit public_member(Class* const obj) :
|
||||
boost::contract::aux::check::subcontracted_pre_post_inv<Class, Intro,
|
||||
Func, Arg0>(obj),
|
||||
virt_(boost::contract::virtual_body::user_call)
|
||||
{
|
||||
BOOST_CONTRACT_AUX_DEBUG((boost::is_same<Intro,
|
||||
@@ -144,7 +124,7 @@ private:
|
||||
boost::contract::virtual_body const virt_;
|
||||
};
|
||||
|
||||
} } } // namespace
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_FUNCTION_PUBLIC_STATIC_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_FUNCTION_PUBLIC_STATIC_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/check/pre_post_inv.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace function {
|
||||
|
||||
template<class Class> class public_static_member :
|
||||
public boost::contract::aux::check::pre_post_inv<Class> {
|
||||
public:
|
||||
explicit public_static_member() :
|
||||
boost::contract::aux::check::pre_post_inv<Class>() {
|
||||
entry();
|
||||
}
|
||||
|
||||
~public_static_member() { exit(); }
|
||||
|
||||
private:
|
||||
// Static members have no object so they do not participate in virtual
|
||||
// function polymorphism according to substitution principle (so no
|
||||
// subcontracting for any of the checks below).
|
||||
|
||||
// Static so no object so check static inv only.
|
||||
void entry() { this->check_inv(/* static_inv_only = */ true); }
|
||||
|
||||
// Check pre (as soon as related functor set).
|
||||
void pre_available() { this->check_pre(); }
|
||||
|
||||
// Post always checked after body, at exit (see below).
|
||||
void post_available() {}
|
||||
|
||||
// Static so no object and only static inv checked, plus check post but
|
||||
// only if body did not throw.
|
||||
void exit() {
|
||||
bool const body_threw = std::uncaught_exception();
|
||||
this->check_inv(/* static_inv_only = */ true);
|
||||
if(!body_threw) this->check_post();
|
||||
}
|
||||
};
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_PRIVATE_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_PRIVATE_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/free_function.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
|
||||
// Not public members (i.e., private members) are allowed to fail class
|
||||
// invariants (so no inv) and they do not participate in virtual function
|
||||
// polymorphism according to substitution principle (so no subcontracting).
|
||||
// Therefore, their contracts behave like contracts of free functions.
|
||||
typedef free_function private_member;
|
||||
|
||||
} } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_PROTECTED_MEMBER_HPP_
|
||||
#define BOOST_CONTRACT_AUX_PROTECTED_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/aux_/free_function.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
|
||||
// Not public members (i.e., protected members) are allowed to fail class
|
||||
// invariants (so no inv) and they do not participate in virtual function
|
||||
// polymorphism according to substitution principle (so no subcontracting).
|
||||
// Therefore, their contracts behave like contracts of free functions.
|
||||
typedef free_function protected_member;
|
||||
|
||||
} } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
19
include/boost/contract/aux_/type_traits/bases.hpp
Normal file
19
include/boost/contract/aux_/type_traits/bases.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_TYPE_TRAITS_BASES_HPP_
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_BASES_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/aux_/type_traits/introspection.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace type_traits {
|
||||
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_TYPE(has_bases,
|
||||
BOOST_CONTRACT_CONFIG_BASE_TYPES)
|
||||
|
||||
template< class C >
|
||||
struct bases_of { typedef typename C::BOOST_CONTRACT_CONFIG_BASE_TYPES type; };
|
||||
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_TTI_HPP_
|
||||
#define BOOST_CONTRACT_AUX_TTI_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HPP_
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HPP_
|
||||
|
||||
#include <boost/contract/aux_/name.hpp>
|
||||
#include <boost/function_types/member_function_pointer.hpp>
|
||||
@@ -19,29 +19,32 @@
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
#define BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_TYPE(trait, type_name) \
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_TYPE(trait, type_name)\
|
||||
template<typename BOOST_CONTRACT_AUX_NAME1(T)> \
|
||||
class trait { \
|
||||
template<class BOOST_CONTRACT_AUX_NAME1(C)> \
|
||||
static boost::contract::aux::tti::yes& check(typename \
|
||||
BOOST_CONTRACT_AUX_NAME1(C)::type_name*); \
|
||||
static boost::contract::aux::type_traits::introspection::yes& check( \
|
||||
typename BOOST_CONTRACT_AUX_NAME1(C)::type_name*); \
|
||||
\
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_END_(BOOST_CONTRACT_AUX_NAME1(T)) \
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_END_( \
|
||||
BOOST_CONTRACT_AUX_NAME1(T)) \
|
||||
};
|
||||
|
||||
#define BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION(trait, func_name) \
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION_(/* is_static = */ 0, \
|
||||
trait, func_name)
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION( \
|
||||
trait, func_name) \
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION_( \
|
||||
/* is_static = */ 0, trait, func_name)
|
||||
|
||||
#define BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_STATIC_MEMBER_FUNCTION(trait, \
|
||||
#define \
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_STATIC_MEMBER_FUNCTION(trait, \
|
||||
func_name) \
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION_(/* is_static = */ 1, \
|
||||
trait, func_name)
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION_( \
|
||||
/* is_static = */ 1, trait, func_name)
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
#define BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION_(is_static, trait, \
|
||||
func_name) \
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION_( \
|
||||
is_static, trait, func_name) \
|
||||
template< \
|
||||
typename BOOST_CONTRACT_AUX_NAME1(T), \
|
||||
typename BOOST_CONTRACT_AUX_NAME1(R), \
|
||||
@@ -50,8 +53,8 @@
|
||||
> \
|
||||
class trait { \
|
||||
template<class BOOST_CONTRACT_AUX_NAME1(C)> \
|
||||
static boost::contract::aux::tti::yes& check( \
|
||||
boost::contract::aux::tti::check_function< \
|
||||
static boost::contract::aux::type_traits::introspection::yes& check( \
|
||||
boost::contract::aux::type_traits::introspection::check_function< \
|
||||
typename \
|
||||
BOOST_PP_IIF(is_static, \
|
||||
boost::function_types::function_pointer \
|
||||
@@ -79,21 +82,24 @@
|
||||
>* \
|
||||
); \
|
||||
\
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_END_(BOOST_CONTRACT_AUX_NAME1(T)) \
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_END_( \
|
||||
BOOST_CONTRACT_AUX_NAME1(T)) \
|
||||
};
|
||||
|
||||
#define BOOST_CONTRACT_AUX_TTI_TRAIT_END_(tparam) \
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_END_(tparam) \
|
||||
template<typename> \
|
||||
static boost::contract::aux::tti::no& check(...); \
|
||||
static boost::contract::aux::type_traits::introspection::no& check( \
|
||||
...); \
|
||||
\
|
||||
public: \
|
||||
static bool const value = sizeof(check<tparam>(0)) == \
|
||||
sizeof(boost::contract::aux::tti::yes); \
|
||||
sizeof(boost::contract::aux::type_traits::introspection::yes); \
|
||||
typedef boost::mpl::bool_<value> type;
|
||||
|
||||
/* CODE */
|
||||
|
||||
namespace boost { namespace contract { namespace aux { namespace tti {
|
||||
namespace boost { namespace contract { namespace aux { namespace type_traits {
|
||||
namespace introspection {
|
||||
|
||||
typedef struct {} yes;
|
||||
typedef yes no[2];
|
||||
@@ -101,7 +107,7 @@ typedef yes no[2];
|
||||
template<typename F, F>
|
||||
struct check_function;
|
||||
|
||||
} } } } // namespace
|
||||
} } } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
|
||||
#ifndef BOOST_CONTRACT_AUX_INVARIANT_HPP_
|
||||
#define BOOST_CONTRACT_AUX_INVARIANT_HPP_
|
||||
#ifndef BOOST_CONTRACT_AUX_TYPE_TRAITS_INVARIANT_HPP_
|
||||
#define BOOST_CONTRACT_AUX_TYPE_TRAITS_INVARIANT_HPP_
|
||||
|
||||
#include <boost/contract/config.hpp>
|
||||
#include <boost/contract/aux_/tti.hpp>
|
||||
#include <boost/contract/aux_/type_traits/introspection.hpp>
|
||||
#include <boost/function_types/property_tags.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
namespace boost { namespace contract { namespace aux {
|
||||
namespace boost { namespace contract { namespace aux { namespace type_traits {
|
||||
|
||||
namespace invariant_ {
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION(has_invariant,
|
||||
BOOST_CONTRACT_CONFIG_INVARIANT)
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION(
|
||||
has_invariant, BOOST_CONTRACT_CONFIG_INVARIANT)
|
||||
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION(
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION(
|
||||
has_non_static_invariant, BOOST_CONTRACT_CONFIG_STATIC_INVARIANT)
|
||||
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_STATIC_MEMBER_FUNCTION(
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_STATIC_MEMBER_FUNCTION(
|
||||
has_static_invariant, BOOST_CONTRACT_CONFIG_STATIC_INVARIANT)
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ template<typename T>
|
||||
struct has_non_static_invariant : invariant_::has_non_static_invariant<T, void,
|
||||
boost::mpl::vector<> > {};
|
||||
|
||||
} } } // namespace
|
||||
} } } } // namespace
|
||||
|
||||
#endif // #include guard
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <boost/contract/aux_/preprocessor/keyword/protected.hpp>
|
||||
#include <boost/contract/aux_/preprocessor/keyword/private.hpp>
|
||||
#include <boost/contract/aux_/preprocessor/keyword/virtual.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/fold_left.hpp>
|
||||
#include <boost/preprocessor/seq/push_back.hpp>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define BOOST_CONTRACT_CONSTRUCTOR_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/aux_/constructor.hpp>
|
||||
#include <boost/contract/aux_/function/constructor.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace boost { namespace contract {
|
||||
@@ -11,7 +11,7 @@ namespace boost { namespace contract {
|
||||
template<class Class>
|
||||
boost::contract::type constructor(Class* const object) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
constructor<Class> >(object));
|
||||
function::constructor<Class> >(object));
|
||||
}
|
||||
|
||||
// Uses Class tparam to avoid multiple inheritance from same type.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define BOOST_CONTRACT_DESTRUCTOR_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/aux_/destructor.hpp>
|
||||
#include <boost/contract/aux_/function/destructor.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace boost { namespace contract {
|
||||
@@ -11,7 +11,7 @@ namespace boost { namespace contract {
|
||||
template<class Class>
|
||||
boost::contract::type destructor(Class* const object) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
destructor<Class> >(object));
|
||||
function::destructor<Class> >(object));
|
||||
}
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
#define BOOST_CONTRACT_FREE_FUNCTION_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/aux_/free_function.hpp>
|
||||
#include <boost/contract/aux_/function/free_function.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
boost::contract::type free_function() {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
free_function>());
|
||||
function::free_function>());
|
||||
}
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
#ifndef BOOST_CONTRACT_INTROSPECT_HPP_
|
||||
#define BOOST_CONTRACT_INTROSPECT_HPP_
|
||||
|
||||
#include <boost/contract/aux_/tti.hpp>
|
||||
#include <boost/contract/aux_/type_traits/introspection.hpp>
|
||||
#include <boost/contract/aux_/name.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
#define BOOST_CONTRACT_INTROSPECT(function_name) \
|
||||
BOOST_CONTRACT_TRAIT_INTROSPECT(BOOST_PP_CAT(introspect_, function_name), \
|
||||
BOOST_CONTRACT_INTROSPECT_TRAIT(BOOST_PP_CAT(introspect_, function_name), \
|
||||
function_name)
|
||||
|
||||
#define BOOST_CONTRACT_TRAIT_INTROSPECT(trait_name, function_name) \
|
||||
#define BOOST_CONTRACT_INTROSPECT_TRAIT(trait_name, function_name) \
|
||||
struct trait_name { \
|
||||
BOOST_CONTRACT_AUX_TTI_TRAIT_HAS_MEMBER_FUNCTION(has_member_function, \
|
||||
function_name) \
|
||||
BOOST_CONTRACT_AUX_TYPE_TRAITS_INTROSPECTION_HAS_MEMBER_FUNCTION( \
|
||||
has_member_function, function_name) \
|
||||
\
|
||||
template<class BOOST_CONTRACT_AUX_NAME1(C), \
|
||||
typename BOOST_CONTRACT_AUX_NAME1(F)> \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define BOOST_CONTRACT_PRIVATE_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/aux_/private_member.hpp>
|
||||
#include <boost/contract/aux_/function/private_member.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// TOOD: On C++11 Clang... these could static_assert enclosing func is not pub?
|
||||
@@ -12,7 +12,7 @@ namespace boost { namespace contract {
|
||||
|
||||
boost::contract::type private_member() {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
private_member>());
|
||||
function::private_member>());
|
||||
}
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define BOOST_CONTRACT_PROTECTED_MEMBER_HPP_
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/aux_/protected_member.hpp>
|
||||
#include <boost/contract/aux_/function/protected_member.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// TOOD: On C++11 Clang... these could static_assert enclosing func is not pub?
|
||||
@@ -12,7 +12,7 @@ namespace boost { namespace contract {
|
||||
|
||||
boost::contract::type protected_member() {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
protected_member>());
|
||||
function::protected_member>());
|
||||
}
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#include <boost/contract/type.hpp>
|
||||
#include <boost/contract/virtual_body.hpp>
|
||||
#include <boost/contract/aux_/public_member.hpp>
|
||||
#include <boost/contract/aux_/function/public_static_member.hpp>
|
||||
#include <boost/contract/aux_/function/public_member.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// TODO: On C++11 Clang... these could static_assert enclosing func is pub?
|
||||
@@ -42,7 +43,7 @@ template<class Itrospection, class Class, typename Function,
|
||||
boost::contract::type public_member(Class* const object, Function const&,
|
||||
Argument0 argument0, boost::contract::virtual_body const v) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
public_member<Class, Itrospection, Function, Argument0> >(
|
||||
function::public_member<Class, Itrospection, Function, Argument0> >(
|
||||
v, object, argument0)
|
||||
);
|
||||
}
|
||||
@@ -56,7 +57,7 @@ template<class Introspection, class Class, typename Function,
|
||||
boost::contract::type public_member(Class* const object, Function const&,
|
||||
Argument0 argument0) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
public_member<Class, Introspection, Function, Argument0> >(
|
||||
function::public_member<Class, Introspection, Function, Argument0> >(
|
||||
object, argument0)
|
||||
);
|
||||
}
|
||||
@@ -67,7 +68,7 @@ template<class Class>
|
||||
boost::contract::type public_member(Class* const object,
|
||||
boost::contract::virtual_body const v) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
public_member<Class> >(v, object));
|
||||
function::public_member<Class> >(v, object));
|
||||
}
|
||||
|
||||
// Contract for public member functions with a non-virtual body and members of a
|
||||
@@ -75,14 +76,14 @@ boost::contract::type public_member(Class* const object,
|
||||
template<class Class>
|
||||
boost::contract::type public_member(Class* const object) {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
public_member<Class> >(object));
|
||||
function::public_member<Class> >(object));
|
||||
}
|
||||
|
||||
// Contract for public static member functions.
|
||||
template<class Class>
|
||||
boost::contract::type public_member() {
|
||||
return boost::contract::type(boost::make_shared<boost::contract::aux::
|
||||
public_member<Class> >());
|
||||
function::public_static_member<Class> >());
|
||||
}
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -5,9 +5,14 @@
|
||||
namespace boost { namespace contract {
|
||||
|
||||
namespace aux {
|
||||
template<class, class, typename> class base_function;
|
||||
template<class, class, typename, typename> class basic_function;
|
||||
template<class, class, typename, typename> class public_member;
|
||||
namespace check {
|
||||
template<class, class, typename, typename>
|
||||
class subcontracted_pre_post_inv;
|
||||
}
|
||||
namespace function {
|
||||
template<class, class, typename, typename>
|
||||
class public_member;
|
||||
}
|
||||
}
|
||||
|
||||
// Must be efficient to pass this as value param (to limit user API verbosity).
|
||||
@@ -23,12 +28,10 @@ private:
|
||||
// they make the impl hard to follow). These ones are necessary because
|
||||
// they are between public and private APIs of the lib. But maybe
|
||||
// the ones among some of the private APIs of the lib could be reduced...
|
||||
template<class, class, typename> friend class
|
||||
boost::contract::aux::base_function;
|
||||
template<class, class, typename, typename> friend class
|
||||
boost::contract::aux::basic_function;
|
||||
boost::contract::aux::check::subcontracted_pre_post_inv;
|
||||
template<class, class, typename, typename> friend class
|
||||
boost::contract::aux::public_member;
|
||||
boost::contract::aux::function::public_member;
|
||||
|
||||
enum action_type {
|
||||
user_call,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include <boost/contract/aux_/bases.hpp>
|
||||
#include <boost/contract/aux_/type_traits/bases.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
@@ -11,10 +11,10 @@ struct x : y, z {
|
||||
};
|
||||
|
||||
int main() {
|
||||
BOOST_TEST(!boost::contract::aux::has_bases<y>::value);
|
||||
BOOST_TEST(boost::contract::aux::has_bases<x>::value);
|
||||
BOOST_TEST((boost::is_same<boost::contract::aux::bases_of<x>::type,
|
||||
boost::mpl::vector<y, z> >::value));
|
||||
BOOST_TEST(!boost::contract::aux::type_traits::has_bases<y>::value);
|
||||
BOOST_TEST(boost::contract::aux::type_traits::has_bases<x>::value);
|
||||
BOOST_TEST((boost::is_same<boost::contract::aux::type_traits::bases_of<x>::
|
||||
type, boost::mpl::vector<y, z> >::value));
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include <boost/contract/aux_/invariant.hpp>
|
||||
#include <boost/contract/aux_/type_traits/invariant.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct x {}; // Test no invariants.
|
||||
@@ -29,35 +29,37 @@ struct ns {
|
||||
};
|
||||
|
||||
int main() {
|
||||
BOOST_TEST(!boost::contract::aux::has_const_invariant<x>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_const_volatile_invariant<x>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_invariant<x>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_static_invariant<x>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_non_static_invariant<x>::value);
|
||||
using namespace boost::contract::aux::type_traits;
|
||||
|
||||
BOOST_TEST(!has_const_invariant<x>::value);
|
||||
BOOST_TEST(!has_const_volatile_invariant<x>::value);
|
||||
BOOST_TEST(!has_invariant<x>::value);
|
||||
BOOST_TEST(!has_static_invariant<x>::value);
|
||||
BOOST_TEST(!has_non_static_invariant<x>::value);
|
||||
|
||||
BOOST_TEST( boost::contract::aux::has_const_invariant<c>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_const_volatile_invariant<c>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_invariant<c>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_static_invariant<c>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_non_static_invariant<c>::value);
|
||||
BOOST_TEST( has_const_invariant<c>::value);
|
||||
BOOST_TEST(!has_const_volatile_invariant<c>::value);
|
||||
BOOST_TEST(!has_invariant<c>::value);
|
||||
BOOST_TEST(!has_static_invariant<c>::value);
|
||||
BOOST_TEST(!has_non_static_invariant<c>::value);
|
||||
|
||||
BOOST_TEST(!boost::contract::aux::has_const_invariant<cv>::value);
|
||||
BOOST_TEST( boost::contract::aux::has_const_volatile_invariant<cv>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_invariant<cv>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_static_invariant<cv>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_non_static_invariant<cv>::value);
|
||||
BOOST_TEST(!has_const_invariant<cv>::value);
|
||||
BOOST_TEST( has_const_volatile_invariant<cv>::value);
|
||||
BOOST_TEST(!has_invariant<cv>::value);
|
||||
BOOST_TEST(!has_static_invariant<cv>::value);
|
||||
BOOST_TEST(!has_non_static_invariant<cv>::value);
|
||||
|
||||
BOOST_TEST(!boost::contract::aux::has_const_invariant<i>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_const_volatile_invariant<i>::value);
|
||||
BOOST_TEST( boost::contract::aux::has_invariant<i>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_static_invariant<i>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_non_static_invariant<i>::value);
|
||||
BOOST_TEST(!has_const_invariant<i>::value);
|
||||
BOOST_TEST(!has_const_volatile_invariant<i>::value);
|
||||
BOOST_TEST( has_invariant<i>::value);
|
||||
BOOST_TEST(!has_static_invariant<i>::value);
|
||||
BOOST_TEST(!has_non_static_invariant<i>::value);
|
||||
|
||||
BOOST_TEST(!boost::contract::aux::has_const_invariant<ns>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_const_volatile_invariant<ns>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_invariant<ns>::value);
|
||||
BOOST_TEST(!boost::contract::aux::has_static_invariant<ns>::value);
|
||||
BOOST_TEST( boost::contract::aux::has_non_static_invariant<ns>::value);
|
||||
BOOST_TEST(!has_const_invariant<ns>::value);
|
||||
BOOST_TEST(!has_const_volatile_invariant<ns>::value);
|
||||
BOOST_TEST(!has_invariant<ns>::value);
|
||||
BOOST_TEST(!has_static_invariant<ns>::value);
|
||||
BOOST_TEST( has_non_static_invariant<ns>::value);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user