feat():initial version

This commit is contained in:
2026-06-09 20:16:47 +08:00
commit 85fbb3188c
14809 changed files with 3044607 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
#ifndef BOOST_CONTRACT_DETAIL_ASSERT_HPP_
#define BOOST_CONTRACT_DETAIL_ASSERT_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/detail/noop.hpp>
#include <boost/preprocessor/stringize.hpp>
// In detail because used by both ASSERT and CHECK.
// Use ternary operator `?:` and no trailing `;` here to allow `if(...) ASSERT(
// ...); else ...` (won't compile if expands using an if statement instead even
// if wrapped by {}, and else won't compile if expands trailing `;`).
#define BOOST_CONTRACT_DETAIL_ASSERT(cond) \
/* no if-statement here */ \
((cond) ? \
BOOST_CONTRACT_DETAIL_NOOP \
: \
throw boost::contract::assertion_failure( \
__FILE__, __LINE__, BOOST_PP_STRINGIZE(cond)) \
) /* no ; here */
#endif // #include guard

View File

@@ -0,0 +1,53 @@
#ifndef BOOST_CONTRACT_DETAIL_AUTO_PTR_HPP_
#define BOOST_CONTRACT_DETAIL_AUTO_PTR_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/operator_safe_bool.hpp>
#include <boost/contract/detail/debug.hpp>
#include <boost/config.hpp>
namespace boost { namespace contract { namespace detail {
// Using this instead of std::auto_ptr because std::auto_ptr will be removed in
// C++17 (this library always uses release() to avoid ownership issues).
template<typename T>
class auto_ptr { // Copyable (using default copy operations).
public:
explicit auto_ptr(T* ptr = 0) : ptr_(ptr) {}
~auto_ptr() BOOST_NOEXCEPT_IF(false) { delete ptr_; }
T* release() {
T* ptr = ptr_;
ptr_ = 0;
return ptr;
}
T& operator*() {
BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
return *ptr_;
}
T const& operator*() const {
BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
return *ptr_;
}
T* operator->() { return ptr_; }
T const* operator->() const { return ptr_; }
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(auto_ptr<T>, !!ptr_)
private:
T* ptr_;
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,48 @@
#ifndef BOOST_CONTRACT_DETAIL_CHECK_HPP_
#define BOOST_CONTRACT_DETAIL_CHECK_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/config.hpp>
#ifndef BOOST_CONTRACT_NO_CHECKS
#include <boost/contract/core/exception.hpp>
/* PRIVATE */
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
#include <boost/contract/detail/checking.hpp>
#include <boost/contract/detail/name.hpp>
#define BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ \
if(!boost::contract::detail::checking::already())
#define BOOST_CONTRACT_CHECK_CHECKING_VAR_(guard) \
/* this name somewhat unique to min var shadow warnings */ \
boost::contract::detail::checking BOOST_CONTRACT_DETAIL_NAME2( \
guard, __LINE__);
#else
#define BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ /* nothing */
#define BOOST_CONTRACT_CHECK_CHECKING_VAR_(guard) /* nothing */
#endif
/* PUBLIC */
#define BOOST_CONTRACT_DETAIL_CHECK(assertion) \
{ \
try { \
BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ \
{ \
BOOST_CONTRACT_CHECK_CHECKING_VAR_(k) \
{ assertion; } \
} \
} catch(...) { boost::contract::check_failure(); } \
}
#else
#define BOOST_CONTRACT_DETAIL_CHECK(assertion) {}
#endif
#endif // #include guard

View File

@@ -0,0 +1,82 @@
#ifndef BOOST_CONTRACT_DETAIL_CHECKING_HPP_
#define BOOST_CONTRACT_DETAIL_CHECKING_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/static_local_var.hpp>
#include <boost/contract/detail/declspec.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>
#include <boost/config.hpp>
namespace boost { namespace contract { namespace detail {
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable: 4275) // Base w/o DLL spec (noncopyable).
#pragma warning(disable: 4251) // Member w/o DLL spec (mutex_ type).
#endif
// RAII facility to disable assertions while checking other assertions.
class BOOST_CONTRACT_DETAIL_DECLSPEC checking :
private boost::noncopyable // Non-copyable resource (might use mutex, etc.).
{
public:
explicit checking() {
#ifndef BOOST_CONTRACT_DISABLE_THREADS
init_locked();
#else
init_unlocked();
#endif
}
~checking() {
#ifndef BOOST_CONTRACT_DISABLE_THREADS
done_locked();
#else
done_unlocked();
#endif
}
static bool already() {
#ifndef BOOST_CONTRACT_DISABLE_THREADS
return already_locked();
#else
return already_unlocked();
#endif
}
private:
void init_unlocked();
void init_locked();
void done_unlocked();
void done_locked();
static bool already_unlocked();
static bool already_locked();
struct mutex_tag;
typedef static_local_var<mutex_tag, boost::mutex> mutex;
struct checking_tag;
typedef static_local_var_init<checking_tag, bool, bool, false> flag;
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
} } } // namespace
#ifdef BOOST_CONTRACT_HEADER_ONLY
#include <boost/contract/detail/inlined/detail/checking.hpp>
#endif
#endif // #include guard

View File

@@ -0,0 +1,153 @@
#ifndef BOOST_CONTRACT_DETAIL_COND_BASE_HPP_
#define BOOST_CONTRACT_DETAIL_COND_BASE_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// NOTE: It seemed not possible to implement this library without inheritance
// here because some sort of base type needs to be used to hold contract objects
// in instances of boost::contract::check while polymorphically calling
// init and destructor functions to check contracts at entry and exit. This
// could be possible without inheritance only if boost::contract::check was made
// a template type but that would complicate user code. In any case, early
// experimentation with removing this base class and its virtual methods did not
// seem to reduce compilation and/or run time.
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_OLDS) || \
!defined(BOOST_CONTRACT_NO_EXEPTS)
#include <boost/function.hpp>
#endif
#include <boost/noncopyable.hpp>
#ifndef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
#include <boost/assert.hpp>
#endif
#include <boost/config.hpp>
namespace boost { namespace contract { namespace detail {
class cond_base : // Base to hold all contract objects for RAII.
private boost::noncopyable // Avoid copying possible user's ftor captures.
{
public:
explicit cond_base(boost::contract::from from) :
BOOST_CONTRACT_ERROR_missing_check_object_declaration(false)
, init_asserted_(false)
#ifndef BOOST_CONTRACT_NO_CONDITIONS
, from_(from)
, failed_(false)
#endif
{}
// Can override for checking on exit, but should call assert_initialized().
virtual ~cond_base() BOOST_NOEXCEPT_IF(false) {
// Catch error (but later) even if overrides miss assert_initialized().
if(!init_asserted_) assert_initialized();
}
void initialize() { // Must be called by owner ctor (i.e., check class).
BOOST_CONTRACT_ERROR_missing_check_object_declaration = true;
this->init(); // So all inits (pre, old, post) done after owner decl.
}
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
template<typename F>
void set_pre(F const& f) { pre_ = f; }
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
template<typename F>
void set_old(F const& f) { old_ = f; }
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
template<typename F>
void set_except(F const& f) { except_ = f; }
#endif
protected:
void assert_initialized() { // Derived dtors must assert this at entry.
init_asserted_ = true;
#ifdef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
if(!BOOST_CONTRACT_ERROR_missing_check_object_declaration) {
BOOST_CONTRACT_ON_MISSING_CHECK_DECL;
}
#else
// Cannot use a macro instead of this ERROR_... directly here
// because assert will not expand it in the error message.
BOOST_ASSERT(BOOST_CONTRACT_ERROR_missing_check_object_declaration);
#endif
}
virtual void init() {} // Override for checking on entry.
// Return true if actually checked calling user ftor.
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
bool check_pre(bool throw_on_failure = false) {
if(failed()) return true;
try { if(pre_) pre_(); else return false; }
catch(...) {
// Subcontracted pre must throw on failure (instead of
// calling failure handler) so to be checked in logic-or.
if(throw_on_failure) throw;
fail(&boost::contract::precondition_failure);
}
return true;
}
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
void copy_old() {
if(failed()) return;
try { if(old_) old_(); }
catch(...) { fail(&boost::contract::old_failure); }
}
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
void check_except() {
if(failed()) return;
try { if(except_) except_(); }
catch(...) { fail(&boost::contract::except_failure); }
}
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
void fail(void (*h)(boost::contract::from)) {
failed(true);
if(h) h(from_);
}
// Virtual so overriding pub func can use virtual_::failed_ instead.
virtual bool failed() const { return failed_; }
virtual void failed(bool value) { failed_ = value; }
#endif
private:
bool BOOST_CONTRACT_ERROR_missing_check_object_declaration;
bool init_asserted_; // Avoid throwing twice from dtors (undef behavior).
#ifndef BOOST_CONTRACT_NO_CONDITIONS
boost::contract::from from_;
bool failed_;
#endif
// Following use Boost.Function to handle also lambdas, binds, etc.
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
boost::function<void ()> pre_;
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
boost::function<void ()> old_;
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
boost::function<void ()> except_;
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,232 @@
#ifndef BOOST_CONTRACT_DETAIL_COND_INV_HPP_
#define BOOST_CONTRACT_DETAIL_COND_INV_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_post.hpp>
#ifndef BOOST_CONTRACT_NO_INVARIANTS
#include <boost/contract/core/access.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/utility/enable_if.hpp>
#ifndef BOOST_CONTRACT_PERMISSIVE
#include <boost/function_types/property_tags.hpp>
#include <boost/static_assert.hpp>
#endif
#endif
namespace boost { namespace contract { namespace detail {
template<typename VR, class C>
class cond_inv : public cond_post<VR> { // Non-copyable base.
#if !defined(BOOST_CONTRACT_NO_INVARIANTS) && \
!defined(BOOST_CONTRACT_PERMISSIVE)
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_static_invariant_f<
C, void, boost::mpl:: vector<>
>::value),
"static invariant member function cannot be mutable "
"(it must be static instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_static_invariant_f<
C, void, boost::mpl::vector<>,
boost::function_types::const_non_volatile
>::value),
"static invariant member function cannot be const qualified "
"(it must be static instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_static_invariant_f<
C, void, boost::mpl::vector<>,
boost::function_types::volatile_non_const
>::value),
"static invariant member function cannot be volatile qualified "
"(it must be static instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_static_invariant_f<
C, void, boost::mpl::vector<>,
boost::function_types::cv_qualified
>::value),
"static invariant member function cannot be const volatile "
"qualified (it must be static instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_invariant_s<
C, void, boost::mpl::vector<>
>::value),
"non-static invariant member function cannot be static "
"(it must be either const or const volatile qualified instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_invariant_f<
C, void, boost::mpl::vector<>,
boost::function_types::non_cv
>::value),
"non-static invariant member function cannot be mutable "
"(it must be either const or const volatile qualified instead)"
);
BOOST_STATIC_ASSERT_MSG(
(!boost::contract::access::has_invariant_f<
C, void, boost::mpl::vector<>,
boost::function_types::volatile_non_const
>::value),
"non-static invariant member function cannot be volatile qualified "
"(it must be const or const volatile qualified instead)"
);
#endif
public:
// obj can be 0 for static member functions.
explicit cond_inv(boost::contract::from from, C* obj) :
cond_post<VR>(from)
#ifndef BOOST_CONTRACT_NO_CONDITIONS
, obj_(obj)
#endif
{}
protected:
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
void check_entry_inv() { check_inv(true, false, false); }
void check_entry_static_inv() { check_inv(true, true, false); }
void check_entry_all_inv() { check_inv(true, false, true); }
#endif
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
void check_exit_inv() { check_inv(false, false, false); }
void check_exit_static_inv() { check_inv(false, true, false); }
void check_exit_all_inv() { check_inv(false, false, true); }
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
C* object() { return obj_; }
#endif
private:
#ifndef BOOST_CONTRACT_NO_INVARIANTS
// Static, cv, and const inv in that order as strongest qualifier first.
void check_inv(bool on_entry, bool static_only, bool const_and_cv) {
if(this->failed()) return;
try {
// Static members only check static inv.
check_static_inv<C>();
if(!static_only) {
if(const_and_cv) {
check_cv_inv<C>();
check_const_inv<C>();
} else if(boost::is_volatile<C>::value) {
check_cv_inv<C>();
} else {
check_const_inv<C>();
}
}
} catch(...) {
if(on_entry) {
this->fail(&boost::contract::entry_invariant_failure);
} else this->fail(&boost::contract::exit_invariant_failure);
}
}
template<class C_>
typename boost::disable_if<
boost::contract::access::has_const_invariant<C_> >::type
check_const_inv() {}
template<class C_>
typename boost::enable_if<
boost::contract::access::has_const_invariant<C_> >::type
check_const_inv() { boost::contract::access::const_invariant(obj_); }
template<class C_>
typename boost::disable_if<
boost::contract::access::has_cv_invariant<C_> >::type
check_cv_inv() {}
template<class C_>
typename boost::enable_if<
boost::contract::access::has_cv_invariant<C_> >::type
check_cv_inv() { boost::contract::access::cv_invariant(obj_); }
template<class C_>
typename boost::disable_if<
boost::contract::access::has_static_invariant<C_> >::type
check_static_inv() {}
template<class C_>
typename boost::enable_if<
boost::contract::access::has_static_invariant<C_> >::type
check_static_inv() {
// SFINAE HAS_STATIC_... returns true even when member is inherited
// so extra run-time check here (not the same for non static).
if(!inherited<boost::contract::access::has_static_invariant,
boost::contract::access::static_invariant_addr>::apply()) {
boost::contract::access::static_invariant<C_>();
}
}
// Check if class's func is inherited from its base types or not.
template<template<class> class HasFunc, template<class> class FuncAddr>
struct inherited {
static bool apply() {
try {
boost::mpl::for_each<
// For now, no reason to deeply search inheritance tree
// (SFINAE HAS_STATIC_... already fails in that case).
typename boost::mpl::transform<
typename boost::mpl::copy_if<
typename boost::mpl::eval_if<boost::contract::
access::has_base_types<C>,
typename boost::contract::access::
base_types_of<C>
,
boost::mpl::vector<>
>::type,
HasFunc<boost::mpl::_1>
>::type,
boost::add_pointer<boost::mpl::_1>
>::type
>(compare_func_addr());
} catch(signal_equal const&) { return true; }
return false;
}
private:
class signal_equal {}; // Except. to stop for_each as soon as found.
struct compare_func_addr {
template<typename B>
void operator()(B*) {
// Inherited func has same addr as in its base.
if(FuncAddr<C>::apply() == FuncAddr<B>::apply()) {
throw signal_equal();
}
}
};
};
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
C* obj_;
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,89 @@
#ifndef BOOST_CONTRACT_DETAIL_COND_POST_HPP_
#define BOOST_CONTRACT_DETAIL_COND_POST_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_base.hpp>
#include <boost/contract/detail/none.hpp>
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
#include <boost/contract/detail/type_traits/optional.hpp>
#include <boost/optional.hpp>
#include <boost/function.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#endif
/* PRIVATE */
#define BOOST_CONTRACT_DETAIL_COND_POST_DEF_( \
result_type, result_param, ftor_type, ftor_var, ftor_call) \
public: \
template<typename F> \
void set_post(F const& f) { ftor_var = f; } \
\
protected: \
void check_post(result_type const& result_param) { \
if(failed()) return; \
try { if(ftor_var) { ftor_call; } } \
catch(...) { fail(&boost::contract::postcondition_failure); } \
} \
\
private: \
boost::function<ftor_type> ftor_var; /* Boost.Func for lambdas, etc. */
/* CODE */
namespace boost { namespace contract { namespace detail {
template<typename VR>
class cond_post : public cond_base { // Non-copyable base.
public:
explicit cond_post(boost::contract::from from) : cond_base(from) {}
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
private: typedef typename boost::mpl::if_<is_optional<VR>,
boost::optional<typename boost::remove_reference<typename
optional_value_type<VR>::type>::type const&> const&
,
VR const&
>::type r_type;
BOOST_CONTRACT_DETAIL_COND_POST_DEF_(
r_type,
r,
void (r_type),
// Won't raise this error if NO_POST (for optimization).
BOOST_CONTRACT_ERROR_postcondition_result_parameter_required,
BOOST_CONTRACT_ERROR_postcondition_result_parameter_required(r)
)
#endif
};
template<>
class cond_post<none> : public cond_base { // Non-copyable base.
public:
explicit cond_post(boost::contract::from from) : cond_base(from) {}
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_COND_POST_DEF_(
none,
/* r */ BOOST_PP_EMPTY(),
void (),
// Won't raise this error if NO_POST (for optimization).
BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed,
BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed()
)
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,475 @@
#ifndef BOOST_CONTRACT_DETAIL_COND_SUBCONTRACTING_HPP_
#define BOOST_CONTRACT_DETAIL_COND_SUBCONTRACTING_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/config.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/contract/core/exception.hpp>
#endif
#include <boost/contract/detail/condition/cond_inv.hpp>
#include <boost/contract/detail/decl.hpp>
#include <boost/contract/detail/tvariadic.hpp>
#ifndef BOOST_CONTRACT_NO_CONDITIONS
#include <boost/contract/core/virtual.hpp>
#include <boost/contract/core/access.hpp>
#include <boost/contract/detail/type_traits/optional.hpp>
#include <boost/contract/detail/type_traits/member_function_types.hpp>
#include <boost/contract/detail/debug.hpp>
#include <boost/contract/detail/none.hpp>
#include <boost/contract/detail/name.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/placeholders.hpp>
#ifndef BOOST_CONTRACT_PERMISSIVE
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/static_assert.hpp>
#endif
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/config.hpp>
#endif
#include <boost/mpl/vector.hpp>
#if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/mpl/for_each.hpp>
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOSOT_CONTRACT_NO_EXCEPTS)
#include <boost/any.hpp>
#include <boost/optional.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <typeinfo>
#endif
namespace boost { namespace contract { namespace detail {
namespace cond_subcontracting_ {
// Exception signals (must not inherit).
class signal_no_error {};
class signal_not_checked {};
}
// O, VR, F, and Args-i can be none types (but C cannot).
BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
/* is_friend = */ 0, O, VR, F, C, Args) : public cond_inv<VR, C>
{ // Non-copyable base.
#ifndef BOOST_CONTRACT_NO_CONDITIONS
template<class Class, typename Result = boost::mpl::vector<> >
class overridden_bases_of {
struct search_bases {
typedef typename boost::mpl::fold<
typename boost::contract::access::base_types_of<Class>::
type,
Result,
// Fold: _1 = result, _2 = current base from base_types.
boost::mpl::eval_if<boost::mpl::contains<boost::mpl::_1,
boost::add_pointer<boost::mpl::_2> >,
boost::mpl::_1 // Base in result, do not add it again.
,
boost::mpl::eval_if<
typename O::template BOOST_CONTRACT_DETAIL_NAME1(
has_member_function)<
boost::mpl::_2,
typename member_function_types<C, F>::
result_type,
typename member_function_types<C, F>::
virtual_argument_types,
typename member_function_types<C, F>::
property_tag
>
,
boost::mpl::push_back<
overridden_bases_of<boost::mpl::_2,
boost::mpl::_1>,
// Bases as * since for_each constructs them.
boost::add_pointer<boost::mpl::_2>
>
,
overridden_bases_of<boost::mpl::_2, boost::mpl::_1>
>
>
>::type type;
};
public:
typedef typename boost::mpl::eval_if<
boost::contract::access::has_base_types<Class>,
search_bases
,
boost::mpl::identity<Result> // Return result (stop recursion).
>::type type;
};
typedef typename boost::mpl::eval_if<boost::is_same<O, none>,
boost::mpl::vector<>
,
overridden_bases_of<C>
>::type overridden_bases;
#ifndef BOOST_CONTRACT_PERMISSIVE
BOOST_STATIC_ASSERT_MSG(
(boost::mpl::or_<
boost::is_same<O, none>,
boost::mpl::not_<boost::mpl::empty<overridden_bases> >
>::value),
"subcontracting function specified as 'override' but does not "
"override any contracted member function"
);
#endif
#else
typedef boost::mpl::vector<> overridden_bases;
#endif
public:
explicit cond_subcontracting(
boost::contract::from from,
boost::contract::virtual_* v,
C* obj,
VR&
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS // Avoid unused param warning.
r
#endif
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args, &, args)
) :
cond_inv<VR, C>(from, obj)
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
, r_(r)
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(1,
BOOST_CONTRACT_MAX_ARGS, args_, args)
#endif
{
#ifndef BOOST_CONTRACT_NO_CONDITIONS
if(v) {
base_call_ = true;
v_ = v; // Invariant: v_ never null if base_call_.
BOOST_CONTRACT_DETAIL_DEBUG(v_);
} else {
base_call_ = false;
if(!boost::mpl::empty<overridden_bases>::value) {
v_ = new boost::contract::virtual_(
boost::contract::virtual_::no_action);
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
v_->result_ptr_ = &r_;
v_->result_type_name_ = typeid(VR).name();
v_->result_optional_ = is_optional<VR>::value;
#endif
} else v_ = 0;
}
#endif
}
#ifndef BOOST_CONTRACT_NO_CONDITIONS
virtual ~cond_subcontracting() BOOST_NOEXCEPT_IF(false) {
if(!base_call_) delete v_;
}
#endif
protected:
#ifndef BOOST_CONTRACT_NO_OLDS
void init_subcontracted_old() {
// Old values of overloaded func on stack (so no `f` param here).
exec_and(boost::contract::virtual_::push_old_init_copy);
}
#endif
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
void check_subcontracted_entry_inv() {
exec_and(boost::contract::virtual_::check_entry_inv,
&cond_subcontracting::check_entry_inv);
}
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
void check_subcontracted_pre() {
exec_or(
boost::contract::virtual_::check_pre,
&cond_subcontracting::check_pre,
&boost::contract::precondition_failure
);
}
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
void copy_subcontracted_old() {
exec_and(boost::contract::virtual_::call_old_ftor,
&cond_subcontracting::copy_virtual_old);
}
#endif
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
void check_subcontracted_exit_inv() {
exec_and(boost::contract::virtual_::check_exit_inv,
&cond_subcontracting::check_exit_inv);
}
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
void check_subcontracted_post() {
exec_and(boost::contract::virtual_::check_post,
&cond_subcontracting::check_virtual_post);
}
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
void check_subcontracted_except() {
exec_and(boost::contract::virtual_::check_except,
&cond_subcontracting::check_virtual_except);
}
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
bool base_call() const { return base_call_; }
bool failed() const /* override */ {
if(v_) return v_->failed_;
else return cond_base::failed();
}
void failed(bool value) /* override */ {
if(v_) v_->failed_ = value;
else cond_base::failed(value);
}
#endif
private:
#ifndef BOOST_CONTRACT_NO_OLDS
void copy_virtual_old() {
boost::contract::virtual_::action_enum a;
if(base_call_) {
a = v_->action_;
v_->action_ = boost::contract::virtual_::push_old_ftor_copy;
}
this->copy_old();
if(base_call_) v_->action_ = a;
}
void pop_base_old() {
if(base_call_) {
boost::contract::virtual_::action_enum a = v_->action_;
v_->action_ = boost::contract::virtual_::pop_old_ftor_copy;
this->copy_old();
v_->action_ = a;
} // Else, do nothing (for base calls only).
}
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
void check_virtual_post() {
pop_base_old();
typedef typename boost::remove_reference<typename
optional_value_type<VR>::type>::type r_type;
boost::optional<r_type const&> r; // No result copy in this code.
if(!base_call_) r = optional_get(r_);
else if(v_->result_optional_) {
try {
r = **boost::any_cast<boost::optional<r_type>*>(
v_->result_ptr_);
} catch(boost::bad_any_cast const&) {
try { // Handle optional<...&>.
r = **boost::any_cast<boost::optional<r_type&>*>(
v_->result_ptr_);
} catch(boost::bad_any_cast const&) {
try {
throw boost::contract::bad_virtual_result_cast(v_->
result_type_name_, typeid(r_type).name());
} catch(...) {
this->fail(&boost::contract::postcondition_failure);
}
}
}
} else {
try {
r = *boost::any_cast<r_type*>(v_->result_ptr_);
} catch(boost::bad_any_cast const&) {
try {
throw boost::contract::bad_virtual_result_cast(
v_->result_type_name_, typeid(r_type).name());
} catch(...) {
this->fail(&boost::contract::postcondition_failure);
}
}
}
check_virtual_post_with_result<VR>(r);
}
template<typename R_, typename Result>
typename boost::enable_if<is_optional<R_> >::type
check_virtual_post_with_result(Result const& r) {
this->check_post(r);
}
template<typename R_, typename Result>
typename boost::disable_if<is_optional<R_> >::type
check_virtual_post_with_result(Result const& r) {
BOOST_CONTRACT_DETAIL_DEBUG(r);
this->check_post(*r);
}
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
void check_virtual_except() {
pop_base_old();
this->check_except();
}
#endif
#if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
void exec_and( // Execute action in short-circuit logic-and with bases.
boost::contract::virtual_::action_enum a,
void (cond_subcontracting::* f)() = 0
) {
if(failed()) return;
if(!base_call_ || v_->action_ == a) {
if(!base_call_ && v_) {
v_->action_ = a;
boost::mpl::for_each<overridden_bases>(call_base(*this));
}
if(f) (this->*f)();
if(base_call_) {
throw cond_subcontracting_::signal_no_error();
}
}
}
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
void exec_or( // Execute action in short-circuit logic-or with bases.
boost::contract::virtual_::action_enum a,
bool (cond_subcontracting::* f)(bool) = 0,
void (*h)(boost::contract::from) = 0
) {
if(failed()) return;
if(!base_call_ || v_->action_ == a) {
if(!base_call_ && v_) {
v_->action_ = a;
try {
exec_or_bases<overridden_bases>();
return; // A base checked with no error (done).
} catch(...) {
bool checked = f ? (this->*f)(
/* throw_on_failure = */ false) : false;
if(!checked) {
try { throw; } // Report latest exception found.
catch(...) { this->fail(h); }
}
return; // Checked and no exception (done).
}
}
bool checked = f ?
(this->*f)(/* throw_on_failure = */ base_call_) : false;
if(base_call_) {
if(!checked) {
throw cond_subcontracting_::signal_not_checked();
}
throw cond_subcontracting_::signal_no_error();
}
}
}
template<typename Bases>
typename boost::enable_if<boost::mpl::empty<Bases>, bool>::type
exec_or_bases() { return false; }
template<typename Bases>
typename boost::disable_if<boost::mpl::empty<Bases>, bool>::type
exec_or_bases() {
if(boost::mpl::empty<Bases>::value) return false;
try {
call_base(*this)(typename boost::mpl::front<Bases>::type());
} catch(cond_subcontracting_::signal_not_checked const&) {
return exec_or_bases<
typename boost::mpl::pop_front<Bases>::type>();
} catch(...) {
bool checked = false;
try {
checked = exec_or_bases<
typename boost::mpl::pop_front<Bases>::type>();
} catch(...) { checked = false; }
if(!checked) throw;
}
return true;
}
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
class call_base { // Copyable (as &).
public:
explicit call_base(cond_subcontracting& me) : me_(me) {}
template<class B>
void operator()(B*) {
BOOST_CONTRACT_DETAIL_DEBUG(me_.object());
BOOST_CONTRACT_DETAIL_DEBUG(me_.v_);
BOOST_CONTRACT_DETAIL_DEBUG(me_.v_->action_ !=
boost::contract::virtual_::no_action);
try {
call<B>(BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(
Args));
} catch(cond_subcontracting_::signal_no_error const&) {
// No error (do not throw).
}
}
private:
template<
class B
// Can't use TVARIADIC_COMMA here.
BOOST_PP_COMMA_IF(BOOST_CONTRACT_DETAIL_TVARIADIC)
BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(I)
>
void call(
BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(I)) {
O::template BOOST_CONTRACT_DETAIL_NAME1(call_base)<B>(
me_.v_,
me_.object()
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(
BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z(1,
BOOST_CONTRACT_MAX_ARGS, I, me_.args_)
);
}
cond_subcontracting& me_;
};
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
VR& r_;
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
boost::contract::virtual_* v_;
bool base_call_;
BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args, &, args_)
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,26 @@
#ifndef BOOST_CONTRACT_DETAIL_CONFIG_HPP_
#define BOOST_CONTRACT_DETAIL_CONFIG_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/preprocessor/cat.hpp>
// Turn off BOOST_ASSERT(...) in lib's implementation (always on by default).
// BOOST_CONTRACT_DETAIL_NDEBUG
#ifndef BOOST_CONTRACT_DETAIL_NAME_INFIX
// Do not use underscore "_" to avoid generating reserved names with "__".
#define BOOST_CONTRACT_DETAIL_NAME_INFIX X
#endif
#ifndef BOOST_CONTRACT_DETAIL_NAME_PREFIX
#define BOOST_CONTRACT_DETAIL_NAME_PREFIX \
BOOST_PP_CAT(boost_contract_detail, BOOST_CONTRACT_DETAIL_NAME_INFIX)
#endif
#endif // #include guard

View File

@@ -0,0 +1,20 @@
#ifndef BOOST_CONTRACT_DETAIL_DEBUG_HPP_
#define BOOST_CONTRACT_DETAIL_DEBUG_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// Usually, never #defined (so "debug" assertions always in code).
#ifdef BOOST_CONTRACT_DETAIL_NDEBUG
#define BOOST_CONTRACT_DETAIL_DEBUG(cond) /* nothing */
#else
#include <boost/assert.hpp>
// Extra parenthesis around BOOST_ASSERT to be safe because its is a macro.
#define BOOST_CONTRACT_DETAIL_DEBUG(cond) (BOOST_ASSERT(cond))
#endif
#endif // #include guard

View File

@@ -0,0 +1,129 @@
#ifndef BOOST_CONTRACT_DETAIL_DECL_HPP_
#define BOOST_CONTRACT_DETAIL_DECL_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// Cannot include core/*.hpp other than config.hpp here (avoid circular incl).
#include <boost/contract/detail/tvariadic.hpp>
#if !BOOST_CONTRACT_DETAIL_TVARIADIC
#include <boost/contract/core/config.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#endif
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
/* PUBLIC */
#define BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
arity, is_friend, has_result, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
template< \
class O \
BOOST_PP_COMMA_IF(has_result) \
BOOST_PP_EXPR_IIF(has_result, typename VR) \
, typename F \
, class C \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, Args) \
> \
BOOST_PP_EXPR_IIF(is_friend, friend) \
boost::contract::specify_precondition_old_postcondition_except< \
BOOST_PP_EXPR_IIF(has_result, VR)> \
/* no boost::contract:: here for friends (otherwise need fwd decl) */ \
public_function( \
boost::contract::virtual_* v \
BOOST_PP_COMMA_IF(has_result) \
BOOST_PP_EXPR_IIF(has_result, VR& r) \
, F f \
, C* obj \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, Args, &, args) \
)
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
~, /* is_friend = */ 1, /* has_result = */ 0, \
O, VR, F, C, Args, v, r, f, obj, args \
); \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
~, /* is_friend = */ 1, /* has_result = */ 1, \
O, VR, F, C, Args, v, r, f, obj, args \
);
#else
/* PRIVATE */
#define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_( \
z, n, result_O_R_F_C_Args_v_r_f_obj_args) \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
/* arity = */ n, \
/* is_friend = */ 1, \
BOOST_PP_TUPLE_ELEM(11, 0, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 1, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 2, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 3, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 4, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 5, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 6, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 7, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 8, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 9, result_O_R_F_C_Args_v_r_f_obj_args), \
BOOST_PP_TUPLE_ELEM(11, 10, result_O_R_F_C_Args_v_r_f_obj_args) \
);
/* PUBLIC */
#define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
BOOST_PP_REPEAT_ ## z( \
BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
(/* has_result = */ 0, O, VR, F, C, Args, v, r, f, obj, args) \
) \
BOOST_PP_REPEAT_ ## z( \
BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
(/* has_result = */ 1, O, VR, F, C, Args, v, r, f, obj, args) \
)
#endif
#define BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z( \
z, is_friend, O, VR, F, C, Args) \
template< \
class O, typename VR, typename F, class C \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS) \
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, \
BOOST_CONTRACT_MAX_ARGS, Args) \
> \
BOOST_PP_IIF(is_friend, \
friend class boost::contract::detail:: \
, \
class \
) \
cond_subcontracting
/* CODE */
namespace boost {
namespace contract {
class virtual_;
template<typename VR = void>
class specify_precondition_old_postcondition_except;
}
}
#endif // #include guard

View File

@@ -0,0 +1,51 @@
#ifndef BOOST_CONTRACT_DETAIL_DECLSPEC_HPP_
#define BOOST_CONTRACT_DETAIL_DECLSPEC_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// IMPORTANT: Indirectly included by contract_macro.hpp so trivial headers only.
#include <boost/contract/core/config.hpp> // No compile-time overhead.
#include <boost/config.hpp>
/* PUBLIC */
// IMPORTANT: In general, this library should always and only be compiled and
// used as a shared library. Otherwise, lib's state won't be shared among
// different user programs and user libraries. However, this library can be
// safely compiled and used as a static or header-only library only when it is
// being used by a single program unit (e.g., a single program with only
// statically linked libraries that check contracts).
#ifdef BOOST_CONTRACT_DYN_LINK
#ifdef BOOST_CONTRACT_SOURCE
#define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_EXPORT
#else
#define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_IMPORT
#endif
#else
#define BOOST_CONTRACT_DETAIL_DECLSPEC /* nothing */
#endif
#ifdef BOOST_CONTRACT_HEADER_ONLY
#define BOOST_CONTRACT_DETAIL_DECLINLINE inline
#else
#define BOOST_CONTRACT_DETAIL_DECLINLINE /* nothing */
// Automatically link this lib to correct build variant (for MSVC, etc.).
#if !defined(BOOST_ALL_NO_LIB) && \
!defined(BOOST_CONTRACT_NO_LIB) && \
!defined(BOOST_CONTRACT_SOURCE)
#define BOOST_LIB_NAME boost_contract // This lib (static or shared).
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTRACT_DYN_LINK)
#define BOOST_DYN_LINK // This lib as shared.
#endif
#include <boost/config/auto_link.hpp> // Also #undef BOOST_LIB_NAME.
#endif
#endif
#endif // #include guard

View File

@@ -0,0 +1,31 @@
#ifndef BOOST_CONTRACT_DETAIL_EXCEPTION_HPP_
#define BOOST_CONTRACT_DETAIL_EXCEPTION_HPP_
// Copyright (C) 2008-2019 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/config.hpp>
#include <exception>
namespace boost { namespace contract { namespace detail {
// Using this instead of std::uncaught_exception() because
// std::uncaught_exception will be removed in C++20.
inline bool uncaught_exception() BOOST_NOEXCEPT {
// Alternatively, this could just return `boost::core::uncaught_exceptions()
// > 0` but that emulates the exception count which is not needed by this
// lib (the implementation below is simpler and could be faster).
#ifdef __cpp_lib_uncaught_exceptions
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
#endif
}
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,15 @@
#ifndef BOOST_CONTRACT_DETAIL_INLINED_HPP_
#define BOOST_CONTRACT_DETAIL_INLINED_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/inlined/old.hpp>
#include <boost/contract/detail/inlined/core/exception.hpp>
#include <boost/contract/detail/inlined/detail/checking.hpp>
#endif // #include guard

View File

@@ -0,0 +1,502 @@
#ifndef BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
#define BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
// .cpp does not need recompiling if config changes (recompile only user code).
#include <boost/contract/core/exception.hpp>
#include <boost/contract/detail/static_local_var.hpp>
#include <boost/contract/detail/declspec.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/config.hpp>
#include <string>
#include <sstream>
#include <iostream>
#include <exception>
namespace boost { namespace contract {
BOOST_CONTRACT_DETAIL_DECLINLINE
exception::~exception() BOOST_NOEXCEPT_OR_NOTHROW {}
BOOST_CONTRACT_DETAIL_DECLINLINE
bad_virtual_result_cast::bad_virtual_result_cast(char const* from_type_name,
char const* to_type_name) {
std::ostringstream text;
text
<< "incompatible contracted virtual function result type "
<< "conversion from '" << from_type_name << "' to '"
<< to_type_name << "'"
;
what_ = text.str();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
bad_virtual_result_cast::~bad_virtual_result_cast() BOOST_NOEXCEPT_OR_NOTHROW {}
BOOST_CONTRACT_DETAIL_DECLINLINE
char const* bad_virtual_result_cast::what() const BOOST_NOEXCEPT_OR_NOTHROW {
return what_.c_str();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
assertion_failure::assertion_failure(char const* const file,
unsigned long const line, char const* const code) :
file_(file), line_(line), code_(code)
{ init(); }
BOOST_CONTRACT_DETAIL_DECLINLINE
assertion_failure::assertion_failure(char const* const code) :
file_(""), line_(0), code_(code)
{ init(); }
BOOST_CONTRACT_DETAIL_DECLINLINE
assertion_failure::~assertion_failure() BOOST_NOEXCEPT_OR_NOTHROW {}
BOOST_CONTRACT_DETAIL_DECLINLINE
char const* assertion_failure::what() const BOOST_NOEXCEPT_OR_NOTHROW {
return what_.c_str();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
char const* assertion_failure::file() const { return file_; }
BOOST_CONTRACT_DETAIL_DECLINLINE
unsigned long assertion_failure::line() const { return line_; }
BOOST_CONTRACT_DETAIL_DECLINLINE
char const* assertion_failure::code() const { return code_; }
BOOST_CONTRACT_DETAIL_DECLINLINE
void assertion_failure::init() {
std::ostringstream text;
text << "assertion";
if(std::string(code_) != "") text << " \"" << code_ << "\"";
text << " failed";
if(std::string(file_) != "") {
text << ": file \"" << file_ << "\"";
if(line_ != 0) text << ", line " << line_;
}
what_ = text.str();
}
namespace exception_ {
enum failure_key {
check_failure_key,
pre_failure_key,
post_failure_key,
except_failure_key,
old_failure_key,
entry_inv_failure_key,
exit_inv_failure_key
};
template<failure_key Key>
void default_handler() {
std::string k = "";
switch(Key) {
case check_failure_key: k = "check "; break;
case pre_failure_key: k = "precondition "; break;
case post_failure_key: k = "postcondition "; break;
case except_failure_key: k = "except "; break;
case old_failure_key: k = "old copy "; break;
case entry_inv_failure_key: k = "entry invariant "; break;
case exit_inv_failure_key: k = "exit invariant "; break;
// No default (so compiler warning/error on missing enum case).
}
try { throw; }
catch(boost::contract::assertion_failure const& error) {
// what = "assertion '...' failed: ...".
std::cerr << k << error.what() << std::endl;
} catch(...) { // old_failure_key prints this, not above.
std::cerr << k << "threw following exception:" << std::endl
<< boost::current_exception_diagnostic_information();
}
std::terminate(); // Default handlers log and call terminate.
}
template<failure_key Key>
void default_from_handler(from) { default_handler<Key>(); }
// Check failure.
struct check_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<check_failure_mutex_tag,
boost::mutex> check_failure_mutex;
struct check_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
check_failure_handler_tag,
failure_handler,
void (*)(),
&default_handler<check_failure_key>
> check_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
failure_handler const& set_check_failure_unlocked(failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW {
check_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
failure_handler const& set_check_failure_locked(failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
return set_check_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
failure_handler get_check_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
return check_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
failure_handler get_check_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
return get_check_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void check_failure_unlocked() /* can throw */ {
check_failure_handler::ref()();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void check_failure_locked() /* can throw */ {
boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
check_failure_unlocked();
}
// Precondition failure.
struct pre_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<pre_failure_mutex_tag,
boost::mutex> pre_failure_mutex;
struct pre_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
pre_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<pre_failure_key>
> pre_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_pre_failure_unlocked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
pre_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_pre_failure_locked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
return set_pre_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_pre_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
return pre_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_pre_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
return get_pre_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void pre_failure_unlocked(from where) /* can throw */ {
pre_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void pre_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
pre_failure_unlocked(where);
}
// Postcondition failure.
struct post_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<post_failure_mutex_tag,
boost::mutex> post_failure_mutex;
struct post_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
post_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<post_failure_key>
> post_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_post_failure_unlocked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
post_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_post_failure_locked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
return set_post_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_post_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
return post_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_post_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
return get_post_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void post_failure_unlocked(from where) /* can throw */ {
post_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void post_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
post_failure_unlocked(where);
}
// Except failure.
struct except_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<except_failure_mutex_tag,
boost::mutex> except_failure_mutex;
struct except_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
except_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<except_failure_key>
> except_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_except_failure_unlocked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
except_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_except_failure_locked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
return set_except_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_except_failure_unlocked()
BOOST_NOEXCEPT_OR_NOTHROW {
return except_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_except_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
return get_except_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void except_failure_unlocked(from where) /* can throw */ {
except_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void except_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
except_failure_unlocked(where);
}
// Old-copy failure.
struct old_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<old_failure_mutex_tag,
boost::mutex> old_failure_mutex;
struct old_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
old_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<old_failure_key>
> old_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_old_failure_unlocked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
old_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_old_failure_locked(from_failure_handler
const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
return set_old_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_old_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
return old_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_old_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
return get_old_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void old_failure_unlocked(from where) /* can throw */ {
old_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void old_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
old_failure_unlocked(where);
}
// Entry invariant failure.
struct entry_inv_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<
entry_inv_failure_mutex_tag, boost::mutex> entry_inv_failure_mutex;
struct entry_inv_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
entry_inv_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<entry_inv_failure_key>
> entry_inv_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_entry_inv_failure_unlocked(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
entry_inv_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_entry_inv_failure_locked(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
return set_entry_inv_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_entry_inv_failure_unlocked()
BOOST_NOEXCEPT_OR_NOTHROW {
return entry_inv_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_entry_inv_failure_locked()
BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
return get_entry_inv_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void entry_inv_failure_unlocked(from where) /* can throw */ {
entry_inv_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void entry_inv_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
entry_inv_failure_unlocked(where);
}
// Exit invariant failure.
struct exit_inv_failure_mutex_tag;
typedef boost::contract::detail::static_local_var<
exit_inv_failure_mutex_tag, boost::mutex> exit_inv_failure_mutex;
struct exit_inv_failure_handler_tag;
typedef boost::contract::detail::static_local_var_init<
exit_inv_failure_handler_tag,
from_failure_handler,
void (*)(from),
&default_from_handler<exit_inv_failure_key>
> exit_inv_failure_handler;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_exit_inv_failure_unlocked(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
exit_inv_failure_handler::ref() = f;
return f;
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_exit_inv_failure_locked(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
return set_exit_inv_failure_unlocked(f);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_exit_inv_failure_unlocked()
BOOST_NOEXCEPT_OR_NOTHROW {
return exit_inv_failure_handler::ref();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler get_exit_inv_failure_locked()
BOOST_NOEXCEPT_OR_NOTHROW {
boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
return get_exit_inv_failure_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void exit_inv_failure_unlocked(from where) /* can throw */ {
exit_inv_failure_handler::ref()(where);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void exit_inv_failure_locked(from where) /* can throw */ {
boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
exit_inv_failure_unlocked(where);
}
}
from_failure_handler const& set_entry_invariant_failure(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
from_failure_handler const& set_exit_invariant_failure(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
BOOST_CONTRACT_DETAIL_DECLINLINE
from_failure_handler const& set_invariant_failure(
from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
set_entry_invariant_failure(f);
set_exit_invariant_failure(f);
return f;
}
} } // namespace
#endif // #include guard

View File

@@ -0,0 +1,49 @@
#ifndef BOOST_CONTRACT_DETAIL_INLINED_DETAIL_CHECKING_HPP_
#define BOOST_CONTRACT_DETAIL_INLINED_DETAIL_CHECKING_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
// .cpp does not need recompiling if config changes (recompile only user code).
#include <boost/contract/detail/checking.hpp>
#include <boost/contract/detail/declspec.hpp>
#include <boost/thread/lock_guard.hpp>
namespace boost { namespace contract { namespace detail {
BOOST_CONTRACT_DETAIL_DECLINLINE
void checking::init_unlocked() { flag::ref() = true; }
BOOST_CONTRACT_DETAIL_DECLINLINE
void checking::init_locked() {
boost::lock_guard<boost::mutex> lock(mutex::ref());
init_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
void checking::done_unlocked() { flag::ref() = false; }
BOOST_CONTRACT_DETAIL_DECLINLINE
void checking::done_locked() {
boost::lock_guard<boost::mutex> lock(mutex::ref());
done_unlocked();
}
BOOST_CONTRACT_DETAIL_DECLINLINE
bool checking::already_unlocked() { return flag::ref(); }
BOOST_CONTRACT_DETAIL_DECLINLINE
bool checking::already_locked() {
boost::lock_guard<boost::mutex> lock(mutex::ref());
return already_unlocked();
}
} } } // namespace
#endif

View File

@@ -0,0 +1,34 @@
#ifndef BOOST_CONTRACT_DETAIL_INLINED_OLD_HPP_
#define BOOST_CONTRACT_DETAIL_INLINED_OLD_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
// .cpp does not need recompiling if config changes (recompile only user code).
#include <boost/contract/old.hpp>
#include <boost/contract/detail/declspec.hpp>
namespace boost { namespace contract {
BOOST_CONTRACT_DETAIL_DECLINLINE
old_value null_old() { return old_value(); }
BOOST_CONTRACT_DETAIL_DECLINLINE
old_pointer make_old(old_value const& old) {
return old_pointer(0, old);
}
BOOST_CONTRACT_DETAIL_DECLINLINE
old_pointer make_old(virtual_* v, old_value const& old) {
return old_pointer(v, old);
}
} } // namespacd
#endif // #include guard

View File

@@ -0,0 +1,26 @@
#ifndef BOOST_CONTRACT_DETAIL_NAME_HPP_
#define BOOST_CONTRACT_DETAIL_NAME_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/config.hpp>
#include <boost/preprocessor/cat.hpp>
/* PUBLIC */
// NOTE: Explicitly list number of names to concatenate using ..._NAME-n
// (instead of using ..._SEQ_CAT or similar) for optimal speed and reentrancy.
#define BOOST_CONTRACT_DETAIL_NAME1(name1) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_PREFIX, name1)
#define BOOST_CONTRACT_DETAIL_NAME2(name1, name2) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_PREFIX, BOOST_PP_CAT(name1, \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_INFIX, name2)))
#endif // #include guard

View File

@@ -0,0 +1,28 @@
#ifndef BOOST_CONTRACT_DETAIL_NONE_HPP_
#define BOOST_CONTRACT_DETAIL_NONE_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
namespace boost { namespace contract { namespace detail {
// Tag for "no type".
struct none {
// Some lib code use this to avoid unused local var warnings on #if, etc.
static none& value() {
static none none_value;
return none_value;
}
};
// Transform `void` to `none` type (for convenience, instead of using MPL).
template<typename T> struct none_if_void { typedef T type; };
template<> struct none_if_void<void> { typedef none type; };
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,19 @@
#ifndef BOOST_CONTRACT_DETAIL_NOOP_HPP_
#define BOOST_CONTRACT_DETAIL_NOOP_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
// Following must be expressions, not statements (as used with if.., etc.).
#define BOOST_CONTRACT_DETAIL_NOOP ((void)0)
// Following always compiles but never evaluates cond (so check correct syntax).
#define BOOST_CONTRACT_DETAIL_NOEVAL(cond) \
(true || (cond) ? BOOST_CONTRACT_DETAIL_NOOP : BOOST_CONTRACT_DETAIL_NOOP)
#endif // #include guard

View File

@@ -0,0 +1,96 @@
#ifndef BOOST_CONTRACT_DETAIL_CONSTRUCTOR_HPP_
#define BOOST_CONTRACT_DETAIL_CONSTRUCTOR_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_inv.hpp>
#include <boost/contract/detail/none.hpp>
#include <boost/contract/detail/exception.hpp>
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
!defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS))
#include <boost/contract/detail/checking.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/config.hpp>
#include <exception>
#endif
namespace boost { namespace contract { namespace detail {
// Ctor subcontracting impl via C++ obj construction mechanism.
template<class C> // Non-copyable base.
class constructor : public cond_inv</* VR = */ none, C> {
public:
explicit constructor(C* obj) : cond_inv</* VR = */ none, C>(
boost::contract::from_constructor, obj) {}
private:
#if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_OLDS)
void init() /* override */ {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
#endif
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
{
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
checking k;
#endif
this->check_entry_static_inv();
// No object before ctor body so check only static inv at
// entry. Ctor pre checked by constructor_precondition.
}
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_old();
#endif
}
#endif
public:
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
~constructor() BOOST_NOEXCEPT_IF(false) {
this->assert_initialized();
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
checking k;
#endif
// If ctor body threw, no obj so check only static inv. Otherwise,
// obj constructed so check static inv, non-static inv, and post.
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_exit_static_inv();
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_exit_all_inv();
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_post(none());
#endif
}
}
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,103 @@
#ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
#define BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_inv.hpp>
#include <boost/contract/detail/none.hpp>
#include <boost/contract/detail/exception.hpp>
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
!defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS))
#include <boost/contract/detail/checking.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/config.hpp>
#include <exception>
#endif
namespace boost { namespace contract { namespace detail {
// Dtor subcontracting impl via C++ obj destruction mechanism.
template<class C> // Non-copyable base.
class destructor : public cond_inv</* VR = */ none, C> {
public:
explicit destructor(C* obj) : cond_inv</* VR = */ none, C>(
boost::contract::from_destructor, obj) {}
private:
#if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_OLDS)
void init() /* override */ {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
#endif
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
{
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
checking k;
#endif
// Obj exists (before dtor body), check static and non- inv.
this->check_entry_all_inv();
// Dtor cannot have pre because it has no parameters.
}
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_old();
#endif
}
#endif
public:
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
~destructor() BOOST_NOEXCEPT_IF(false) {
this->assert_initialized();
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
checking k;
#endif
// If dtor body threw, obj still exists so check subcontracted
// static and non- inv (but no post because of throw). Otherwise,
// obj destructed so check static inv and post (even if there is no
// obj after dtor body, this library allows dtor post, for example
// to check static members for an instance counter class).
// NOTE: In theory C++ destructors should not throw, but the
// language allows for that (even if in C++11 dtors declarations are
// implicitly noexcept(true) unless specified otherwise) so this
// library must handle such a case.
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_exit_all_inv();
#endif
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_exit_static_inv();
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_post(none());
#endif
}
}
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,83 @@
#ifndef BOOST_CONTRACT_DETAIL_FUNCTION_HPP_
#define BOOST_CONTRACT_DETAIL_FUNCTION_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_post.hpp>
#include <boost/contract/detail/exception.hpp>
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS))
#include <boost/contract/detail/checking.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/config.hpp>
#include <exception>
#endif
namespace boost { namespace contract { namespace detail {
// Used for free function, private and protected member functions.
class function : public cond_post</* VR = */ none> { // Non-copyable base.
public:
explicit function() : cond_post</* VR = */ none>(
boost::contract::from_function) {}
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_OLDS)
void init() /* override */ {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
{
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && \
!defined( \
BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION)
checking k;
#endif
this->check_pre();
}
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_old();
#endif
}
#endif
public:
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
~function() BOOST_NOEXCEPT_IF(false) {
this->assert_initialized();
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
checking k;
#endif
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_post(none());
#endif
}
}
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,162 @@
#ifndef BOOST_CONTRACT_DETAIL_PUBLIC_FUNCTION_HPP_
#define BOOST_CONTRACT_DETAIL_PUBLIC_FUNCTION_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/virtual.hpp>
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/core/virtual.hpp>
#include <boost/contract/detail/condition/cond_subcontracting.hpp>
#include <boost/contract/detail/tvariadic.hpp>
#include <boost/contract/detail/exception.hpp>
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
!defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS))
#include <boost/contract/detail/checking.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/config.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <exception>
#endif
namespace boost { namespace contract { namespace detail {
template<
class O, typename VR, typename F, class C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
>
class public_function : // Non-copyable base.
public cond_subcontracting<
O, VR, F, C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
>
{
public:
explicit public_function(
boost::contract::virtual_* v, C* obj, VR& r
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args, &, args)
) :
cond_subcontracting<
O, VR, F, C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args)
>(
boost::contract::from_function, v, obj, r
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
BOOST_CONTRACT_MAX_ARGS, args)
)
{}
private:
#if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
void init() /* override */ {
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
this->init_subcontracted_old();
#endif
if(!this->base_call()) {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
#endif
{ // Acquire checking guard.
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
checking k;
#endif
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
this->check_subcontracted_entry_inv();
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
#ifndef \
BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
this->check_subcontracted_pre();
} // Release checking guard (after pre check).
#else
} // Release checking guard (before pre check).
this->check_subcontracted_pre();
#endif
#else
} // Release checking guard.
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_subcontracted_old();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
this->check_subcontracted_entry_inv();
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
this->check_subcontracted_pre();
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_subcontracted_old();
#endif
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_subcontracted_exit_inv();
#endif
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_subcontracted_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_subcontracted_post();
#endif
}
}
}
#endif
public:
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
~public_function() BOOST_NOEXCEPT_IF(false) {
this->assert_initialized();
if(!this->base_call()) {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
checking k;
#endif
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_subcontracted_exit_inv();
#endif
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_subcontracted_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_subcontracted_post();
#endif
}
}
}
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,104 @@
#ifndef BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_HPP_
#define BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/condition/cond_inv.hpp>
#include <boost/contract/detail/none.hpp>
#include <boost/contract/detail/exception.hpp>
#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
!defined(BOOST_CONTRACT_NO_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS))
#include <boost/contract/detail/checking.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
#include <boost/config.hpp>
#include <exception>
#endif
namespace boost { namespace contract { namespace detail {
// No subcontracting because static so no obj and no substitution principle.
template<class C> // Non-copyable base.
class static_public_function : public cond_inv</* VR = */ none, C> {
public:
explicit static_public_function() : cond_inv</* VR = */ none, C>(
boost::contract::from_function, /* obj = */ 0) {}
private:
#if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_OLDS)
void init() /* override */ {
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
#endif
#if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS)
{ // Acquire checking guard.
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
checking k;
#endif
#ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
this->check_entry_static_inv();
#endif
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
#ifndef \
BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
this->check_pre();
} // Release checking guard (after pre check).
#else
} // Release checking guard (before pre check).
this->check_pre();
#endif
#else
} // Release checking guard
#endif
#endif
#ifndef BOOST_CONTRACT_NO_OLDS
this->copy_old();
#endif
}
#endif
public:
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_EXCEPTS)
~static_public_function() BOOST_NOEXCEPT_IF(false) {
this->assert_initialized();
#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
if(checking::already()) return;
checking k;
#endif
#ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
this->check_exit_static_inv();
#endif
if(uncaught_exception()) {
#ifndef BOOST_CONTRACT_NO_EXCEPTS
this->check_except();
#endif
} else {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
this->check_post(none());
#endif
}
}
#endif
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,73 @@
#ifndef BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL_HPP_
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/name.hpp>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// NOTE: This code is inspired by <boost/shared_ptr/detail/operator_bool.hpp>.
/* PRIVATE */
// operator! is redundant, but some compilers need it.
#define BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr) \
bool operator!() const BOOST_NOEXCEPT { return !(bool_expr); }
/* PUBLIC */
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && \
!defined(BOOST_NO_CXX11_NULLPTR)
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
explicit operator bool() const BOOST_NOEXCEPT { return (bool_expr); } \
BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
#elif (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || \
defined(__CINT__)
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
operator bool() const BOOST_NOEXCEPT { return (bool_expr); } \
BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
#elif defined(_MANAGED)
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
static void BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func)( \
this_type***) {} \
typedef void (*BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type))( \
this_type***); \
operator BOOST_CONTRACT_DETAIL_NANE(operator_safe_bool_type)() \
const BOOST_NOEXCEPT { \
return (bool_expr) ? \
&BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func) : 0; \
} \
BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
#elif (defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200)) || \
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304)) || \
(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590))
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
void BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func)() const {} \
typedef void (this_type::*BOOST_CONTRACT_DETAIL_NAME1( \
operator_safe_bool_type))() const; \
operator BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type)() \
const BOOST_NOEXCEPT { \
return (bool_expr) ? &this_type:: \
BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func) : 0; \
} \
BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
#else
#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
void* BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_data); \
typedef void* this_type::*BOOST_CONTRACT_DETAIL_NAME1( \
operator_safe_bool_type);\
operator BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type)() \
const BOOST_NOEXCEPT { \
return (bool_expr) ? &this_type:: \
BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_data) : 0; \
} \
BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
#endif
#endif // #include guard

View File

@@ -0,0 +1,35 @@
#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_HPP_
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
#include <boost/preprocessor/cat.hpp>
/* PRIVATE */
// Must expand to a single comma `,` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_COMMAprivate ,
// Must expand to empty `` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_EMPTYprivate
/* PUBLIC */
// Precondition: tokens must start with a token concatenable to a macro name
// (e.g., a literal or integral token).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(tokens) \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_COMMA, tokens)
// Precondition: tokens must start with `private` (this can be
// checked with `..._IS_PRIVATE` macro above).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PRIVATE(tokens) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_EMPTY, tokens)
#endif // #include guard

View File

@@ -0,0 +1,36 @@
#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_HPP_
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
#include <boost/preprocessor/cat.hpp>
/* PRIVATE */
// Must expand to a single comma `,` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_COMMAprotected ,
// Must expand to empty `` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_EMPTYprotected
/* PUBLIC */
// Precondition: tokens must start with a token concatenable to a macro name
// (e.g., a literal or integral token).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(tokens) \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_COMMA, tokens)
// Precondition: tokens must start with `protected` (this can be
// checked with `..._IS_PROTECTED` macro above).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PROTECTED(tokens) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_EMPTY, \
tokens)
#endif // #include guard

View File

@@ -0,0 +1,35 @@
#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_HPP_
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
#include <boost/preprocessor/cat.hpp>
/* PRIVATE */
// Must expand to a single comma `,` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_COMMApublic ,
// Must expand to empty `` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_EMPTYpublic
/* PUBLIC */
// Precondition: tokens must start with a token concatenable to a macro name
// (e.g., a literal or integral token).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(tokens) \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_COMMA, tokens)
// Precondition: tokens must start with `public` (this can be
// checked with `..._IS_PUBLIC` macro above).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(tokens) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_EMPTY, tokens)
#endif // #include guard

View File

@@ -0,0 +1,30 @@
#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_HPP_
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/variadic/size.hpp>
/* PRIVATE */
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_1 0
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_2 1
/* PUBLIC */
// Precondition: A macro named `cat_to_comma_prefix ## token-to-check` must be
// #defined to expand to `,`.
// Precondition: tokens must start with a token concatenable to a macro name
// (e.g., a literal or integral token).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
cat_to_comma_prefix, tokens) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_, \
BOOST_PP_VARIADIC_SIZE(BOOST_PP_CAT(cat_to_comma_prefix, tokens)))
#endif // #include guard

View File

@@ -0,0 +1,35 @@
#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_HPP_
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
#include <boost/preprocessor/cat.hpp>
/* PRIVATE */
// Must expand to a single comma `,` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_COMMAvirtual ,
// Must expand to empty `` (not local macros, do not #undefine).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_EMPTYvirtual
/* PUBLIC */
// Precondition: tokens must start with a token concatenable to a macro name
// (e.g., a literal or integral token).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(tokens) \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_COMMA, tokens)
// Precondition: tokens must start with `virtual` (this can be
// checked with `..._IS_VIRTUAL` macro above).
#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL(tokens) \
BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_EMPTY, tokens)
#endif // #include guard

View File

@@ -0,0 +1,41 @@
#ifndef BOOST_CONTRACT_DETAIL_STATIC_LOCAL_VAR_HPP_
#define BOOST_CONTRACT_DETAIL_STATIC_LOCAL_VAR_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
namespace boost { namespace contract { namespace detail {
// This is used to hold the state of this library (already checking assertions,
// failure handers, mutexes, etc.). Local static variables are used instead of
// global or class-level static variables to avoid ODR errors when this library
// is used as header-only.
// Use T's default constructor to init the local var.
template<typename Tag, typename T>
struct static_local_var {
static T& ref() {
static T data;
return data;
}
};
// Use `init` param to init local var (Init same as or convertible to T).
// NOTE: Template specializations could be used to program both this and the
// template above together but some pre-C++11 compilers give errors (e.g., Clang
// without -std=c++11), plus the `_init` postfix is more readable at call site.
template<typename Tag, typename T, typename Init, Init init>
struct static_local_var_init {
static T& ref() {
static T data = init;
return data;
}
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,190 @@
#ifndef BOOST_CONTRACT_DETAIL_TVARIADIC_HPP_
#define BOOST_CONTRACT_DETAIL_TVARIADIC_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/config.hpp>
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_CONTRACT_DETAIL_TVARIADIC 0
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC 1
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#include <tuple>
/* CODE */
namespace boost { namespace contract { namespace detail {
namespace tvariadic_ {
template<int...> struct indexes {};
template<int N, int... I> struct indexes_of :
indexes_of<N - 1, N - 1, I...> {};
template<int... I> struct indexes_of<0, I...>
{ typedef indexes<I...> type; };
} } } } // namespace
#else
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/cat.hpp>
/* PRIVATE */
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEM_(z, n, tuple) \
BOOST_PP_CAT(tuple, n)
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_(z, n, tuplevar_values) \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, tuplevar_values), n)( \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, tuplevar_values), n))
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_(z, n, type_qualifier_name) \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, type_qualifier_name), n) \
BOOST_PP_TUPLE_ELEM(3, 1, type_qualifier_name) \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 2, type_qualifier_name), n) \
;
#define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_(z, n, tokens) \
tokens
#define BOOST_CONTRACT_DETAIL_TVARIADIC_ARG_(z, n, name) \
BOOST_PP_CAT(name, n)
#define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAM_(z, n, type_qualifier_name) \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, type_qualifier_name), n) \
BOOST_PP_TUPLE_ELEM(3, 1, type_qualifier_name) \
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 2, type_qualifier_name), n)
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAM_(z, n, name) \
typename BOOST_PP_CAT(name, n)
#endif
/* PUBLIC */
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
,
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
BOOST_PP_COMMA_IF(arity)
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity) /* nothing */
#else
#define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity) \
BOOST_PP_COMMA_IF(arity)
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, name) sizeof...(name)
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, name) arity
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, name) \
typename... name
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, name) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAM_, \
name)
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z( \
z, arity, type, qualifier, name) \
type qualifier ... name
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z( \
z, arity, type, qualifier, name) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAM_, \
(type, qualifier, name))
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, name) \
name...
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, name) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_ARG_, name)
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity, tokens) \
/* nothing */
#else
#define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity, tokens) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_, \
tokens)
#endif
// Tuple.
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z( \
z, arity, type, qualifier, name) \
std::tuple<type qualifier ...> name;
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z( \
z, arity, type, qualifier, name) \
BOOST_PP_REPEAT_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_, \
(type, qualifier, name))
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(z, \
arity, tuple, values) \
tuple(values...)
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(z, \
arity, tuple, values) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_,\
(tuple, values))
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(indexes) \
int... indexes
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(indexes) \
/* nothing */
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(_indexes) \
boost::contract::detail::tvariadic_::indexes<_indexes...>
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(_indexes) \
/* nothing */
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(tuple_type) \
typename boost::contract::detail::tvariadic_::indexes_of< \
sizeof...(tuple_type)>::type()
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(unused) \
/* nothing */
#endif
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z( \
z, arity, indexes, tuple) \
std::get<indexes>(tuple)...
#else
#define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z( \
z, arity, indexes, tuple) \
BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEM_,\
tuple)
#endif
#endif // #include guard

View File

@@ -0,0 +1,72 @@
#ifndef BOOST_CONTRACT_DETAIL_MEMBER_FUNCTION_TYPES_HPP_
#define BOOST_CONTRACT_DETAIL_MEMBER_FUNCTION_TYPES_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/none.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/property_tags.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
namespace boost {
namespace contract {
class virtual_;
}
}
namespace boost { namespace contract { namespace detail {
template<class C, typename F>
struct member_function_types {
typedef typename boost::function_types::result_type<F>::type result_type;
// Never include leading class type.
typedef typename boost::mpl::pop_front<typename boost::function_types::
parameter_types<F>::type>::type argument_types;
// Always include trailing virtual_* type.
typedef typename boost::mpl::if_<boost::is_same<typename boost::
mpl::back<argument_types>::type, boost::contract::virtual_*>,
boost::mpl::identity<argument_types>
,
boost::mpl::push_back<argument_types, boost::contract::virtual_*>
>::type::type virtual_argument_types;
typedef typename boost::mpl::if_<boost::mpl::and_<boost::is_const<C>,
boost::is_volatile<C> >,
boost::function_types::cv_qualified
, typename boost::mpl::if_<boost::is_const<C>,
boost::function_types::const_non_volatile
, typename boost::mpl::if_<boost::is_volatile<C>,
boost::function_types::volatile_non_const
,
boost::function_types::null_tag
>::type>::type>::type property_tag;
};
// Also handles none type.
template<class C>
struct member_function_types<C, none> {
typedef none result_type;
typedef none argument_types;
typedef none virtual_argument_types;
typedef none property_tag;
};
} } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,111 @@
#ifndef BOOST_CONTRACT_DETAIL_MIRROR_HPP_
#define BOOST_CONTRACT_DETAIL_MIRROR_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract/detail/name.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/property_tags.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/tuple/rem.hpp>
#include <boost/preprocessor/tuple/eat.hpp>
// NOTE: Unfortunately, it is not possible to use Boost.TTI because it not
// always works on MSVC (e.g., when the mirror meta-function is invoked
// multiple times, MSVC 2010 gives an internal compiler error). This is a
// simpler mirror implementation that seems to work better on MSVC.
/* PRIVATE */
#define BOOST_CONTRACT_DETAIL_MIRROR_END_(tparam) \
template<typename> \
static boost::contract::detail::mirror::no& apply(...); \
public: \
static bool const value = sizeof(apply<tparam>(0)) == \
sizeof(boost::contract::detail::mirror::yes); \
typedef boost::mpl::bool_<value> type;
#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_(is_static, \
trait, func_name) \
template< \
typename BOOST_CONTRACT_DETAIL_NAME1(T), \
typename BOOST_CONTRACT_DETAIL_NAME1(R), \
class BOOST_CONTRACT_DETAIL_NAME1(P), \
class BOOST_CONTRACT_DETAIL_NAME1(G) = boost::function_types::null_tag \
> \
class trait { \
template<class BOOST_CONTRACT_DETAIL_NAME1(C)> \
static boost::contract::detail::mirror::yes& apply( \
boost::contract::detail::mirror::check_function< \
typename \
BOOST_PP_IIF(is_static, \
boost::function_types::function_pointer \
, \
boost::function_types::member_function_pointer \
) \
< \
typename boost::mpl::push_front< \
BOOST_PP_IIF(is_static, \
BOOST_CONTRACT_DETAIL_NAME1(P) \
BOOST_PP_TUPLE_EAT(2) \
, \
BOOST_PP_TUPLE_REM(2) \
)( \
typename boost::mpl::push_front< \
BOOST_CONTRACT_DETAIL_NAME1(P), \
BOOST_CONTRACT_DETAIL_NAME1(C) \
>::type \
) \
, BOOST_CONTRACT_DETAIL_NAME1(R) \
>::type, \
BOOST_CONTRACT_DETAIL_NAME1(G) \
>::type, \
&BOOST_CONTRACT_DETAIL_NAME1(C)::func_name \
>* \
); \
BOOST_CONTRACT_DETAIL_MIRROR_END_( \
BOOST_CONTRACT_DETAIL_NAME1(T)) \
};
/* PUBLIC */
#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(trait, type_name)\
template<typename BOOST_CONTRACT_DETAIL_NAME1(T)> \
class trait { \
template<class BOOST_CONTRACT_DETAIL_NAME1(C)> \
static boost::contract::detail::mirror::yes& apply( \
typename BOOST_CONTRACT_DETAIL_NAME1(C)::type_name*); \
BOOST_CONTRACT_DETAIL_MIRROR_END_( \
BOOST_CONTRACT_DETAIL_NAME1(T)) \
};
#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \
trait, func_name) \
BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \
/* is_static = */ 0, trait, func_name)
#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(trait, \
func_name) \
BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \
/* is_static = */ 1, trait, func_name)
/* CODE */
namespace boost { namespace contract { namespace detail { namespace mirror {
typedef class {} yes;
typedef yes no[2];
template<typename F, F> class check_function;
} } } } // namespace
#endif // #include guard

View File

@@ -0,0 +1,42 @@
#ifndef BOOST_CONTRACT_DETAIL_OPTIONAL_HPP_
#define BOOST_CONTRACT_DETAIL_OPTIONAL_HPP_
// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/optional.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/integral_constant.hpp>
namespace boost { namespace contract { namespace detail {
template<typename T>
struct is_optional : boost::false_type {};
template<typename T>
struct is_optional<boost::optional<T> > : boost::true_type {};
template<typename T>
struct optional_value_type { typedef T type; };
template<typename T>
struct optional_value_type<boost::optional<T> > { typedef T type; };
template<typename T>
struct remove_value_reference_if_optional { typedef T type; };
template<typename T>
struct remove_value_reference_if_optional<boost::optional<T> >
{ typedef typename boost::remove_reference<T>::type type; };
template<typename T>
T& optional_get(T& x) { return x; }
template<typename T>
T& optional_get(boost::optional<T>& x) { return x.get(); }
template<typename T>
T& optional_get(boost::optional<T&>& x) { return x.get(); }
} } } // namespace
#endif // #include guard