/usr/include/boost/contract/detail/condition
Edit: /usr/include/boost/contract/detail/condition/cond_inv.hpp (9166B)
#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
#include
#include
#ifndef BOOST_CONTRACT_NO_INVARIANTS
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef BOOST_CONTRACT_PERMISSIVE
#include
#include
#endif
#endif
namespace boost { namespace contract { namespace detail {
template
class cond_inv : public cond_post { // 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(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();
if(!static_only) {
if(const_and_cv) {
check_cv_inv();
check_const_inv();
} else if(boost::is_volatile::value) {
check_cv_inv();
} else {
check_const_inv();
}
}
} catch(...) {
if(on_entry) {
this->fail(&boost::contract::entry_invariant_failure);
} else this->fail(&boost::contract::exit_invariant_failure);
}
}
template
typename boost::disable_if<
boost::contract::access::has_const_invariant >::type
check_const_inv() {}
template
typename boost::enable_if<
boost::contract::access::has_const_invariant >::type
check_const_inv() { boost::contract::access::const_invariant(obj_); }
template
typename boost::disable_if<
boost::contract::access::has_cv_invariant >::type
check_cv_inv() {}
template
typename boost::enable_if<
boost::contract::access::has_cv_invariant >::type
check_cv_inv() { boost::contract::access::cv_invariant(obj_); }
template
typename boost::disable_if<
boost::contract::access::has_static_invariant >::type
check_static_inv() {}
template
typename boost::enable_if<
boost::contract::access::has_static_invariant >::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::apply()) {
boost::contract::access::static_invariant();
}
}
// Check if class's func is inherited from its base types or not.
template class HasFunc, template 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,
typename boost::contract::access::
base_types_of
,
boost::mpl::vector<>
>::type,
HasFunc
>::type,
boost::add_pointer
>::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
void operator()(B*) {
// Inherited func has same addr as in its base.
if(FuncAddr::apply() == FuncAddr::apply()) {
throw signal_equal();
}
}
};
};
#endif
#ifndef BOOST_CONTRACT_NO_CONDITIONS
C* obj_;
#endif
};
} } } // namespace
#endif // #include guard