?????????? ????????? - ??????????????? - /home/agenciai/public_html/cd38d8/contract.tar
???????
call_if.hpp 0000644 00000064137 15125525375 0006673 0 ustar 00 #ifndef BOOST_CONTRACT_CALL_IF_HPP_ #define BOOST_CONTRACT_CALL_IF_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 /** @file Statically disable compilation and execution of functor calls. @note These facilities allow to emulate C++17 <c>if constexpr</c> statements when used together with functor templates (and C++14 generic lambdas). Therefore, they are not useful on C++17 compilers where <c> if constexpr</c> can be directly used instead. */ #include <boost/contract/detail/none.hpp> #include <boost/make_shared.hpp> #include <boost/shared_ptr.hpp> #include <boost/utility/enable_if.hpp> #include <boost/config.hpp> /* PRIVATE */ /** @cond */ // Boost.ResultOf not always able to deduce lambda result type (on MSVC). #ifndef BOOST_NO_CXX11_DECLTYPE #include <boost/utility/declval.hpp> #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \ decltype(boost::declval<F>()()) #else #include <boost/utility/result_of.hpp> #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \ typename boost::result_of<F()>::type #endif /** @endcond */ /* CODE */ namespace boost { namespace contract { /** Select compilation and execution of functor template calls using a static boolean predicate (not needed on C++17 compilers, use <c>if constexpr</c> instead). This class template has no members because it is never used directly, it is only used via its specializations. Usually this class template is instantiated only via the return value of @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @tparam Pred Static boolean predicate that selects which functor template call to compile and execute. @tparam Then Type of the functor template to call if the static predicate @c Pred is @c true. @tparam ThenResult Return type of then-branch functor template call (this is usually automatically deduced by this library so it is never explicitly specified by the user, and that is why it is often marked as @c internal_type in this documentation). */ template<bool Pred, typename Then, typename ThenResult = #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN boost::contract::detail::none #else internal_type #endif > struct call_if_statement {}; // Empty so cannot be used (but copyable). /** Template specialization to dispatch between then-branch functor template calls that return void and the ones that return non-void (not needed on C++17 compilers, use <c>if constexpr</c> instead). The base class is a call-if statement so the else and else-if statements can be specified if needed. Usually this class template is instantiated only via the return value of @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}. @note The <c>result_of<Then()>::type</c> expression needs be evaluated only when the static predicate is already checked to be @c true (because @c Then() is required to compile only in that case). Thus, this template specialization introduces an extra level of indirection necessary for proper lazy evaluation of this result-of expression. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @tparam Then Type of functor template to call when the static predicate is @c true (as it is for this template specialization). */ template<typename Then> struct call_if_statement<true, Then, #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN boost::contract::detail::none #else internal_type #endif > : call_if_statement<true, Then, #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then) #else typename result_of<Then()>::type #endif > { // Copyable (as its base). /** Construct this object with the then-branch functor template. @param f Then-branch nullary functor template. The functor template call @c f() is compiled and called for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be the same as (or implicitly convertible to) the return type of all other functor template calls specified for this call-if object. */ explicit call_if_statement(Then f) : call_if_statement<true, Then, BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>(f) {} }; /** Template specialization to handle static predicates that are @c true for then-branch functor template calls that do not return void (not needed on C++17 compilers, use <c>if constexpr</c> instead). Usually this class template is instantiated only via the return value of @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @tparam Then Type of functor template to call when the static predicate is @c true (as it is for this template specialization). @tparam ThenResult Non-void return type of the then-branch functor template call. */ template<typename Then, typename ThenResult> struct call_if_statement<true, Then, ThenResult> { // Copyable (as *). /** Construct this object with the then-branch functor template. @param f Then-branch nullary functor template. The functor template call @c f() is actually compiled and executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be the same as (or implicitly convertible to) the @p ThenResult type. */ explicit call_if_statement(Then f) : r_(boost::make_shared<ThenResult>(f())) {} /** This implicit type conversion returns a copy of the value returned by the call to the then-branch functor template. */ operator ThenResult() const { return *r_; } /** Specify the else-branch functor template. @param f Else-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be the same as (or implicitly convertible to) the @p ThenResult type. @return A copy of the value returned by the call to the then-branch functor template (because the else-branch functor template call is not executed). */ template<typename Else> ThenResult else_(Else const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN f #endif ) const { return *r_; } /** Specify an else-if-branch functor template (using a static boolean predicate). @param f Else-if-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be the same as (or implicitly convertible to) the @p ThenResult type. @tparam ElseIfPred Static boolean predicate selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, it will be the return value of the then-branch functor template call for this template specialization (because the if-statement static predicate is @c true). */ template<bool ElseIfPred, typename ElseIfThen> call_if_statement<true, Then, ThenResult> else_if_c( ElseIfThen const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning. f #endif ) const { return *this; } /** Specify an else-if-branch functor template (using a nullary boolean meta-function). @param f Else-if-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be the same as (or implicitly convertible to) the @p ThenResult type. @tparam ElseIfPred Nullary boolean meta-function selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, it will be the return value of the then-branch functor template call for this template specialization (because the if-statement static predicate is @c true). */ template<class ElseIfPred, typename ElseIfThen> call_if_statement<true, Then, ThenResult> else_if( ElseIfThen const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning. f #endif ) const { return *this; } private: boost::shared_ptr<ThenResult> r_; }; /** Template specialization to handle static predicates that are @c true for then-branch functor template calls that return void (not needed on C++17 compilers, use <c>if constexpr</c> instead). Usually this class template is instantiated only via the return value of @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @tparam Then Type of functor template to call when the static predicate if @c true (as it is for this template specialization). */ template<typename Then> struct call_if_statement<true, Then, void> { // Copyable (no data). /** Construct this object with the then-branch functor template. @param f Then-branch nullary functor template. The functor template call @c f() is actually compiled and executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be @c void for this template specialization (because the then-branch functor template calls return void). */ explicit call_if_statement(Then f) { f(); } // Cannot provide `operator ThenResult()` here, because ThenResult is void. /** Specify the else-branch functor template. @param f Else-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be @c void for this template specialization (because the then-branch functor template calls return void). */ template<typename Else> void else_(Else const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN f #endif ) const {} /** Specify an else-if-branch functor template (using a static boolean predicate). @param f Else-if-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be @c void for this template specialization (because the then-branch functor template calls return void). @tparam ElseIfPred Static boolean predicate selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, it will return void for this template specialization (because the then-branch functor template calls return void). */ template<bool ElseIfPred, typename ElseIfThen> call_if_statement<true, Then, void> else_if_c( ElseIfThen const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning. f #endif ) const { return *this; } /** Specify an else-if-branch functor template (using a nullary boolean meta-function). @param f Else-if-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c true). The return type of @c f() must be @c void for this template specialization (because the then-branch functor template calls return void). @tparam ElseIfPred Nullary boolean meta-function selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, it will return void for this template specialization (because the then-branch functor template calls return void). */ template<class ElseIfPred, typename ElseIfThen> call_if_statement<true, Then, void> else_if( ElseIfThen const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning. f #endif ) const { return *this; } }; /** Template specialization to handle static predicates that are @c false (not needed on C++17 compilers, use <c>if constexpr</c> instead). This template specialization handles all else-branch functor template calls (whether they return void or not). Usually this class template is instantiated only via the return value of @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @tparam Then Type of functor template to call when the static predicate is @c true (never the case for this template specialization). */ template<typename Then> // Copyable (no data). struct call_if_statement<false, Then, #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN boost::contract::detail::none #else internal_type #endif > { /** Construct this object with the then-branch functor template. @param f Then-branch nullary functor template. The functor template call @c f() is never compiled or executed for this template specialization (because the if-statement static predicate is @c false). The return type of @c f() must be the same as (or implicitly convertible to) the return type of all other functor template calls specified for this call-if object. */ explicit call_if_statement(Then const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN f #endif ) {} // Do not provide `operator result_type()` here, require else_ instead. /** Specify the else-branch functor template. @note The <c>result_of<Else()>::type</c> expression needs be evaluated only when the static predicate is already checked to be @c false (because @c Else() is required to compile only in that case). Thus, this result-of expression is evaluated lazily and only in instantiations of this template specialization. @param f Else-branch nullary functor template. The functor template call @c f() is actually compiled and executed for this template specialization (because the if-statement static predicate is @c false). The return type of @c f() must be the same as (or implicitly convertible to) the return type of all other functor template calls specified for this call-if object. @return A copy of the value returned by the call to the else-branch functor template @c f(). */ template<typename Else> #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CALL_IF_RESULT_OF_(Else) #else typename result_of<Else()>::type #endif else_(Else f) const { return f(); } /** Specify an else-if-branch functor template (using a static boolean predicate). @param f Else-if-branch nullary functor template. The functor template call @c f() is actually compiled and executed if and only if @c ElseIfPred is @c true (because the if-statement static predicate is already @c false for this template specialization). The return type of @c f() must be the same as (or implicitly convertible to) the return type of all other functor template calls specified for this call-if object. @tparam ElseIfPred Static boolean predicate selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, this will be the return value of the one functor template call being compiled and executed. */ template<bool ElseIfPred, typename ElseIfThen> call_if_statement<ElseIfPred, ElseIfThen> else_if_c(ElseIfThen f) const { return call_if_statement<ElseIfPred, ElseIfThen>(f); } /** Specify an else-if-branch functor template (using a nullary boolen meta-function). @param f Else-if-branch nullary functor template. The functor template call @c f() is actually compiled and executed if and only if @c ElseIfPred::value is @c true (because the if-statement static predicate is already @c false for this template specialization). The return type of @c f() must be the same as (or implicitly convertible to) the return type of all other functor template calls specified for this call-if object. @tparam ElseIfPred Nullary boolean meta-function selecting which functor template call to compile and execute. @return A call-if statement so the else statement and additional else-if statements can be specified if needed. Eventually, this will be the return value of the one functor template call being compiled and executed. */ template<class ElseIfPred, typename ElseIfThen> call_if_statement<ElseIfPred::value, ElseIfThen> else_if(ElseIfThen f) const { return call_if_statement<ElseIfPred::value, ElseIfThen>(f); } }; /** Select compilation and execution of functor template calls using a static boolean predicate (not needed on C++17 compilers, use <c>if constexpr</c> instead). Create a call-if object with the specified then-branch functor template: @code boost::contract::call_if_c<Pred1>( then_functor_template1 ).template else_if_c<Pred2>( // Optional. then_functor_template2 ) // Optionally, other `else_if_c` or ... // `else_if`. .else_( // Optional for `void` functors, else_functor_template // but required for non `void`. ) @endcode Optional functor templates for else-if-branches and the else-branch can be specified as needed (the else-branch function template is required if @c f returns non-void). @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @param f Then-branch nullary functor template. The functor template call @c f() is compiled and executed if and only if @c Pred is @c true. The return type of other functor template calls specified for this call-if statement (else-branch, else-if-branches, etc.) must be the same as (or implicitly convertible to) the return type of then-branch functor call @c f(). @tparam Pred Static boolean predicate selecting which functor template call to compile and execute. @return A call-if statement so else and else-if statements can be specified if needed. Eventually, this will be the return value of the one functor template call being compiled and executed (which could also be @c void). */ template<bool Pred, typename Then> call_if_statement<Pred, Then> call_if_c(Then f) { return call_if_statement<Pred, Then>(f); } /** Select compilation and execution of functor template calls using a nullary boolean meta-function (not needed on C++17 compilers, use <c>if constexpr</c> instead). This is equivalent to <c>boost::contract::call_if_c<Pred::value>(f)</c>. Create a call-if object with the specified then-branch functor template: @code boost::contract::call_if<Pred1>( then_functor_template1 ).template else_if<Pred2>( // Optional. then_functor_template2 ) // Optionally, other `else_if` or ... // `else_if_c`. .else_( // Optional for `void` functors, else_functor_template // but required for non `void`. ) @endcode Optional functor templates for else-if-branches and the else-branch can be specified as needed (the else-branch functor template is required if @c f returns non-void). @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @param f Then-branch nullary functor template. The functor template call @c f() is compiled and executed if and only if @c Pred::value is @c true. The return type of other functor template calls specified for this call-if statement (else-branch, else-if-branches, etc.) must be the same as (or implicitly convertible to) the return type of then-branch functor template call @c f(). @tparam Pred Nullary boolean meta-function selecting which functor template call to compile and execute. @return A call-if statement so else and else-if statements can be specified if needed. Eventually, this will be the return value of the one functor template call being compiled and executed (which could also be @c void). */ template<class Pred, typename Then> call_if_statement<Pred::value, Then> call_if(Then f) { return call_if_statement<Pred::value, Then>(f); } /** Select compilation and execution of a boolean functor template condition using a static boolean predicate (not needed on C++17 compilers, use <c>if constexpr</c> instead). Compile and execute the nullary boolean functor template call @c f() if and only if the specified static boolean predicate @p Pred is @c true, otherwise trivially return @p else_ (@c true by default) at run-time. A call to <c>boost::contract::condition_if_c<Pred>(f, else_)</c> is logically equivalent to <c>boost::contract::call_if_c<Pred>(f, [] { return else_; })</c> (but its internal implementation is optimized and it does not actually use @c call_if_c). @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @param f Nullary boolean functor template. The functor template call @c f() is compiled and executed if and only if @c Pred is @c true. @tparam Pred Static boolean predicate selecting when the functor template call @c f() should be compiled and executed. @param else_ Boolean value to return when @c Pred is @c false (instead of compiling and executing the functor template call @c f()). @return Boolean value returned by @c f() if the static predicate @c Pred is @c true. Otherwise, trivially return @p else_. */ #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN template<bool Pred, typename Then> bool condition_if_c(Then f, bool else_ = true); #else // NOTE: condition_if is a very simple special case of call_if so it can be // trivially implemented using enable_if instead of call_if as done below. template<bool Pred, typename Then> typename boost::enable_if_c<Pred, bool>::type condition_if_c(Then f, bool /* else_ */ = true) { return f(); } template<bool Pred, typename Then> typename boost::disable_if_c<Pred, bool>::type condition_if_c(Then /* f */, bool else_ = true) { return else_; } #endif /** Select compilation and execution of a boolean functor template condition using a nullary boolean meta-function (not needed on C++17 compilers, use <c>if constexpr</c> instead). This is equivalent to <c>boost::contract::condition_if_c<Pred::value>(f, else_)</c>. Compile and execute the nullary boolean functor template call @c f() if and only if the specified nullary boolean meta-function @p Pred::value is @c true, otherwise trivially return @p else_ (@c true by default) at run-time. @see @RefSect{extras.assertion_requirements__templates_, Assertion Requirements} @param f Nullary boolean functor template. The functor template call @c f() is compiled and executed if and only if @c Pred::value is @c true. @param else_ Boolean value to return when @c Pred::value is @c false (instead of compiling and executing the functor template call @c f()). @tparam Pred Nullary boolean meta-function selecting when the functor template call @c f() should be compiled and executed. @return Boolean value returned by @c f() if the static predicate @c Pred::value is @c true. Otherwise, trivially return @p else_. */ template<class Pred, typename Then> bool condition_if(Then f, bool else_ = true) { return condition_if_c<Pred::value>(f, else_); } } } // namespace #endif // #include guard base_types.hpp 0000644 00000016333 15125525375 0007433 0 ustar 00 #ifndef BOOST_CONTRACT_BASE_TYPES_HPP_ #define BOOST_CONTRACT_BASE_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 /** @file Specify inheritance form base classes (for subcontracting). */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #include <boost/preprocessor/config/config.hpp> #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Used to program the @c typedef that lists the bases of a derived class. In order to support subcontracting, a derived class that specifies contracts for one or more overriding public functions must declare a @c typedef named @c base_types (or @RefMacro{BOOST_CONTRACT_BASES_TYPEDEF}) using this macro: @code class u #define BASES public b, protected virtual w1, private w2 : BASES { friend class boost::contract:access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES ... }; @endcode This @c typedef must be @c public unless @RefClass{boost::contract::access} is used. @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes} @param ... Comma separated list of base classes. Each base must explicitly specify its access specifier @c public, @c protected, or @c private, and also @c virtual when present (this not always required in C++ instead). There is a limit of about 20 maximum bases that can be listed (because of similar limits in Boost.MPL internally used by this library). This is a variadic macro parameter, on compilers that do not support variadic macros, the @c typedef for base classes can be programmed manually without using this macro (see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}). */ #define BOOST_CONTRACT_BASE_TYPES(...) #elif !BOOST_PP_VARIADICS #define BOOST_CONTRACT_BASE_TYPES \ BOOST_CONTRACT_ERROR_macro_BASE_TYPES_requires_variadic_macros_otherwise_manually_program_base_types #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) #include <boost/mpl/vector.hpp> #include <boost/contract/detail/preprocessor/keyword/virtual.hpp> #include <boost/contract/detail/preprocessor/keyword/public.hpp> #include <boost/contract/detail/preprocessor/keyword/protected.hpp> #include <boost/contract/detail/preprocessor/keyword/private.hpp> #include <boost/preprocessor/variadic/to_seq.hpp> #include <boost/preprocessor/seq/fold_left.hpp> #include <boost/preprocessor/seq/enum.hpp> #include <boost/preprocessor/seq/push_back.hpp> #include <boost/preprocessor/seq/size.hpp> #include <boost/preprocessor/seq/seq.hpp> // For HEAD, TAIL, etc. #include <boost/preprocessor/tuple/elem.hpp> #include <boost/preprocessor/tuple/rem.hpp> #include <boost/preprocessor/tuple/eat.hpp> #include <boost/preprocessor/comparison/equal.hpp> #include <boost/preprocessor/control/iif.hpp> #include <boost/preprocessor/facilities/expand.hpp> /* PRIVATE */ #define BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \ BOOST_PP_EXPAND( \ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(base), \ BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL \ , \ BOOST_PP_TUPLE_REM(1) \ )(base) \ ) #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_(is_public, types_nilseq, base) \ ( \ is_public, \ BOOST_PP_IIF(is_public, \ BOOST_PP_SEQ_PUSH_BACK \ , \ types_nilseq BOOST_PP_TUPLE_EAT(2) \ )(types_nilseq, base) \ ) #define BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_(is_public, types_nilseq, \ base) \ (0, types_nilseq) // Precondition: base = `public [virtual] ...`. #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_(is_public, types_nilseq, \ base) \ ( \ 1, \ BOOST_PP_SEQ_PUSH_BACK(types_nilseq, \ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_( \ BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(base)) \ ) \ ) #define BOOST_CONTRACT_BASE_TYPES_ACCESS_(is_public, types_nilseq, base) \ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \ BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_ \ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \ BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \ BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \ , \ BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_ \ )))(is_public, types_nilseq, base) #define BOOST_CONTRACT_BASE_TYPES_(s, public_types, base) \ BOOST_CONTRACT_BASE_TYPES_ACCESS_( \ BOOST_PP_TUPLE_ELEM(2, 0, public_types), \ BOOST_PP_TUPLE_ELEM(2, 1, public_types), \ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \ ) #define BOOST_CONTRACT_BASE_TYPES_RETURN_YES_(types_nilseq) \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(types_nilseq)) #define BOOST_CONTRACT_BASE_TYPES_RETURN_(types_nilseq) \ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(types_nilseq), 1), \ BOOST_PP_TUPLE_EAT(1) \ , \ BOOST_CONTRACT_BASE_TYPES_RETURN_YES_ \ )(types_nilseq) #define BOOST_CONTRACT_BASE_TYPES_OK_(base_tuple, bases_seq) \ boost::mpl::vector< \ BOOST_CONTRACT_BASE_TYPES_RETURN_(BOOST_PP_TUPLE_ELEM(2, 1, \ BOOST_PP_SEQ_FOLD_LEFT( \ BOOST_CONTRACT_BASE_TYPES_, \ (0, (BOOST_PP_NIL)), \ bases_seq \ ) \ )) \ > #define BOOST_CONTRACT_BASE_TYPES_ERR_(bases_tuple, bases_seq) \ BOOST_CONTRACT_ERROR_all_bases_must_explicitly_specify_public_protected_or_private base_tuple #define BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_(base) \ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \ 1 \ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \ 1 \ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \ 1 \ , \ 0 \ ))) // Cannot check that all base types have access specifiers (unless users have to // specify bases using pp-seq, because user specified base list can have // unwrapped commas between bases but also within a given base type, when base // types are templates), but at least check the very first base type explicitly // specifies access `[virtual] public | protected | private [virtual] ...`. #define BOOST_CONTRACT_BASE_TYPES_CHECK_(bases_tuple, bases_seq) \ BOOST_PP_IIF(BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_( \ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(BOOST_PP_SEQ_HEAD( \ bases_seq))), \ BOOST_CONTRACT_BASE_TYPES_OK_ \ , \ BOOST_CONTRACT_BASE_TYPES_ERR_ \ )(bases_tuple, bases_seq) /* PUBLIC */ #define BOOST_CONTRACT_BASE_TYPES(...) \ BOOST_CONTRACT_BASE_TYPES_CHECK_((__VA_ARGS__), \ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) #else #define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */ #endif #endif // #include guard check.hpp 0000644 00000035764 15125525375 0006363 0 ustar 00 #ifndef BOOST_CONTRACT_CHECK_HPP_ #define BOOST_CONTRACT_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 /** @file RAII object that checks contracts. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/check_macro.hpp> #include <boost/contract/core/specify.hpp> #include <boost/contract/core/exception.hpp> // For set_... (if always in code). #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/condition/cond_base.hpp> #include <boost/contract/detail/auto_ptr.hpp> #include <boost/contract/detail/debug.hpp> #endif #include <boost/contract/detail/check.hpp> #include <boost/config.hpp> /* PRIVATE */ /** @cond */ #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) \ : cond_(const_cast<contract_type&>(contract).cond_.release()) \ { \ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ cond_->initialize(); \ } #else #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) {} #endif /** @endcond */ /* CODE */ namespace boost { namespace contract { /** RAII object that checks the contracts. In general, when this object is constructed it checks class invariants at entry, preconditions, and makes old value copies at body. When it is destructed, it checks class invariants at exist, postconditions, and exception guarantees. This object enforces the following (see @RefSect{contract_programming_overview, Contract Programming Overview}): @li Postconditions are checked only if the body does not throw an exception. @li Exceptions guarantees are checked only if the body throws an exception. @li Constructor entry never checks class invariants. @li Destructor exit checks class invariants only if the body throws an exception (even if destructors should usually not be programmed to throw exceptions in C++ and they are implicitly declared @c noexcept since C++11). @li Static invariants are always checked at entry and exit (and regardless of the body throwing exceptions or not). When used this way, this object is constructed and initialized to the return value of one of the contract functions @RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, or @RefFunc{boost::contract::public_function}. In addition to that, this object can be constructed from a nullary functor when it is used to program implementation checks. @see @RefSect{tutorial, Tutorial}, @RefSect{advanced.implementation_checks, Implementation Checks} */ class check { // Copy ctor only (as move via ptr release). public: // NOTE: Unfortunately, Apple compilers define a `check(...)` macro that // clashes with the name of this class. In the following code, // BOOST_PREVENT_MACRO_SUBSTITUTION is used to workaround these name // clashes. In user code, `check c = ...` syntax is typically used also // avoiding clashes. /** Construct this object for implementation checks. This can be used to program checks within implementation code (body, etc.). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param f Nullary functor that asserts implementation checks. @c f() will be called as soon as this object is constructed at the point it is declared within the implementation code (see @RefSect{advanced.implementation_checks, Implementation Checks}). */ template<typename F> // Cannot check `if(f) ...` as f can be a lambda. // f must be a valid callable object (not null func ptr, empty ftor, etc. /* implicit */ check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( F const& f) { BOOST_CONTRACT_DETAIL_CHECK({ f(); }) } /** Construct this object copying it from the specified one. This object will check the contract, the copied-from object will not (i.e., contract check ownership is transferred from the copied object to the new object being created by this constructor). @param other Copied-from object. */ check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( check const& other) #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) // Copy ctor moves cond_ pointer to dest. : cond_(const_cast<check&>(other).cond_.release()) #endif {} /** Construct this object to check the specified contract. This checks class invariants at entry (if those were specified for the given contract). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param contract Contract to be checked (usually the return value of @RefFunc{boost::contract::function} or @RefFunc{boost::contract::public_function}). @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template<typename VirtualResult> /* implicit */ check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( specify_precondition_old_postcondition_except<VirtualResult> const& contract ) #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CHECK_CTOR_DEF_( specify_precondition_old_postcondition_except<VirtualResult>) #else ; #endif /** Construct this object to check the specified contract. This checks class invariants at entry and preconditions (if any of those were specified for the given contract). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param contract Contract to be checked (usually the return value of @RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, or @RefFunc{boost::contract::public_function}). @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template<typename VirtualResult> /* implicit */ check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( specify_old_postcondition_except<VirtualResult> const& contract) #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CHECK_CTOR_DEF_( specify_old_postcondition_except<VirtualResult>) #else ; #endif /** Construct this object to check the specified contract. This checks class invariants at entry and preconditions then it makes old value copies at body (if any of those were specified for the given contract). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating te program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param contract Contract to be checked (usually the return value of @RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, or @RefFunc{boost::contract::public_function}). @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template<typename VirtualResult> /* implicit */ check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( specify_postcondition_except<VirtualResult> const& contract) #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CHECK_CTOR_DEF_( specify_postcondition_except<VirtualResult>) #else ; #endif /** Construct this object to check the specified contract. This checks class invariants at entry and preconditions then it makes old value copies at body, plus the destructor of this object will also check postconditions in this case (if any of those were specified for the given contract). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param contract Contract to be checked (usually the return value of @RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, or @RefFunc{boost::contract::public_function}). @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ /* implicit */ check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( specify_except const& contract) #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_except) #else ; #endif /** Construct this object to check the specified contract. This checks class invariants at entry and preconditions then it makes old value copies at body, plus the destructor of this object will also check postconditions and exception guarantees in this case (if any of those were specified for the given contract). This constructor is not declared @c explicit so initializations can use assignment syntax @c =. @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). @param contract Contract to be checked (usually the return value of @RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, or @RefFunc{boost::contract::public_function}). @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ /* implicit */ check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( specify_nothing const& contract) #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_nothing) #else ; #endif /** Destruct this object. This checks class invariants at exit and either postconditions when the enclosing function body did not throw an exception, or exception guarantees when the function body threw an exception (if class invariants, postconditions, and exception guarantees respectively were specified for the enclosing class and the contract parameter given when constructing this object). @b Throws: This can throw in case programmers specify contract failure handlers that throw exceptions instead of terminating the program (see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). (This is declared @c noexcept(false) since C++11.) */ ~check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ () BOOST_NOEXCEPT_IF(false) /* allow auto_ptr dtor to throw */ {} /** @cond */ private: check& operator=(check const&); // Cannot copy outside of `check c = ...`. #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) boost::contract::detail::auto_ptr<boost::contract::detail::cond_base> cond_; #endif /** @endcond */ }; } } // namespace #endif // #include guard detail/static_local_var.hpp 0000644 00000002643 15125525375 0012047 0 ustar 00 #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 detail/none.hpp 0000644 00000001555 15125525375 0007476 0 ustar 00 #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 detail/type_traits/optional.hpp 0000644 00000002535 15125525375 0012732 0 ustar 00 #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 detail/type_traits/mirror.hpp 0000644 00000010275 15125525375 0012417 0 ustar 00 #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 detail/type_traits/member_function_types.hpp 0000644 00000004607 15125525375 0015507 0 ustar 00 #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 detail/operator_safe_bool.hpp 0000644 00000006616 15125525375 0012406 0 ustar 00 #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 detail/auto_ptr.hpp 0000644 00000002621 15125525375 0010367 0 ustar 00 #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 detail/operation/static_public_function.hpp 0000644 00000007627 15125525375 0015277 0 ustar 00 #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 detail/operation/public_function.hpp 0000644 00000014363 15125525375 0013723 0 ustar 00 #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 detail/operation/function.hpp 0000644 00000005470 15125525375 0012364 0 ustar 00 #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 detail/operation/destructor.hpp 0000644 00000007674 15125525375 0012745 0 ustar 00 #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 detail/operation/constructor.hpp 0000644 00000006710 15125525375 0013122 0 ustar 00 #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 detail/config.hpp 0000644 00000001575 15125525375 0010006 0 ustar 00 #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 detail/inlined.hpp 0000644 00000001065 15125525375 0010155 0 ustar 00 #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 detail/debug.hpp 0000644 00000001352 15125525375 0007620 0 ustar 00 #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 detail/tvariadic.hpp 0000644 00000014705 15125525375 0010506 0 ustar 00 #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 detail/check.hpp 0000644 00000003233 15125525375 0007607 0 ustar 00 #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 detail/declspec.hpp 0000644 00000003726 15125525375 0010323 0 ustar 00 #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 detail/exception.hpp 0000644 00000002060 15125525375 0010525 0 ustar 00 #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 detail/noop.hpp 0000644 00000001315 15125525375 0007504 0 ustar 00 #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 detail/name.hpp 0000644 00000001661 15125525375 0007455 0 ustar 00 #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 detail/decl.hpp 0000644 00000011663 15125525375 0007447 0 ustar 00 #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 detail/condition/cond_post.hpp 0000644 00000005660 15125525375 0012516 0 ustar 00 #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 detail/condition/cond_subcontracting.hpp 0000644 00000043227 15125525375 0014557 0 ustar 00 #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 detail/condition/cond_inv.hpp 0000644 00000021716 15125525375 0012325 0 ustar 00 #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 detail/condition/cond_base.hpp 0000644 00000012551 15125525375 0012440 0 ustar 00 #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 detail/checking.hpp 0000644 00000004157 15125525375 0010313 0 ustar 00 #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 detail/preprocessor/keyword/virtual.hpp 0000644 00000002622 15125525375 0014433 0 ustar 00 #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 detail/preprocessor/keyword/public.hpp 0000644 00000002606 15125525375 0014225 0 ustar 00 #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 detail/preprocessor/keyword/private.hpp 0000644 00000002622 15125525375 0014417 0 ustar 00 #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 detail/preprocessor/keyword/utility/is.hpp 0000644 00000002170 15125525375 0015061 0 ustar 00 #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 detail/preprocessor/keyword/protected.hpp 0000644 00000002670 15125525375 0014741 0 ustar 00 #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 detail/inlined/detail/checking.hpp 0000644 00000002732 15125525375 0013174 0 ustar 00 #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 detail/inlined/old.hpp 0000644 00000001772 15125525375 0010740 0 ustar 00 #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 detail/inlined/core/exception.hpp 0000644 00000042046 15125525375 0013107 0 ustar 00 #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 detail/assert.hpp 0000644 00000002074 15125525375 0010035 0 ustar 00 #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 public_function.hpp 0000644 00000113037 15125525375 0010457 0 ustar 00 #ifndef BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_ #define BOOST_CONTRACT_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 /** @file Program contracts for public functions (including subcontracting). The different overloads handle public functions that are static, virtual void, virtual non-void, overriding void, and overriding non-void. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/specify.hpp> #include <boost/contract/core/access.hpp> #include <boost/contract/core/virtual.hpp> /** @cond */ // Needed within macro expansions below instead of defined(...) (PRIVATE macro). #if !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 1 #else #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 0 #endif /** @endcond */ #include <boost/contract/detail/decl.hpp> #include <boost/contract/detail/tvariadic.hpp> #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ #include <boost/contract/detail/operation/static_public_function.hpp> #include <boost/contract/detail/operation/public_function.hpp> #include <boost/contract/detail/type_traits/optional.hpp> #include <boost/contract/detail/none.hpp> #include <boost/function_types/result_type.hpp> #include <boost/function_types/function_arity.hpp> #include <boost/optional.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/static_assert.hpp> #include <boost/preprocessor/tuple/eat.hpp> #endif #if !BOOST_CONTRACT_DETAIL_TVARIADIC #include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/arithmetic/sub.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #endif #include <boost/preprocessor/control/expr_iif.hpp> #include <boost/preprocessor/control/iif.hpp> #include <boost/preprocessor/facilities/empty.hpp> #include <boost/preprocessor/punctuation/comma_if.hpp> namespace boost { namespace contract { // NOTE: Override and (optionally) VirtualResult allowed only when v is present // because: // * An overriding func must override a base func declared virtual so with // v extra param, thus the overriding func must also always have v (i.e., // Override might be present only if v is also present). However, the first // appearing virtual func (e.g., in root class) will not override any // previously declared virtual func so does not need Override (i.e., Override // always optional). // Furthermore, F needs to be specified only together with Override. // * VirtualResult is only used for virtual functions (i.e., VirtualResult might // be present only if v is also present). // However, VirtualResult is never specified, not even for virtual functions, // when the return type is void (i.e., VirtualResult always optional). /** Program contracts for static public functions. This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check static class invariants for static public functions: @code class u { friend class boost::contract::access; static void static_invariant() { // Optional (as for non-static). BOOST_CONTRACT_ASSERT(...); ... } public: static void f(...) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function<u>() .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body. } ... }; @endcode For optimization, this can be omitted for static public functions that do not have preconditions, postconditions and exception guarantees, within classes that have no static invariants. @see @RefSect{tutorial.static_public_functions, Static Public Functions} @tparam Class The type of the class containing the static public function declaring the contract. This template parameter must be explicitly specified for static public functions (because they have no object @c this so there is no function argument from which this type template parameter can be automatically deduced by C++). @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the static public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Class> specify_precondition_old_postcondition_except<> public_function() { #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ return specify_precondition_old_postcondition_except<>( new boost::contract::detail::static_public_function<Class>()); #else return specify_precondition_old_postcondition_except<>(); #endif } /** Program contracts for public functions that are not static, not virtual, and do not not override. This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check class invariants for public functions that are not static, not virtual, and do not override: @code class u { friend class boost::contract::access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: void f(...) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function(this) .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body. } ... }; @endcode For optimization, this can be omitted for public functions that do not have preconditions, postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.public_functions, Public Functions} @param obj The object @c this from the scope of the enclosing public function declaring the contract. This object might be mutable, @c const, @c volatile, or <c>const volatile</c> depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam Class The type of the class containing the public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Class> specify_precondition_old_postcondition_except<> public_function(Class* obj) { #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ return specify_precondition_old_postcondition_except<>( new boost::contract::detail::public_function< boost::contract::detail::none, boost::contract::detail::none, boost::contract::detail::none, Class BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( BOOST_CONTRACT_MAX_ARGS) BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, BOOST_CONTRACT_MAX_ARGS, boost::contract::detail::none ) >( static_cast<boost::contract::virtual_*>(0), obj, boost::contract::detail::none::value() BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( BOOST_CONTRACT_MAX_ARGS) BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, BOOST_CONTRACT_MAX_ARGS, boost::contract::detail::none::value() ) ) ); #else return specify_precondition_old_postcondition_except<>(); #endif } /** @cond */ // For non-static, virtual, and non-overriding public functions (PRIVATE macro). #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \ has_virtual_result) \ template< \ BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \ BOOST_PP_COMMA_IF(has_virtual_result) \ class Class \ > \ specify_precondition_old_postcondition_except< \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \ public_function( \ virtual_* v \ BOOST_PP_COMMA_IF(has_virtual_result) \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \ , Class* obj \ ) { \ BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \ /* no F... so cannot enforce contracted F returns VirtualResult */ \ return (specify_precondition_old_postcondition_except< \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \ new boost::contract::detail::public_function< \ boost::contract::detail::none, \ BOOST_PP_IIF(has_virtual_result, \ VirtualResult \ , \ boost::contract::detail::none \ ), \ boost::contract::detail::none, \ Class \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \ BOOST_CONTRACT_MAX_ARGS) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \ BOOST_CONTRACT_MAX_ARGS, \ boost::contract::detail::none \ ) \ >( \ v, \ obj, \ BOOST_PP_IIF(has_virtual_result, \ r \ , \ boost::contract::detail::none::value() \ ) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \ BOOST_CONTRACT_MAX_ARGS) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \ BOOST_CONTRACT_MAX_ARGS, \ boost::contract::detail::none::value() \ ) \ ) \ )); \ , \ return specify_precondition_old_postcondition_except< \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \ ) \ } /** @endcond */ #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Program contracts for void virtual public functions that do not override. This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check class invariants for public functions that are virtual, do not override, and return @c void: @code class u { friend class boost::contract::access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: void f(..., boost::contract::virtual_* v = 0) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function(v, this) .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(v, old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body. } ... }; @endcode A virtual public function should always call @RefFunc{boost::contract::public_function} otherwise this library will not be able to correctly use it for subcontracting. @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing virtual public function. @param obj The object @c this from the scope of the enclosing virtual public function declaring the contract. This object might be mutable, @c const, @c volatile, or <c>const volatile</c> depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Class> specify_precondition_old_postcondition_except<> public_function( virtual_* v, Class* obj); /** Program contracts for non-void virtual public functions that do not override. This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check class invariants for public functions that are virtual, do not override, and do not return @c void: @code class u { friend class boost::contract::access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: t f(..., boost::contract::virtual_* v = 0) { t result; boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function( v, result, this) .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(v, old_expr); ... }) .postcondition([&] (t const& result) { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body (use `return result = return_expr`). } ... }; @endcode A virtual public function should always call @RefFunc{boost::contract::public_function} otherwise this library will not be able to correctly use it for subcontracting. @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing virtual public function. @param r A reference to the return value of the enclosing virtual public function declaring the contract. This is usually a local variable declared by the enclosing virtual public function just before the contract, but programmers must set it to the actual value being returned by the function at each @c return statement. @param obj The object @c this from the scope of the enclosing virtual public function declaring the contract. This object might be mutable, @c const, @c volatile, or <c>const volatile</c> depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam VirtualResult This type must be the same as, or compatible with, the return type of the enclosing virtual public function declaring the contract (this library might not be able to generate a compile-time error if these types mismatch, but in general that will cause run-time errors or undefined behaviour). Alternatively, <c>boost::optional<<i>return-type</i>></c> can also be used (see @RefSect{advanced.optional_return_values, Optional Return Values}). (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<typename VirtualResult, class Class> specify_precondition_old_postcondition_except<VirtualResult> public_function(virtual_* v, VirtualResult& r, Class* obj); #else BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( /* has_virtual_result = */ 0) BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( /* has_virtual_result = */ 1) #endif /** @cond */ // For non-static, virtual, and overriding public functions (PRIVATE macro). #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \ z, arity, arity_compl, has_virtual_result) \ BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \ arity, /* is_friend = */ 0, has_virtual_result, \ Override, VirtualResult, F, Class, Args, \ v, r, /* f */ BOOST_PP_EMPTY(), obj, args \ ) { \ BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \ /* assert not strictly necessary as compilation will fail */ \ /* anyways, but helps limiting cryptic compiler's errors */ \ BOOST_STATIC_ASSERT_MSG( \ /* -2 for both `this` and `virtual_*` extra parameters */ \ ( \ boost::function_types::function_arity<F>::value - 2 \ == \ BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args) \ ), \ "missing one or more arguments for specified function" \ ); \ } \ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \ /* assert consistency of F's result type and VirtualResult */ \ BOOST_PP_IIF(has_virtual_result, \ BOOST_STATIC_ASSERT_MSG \ , \ BOOST_PP_TUPLE_EAT(2) \ )( \ (boost::is_same< \ typename boost::remove_reference<typename boost:: \ function_types::result_type<F>::type>::type, \ typename boost::contract::detail:: \ remove_value_reference_if_optional< \ VirtualResult \ >::type \ >::value), \ "mismatching result type for specified function" \ ); \ } \ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \ /* assert this so lib can check and enforce override */ \ BOOST_STATIC_ASSERT_MSG( \ boost::contract::access::has_base_types<Class>::value, \ "enclosing class missing 'base-types' typedef" \ ); \ } \ return (specify_precondition_old_postcondition_except< \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \ new boost::contract::detail::public_function< \ Override, \ BOOST_PP_IIF(has_virtual_result, \ VirtualResult \ , \ boost::contract::detail::none \ ), \ F, \ Class \ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \ boost::contract::detail::none) \ >( \ v, \ obj, \ BOOST_PP_IIF(has_virtual_result, \ r \ , \ boost::contract::detail::none::value() \ ) \ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, args) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \ boost::contract::detail::none::value()) \ ) \ )); \ , \ return specify_precondition_old_postcondition_except< \ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \ ) \ } /** @endcond */ #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Program contracts for void public functions overrides (virtual or not). This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check class invariants for public function overrides (virtual or not) that return @c void: @code class u #define BASES private boost::contract::constructor_precondition<u>, \ public b, private w : BASES { friend class boost::contract::access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } BOOST_CONTRACT_OVERRIDES(f) public: // Override from `b::f`. void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function< override_f>(v, &u::f, this, a_1, ..., a_n) .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(v, old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body. } ... }; @endcode A public function override should always call @RefFunc{boost::contract::public_function} otherwise this library will not be able to correctly use it for subcontracting. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing public function override. @param f A pointer to the enclosing public function override declaring the contract (but see @RefSect{advanced.function_overloads, Function Overloads}). @param obj The object @c this from the scope of the enclosing public function override declaring the contract. This object might be mutable, @c const, @c volatile, or <c>const volatile</c> depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @param args All arguments passed to the enclosing public function override declaring the contract (by reference and in the order they appear in the enclosing function declaration), but excluding the trailing argument @c v. @tparam Override The type trait <c>override_<i>function-name</i></c> declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related macros. This template parameter must be explicitly specified (because there is no function argument from which it can be automatically deduced by C++). @tparam F The function pointer type of the enclosing public function override declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam Args The types of all parameters passed to the enclosing public function override declaring the contract, but excluding the trailing parameter type <c>boost::contract::virtual_*</c>. On compilers that do not support variadic templates, this library internally implements this function using preprocessor meta-programming (in this case, the maximum number of supported arguments is defined by @RefMacro{BOOST_CONTRACT_MAX_ARGS}). (Usually these template parameters are automatically deduced by C++ and they do not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Override, typename F, class Class, typename... Args> specify_precondition_old_postcondition_except<> public_function( virtual_* v, F f, Class* obj, Args&... args); /** Program contracts for non-void public functions overrides (virtual or not). This is used to specify preconditions, postconditions, exception guarantees, old value copies at body, and check class invariants for public function overrides (virtual or not) that do not return @c void: @code class u #define BASES private boost::contract::constructor_precondition<u>, \ public b, private w : BASES { friend class boost::contract::access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } BOOST_CONTRACT_OVERRIDES(f) public: // Override from `b::f`. t f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) { t result; boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::public_function< override_f>(v, result, &u::f, this, a_1, ..., a_n) .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(v, old_expr); ... }) .postcondition([&] (t const& result) { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body (use `return result = return_expr`). } ... }; @endcode A public function override should always call @RefFunc{boost::contract::public_function} otherwise this library will not be able to correctly use it for subcontracting. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing public function override. @param r A reference to the return value of the enclosing public function override declaring the contract. This is usually a local variable declared by the enclosing public function override just before the contract, but programmers must set it to the actual value being returned by the function at each @c return statement. @param f A pointer to the enclosing public function override declaring the contract (but see @RefSect{advanced.function_overloads, Function Overloads}). @param obj The object @c this from the scope of the enclosing public function override declaring the contract. This object might be mutable, @c const, @c volatile, or <c>const volatile</c> depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @param args All arguments passed to the enclosing public function override declaring the contract (by reference and in the order they appear in the enclosing function declaration), but excluding the trailing argument @c v. @tparam Override The type trait <c>override_<i>function-name</i></c> declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related macros. This template parameter must be explicitly specified (because there is no function argument from which it can be automatically deduced by C++). @tparam VirtualResult This type must be the same as, or compatible with, the return type of the enclosing public function override declaring the contract (this library might not be able to generate a compile-time error if these types mismatch, but in general that will cause run-time errors or undefined behaviour). Alternatively, <c>boost::optional<<i>return-type</i>></c> can also be used (see @RefSect{advanced.optional_return_values, Optional Return Values}). (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam F The function pointer type of the enclosing public function override declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @tparam Args The types of all parameters passed to the enclosing public function override declaring the contract, but excluding the trailing parameter type <c>boost::contract::virtual_*</c>. On compilers that do not support variadic templates, this library internally implements this function using preprocessor meta-programming (in this case, the maximum number of supported arguments is defined by @RefMacro{BOOST_CONTRACT_MAX_ARGS}). (Usually these template parameters are automatically deduced by C++ and they do not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the public function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Override, typename VirtualResult, typename F, class Class, typename... Args> specify_precondition_old_postcondition_except<VirtualResult> public_function(virtual_* v, VirtualResult& r, F f, Class* obj, Args&... args); #elif BOOST_CONTRACT_DETAIL_TVARIADIC BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~, /* arity_compl = */ ~, /* has_virtual_result = */ 0) BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~, /* arity_compl = */ ~, /* has_virtual_result = */ 1) #else /* PRIVATE */ #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_( \ z, arity, unused) \ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, arity, \ BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), ~) #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \ arity, arity_compl, unused) \ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \ arity, arity_compl, /* has_virtual_result = */ 0) \ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \ arity, arity_compl, /* has_virtual_result = */ 1) /* CODE */ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_, ~) #endif } } // namespace #endif // #include guard old.hpp 0000644 00000070211 15125525375 0006046 0 ustar 00 #ifndef BOOST_CONTRACT_OLD_HPP_ #define BOOST_CONTRACT_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 /** @file Handle old values. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/virtual.hpp> #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION #include <boost/contract/detail/checking.hpp> #endif #include <boost/contract/detail/operator_safe_bool.hpp> #include <boost/contract/detail/declspec.hpp> #include <boost/contract/detail/debug.hpp> #include <boost/make_shared.hpp> #include <boost/shared_ptr.hpp> #include <boost/type_traits/is_copy_constructible.hpp> #include <boost/utility/enable_if.hpp> #include <boost/static_assert.hpp> #include <boost/preprocessor/control/expr_iif.hpp> #include <boost/preprocessor/config/config.hpp> #include <queue> #if !BOOST_PP_VARIADICS #define BOOST_CONTRACT_OLDOF \ BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_program_old_values #else // variadics #include <boost/preprocessor/facilities/overload.hpp> #include <boost/preprocessor/facilities/empty.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/config.hpp> /* PRIVATE */ /** @cond */ #ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value) /* nothing */ #else #include <boost/typeof/typeof.hpp> // Explicitly force old_ptr<...> conversion to allow for C++11 auto decl. #define BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value) \ boost::contract::old_ptr<BOOST_TYPEOF(value)> #endif #define BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_2( \ v, value) \ BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value)(boost::contract::make_old(v, \ boost::contract::copy_old(v) ? (value) : boost::contract::null_old() \ )) #define BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_1( \ value) \ BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value)(boost::contract::make_old( \ boost::contract::copy_old() ? (value) : boost::contract::null_old() \ )) /** @endcond */ /* PUBLIC */ // NOTE: Leave this #defined the same regardless of ..._NO_OLDS. /** Macro typically used to copy an old value expression and assign it to an old value pointer. The expression expanded by this macro should be assigned to an old value pointer of type @RefClass{boost::contract::old_ptr} or @RefClass{boost::contract::old_ptr_if_copyable}. This is an overloaded variadic macro and it can be used in the following different ways. 1\. From within virtual public functions and public functions overrides: @code BOOST_CONTRACT_OLDOF(v, old_expr) @endcode 2\. From all other operations: @code BOOST_CONTRACT_OLDOF(old_expr) @endcode Where: @arg <c><b>v</b></c> is the extra parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing virtual public function or public function overrides declaring the contract. @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied into the old value pointer. (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and <c>BOOST_CONTRACT_OLDOF(v, (old_expr))</c> will always work.) On compilers that do not support variadic macros, programmers can manually copy old value expressions without using this macro (see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}). @see @RefSect{tutorial.old_values, Old Values} */ #define BOOST_CONTRACT_OLDOF(...) \ BOOST_PP_CAT( /* CAT(..., EMTPY()) required on MSVC */ \ BOOST_PP_OVERLOAD( \ BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_, \ __VA_ARGS__ \ )(__VA_ARGS__), \ BOOST_PP_EMPTY() \ ) #endif // variadics /* CODE */ namespace boost { namespace contract { /** Trait to check if an old value type can be copied or not. By default, this unary boolean meta-function is equivalent to @c boost::is_copy_constructible<T> but programmers can chose to specialize it for user-defined types (in general some kind of specialization is also needed on compilers that do not support C++11, see <a href="http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference/is_copy_constructible.html"> <c>boost::is_copy_constructible</c></a>): @code class u; // Some user-defined type for which old values shall not be copied. namespace boost { namespace contract { template<> // Specialization to not copy old values of type `u`. struct is_old_value_copyable<u> : boost::false_type {}; } } // namespace @endcode A given old value type @c T is copied only if @c boost::contract::is_old_value_copyable<T>::value is @c true. A copyable old value type @c V is always copied using @c boost::contract::old_value_copy<V>. A non-copyable old value type @c W generates a compile-time error when @c boost::contract::old_ptr<W> is dereferenced, but instead leaves @c boost::contract::old_ptr_if_copyable<W> always null (without generating compile-time errors). @see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ template<typename T> struct is_old_value_copyable : boost::is_copy_constructible<T> {}; /** @cond */ class old_value; template<> // Needed because `old_value` incomplete type when trait first used. struct is_old_value_copyable<old_value> : boost::true_type {}; /** @endcond */ /** Trait to copy an old value. By default, the implementation of this trait uses @c T's copy constructor to make one single copy of the specified value. However, programmers can specialize this trait to copy old values using user-specific operations different from @c T's copy constructor. The default implementation of this trait is equivalent to: @code template<typename T> class old_value_copy { public: explicit old_value_copy(T const& old) : old_(old) // One single copy of value using T's copy constructor. {} T const& old() const { return old_; } private: T const old_; // The old value copy. }; @endcode This library will instantiate and use this trait only on old value types @c T that are copyable (i.e., for which <c>boost::contract::is_old_value_copyable<T>::value</c> is @c true). @see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ template<typename T> // Used only if is_old_value_copyable<T>. struct old_value_copy { /** Construct this object by making one single copy of the specified old value. This is the only operation within this library that actually copies old values. This ensures this library makes one and only one copy of an old value (if they actually need to be copied, see @RefMacro{BOOST_CONTRACT_NO_OLDS}). @param old The old value to copy. */ explicit old_value_copy(T const& old) : old_(old) {} // This makes the one single copy of T. /** Return a (constant) reference to the old value that was copied. Contract assertions should not change the state of the program so the old value copy is returned as @c const (see @RefSect{contract_programming_overview.constant_correctness, Constant Correctness}). */ T const& old() const { return old_; } private: T const old_; }; template<typename T> class old_ptr_if_copyable; /** Old value pointer that requires the pointed old value type to be copyable. This pointer can be set to point an actual old value copy using either @RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old} (that is why this class does not have public non-default constructors): @code class u { public: virtual void f(..., boost::contract::virtual_* v = 0) { boost::contract::old_ptr<old_type> old_var = // For copyable `old_type`. BOOST_CONTRACT_OLDOF(v, old_expr); ... } ... }; @endcode @see @RefSect{tutorial.old_values, Old Values} @tparam T Type of the pointed old value. This type must be copyable (i.e., <c>boost::contract::is_old_value_copyable<T>::value</c> must be @c true), otherwise this pointer will always be null and this library will generate a compile-time error when the pointer is dereferenced. */ template<typename T> class old_ptr { /* copyable (as *) */ public: /** Pointed old value type. */ typedef T element_type; /** Construct this old value pointer as null. */ old_ptr() {} /** Dereference this old value pointer. This will generate a run-time error if this pointer is null and a compile-time error if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable<T>::value is @c false). @return The pointed old value. Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a reference to a constant object (see @RefSect{contract_programming_overview.constant_correctness, Constant Correctness}). */ T const& operator*() const { BOOST_STATIC_ASSERT_MSG( boost::contract::is_old_value_copyable<T>::value, "old_ptr<T> requires T copyable (see is_old_value_copyable<T>), " "otherwise use old_ptr_if_copyable<T>" ); BOOST_CONTRACT_DETAIL_DEBUG(typed_copy_); return typed_copy_->old(); } /** Structure-dereference this old value pointer. This will generate a compile-time error if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable<T>::value is @c false). @return A pointer to the old value (null if this old value pointer is null). Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a pointer to a constant object (see @RefSect{contract_programming_overview.constant_correctness, Constant Correctness}). */ T const* operator->() const { BOOST_STATIC_ASSERT_MSG( boost::contract::is_old_value_copyable<T>::value, "old_ptr<T> requires T copyble (see is_old_value_copyable<T>), " "otherwise use old_ptr_if_copyable<T>" ); if(typed_copy_) return &typed_copy_->old(); return 0; } #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr<T>, !!typed_copy_) #else /** Query if this old value pointer is null or not (safe-bool operator). (This is implemented using safe-bool emulation on compilers that do not support C++11 explicit type conversion operators.) @return True if this pointer is not null, false otherwise. */ explicit operator bool() const; #endif /** @cond */ private: #ifndef BOOST_CONTRACT_NO_OLDS explicit old_ptr(boost::shared_ptr<old_value_copy<T> > old) : typed_copy_(old) {} #endif boost::shared_ptr<old_value_copy<T> > typed_copy_; friend class old_pointer; friend class old_ptr_if_copyable<T>; /** @endcond */ }; /** Old value pointer that does not require the pointed old value type to be copyable. This pointer can be set to point to an actual old value copy using either @RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old}: @code template<typename T> // Type `T` might or not be copyable. class u { public: virtual void f(..., boost::contract::virtual_* v = 0) { boost::contract::old_ptr_if_copyable<T> old_var = BOOST_CONTRACT_OLDOF(v, old_expr); ... if(old_var) ... // Always null for non-copyable types. ... } ... }; @endcode @see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} @tparam T Type of the pointed old value. If this type is not copyable (i.e., <c>boost::contract::is_old_value_copyable<T>::value</c> is @c false), this pointer will always be null (but this library will not generate a compile-time error when this pointer is dereferenced). */ template<typename T> class old_ptr_if_copyable { /* copyable (as *) */ public: /** Pointed old value type. */ typedef T element_type; /** Construct this old value pointer as null. */ old_ptr_if_copyable() {} /** Construct this old value pointer from an old value pointer that requires the old value type to be copyable. Ownership of the pointed value object is transferred to this pointer. This constructor is implicitly called by this library when assigning an object of this type using @RefMacro{BOOST_CONTRACT_OLDOF} (this constructor is usually not explicitly called by user code). @param other Old value pointer that requires the old value type to be copyable. */ /* implicit */ old_ptr_if_copyable(old_ptr<T> const& other) : typed_copy_(other.typed_copy_) {} /** Dereference this old value pointer. This will generate a run-time error if this pointer is null, but no compile-time error is generated if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable<T>::value is @c false). @return The pointed old value. Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a reference to a constant object (see @RefSect{contract_programming_overview.constant_correctness, Constant Correctness}). */ T const& operator*() const { BOOST_CONTRACT_DETAIL_DEBUG(typed_copy_); return typed_copy_->old(); } /** Structure-dereference this old value pointer. This will return null but will not generate a compile-time error if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable<T>::value is @c false). @return A pointer to the old value (null if this old value pointer is null). Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a pointer to a constant object (see @RefSect{contract_programming_overview.constant_correctness, Constant Correctness}). */ T const* operator->() const { if(typed_copy_) return &typed_copy_->old(); return 0; } #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_if_copyable<T>, !!typed_copy_) #else /** Query if this old value pointer is null or not (safe-bool operator). (This is implemented using safe-bool emulation on compilers that do not support C++11 explicit type conversion operators.) @return True if this pointer is not null, false otherwise. */ explicit operator bool() const; #endif /** @cond */ private: #ifndef BOOST_CONTRACT_NO_OLDS explicit old_ptr_if_copyable(boost::shared_ptr<old_value_copy<T> > old) : typed_copy_(old) {} #endif boost::shared_ptr<old_value_copy<T> > typed_copy_; friend class old_pointer; /** @endcond */ }; /** Convert user-specified expressions to old values. This class is usually only implicitly used by this library and it does not explicitly appear in user code. On older compilers that cannot correctly deduce the @c boost::contract::is_old_value_copyable trait used in the declaration of this class, programmers can manually specialize that trait to make sure that only old value types that are copyable are actually copied. @see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ class old_value { // Copyable (as *). public: // Following implicitly called by ternary operator `... ? ... : null_old()`. /** Construct this object from the specified old value when the old value type is copy constructible. The specified old value @c old is copied (one time only) using @c boost::contract::old_value_copy, in which case the related old value pointer will not be null (but no copy is made if postconditions and exception guarantees are not being checked, see @RefMacro{BOOST_CONTRACT_NO_OLDS}). @param old Old value to be copied. @tparam T Old value type. */ template<typename T> /* implicit */ old_value( T const& #if !defined(BOOST_CONTRACT_NO_OLDS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) old #endif // Else, no name (avoid unused param warning). , typename boost::enable_if<boost::contract::is_old_value_copyable<T> >::type* = 0 ) #ifndef BOOST_CONTRACT_NO_OLDS : untyped_copy_(new old_value_copy<T>(old)) #endif // Else, leave ptr_ null (thus no copy of T). {} /** Construct this object from the specified old value when the old value type is not copyable. The specified old value @c old cannot be copied in this case so it is not copied and the related old value pointer will always be null (thus calls to this constructor have no effect and they will likely be optimized away by most compilers). @param old Old value (that will not be copied in this case). @tparam T Old value type. */ template<typename T> /* implicit */ old_value( T const& #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN old #endif // Else, no name (avoid unused param warning). , typename boost::disable_if<boost::contract::is_old_value_copyable<T> >::type* = 0 ) {} // Leave ptr_ null (thus no copy of T). /** @cond */ private: explicit old_value() {} #ifndef BOOST_CONTRACT_NO_OLDS boost::shared_ptr<void> untyped_copy_; // Type erasure. #endif friend class old_pointer; friend BOOST_CONTRACT_DETAIL_DECLSPEC old_value null_old(); /** @endcond */ }; /** Convert old value copies into old value pointers. This class is usually only implicitly used by this library and it does not explicitly appear in user code (that is why this class does not have public constructors, etc.). */ class old_pointer { // Copyable (as *). public: /** Convert this object to an actual old value pointer for which the old value type @c T might or not be copyable. For example, this is implicitly called when assigning or initializing old value pointers of type @c boost::contract::old_ptr_if_copyable. @tparam T Type of the pointed old value. The old value pointer will always be null if this type is not copyable (see @c boost::contract::is_old_value_copyable), but this library will not generate a compile-time error. */ template<typename T> /* implicit */ operator old_ptr_if_copyable<T>() { return get<old_ptr_if_copyable<T> >(); } /** Convert this object to an actual old value pointer for which the old value type @c T must be copyable. For example, this is implicitly called when assigning or initializing old value pointers of type @c boost::contract::old_ptr. @tparam T Type of the pointed old value. This type must be copyable (see @c boost::contract::is_old_value_copyable), otherwise this library will generate a compile-time error when the old value pointer is dereferenced. */ template<typename T> /* implicit */ operator old_ptr<T>() { return get<old_ptr<T> >(); } /** @cond */ private: #ifndef BOOST_CONTRACT_NO_OLDS explicit old_pointer(virtual_* v, old_value const& old) : v_(v), untyped_copy_(old.untyped_copy_) {} #else explicit old_pointer(virtual_* /* v */, old_value const& /* old */) {} #endif template<typename Ptr> Ptr get() { #ifndef BOOST_CONTRACT_NO_OLDS if(!boost::contract::is_old_value_copyable<typename Ptr::element_type>::value) { BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_); return Ptr(); // Non-copyable so no old value and return null. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION } else if(!v_ && boost::contract::detail::checking::already()) { return Ptr(); // Not checking (so return null). #endif } else if(!v_) { BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy_); typedef old_value_copy<typename Ptr::element_type> copied_type; boost::shared_ptr<copied_type> typed_copy = // Un-erase type. boost::static_pointer_cast<copied_type>(untyped_copy_); BOOST_CONTRACT_DETAIL_DEBUG(typed_copy); return Ptr(typed_copy); } else if( v_->action_ == boost::contract::virtual_::push_old_init_copy || v_->action_ == boost::contract::virtual_::push_old_ftor_copy ) { BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy_); std::queue<boost::shared_ptr<void> >& copies = v_->action_ == boost::contract::virtual_::push_old_ftor_copy ? v_->old_ftor_copies_ : v_->old_init_copies_ ; copies.push(untyped_copy_); return Ptr(); // Pushed (so return null). } else if( boost::contract::virtual_::pop_old_init_copy(v_->action_) || v_->action_ == boost::contract::virtual_::pop_old_ftor_copy ) { // Copy not null, but still pop it from the queue. BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_); std::queue<boost::shared_ptr<void> >& copies = v_->action_ == boost::contract::virtual_::pop_old_ftor_copy ? v_->old_ftor_copies_ : v_->old_init_copies_ ; boost::shared_ptr<void> untyped_copy = copies.front(); BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy); copies.pop(); typedef old_value_copy<typename Ptr::element_type> copied_type; boost::shared_ptr<copied_type> typed_copy = // Un-erase type. boost::static_pointer_cast<copied_type>(untyped_copy); BOOST_CONTRACT_DETAIL_DEBUG(typed_copy); return Ptr(typed_copy); } BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_); #endif return Ptr(); } #ifndef BOOST_CONTRACT_NO_OLDS virtual_* v_; boost::shared_ptr<void> untyped_copy_; // Type erasure. #endif friend BOOST_CONTRACT_DETAIL_DECLSPEC old_pointer make_old(old_value const&); friend BOOST_CONTRACT_DETAIL_DECLSPEC old_pointer make_old(virtual_*, old_value const&); /** @endcond */ }; /** Return a "null" old value. The related old value pointer will also be null. This function is usually only called by the code expanded by @RefMacro{BOOST_CONTRACT_OLDOF}. @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @return Null old value. */ /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */ old_value null_old(); /** Make an old value pointer (but not for virtual public functions and public functions overrides). The related old value pointer will not be null if the specified old value was actually copied. This function is usually only called by code expanded by @c BOOST_CONTRACT_OLDOF(old_expr) as in: @code boost::contract::make_old(boost::contract::copy_old() ? old_expr : boost::contract::null_old()) @endcode @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param old Old value which is usually implicitly constructed from the user old value expression to be copied (use the ternary operator <c>?:</c> to completely avoid to evaluate the old value expression when @c boost::contract::copy_old() is @c false). @return Old value pointer (usually implicitly converted to either @RefClass{boost::contract::old_ptr} or @RefClass{boost::contract::old_ptr_if_copyable} in user code). */ /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */ old_pointer make_old(old_value const& old); /** Make an old value pointer (for virtual public functions and public functions overrides). The related old value pointer will not be null if the specified old value was actually copied. This function is usually only called by code expanded by @c BOOST_CONTRACT_OLDOF(v, old_expr) as in: @code boost::contract::make_old(v, boost::contract::copy_old(v) ? old_expr : boost::contract::null_old()) @endcode @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing virtual or overriding public function declaring the contract. @param old Old value which is usually implicitly constructed from the user old value expression to be copied (use the ternary operator <c>?:</c> to completely avoid to evaluate the old value expression when @c boost::contract::copy_old(v) is @c false). @return Old value pointer (usually implicitly converted to either @RefClass{boost::contract::old_ptr} or @RefClass{boost::contract::old_ptr_if_copyable} in user code). */ /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */ old_pointer make_old(virtual_* v, old_value const& old); /** Query if old values need to be copied (but not for virtual public functions and public function overrides). For example, this function always returns false when both postconditions and exception guarantees are not being checked (see @RefMacro{BOOST_CONTRACT_NO_OLDS}). This function is usually only called by the code expanded by @RefMacro{BOOST_CONTRACT_OLDOF}. @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @return True if old values need to be copied, false otherwise. */ inline bool copy_old() { #ifndef BOOST_CONTRACT_NO_OLDS #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION return !boost::contract::detail::checking::already(); #else return true; #endif #else return false; // No post checking, so never copy old values. #endif } /** Query if old values need to be copied (for virtual public functions and public function overrides). For example, this function always returns false when both postconditions and exception guarantees are not being checked (see @RefMacro{BOOST_CONTRACT_NO_OLDS}). In addition, this function returns false when overridden functions are being called subsequent times by this library to support subcontracting. This function is usually only called by the code expanded by @RefMacro{BOOST_CONTRACT_OLDOF}. @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 from the enclosing virtual or overriding public function declaring the contract. @return True if old values need to be copied, false otherwise. */ #ifndef BOOST_CONTRACT_NO_OLDS inline bool copy_old(virtual_* v) { if(!v) { #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION return !boost::contract::detail::checking::already(); #else return true; #endif } return v->action_ == boost::contract::virtual_::push_old_init_copy || v->action_ == boost::contract::virtual_::push_old_ftor_copy; } #else inline bool copy_old(virtual_* #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN v #endif ) { return false; // No post checking, so never copy old values. } #endif } } // namespace #ifdef BOOST_CONTRACT_HEADER_ONLY #include <boost/contract/detail/inlined/old.hpp> #endif #endif // #include guard function.hpp 0000644 00000006161 15125525375 0007120 0 ustar 00 #ifndef BOOST_CONTRACT_FUNCTION_HPP_ #define BOOST_CONTRACT_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 /** @file Program contracts for (non-public) functions. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/specify.hpp> #if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/operation/function.hpp> #endif namespace boost { namespace contract { /** Program contracts for non-member, private and protected functions. This is used to specify preconditions, postconditions, exception guarantees, and old value copies at body for non-member, private and protected functions (these functions never check class invariants, see @RefSect{contract_programming_overview.function_calls, Function Calls}): @code void f(...) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::function() .precondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Function body. } @endcode This can be used also to program contracts in implementation code for lambda functions, loops, and arbitrary blocks of code. For optimization, this can be omitted for code that does not have preconditions, postconditions, and exception guarantees. @see @RefSect{tutorial.non_member_functions, Non-Member Functions}, @RefSect{advanced.private_and_protected_functions, Private and Protected Functions}, @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__, Lambdas\, Loops\, Code Blocks} @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ inline specify_precondition_old_postcondition_except<> function() { // Must #if also on ..._INVARIANTS here because specify_... is generic. #if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \ defined(BOOST_CONTRACT_STATIC_LINK) return specify_precondition_old_postcondition_except<>( new boost::contract::detail::function()); #else return specify_precondition_old_postcondition_except<>(); #endif } } } // namespace #endif // #include guard destructor.hpp 0000644 00000007234 15125525375 0007473 0 ustar 00 #ifndef BOOST_CONTRACT_DESTRUCTOR_HPP_ #define BOOST_CONTRACT_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 /** @file Program contracts for destructors. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/specify.hpp> #include <boost/contract/core/access.hpp> #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/operation/destructor.hpp> #endif namespace boost { namespace contract { /** Program contracts for destructors. This is used to specify postconditions, exception guarantees, old value copies at body, and check class invariants for destructors (destructors cannot have preconditions, see @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}): @code class u { friend class boost::contract::access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: ~u() { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::destructor(this) // No `.precondition` (destructors have no preconditions). .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Destructor body. } ... }; @endcode For optimization, this can be omitted for destructors that do not have postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.destructors, Destructors} @param obj The object @c this from the scope of the enclosing destructor declaring the contract. (Destructors check all class invariants, including static and volatile invariants, see @RefSect{tutorial.class_invariants, Class Invariants} and @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam Class The type of the class containing the destructor declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the destructor body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Class> specify_old_postcondition_except<> destructor(Class* obj) { // Must #if also on ..._PRECONDITIONS here because specify_... is generic. #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) return specify_old_postcondition_except<>( new boost::contract::detail::destructor<Class>(obj)); #else return specify_old_postcondition_except<>(); #endif } } } // namespace #endif // #include guard override.hpp 0000644 00000017265 15125525375 0007121 0 ustar 00 #ifndef BOOST_CONTRACT_OVERRIDE_HPP_ #define BOOST_CONTRACT_OVERRIDE_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 /** @file Handle public function overrides (for subcontracting). */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/config/config.hpp> #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Declare an override type trait with an arbitrary name. Declare the override type trait named @c type_name to pass as an explicit template parameter to @RefFunc{boost::contract::public_function} for public function overrides. @see @RefSect{advanced.named_overrides, Named Overrides} @param type_name Name of the override type trait this macro will declare. (This is not a variadic macro parameter but it should never contain commas because it is an identifier.) @param func_name Function name of the public function override. This macro is called just once even if the function name is overloaded (the same override type trait is used for all overloaded functions with the same name, see @RefSect{advanced.function_overloads, Function Overloads}). (This is not a variadic macro parameter but it should never contain commas because it is an identifier.) */ #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) #include <boost/contract/core/virtual.hpp> #include <boost/contract/detail/type_traits/mirror.hpp> #include <boost/contract/detail/tvariadic.hpp> #include <boost/contract/detail/none.hpp> #include <boost/contract/detail/name.hpp> /* PRIVATE */ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, arity_compl, \ func_name) \ template< \ class BOOST_CONTRACT_DETAIL_NAME1(B), \ class BOOST_CONTRACT_DETAIL_NAME1(C) \ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \ BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, \ BOOST_CONTRACT_DETAIL_NAME1(Args)) \ > \ static void BOOST_CONTRACT_DETAIL_NAME1(call_base)( \ boost::contract::virtual_* BOOST_CONTRACT_DETAIL_NAME1(v), \ BOOST_CONTRACT_DETAIL_NAME1(C)* BOOST_CONTRACT_DETAIL_NAME1(obj) \ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \ BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, \ BOOST_CONTRACT_DETAIL_NAME1(Args), \ &, \ BOOST_CONTRACT_DETAIL_NAME1(args) \ ) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \ boost::contract::detail::none&) \ ) { \ BOOST_CONTRACT_DETAIL_NAME1(obj)-> \ BOOST_CONTRACT_DETAIL_NAME1(B)::func_name( \ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, \ BOOST_CONTRACT_DETAIL_NAME1(args)) \ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \ BOOST_CONTRACT_DETAIL_NAME1(v) \ ); \ } #if BOOST_CONTRACT_DETAIL_TVARIADIC #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \ BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, func_name) #else #include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/arithmetic/sub.hpp> #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \ BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, func_name) \ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, func_name) \ BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, \ BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), func_name) #endif /* PUBLIC */ #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \ struct type_name { \ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \ BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \ func_name \ ) \ BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \ }; #else #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \ struct type_name {}; /* empty (not used), just to compile */ #endif /* PUBLIC */ /** Declare an override type trait named <c>override_<i>func_name</i></c>. Declare the override type trait named <c>override_<i>func_name</i></c> to pass as an explicit template parameter to @RefFunc{boost::contract::public_function} for public function overrides. Use @RefMacro{BOOST_CONTRACT_NAMED_OVERRIDE} to generate an override type trait with a name different than <c>override_<i>func_name</i></c> (usually not needed). @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @param func_name Function name of the public function override. This macro is called just once even if the function name is overloaded (the same override type trait is used for all overloaded functions with the same name, see @RefSect{advanced.function_overloads, Function Overloads}). (This is not a variadic macro parameter but it should never contain any comma because it is an identifier.) */ #define BOOST_CONTRACT_OVERRIDE(func_name) \ BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, func_name), func_name) #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Declare multiple override type traits at once naming them <c>override_...</c> (for convenience). This variadic macro is provided for convenience as <c>BOOST_CONTRACT_OVERRIDES(f_1, f_2, ..., f_n)</c> expands to code equivalent to: @code BOOST_CONTRACT_OVERRIDE(f_1) BOOST_CONTRACT_OVERRIDE(f_2) ... BOOST_CONTRACT_OVERRIDE(f_n) @endcode On compilers that do not support variadic macros, the override type traits can be equivalently programmed one-by-one calling @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name as shown above. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @param ... A comma separated list of one or more function names of public function overrides. (Each function name should never contain commas because it is an identifier.) */ #define BOOST_CONTRACT_OVERRIDES(...) #elif BOOST_PP_VARIADICS #include <boost/preprocessor/seq/for_each.hpp> #include <boost/preprocessor/variadic/to_seq.hpp> /* PRIVATE */ #define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, func_name) \ BOOST_CONTRACT_OVERRIDE(func_name) /* PUBLIC */ #define BOOST_CONTRACT_OVERRIDES(...) \ BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) #else #define BOOST_CONTRACT_OVERRIDES \ BOOST_CONTRACT_ERROR_macro_OVERRIDES_requires_variadic_macros_otherwise_manually_repeat_OVERRIDE_macro #endif #endif // #include guard core/check_macro.hpp 0000644 00000011727 15125525375 0010465 0 ustar 00 #ifndef BOOST_CONTRACT_CHECK_MACRO_HPP_ #define BOOST_CONTRACT_CHECK_MACRO_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 /** @file Macros for implementation checks. */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #include <boost/contract/detail/noop.hpp> #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Preferred way to assert implementation check conditions. It is preferred to use this macro instead of programming implementation checks in a nullary functor passed to @RefClass{boost::contract::check} constructor because this macro will completely remove implementation checks from the code when @RefMacro{BOOST_CONTRACT_NO_CHECKS} is defined: @code void f() { ... BOOST_CONTRACT_CHECK(cond); ... } @endcode @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels predefined by this library for implementation checks. @see @RefSect{advanced.implementation_checks, Implementation Checks} @param cond Boolean condition to check within implementation code (function body, etc.). (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_CHECK((cond)) will always work.) */ #define BOOST_CONTRACT_CHECK(cond) #elif !defined(BOOST_CONTRACT_NO_CHECKS) #include <boost/contract/detail/check.hpp> #include <boost/contract/detail/assert.hpp> #define BOOST_CONTRACT_CHECK(cond) \ BOOST_CONTRACT_DETAIL_CHECK(BOOST_CONTRACT_DETAIL_ASSERT(cond)) #else #define BOOST_CONTRACT_CHECK(cond) /* nothing */ #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Preferred way to assert implementation check conditions that are computationally expensive, at least compared to the computational cost of executing the function body. The specified condition will always be compiled and validated syntactically, but it will not be checked at run-time unless @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default). This macro is defined by code equivalent to: @code #ifdef BOOST_CONTRACT_AUDITS #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ BOOST_CONTRACT_CHECK(cond) #else #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ BOOST_CONTRACT_CHECK(true || cond) #endif @endcode @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels predefined by this library for implementation checks. If there is a need, programmers are free to implement their own assertion levels defining macros similar to the one above. @see @RefSect{extras.assertion_levels, Assertion Levels} @param cond Boolean condition to check within implementation code (function body, etc.). (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_CHECK_AUDIT((cond)) will always work.) */ #define BOOST_CONTRACT_CHECK_AUDIT(cond) #elif defined(BOOST_CONTRACT_AUDITS) #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ BOOST_CONTRACT_CHECK(cond) #else #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif /** Preferred way to document in the code implementation check conditions that are computationally prohibitive, at least compared to the computational cost of executing the function body. The specified condition will always be compiled and validated syntactically, but it will never be checked at run-time. This macro is defined by code equivalent to: @code #define BOOST_CONTRACT_CHECK_AXIOM(cond) \ BOOST_CONTRACT_CHECK(true || cond) @endcode @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels predefined by this library for implementation checks. If there is a need, programmers are free to implement their own assertion levels defining macros similar to the one above. @see @RefSect{extras.assertion_levels, Assertion Levels} @param cond Boolean condition to check within implementation code (function body, etc.). (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_CHECK_AXIOM((cond)) will always work.) */ #define BOOST_CONTRACT_CHECK_AXIOM(cond) \ BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif // #include guard core/config.hpp 0000644 00000103214 15125525375 0007465 0 ustar 00 #ifndef BOOST_CONTRACT_CONFIG_HPP_ #define BOOST_CONTRACT_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 /** @file Configure this library compile-time and run-time behaviours. */ // IMPORTANT: This header MUST NOT #include any other header of this lib. // That way users can #include this header and not #include any of this lib // headers after that depending on the contract 0/1 macros below ensuring no // compilation overhead. // Export symbols when compiling as shared lib (for internal use only). (Named // after similar macros in all Boost libs.) // BOOST_CONTRACT_SOURCE // Disable automatic library selection for linking. (Named after similar macros // in all Boost libs.) // BOOST_CONTRACT_NO_LIB // BOOST_ALL_NO_LIB #if (!defined(BOOST_CONTRACT_DYN_LINK) && defined(BOOST_ALL_DYN_LINK)) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) /** Define this macro to compile this library as a shared library (recommended). If this macro is defined, this library is compiled so it can be linked as a shared library (a.k.a., Dynamically Linked Library or DLL) to user code. This library will automatically define this macro when Boost libraries are built as shared libraries (e.g., defining @c BOOST_ALL_DYN_LINK or using <c>bjam link=shared ...</c>). @warning In general this library will correctly check contracts at run-time only when compiled as a shared library, unless user code checks contracts in a single program unit (e.g., a single program with only statically linked libraries). Therefore, it is recommended to build and use this library as a shared library by defining this macro (or equivalently by building all Boost libraries as shared libraries). @see @RefSect{getting_started, Getting Started} */ #define BOOST_CONTRACT_DYN_LINK #elif defined(BOOST_CONTRACT_DYN_LINK) && defined(BOOST_CONTRACT_STATIC_LINK) #error "DYN_LINK defined with STATIC_LINK" #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Define this macro to compile this library as a static library (not recommended). If this macro is defined, this library is compiled so it can be linked statically to user code. This library will automatically define this macro when Boost libraries are built as static libraries. @warning This library is not guaranteed to always work correctly at run-time when this macro is defined (define @RefMacro{BOOST_CONTRACT_DYN_LINK} or @c BOOST_ALL_DYN_LINK instead). However, this macro can be defined and this library can be safely used as a static library for user code that checks contracts in a single program unit (e.g., a single program with only statically linked libraries). @see @RefSect{getting_started, Getting Started} */ #define BOOST_CONTRACT_STATIC_LINK #elif defined(BOOST_CONTRACT_STATIC_LINK) && defined(BOOST_CONTRACT_DYN_LINK) #error "STATIC_LINK defined with DYN_LINK" #endif #ifdef BOOST_CONTRACT_HEADER_ONLY #error "leave DYN_LINK and STATIC_LINK undefined instead" #elif (!defined(BOOST_CONTRACT_DYN_LINK) && \ !defined(BOOST_CONTRACT_STATIC_LINK)) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) /** Automatically defined by this library when it is being used as a header-only library (not recommended). This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users do not define @RefMacro{BOOST_CONTRACT_DYN_LINK} (or @c BOOST_ALL_DYN_LINK) and @RefMacro{BOOST_CONTRACT_STATIC_LINK}. When used as a header-only library, this library code does not have to be compiled separately from user code, this library headers are simply included and compiled as part of the user program. @warning This library is not guaranteed to always work correctly at run-time when this macro is defined (define @RefMacro{BOOST_CONTRACT_DYN_LINK} or @c BOOST_ALL_DYN_LINK instead). However, this macro can be defined and this library can be safely used as a header-only library for user code that checks contracts in a single program unit (e.g., a single program with only statically linked libraries). @see @RefSect{getting_started, Getting Started} */ #define BOOST_CONTRACT_HEADER_ONLY #endif #if (!defined(BOOST_CONTRACT_DISABLE_THREADS) && \ defined(BOOST_DISABLE_THREADS)) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) /** Define this macro to not lock internal library data for thread safety (undefined by default). Defining this macro will make the library implementation code not thread safe so this macro should not be defined unless the library is being used by single-threaded applications only. This library will automatically define this macro when Boost libraries are built without threads (e.g., defining @c BOOST_DISABLE_THREADS). @note When this macro is left undefined this library needs to internally use some sort of global lock (to ensure contract checking is globally disabled when other contracts are being checked and also to safely access failure handler functors). That could introduce an undesired amount of synchronization in some multi-threaded applications. @see @RefSect{contract_programming_overview.assertions, Assertions} */ #define BOOST_CONTRACT_DISABLE_THREADS #endif #ifndef BOOST_CONTRACT_MAX_ARGS /** Maximum number of arguments for public function overrides on compilers that do not support variadic templates (default to @c 10). On compilers that do not support C++11 variadic templates, this macro is defined to the maximum number of arguments that public function overrides can have and pass to @RefFunc{boost::contract::public_function} (users can redefine this macro to a different value). On compilers that support variadic templates, this macro has no effect. @note Regardless of the value of this macro and of compiler support for variadic templates, there might be an intrinsic limit of about 18 arguments for public function overrides (because of similar limits in Boost.MPL and Boost.FunctionTypes internally used by this library). @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} */ #define BOOST_CONTRACT_MAX_ARGS 10 #endif #ifndef BOOST_CONTRACT_BASES_TYPEDEF /** Define the name of the base type @c typedef (@c base_types by default). This macro expands to the name of the @c typedef that lists the base classes for subcontracting via @RefMacro{BOOST_CONTRACT_BASE_TYPES}: @code class u #define BASES public b, private w : BASES { friend class boost::contract:access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) BOOST_CONTRACT_TYPEDEF; #undef BASES ... }; @endcode When used this way, users can redefine this macro if the @c typedef must have a name different from @c base_types (because of name clashes in user code, etc.). @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes} */ #define BOOST_CONTRACT_BASES_TYPEDEF base_types #endif #ifndef BOOST_CONTRACT_INVARIANT_FUNC /** Define the name of the class invariant member function (@c invariant by default). This macro expands to the name of the @c const and <c>const volatile</c> member functions that check class invariants and volatile class invariants respectively: @code class u { friend class boost::contract::access; void BOOST_CONTRACT_INVARIANT_FUNC() const { BOOST_CONTRACT_ASSERT(...); ... } void BOOST_CONTRACT_INVARIANT_FUNC() const volatile { BOOST_CONTRACT_ASSERT(...); ... } ... }; @endcode When used this way, users can redefine this macro if the invariant functions must have a name different from @c invariant (because of name clashes in user code, etc.). @note C++ does not allow to overload member functions based on the @c static classifier, so this macro must always be defined to be different than the function name defined for @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT_FUNC}. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ #define BOOST_CONTRACT_INVARIANT_FUNC invariant #endif #ifndef BOOST_CONTRACT_STATIC_INVARIANT_FUNC /** Define the name of the static invariant member function (@c static_invariant by default). This macro expands to the name of the @c static member function that checks static class invariants: @code class u { friend class boost::contract::access; static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() { BOOST_CONTRACT_ASSERT(...); ... } ... }; @endcode When used this way, users can redefine this macro if the static invariant function must have a name different from @c static_invariant (because of name clashes in user code, etc.). @note C++ does not allow to overload member functions based on the @c static classifier, so this macro must always be defined to be different than the function name defined for @RefMacro{BOOST_CONTRACT_INVARIANT_FUNC}. @see @RefSect{tutorial.class_invariants, Class Invariants} */ #define BOOST_CONTRACT_STATIC_INVARIANT_FUNC static_invariant #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Disable some compile-time errors generated by this library (undefined by default). Defining this macro disables a number of static checks and related compile-time errors generated by this library, for example: @li The static invariant member function named as @c BOOST_CONTRACT_STATIC_INVARIANT_FUNC must be declared @c static. @li Non-static invariant member functions named as @c BOOST_CONTRACT_INVARIANT_FUNC must be declared either @c const, <c>const volatile</c>, or <c>volatile const</c>. @li Derived classes that program contracts for one or more public function overrides via @RefFunc{boost::contract::public_function} must also define the @RefMacro{BOOST_CONTRACT_BASE_TYPES} @c typedef. In general, it is not recommended to define this macro because these compile-time checks can guard against misuses of this library. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{tutorial.base_classes__subcontracting_, Base Classes} */ #define BOOST_CONTRACT_PERMISSIVE #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Code block to execute if contracts are not assigned to a @RefClass{boost::contract::check} variable (undefined and executes @c BOOST_ASSERT(false) by default). In general, there is a logic error in the program when contracts are not explicitly assigned to a local variable of type @RefClass{boost::contract::check} and without using C++11 @c auto declarations (because that is a misuse of this library). Therefore, by default (i.e., when this macro is not defined) this library calls <c>BOOST_ASSERT(false)</c> in those cases. If this macro is defined, this library will execute the code expanded by this macro instead of calling @c BOOST_ASSERT(false) (if programmers prefer to throw an exception, etc.). This macro can also be defined to be any block of code (and use empty curly brackets @c {} to generate no error, not recommended), for example (on GCC): @code gcc -DBOOST_CONTRACT_ON_MISSING_CHECK_DECL='{ throw std::logic_error("missing contract check declaration"); }' ... @endcode @see @RefSect{tutorial, Tutorial} */ #define BOOST_CONTRACT_ON_MISSING_CHECK_DECL #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Define this macro to not disable other assertions while checking preconditions (undefined by default). Not disabling other assertions while checking preconditions can lead to infinite recursion in user code so by default this macro is not defined. However, the @RefSect{bibliography, [N1962]} proposal does not disable assertions while checking preconditions because arguments can reach the function body unchecked if assertions are disabled while checking preconditions (e.g., when these same functions bodies are called to check the preconditions in question). This macro can be defined to obtain the behaviour specified in @RefSect{bibliography, [N1962]} (at the risk of infinite recursion). @see @RefSect{contract_programming_overview.feature_summary, Feature Summary} */ #define BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Define this macro to not disable any assertion while checking other assertions (undefined by default). Not disabling assertions while checking other assertions can lead to infinite recursion in user code so by default this macro is not defined. (Defining this macro automatically implies that other assertion checking is disabled while checking preconditions as if @RefMacro{BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION} was also defined.) @see @RefSect{contract_programming_overview.feature_summary, Feature Summary} */ #define BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Define this macro to evaluate and check audit assertions at run-time (undefined by default). Audit assertions and implementation checks programmed via @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and @RefMacro{BOOST_CONTRACT_CHECK_AUDIT} are always compiled and validated syntactically. However, they are not evaluated and checked at run-time unless this macro is defined (because these conditions can be computationally expensive, at least compared to the computational cost of executing the function body). @see @RefSect{extras.assertion_levels, Assertion Levels} */ #define BOOST_CONTRACT_AUDITS #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** If defined, this library disables implementation checks (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with implementation checks. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of implementation checks or use @RefMacro{BOOST_CONTRACT_CHECK} (recommended). @see @RefSect{advanced.implementation_checks, Implementation Checks}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CHECKS #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** If defined, this library does not check preconditions (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking preconditions. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of preconditions or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{tutorial.preconditions, Preconditions}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_PRECONDITIONS #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** If defined, this library does not check postconditions (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking postconditions. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of postconditions or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). It is necessary to disable both postconditions and exception guarantees defining @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} in order to disable old value copies (see @RefMacro{BOOST_CONTRACT_NO_OLDS}). @see @RefSect{tutorial.postconditions, Postconditions}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_POSTCONDITIONS #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** If defined, this library does not check exception guarantees (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking exception guarantees. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of exception guarantees or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). It is necessary to disable both postconditions and exception guarantees defining @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} in order to disable old value copies (see @RefMacro{BOOST_CONTRACT_NO_OLDS}). @see @RefSect{tutorial.exception_guarantees, Exception Guarantees}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_EXCEPTS #endif #if defined(BOOST_CONTRACT_DETAIL_DOXYGEN) || \ ( \ !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_INVARIANTS) \ ) /** If defined, this library does not check class invariants at entry (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking class invariants at entry. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of entry class invariants or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). This macro is automatically defined when @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_ENTRY_INVARIANTS #endif #if defined(BOOST_CONTRACT_DETAIL_DOXYGEN) || \ ( \ !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_INVARIANTS) \ ) /** If defined, this library does not check class invariants at exit (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking class invariants at exit. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of exit class invariants or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). This macro is automatically defined when @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_EXIT_INVARIANTS #endif #if !defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) /** If defined, this library does not check class invariants (undefined by default). If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with checking class invariants. In addition, users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of class invariants or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). Defining this macro is equivalent to defining both @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS} and @RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.disable_contract_checking, Disable Contract Checking}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_INVARIANTS #endif #ifdef BOOST_CONTRACT_NO_OLDS #error "define NO_POSTCONDITIONS and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when old value copies are not to be performed. This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define both @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of old value copies or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{tutorial.old_values, Old Values}, @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_OLDS #endif // Ctor pre checked separately and outside RAII so not part of this #define. #ifdef BOOST_CONTRACT_NO_CONSTRUCTORS #error "define NO_INVARIANTS, NO_POSTCONDITIONS, and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when contracts are not checked for constructors. This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of contracts for constructors or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @note Constructor preconditions are checked separately by @RefClass{boost::contract::constructor_precondition} so they are disabled by @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} instead. @see @RefSect{tutorial.constructors, Constructors}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CONSTRUCTORS #endif #ifdef BOOST_CONTRACT_NO_DESTRUCTORS #error "define NO_INVARIANTS, NO_POSTCONDITIONS, and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when contracts are not checked for destructors. This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of contracts for destructors or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{tutorial.destructors, Destructors}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_DESTRUCTORS #endif #ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when contracts are not checked for public functions. This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of contracts for public functions or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{tutorial.public_functions, Public Functions}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS #endif #ifdef BOOST_CONTRACT_NO_FUNCTIONS #error "define NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when contracts are not checked for non-member, private, or protected functions. This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of contracts for non-member, private and protected functions, or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). This macro is also used when contracts are not checked for private or protected functions, lambda functions, code blocks, loops, etc. @see @RefSect{tutorial.non_member_functions, Non-Member Functions}, @RefSect{advanced.private_and_protected_functions, Private and Protected Functions}, @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__, Lambdas\, Loops\, Code Blocks}, @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_FUNCTIONS #endif #ifdef BOOST_CONTRACT_NO_CONDITIONS #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead" #elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** Automatically defined by this library when contracts are not checked for preconditions, postconditions, exceptions guarantees, and class invariants (excluding implementation checks). This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}, and @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of contracts within specifications (so excluding implementation checks which are contracts within implementations instead), or use the macros defined in @c boost/contract_macro.hpp (recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CONDITIONS #endif #ifdef BOOST_CONTRACT_NO_ALL #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, NO_EXCEPTS, and NO_CHECKS instead" #elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) && \ defined(BOOST_CONTRACT_NO_CHECKS) /** Automatically defined by this library when contracts are not checked at all (neither for specifications nor for implementations). This macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly. This library will automatically define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}, and @RefMacro{BOOST_CONTRACT_NO_CHECKS}. For example, users can manually program @c \#ifndef statements in their code using this macro to avoid including the @c boost/contract.hpp header all together: @code #include <boost/contract/core/config.hpp> #ifndef BOOST_CONTRACT_NO_ALL #include <boost/contract.hpp> #endif @endcode Or, use the @c boost/contract_macro.hpp header and related macros instead (because the @c boost/contract_macro.hpp header is already optimized to not include other headers from this library when contracts are not checked, but recommended only for applications where it is truly necessary to completely remove contract code compilation from production code). @see @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_ALL #endif #endif // #include guard core/virtual.hpp 0000644 00000013235 15125525375 0007711 0 ustar 00 #ifndef BOOST_CONTRACT_VIRTUAL_HPP_ #define BOOST_CONTRACT_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 /** @file Handle virtual public functions with contracts (for subcontracting). */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #ifndef BOOST_CONTRACT_NO_CONDITIONS #include <boost/contract/detail/decl.hpp> #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS #include <boost/any.hpp> #endif #ifndef BOOST_CONTRACT_NO_OLDS #include <boost/shared_ptr.hpp> #include <queue> #endif namespace boost { namespace contract { #ifndef BOOST_CONTRACT_NO_CONDITIONS namespace detail { BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, /* is_friend = */ 0, OO, RR, FF, CC, AArgs); } #endif /** Type of extra function parameter to handle contracts for virtual public functions (for subcontracting). Virtual public functions (and therefore also public function overrides) declaring contracts using this library must specify an extra function parameter at the very end of their parameter list. This parameter must be a pointer to this class and it must have default value @c 0 or @c nullptr (this extra parameter is often named @c v in this documentation, but any name can be used): @code class u { public: virtual void f(int x, boost::contract::virtual_* v = 0) { // Declare `v`. ... // Contract declaration (which will use `v`) and function body. } ... }; @endcode In practice this extra parameter does not alter the calling interface of the enclosing function declaring the contract because it is always the very last parameter and it has a default value (so it can always be omitted when users call the function). This extra parameter must be passed to @RefFunc{boost::contract::public_function}, @RefMacro{BOOST_CONTRACT_OLDOF}, and all other operations of this library that accept a pointer to @RefClass{boost::contract::virtual_}. A part from that, this class is not intended to be directly used by programmers (and that is why this class does not have any public member and it is not copyable). @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}, @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} */ class virtual_ { // Non-copyable (see below) to avoid copy queue, stack, etc. /** @cond */ private: // No public API (so users cannot use it directly by mistake). // No boost::noncopyable to avoid its overhead when contracts disabled. virtual_(virtual_&); virtual_& operator=(virtual_&); #ifndef BOOST_CONTRACT_NO_CONDITIONS enum action_enum { // virtual_ always held/passed as ptr so nullptr used for user call. no_action, #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS check_entry_inv, #endif #ifndef BOOST_CONTRACT_NO_PRECONDITIONS check_pre, #endif #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS check_exit_inv, #endif #ifndef BOOST_CONTRACT_NO_OLDS // For outside .old(...). push_old_init_copy, // pop_old_init_copy as static function below. // For inside .old(...). call_old_ftor, push_old_ftor_copy, pop_old_ftor_copy, #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS check_post, #endif #ifndef BOOST_CONTRACT_NO_EXCEPTS check_except, #endif }; #endif #ifndef BOOST_CONTRACT_NO_OLDS // Not just an enum value because the logical combination of two values. inline static bool pop_old_init_copy(action_enum a) { return #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS a == check_post #endif #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ !defined(BOOST_CONTRACT_NO_EXCEPTS) || #endif #ifndef BOOST_CONTRACT_NO_EXCEPTS a == check_except #endif ; } #endif #ifndef BOOST_CONTRACT_NO_CONDITIONS explicit virtual_(action_enum a) : action_(a) , failed_(false) #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS , result_type_name_() , result_optional_() #endif {} #endif #ifndef BOOST_CONTRACT_NO_CONDITIONS action_enum action_; bool failed_; #endif #ifndef BOOST_CONTRACT_NO_OLDS std::queue<boost::shared_ptr<void> > old_init_copies_; std::queue<boost::shared_ptr<void> > old_ftor_copies_; #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS boost::any result_ptr_; // Result for virtual and overriding functions. char const* result_type_name_; bool result_optional_; #endif // Friends (used to limit library's public API). #ifndef BOOST_CONTRACT_NO_OLDS friend bool copy_old(virtual_*); friend class old_pointer; #endif #ifndef BOOST_CONTRACT_NO_CONDITIONS BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, /* is_friend = */ 1, OO, RR, FF, CC, AArgs); #endif /** @endcond */ }; } } // namespace #endif // #include guard core/specify.hpp 0000644 00000071036 15125525375 0007670 0 ustar 00 #ifndef BOOST_CONTRACT_SPECIFY_HPP_ #define BOOST_CONTRACT_SPECIFY_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 /** @file Specify preconditions, old values copied at body, postconditions, and exception guarantees Preconditions, old values copied at body, postconditions, and exception guarantees are all optionals but, when they are specified, they need to be specified in that order. */ #include <boost/contract/core/config.hpp> #include <boost/contract/detail/decl.hpp> #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/condition/cond_base.hpp> #include <boost/contract/detail/condition/cond_post.hpp> #include <boost/contract/detail/auto_ptr.hpp> #include <boost/contract/detail/none.hpp> #endif #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ !defined(BOOST_CONTRACT_NO_EXCEPTS) #include <boost/contract/detail/debug.hpp> #endif #include <boost/config.hpp> // NOTE: No inheritance for faster run-times (macros to avoid duplicated code). /* PRIVATE */ /* @cond */ // NOTE: Private copy ops below will force compile-time error is `auto c = ...` // is used instead of `check c = ...` but only up to C++17. C++17 strong copy // elision on function return values prevents this lib from generating a // compile-time error in those cases, but the lib will still generate a run-time // error according with ON_MISSING_CHECK_DECL. Furthermore, on some C++98 // compilers, this private copy ctor gives a warning (because of lack of copy // optimization on those compilers), this warning can be ignored. #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \ private: \ boost::contract::detail::auto_ptr<cond_type > cond_; \ explicit class_type(cond_type* cond) : cond_(cond) {} \ class_type(class_type const& other) : cond_(other.cond_) {} \ class_type& operator=(class_type const& other) { \ cond_ = other.cond_; \ return *this; \ } #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ cond_.release() #else #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \ private: \ class_type() {} \ class_type(class_type const&) {} \ class_type& operator=(class_type const&) { return *this; } #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ /* nothing */ #endif #ifndef BOOST_CONTRACT_NO_PRECONDITIONS #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ cond_->set_pre(f); \ return specify_old_postcondition_except<VirtualResult>( \ BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #else #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \ return specify_old_postcondition_except<VirtualResult>( \ BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #endif #ifndef BOOST_CONTRACT_NO_OLDS #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ cond_->set_old(f); \ return specify_postcondition_except<VirtualResult>( \ BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #else #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \ return specify_postcondition_except<VirtualResult>( \ BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ cond_->set_post(f); \ return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #else #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \ return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #endif #ifndef BOOST_CONTRACT_NO_EXCEPTS #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ cond_->set_except(f); \ return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #else #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \ return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); #endif /* @endcond */ /* CODE */ namespace boost { namespace contract { class virtual_; template<typename VR> class specify_precondition_old_postcondition_except; template<typename VR> class specify_old_postcondition_except; template<typename VR> class specify_postcondition_except; class specify_except; } } namespace boost { namespace contract { /** Used to prevent setting other contract conditions after exception guarantees. This class has no member function so it is used to prevent specifying additional functors to check any other contract. This object is internally constructed by the library when users specify contracts calling @RefFunc{boost::contract::function} and similar functions (that is why this class does not have a public constructor). @see @RefSect{tutorial, Tutorial} */ class specify_nothing { // Privately copyable (as *). public: /** Destruct this object. @b Throws: This is declared @c noexcept(false) since C++11 to allow users to program failure handlers that throw exceptions on contract assertion failures (not the default, see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). */ ~specify_nothing() BOOST_NOEXCEPT_IF(false) {} // No set member function here. /** @cond */ private: BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_nothing, boost::contract::detail::cond_base) // Friends (used to limit library's public API). friend class check; template<typename VR> friend class specify_precondition_old_postcondition_except; template<typename VR> friend class specify_old_postcondition_except; template<typename VR> friend class specify_postcondition_except; friend class specify_except; /** @endcond */ }; /** Allow to specify exception guarantees. Allow to specify the functor this library will call to check exception guarantees. This object is internally constructed by the library when users specify contracts calling @RefFunc{boost::contract::function} and similar functions (that is why this class does not have a public constructor). @see @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ class specify_except { // Privately copyable (as *). public: /** Destruct this object. @b Throws: This is declared @c noexcept(false) since C++11 to allow users to program failure handlers that throw exceptions on contract assertion failures (not the default, see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). */ ~specify_except() BOOST_NOEXCEPT_IF(false) {} /** Allow to specify exception guarantees. @param f Nullary functor called by this library to check exception guarantees @c f(). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::except_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). @return After exception guarantees have been specified, the object returned by this function does not allow to specify any additional contract. */ template<typename F> specify_nothing except( F const& #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } /** @cond */ private: BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_except, boost::contract::detail::cond_base) // Friends (used to limit library's public API). friend class check; template<typename VR> friend class specify_precondition_old_postcondition_except; template<typename VR> friend class specify_old_postcondition_except; template<typename VR> friend class specify_postcondition_except; /** @endcond */ }; /** Allow to specify postconditions or exception guarantees. Allow to specify functors this library will call to check postconditions or exception guarantees. This object is internally constructed by the library when users specify contracts calling @RefFunc{boost::contract::function} and similar functions (that is why this class does not have a public constructor). @see @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template<typename VirtualResult = void> class specify_postcondition_except { // Privately copyable (as *). public: /** Destruct this object. @b Throws: This is declared @c noexcept(false) since C++11 to allow users to program failure handlers that throw exceptions on contract assertion failures (not the default, see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). */ ~specify_postcondition_except() BOOST_NOEXCEPT_IF(false) {} /** Allow to specify postconditions. @param f Functor called by this library to check postconditions @c f() or @c f(result). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::postcondition_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). This functor must be a nullary functor @c f() if @c VirtualResult is @c void, otherwise it must be a unary functor @c f(result) accepting the return value @c result as a parameter of type <c>VirtualResult const&</c> (to avoid extra copies of the return value, or of type @c VirtualResult or <c>VirtualResult const</c> if extra copies of the return value are irrelevant). @return After postconditions have been specified, the object returned by this function allows to optionally specify exception guarantees. */ template<typename F> specify_except postcondition( F const& #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ } /** Allow to specify exception guarantees. @param f Nullary functor called by this library to check exception guarantees @c f(). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::except_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). @return After exception guarantees have been specified, the object returned by this function does not allow to specify any additional contract. */ template<typename F> specify_nothing except( F const& #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } /** @cond */ private: BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( specify_postcondition_except, boost::contract::detail::cond_post<typename boost::contract::detail::none_if_void<VirtualResult>::type> ) // Friends (used to limit library's public API). friend class check; friend class specify_precondition_old_postcondition_except<VirtualResult>; friend class specify_old_postcondition_except<VirtualResult>; /** @endcond */ }; /** Allow to specify old values copied at body, postconditions, and exception guarantees. Allow to specify functors this library will call to copy old values at body, check postconditions, and check exception guarantees. This object is internally constructed by the library when users specify contracts calling @RefFunc{boost::contract::function} and similar functions (that is why this class does not have a public constructor). @see @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template<typename VirtualResult = void> class specify_old_postcondition_except { // Privately copyable (as *). public: /** Destruct this object. @b Throws: This is declared @c noexcept(false) since C++11 to allow users to program failure handlers that throw exceptions on contract assertion failures (not the default, see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). */ ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} /** Allow to specify old values copied at body. It should often be sufficient to initialize old value pointers as soon as they are declared, without using this function (see @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). @param f Nullary functor called by this library @c f() to assign old value copies just before the body is executed but after entry invariants (when they apply) and preconditions are checked. Old value pointers within this functor call are usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. Any exception thrown by a call to this functor will result in this library calling @RefFunc{boost::contract::old_failure} (because old values could not be copied to check postconditions and exception guarantees). This functor should capture old value pointers by references so they can be assigned (all other variables needed to evaluate old value expressions can be captured by (constant) value, or better by (constant) reference to avoid extra copies). @return After old values copied at body have been specified, the object returned by this function allows to optionally specify postconditions and exception guarantees. */ template<typename F> specify_postcondition_except<VirtualResult> old( F const& #if !defined(BOOST_CONTRACT_NO_OLDS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_OLD_IMPL_ } /** Allow to specify postconditions. @param f Functor called by this library to check postconditions @c f() or @c f(result). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::postcondition_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). This functor must be a nullary functor @c f() if @c VirtualResult is @c void, otherwise it must be a unary functor @c f(result) accepting the return value @c result as a parameter of type <c>VirtualResult const&</c> (to avoid extra copies of the return value, or of type @c VirtualResult or <c>VirtualResult const</c> if extra copies of the return value are irrelevant). @return After postconditions have been specified, the object returned by this function allows to optionally specify exception guarantees. */ template<typename F> specify_except postcondition( F const& #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ } /** Allow to specify exception guarantees. @param f Nullary functor called by this library to check exception guarantees @c f(). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::except_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). @return After exception guarantees have been specified, the object returned by this function does not allow to specify any additional contract. */ template<typename F> specify_nothing except( F const& #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } /** @cond */ private: BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( specify_old_postcondition_except, boost::contract::detail::cond_post<typename boost::contract::detail::none_if_void<VirtualResult>::type> ) // Friends (used to limit library's public API). friend class check; friend class specify_precondition_old_postcondition_except<VirtualResult>; template<class C> friend specify_old_postcondition_except<> constructor(C*); template<class C> friend specify_old_postcondition_except<> destructor(C*); /** @endcond */ }; /** Allow to specify preconditions, old values copied at body, postconditions, and exception guarantees. Allow to specify functors this library will call to check preconditions, copy old values at body, check postconditions, and check exception guarantees. This object is internally constructed by the library when users specify contracts calling @RefFunc{boost::contract::function} and similar functions (that is why this class does not have a public constructor). @see @RefSect{tutorial.preconditions, Preconditions}, @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} @tparam VirtualResult Return type of the enclosing function declaring the contract if that is either a virtual or an overriding public function, otherwise this is always @c void. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) */ template< typename VirtualResult /* = void (already in fwd decl from decl.hpp) */ #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN = void #endif > class specify_precondition_old_postcondition_except { // Priv. copyable (as *). public: /** Destruct this object. @b Throws: This is declared @c noexcept(false) since C++11 to allow users to program failure handlers that throw exceptions on contract assertion failures (not the default, see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}). */ ~specify_precondition_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} /** Allow to specify preconditions. @param f Nullary functor called by this library to check preconditions @c f(). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::precondition_failure}). This functor should capture variables by (constant) value, or better by (constant) reference (to avoid extra copies). @return After preconditions have been specified, the object returned by this function allows to optionally specify old values copied at body, postconditions, and exception guarantees. */ template<typename F> specify_old_postcondition_except<VirtualResult> precondition( F const& #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ } /** Allow to specify old values copied at body. It should often be sufficient to initialize old value pointers as soon as they are declared, without using this function (see @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). @param f Nullary functor called by this library @c f() to assign old value copies just before the body is executed but after entry invariants (when they apply) and preconditions are checked. Old value pointers within this functor call are usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. Any exception thrown by a call to this functor will result in this library calling @RefFunc{boost::contract::old_failure} (because old values could not be copied to check postconditions and exception guarantees). This functor should capture old value pointers by references so they can be assigned (all other variables needed to evaluate old value expressions can be captured by (constant) value, or better by (constant) reference to avoid extra copies). @return After old values copied at body have been specified, the object returned by this functions allows to optionally specify postconditions and exception guarantees. */ template<typename F> specify_postcondition_except<VirtualResult> old( F const& #if !defined(BOOST_CONTRACT_NO_OLDS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_OLD_IMPL_ } /** Allow to specify postconditions. @param f Functor called by this library to check postconditions @c f() or @c f(result). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::postcondition_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). This functor must be a nullary functor @c f() if @c VirtualResult is @c void, otherwise it must be a unary functor @c f(result) accepting the return value @c result as a parameter of type <c>VirtualResult const&</c> (to avoid extra copies of the return value, or of type @c VirtualResult or <c>VirtualResult const</c> if extra copies of the return value are irrelevant). @return After postconditions have been specified, the object returned by this function allows to optionally specify exception guarantees. */ template<typename F> specify_except postcondition( F const& #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ } /** Allow to specify exception guarantees. @param f Nullary functor called by this library to check exception guarantees @c f(). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::except_failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). @return After exception guarantees have been specified, the object returned by this function does not allow to specify any additional contract. */ template<typename F> specify_nothing except( F const& #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ defined(BOOST_CONTRACT_DETAIL_DOXYGEN) f #endif // Else, no name (avoid unused param warning). ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } /** @cond */ private: BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( specify_precondition_old_postcondition_except, boost::contract::detail::cond_post<typename boost::contract::detail::none_if_void<VirtualResult>::type> ) // Friends (used to limit library's public API). friend class check; friend specify_precondition_old_postcondition_except<> function(); template<class C> friend specify_precondition_old_postcondition_except<> public_function(); template<class C> friend specify_precondition_old_postcondition_except<> public_function(C*); template<class C> friend specify_precondition_old_postcondition_except<> public_function( virtual_*, C*); template<typename VR, class C> friend specify_precondition_old_postcondition_except<VR> public_function( virtual_*, VR&, C*); BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1, O, VR, F, C, Args, v, r, f, obj, args) /** @endcond */ }; } } // namespace #endif // #include guard core/exception.hpp 0000644 00000102737 15125525375 0010227 0 ustar 00 #ifndef BOOST_CONTRACT_EXCEPTION_HPP_ #define BOOST_CONTRACT_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 /** @file Handle contract assertion failures. */ // IMPORTANT: Included by contract_macro.hpp so trivial headers only. #include <boost/contract/core/config.hpp> #include <boost/contract/detail/declspec.hpp> // No compile-time overhead. #include <boost/function.hpp> #include <boost/config.hpp> #include <exception> #include <string> // NOTE: This code should not change (not even its impl) based on the // CONTRACT_NO_... macros. For example, preconditions_failure() should still // all the set precondition failure handler even when NO_PRECONDITIONS is // #defined, because user code might explicitly call precondition_failure() // (for whatever reason...). Otherwise, the public API of this lib will change. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Needed for `std::` prefix to show (but removed via `EXCLUDE_SYMBOLS=std`). namespace std { class exception {}; class bad_cast {}; } #endif namespace boost { namespace contract { /** Public base class for all exceptions directly thrown by this library. This class does not inherit from @c std::exception because exceptions deriving from this class will do that (inheriting from @c std::exception, @c std::bad_cast, etc.). @see @RefClass{boost::contract::assertion_failure}, @RefClass{boost::contract::bad_virtual_result_cast}, etc. */ class BOOST_CONTRACT_DETAIL_DECLSPEC exception { public: /** Destruct this object. @b Throws: This is declared @c noexcept (or @c throw() before C++11). */ virtual ~exception() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; }; #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable: 4275) // Bases w/o DLL spec (bad_cast, etc). #pragma warning(disable: 4251) // Members w/o DLL spec (string for what_). #endif /** Exception thrown when inconsistent return values are passed to overridden virtual public functions. This exception is thrown when programmers pass to this library return value parameters for public function overrides in derived classes that are not consistent with the return type parameter passed for the virtual public function being overridden from the base classes. This allows this library to give more descriptive error messages in such cases of misuse. This exception is internally thrown by this library and programmers should not need to throw it from user code. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} */ class BOOST_CONTRACT_DETAIL_DECLSPEC bad_virtual_result_cast : // Copy (as str). public std::bad_cast, public boost::contract::exception { public: /** Construct this object with the name of the from- and to- result types. @param from_type_name Name of the from-type (source of the cast). @param to_type_name Name of the to-type (destination of the cast). */ explicit bad_virtual_result_cast(char const* from_type_name, char const* to_type_name); /** Destruct this object. @b Throws: This is declared @c noexcept (or @c throw() before C++11). */ virtual ~bad_virtual_result_cast() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; /** Description for this error (containing both from- and to- type names). @b Throws: This is declared @c noexcept (or @c throw() before C++11). */ virtual char const* what() const /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; /** @cond */ private: std::string what_; /** @endcond */ }; /** Exception typically used to report a contract assertion failure. This exception is thrown by code expanded by @RefMacro{BOOST_CONTRACT_ASSERT} (but it can also be thrown by user code programmed manually without that macro). This exception is typically used to report contract assertion failures because it contains detailed information about the file name, line number, and source code of the asserted condition (so it can be used by this library to provide detailed error messages when handling contract assertion failures). However, any other exception can be used to report a contract assertion failure (including user-defined exceptions). This library will call the appropriate contract failure handler function (@RefFunc{boost::contract::precondition_failure}, etc.) when this or any other exception is thrown while checking contracts (by default, these failure handler functions print an error message to @c std::cerr and terminate the program, but they can be customized to take any other action). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} */ class BOOST_CONTRACT_DETAIL_DECLSPEC assertion_failure : // Copy (as str, etc.). public std::exception, public boost::contract::exception { public: /** Construct this object with file name, line number, and source code text of an assertion condition (all optional). This constructor can also be used to specify no information (default constructor), or to specify only file name and line number but not source code text (because of the parameter default values). @param file Name of the file containing the assertion (usually set using <c>__FILE__</c>). @param line Number of the line containing the assertion (usually set using <c>__LINE__</c>). @param code Text listing the source code of the assertion condition. */ explicit assertion_failure(char const* file = "", unsigned long line = 0, char const* code = ""); /** Construct this object only with the source code text of the assertion condition. @param code Text listing the source code of the assertion condition. */ explicit assertion_failure(char const* code); /** Destruct this object. @b Throws: This is declared @c noexcept (or @c throw() before C++11). */ virtual ~assertion_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; /** String describing the failed assertion. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A string formatted similarly to the following: <c>assertion "`code()`" failed: file "`file()`", line \`line()\`</c> (where `` indicate execution quotes). File, line, and code will be omitted from this string if they were not specified when constructing this object. */ virtual char const* what() const /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; /** Name of the file containing the assertion. @return File name as specified at construction (or @c "" if no file was specified). */ char const* file() const; /** Number of the line containing the assertion. @return Line number as specified at construction (or @c 0 if no line number was specified). */ unsigned long line() const; /** Text listing the source code of the assertion condition. @return Assertion condition source code as specified at construction (or @c "" if no source code text was specified). */ char const* code() const; /** @cond */ private: void init(); char const* file_; unsigned long line_; char const* code_; std::string what_; /** @endcond */ }; #ifdef BOOST_MSVC #pragma warning(pop) #endif /** Indicate the kind of operation where the contract assertion failed. This is passed as a parameter to the assertion failure handler functions. For example, it might be necessary to know in which operation an assertion failed to make sure exceptions are never thrown from destructors, not even when contract failure handlers are programmed by users to throw exceptions instead of terminating the program. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure} */ enum from { /** Assertion failed when checking contracts for constructors. */ from_constructor, /** Assertion failed when checking contracts for destructors . */ from_destructor, /** Assertion failed when checking contracts for functions (members or not, public or not). */ from_function }; /** Type of assertion failure handler functions (with @c from parameter). Assertion failure handler functions specified by this type must be functors returning @c void and taking a single parameter of type @RefEnum{boost::contract::from}. For example, this is used to specify contract failure handlers for class invariants, preconditions, postconditions, and exception guarantees. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure} */ typedef boost::function<void (from)> from_failure_handler; /** Type of assertion failure handler functions (without @c from parameter). Assertion failure handler functions specified by this type must be nullary functors returning @c void. For example, this is used to specify contract failure handlers for implementation checks. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure} */ typedef boost::function<void ()> failure_handler; /** @cond */ namespace exception_ { // Check failure. BOOST_CONTRACT_DETAIL_DECLSPEC failure_handler const& set_check_failure_unlocked(failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC failure_handler const& set_check_failure_locked(failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC failure_handler get_check_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC failure_handler get_check_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void check_failure_unlocked() /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void check_failure_locked() /* can throw */; // Precondition failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_pre_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_pre_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_pre_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_pre_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void pre_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void pre_failure_locked(from where) /* can throw */; // Postcondition failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_post_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_post_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_post_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_post_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void post_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void post_failure_locked(from where) /* can throw */; // Except failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_except_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_except_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_except_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_except_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void except_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void except_failure_locked(from where) /* can throw */; // Old-copy failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_old_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_old_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_old_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_old_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void old_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void old_failure_locked(from where) /* can throw */; // Entry invariant failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_entry_inv_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_entry_inv_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_entry_inv_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_entry_inv_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void entry_inv_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void entry_inv_failure_locked(from where) /* can throw */; // Exit invariant failure. BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const& set_exit_inv_failure_unlocked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler const&set_exit_inv_failure_locked( from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_exit_inv_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC from_failure_handler get_exit_inv_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW; BOOST_CONTRACT_DETAIL_DECLSPEC void exit_inv_failure_unlocked(from where) /* can throw */; BOOST_CONTRACT_DETAIL_DECLSPEC void exit_inv_failure_locked(from where) /* can throw */; } /** @endcond */ } } // namespace /** @cond */ #ifdef BOOST_CONTRACT_HEADER_ONLY // NOTE: This header must be included in the middle of this file (because // its impl depends on both from and assert_failure types). This is not // ideal, but it is better than splitting this file into multiple // independent ones because all content in this file is logically related // from the user prospective. #include <boost/contract/detail/inlined/core/exception.hpp> #endif /** @endcond */ namespace boost { namespace contract { // Following must be inline for static linkage (no DYN_LINK and no HEADER_ONLY). /** Set failure handler for implementation checks. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.implementation_checks, Implementation Checks} */ inline failure_handler const& set_check_failure(failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_check_failure_locked(f); #else return exception_::set_check_failure_unlocked(f); #endif } /** Return failure handler currently set for implementation checks. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.implementation_checks, Implementation Checks} */ inline failure_handler get_check_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_check_failure_locked(); #else return exception_::get_check_failure_unlocked(); #endif } /** Call failure handler for implementation checks. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on implementation check failures (not the default). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.implementation_checks, Implementation Checks} */ inline void check_failure() /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::check_failure_locked(); #else exception_::check_failure_unlocked(); #endif } /** Set failure handler for preconditions. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline from_failure_handler const& set_precondition_failure(from_failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_pre_failure_locked(f); #else return exception_::set_pre_failure_unlocked(f); #endif } /** Return failure handler currently set for preconditions. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline from_failure_handler get_precondition_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_pre_failure_locked(); #else return exception_::get_pre_failure_unlocked(); #endif } /** Call failure handler for preconditions. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). @param where Operation that failed the contract assertion (when this function is called by this library, this parameter will never be @c from_destructor because destructors do not have preconditions). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline void precondition_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::pre_failure_locked(where); #else exception_::pre_failure_unlocked(where); #endif } /** Set failure handler for postconditions. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline from_failure_handler const& set_postcondition_failure( from_failure_handler const& f ) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_post_failure_locked(f); #else return exception_::set_post_failure_unlocked(f); #endif } /** Return failure handler currently set for postconditions. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline from_failure_handler get_postcondition_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_post_failure_locked(); #else return exception_::get_post_failure_unlocked(); #endif } /** Call failure handler for postconditions. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). @param where Operation that failed the contract assertion (e.g., this might be useful to program failure handler functors that never throw from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline void postcondition_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::post_failure_locked(where); #else exception_::post_failure_unlocked(where); #endif } /** Set failure handler for exception guarantees. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline from_failure_handler const& set_except_failure(from_failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_except_failure_locked(f); #else return exception_::set_except_failure_unlocked(f); #endif } /** Return failure handler currently set for exception guarantees. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline from_failure_handler get_except_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_except_failure_locked(); #else return exception_::get_except_failure_unlocked(); #endif } /** Call failure handler for exception guarantees. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default), however: @warning When this failure handler is called there is already an active exception (the one that caused the exception guarantees to be checked in the first place). Therefore, programming this failure handler to throw yet another exception will force C++ to automatically terminate the program. @param where Operation that failed the contract assertion. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline void except_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::except_failure_locked(where); #else exception_::except_failure_unlocked(where); #endif } /** Set failure handler for old values copied at body. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body} */ inline from_failure_handler const& set_old_failure(from_failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_old_failure_locked(f); #else return exception_::set_old_failure_unlocked(f); #endif } /** Return failure handler currently set for old values copied at body. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body} */ inline from_failure_handler get_old_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_old_failure_locked(); #else return exception_::get_old_failure_unlocked(); #endif } /** Call failure handler for old values copied at body. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). @param where Operation that failed the old value copy (e.g., this might be useful to program failure handler functors that never throw from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body} */ inline void old_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::old_failure_locked(where); #else exception_::old_failure_unlocked(where); #endif } /** Set failure handler for class invariants at entry. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler const& set_entry_invariant_failure( from_failure_handler const& f )/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_entry_inv_failure_locked(f); #else return exception_::set_entry_inv_failure_unlocked(f); #endif } /** Return failure handler currently set for class invariants at entry. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler get_entry_invariant_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_entry_inv_failure_locked(); #else return exception_::get_entry_inv_failure_unlocked(); #endif } /** Call failure handler for class invariants at entry. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). @param where Operation that failed the contract assertion (e.g., this might be useful to program failure handler functors that never throw from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline void entry_invariant_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::entry_inv_failure_locked(where); #else return exception_::entry_inv_failure_unlocked(where); #endif } /** Set failure handler for class invariants at exit. Set a new failure handler and returns it. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler const& set_exit_invariant_failure( from_failure_handler const& f ) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::set_exit_inv_failure_locked(f); #else return exception_::set_exit_inv_failure_unlocked(f); #endif } /** Return failure handler currently set for class invariants at exit. This is often called only internally by this library. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @return A copy of the failure handler currently set. @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler get_exit_invariant_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS return exception_::get_exit_inv_failure_locked(); #else return exception_::get_exit_inv_failure_unlocked(); #endif } /** Call failure handler for class invariants at exit. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). @param where Operation that failed the contract assertion (e.g., this might be useful to program failure handler functors that never throw from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline void exit_invariant_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS exception_::exit_inv_failure_locked(where); #else exception_::exit_inv_failure_unlocked(where); #endif } /** Set failure handler for class invariants (at both entry and exit). This is provided for convenience and it is equivalent to call both @RefFunc{boost::contract::set_entry_invariant_failure} and @RefFunc{boost::contract::set_exit_invariant_failure} with the same functor parameter @p f. @b Throws: This is declared @c noexcept (or @c throw() before C++11). @param f New failure handler functor to set for both entry and exit invariants. @return Same failure handler functor @p f passed as parameter (e.g., for concatenating function calls). @see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */ from_failure_handler const& set_invariant_failure(from_failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; } } // namespace #endif // #include guard core/constructor_precondition.hpp 0000644 00000010600 15125525375 0013356 0 ustar 00 #ifndef BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_HPP_ #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_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 /** @file Program preconditions for constructors. */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #ifndef BOOST_CONTRACT_NO_PRECONDITIONS #include <boost/contract/core/exception.hpp> #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION #include <boost/contract/detail/checking.hpp> #endif #endif namespace boost { namespace contract { /** Program preconditions for constructors. This class must be the very first base of the class declaring the constructor for which preconditions are programmed (that way constructor arguments can be checked by preconditions even before they are used to initialize other base classes): @code class u #define BASES private boost::contract::constructor_precondition<u>, \ public b : BASES { friend class boost::contract::access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES public: explicit u(unsigned x) : boost::contract::constructor_precondition<u>([&] { BOOST_CONTRACT_ASSERT(x != 0); ... }), b(1.0 / float(x)) { ... } ... }; @endcode User-defined classes should inherit privately from this class (to not alter the public interface of user-defined classes). In addition, this class should never be declared as a virtual base (because virtual bases are initialized only once across the entire inheritance hierarchy preventing preconditions of other base classes from being checked). This class cannot be used this way in a @c union because unions cannot have base classes in C++. Instead, this class is used in a @c union to declare a local object within the constructor definition just before @RefFunc{boost::contract::constructor} is used (see @RefSect{extras.unions, Unions}). @see @RefSect{tutorial.constructors, Constructors} @tparam Class The class type of the constructor for which preconditions are being programmed. */ template<class Class> class constructor_precondition { // Copyable (has no data). public: /** Construct this object without specifying constructor preconditions. This is implicitly called for those constructors of the contracted class that do not specify preconditions. @note The implementation of this library is optimized so that calling this default constructor should amount to negligible compile-time and run-time overheads (likely to be optimized away completely by most compilers). */ constructor_precondition() {} /** Construct this object specifying constructor preconditions. @param f Nullary functor called by this library to check constructor preconditions @c f(). Assertions within this functor call are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract failure (and will result in this library calling @RefFunc{boost::contract::precondition_failure}). This functor should capture variables by (constant) value, or better by (constant) reference to avoid extra copies. */ template<typename F> explicit constructor_precondition(F const& f) { #ifndef BOOST_CONTRACT_NO_PRECONDITIONS try { #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION if(boost::contract::detail::checking::already()) return; #ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION boost::contract::detail::checking k; #endif #endif f(); } catch(...) { precondition_failure(from_constructor); } #endif } // Default copy operations (so user's derived classes can be copied, etc.). }; } } // namespace #endif // #include guard core/access.hpp 0000644 00000014704 15125525375 0007466 0 ustar 00 #ifndef BOOST_CONTRACT_ACCESS_HPP_ #define BOOST_CONTRACT_ACCESS_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 /** @file Allow to declare invariants, base types, etc all as private members. */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. #include <boost/contract/core/config.hpp> #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/decl.hpp> #include <boost/contract/detail/type_traits/mirror.hpp> #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS #include <boost/contract/detail/debug.hpp> #include <boost/function_types/property_tags.hpp> #include <boost/mpl/vector.hpp> #endif namespace boost { namespace contract { #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) class virtual_; namespace detail { BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, /* is_friend = */ 0, OO, RR, FF, CC, AArgs); } #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS namespace detail { template<typename RR, class CC> class cond_inv; } #endif /** Declare this class as friend to program invariants and base types as private members. Declare this class a friend of the user-defined class specifying the contracts and then invariant functions and the base types @c typedef can be declared as non-public members: @code class u #define BASES public b, private w : BASES { friend class boost::contract::access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Private. #undef BASES void invariant() const { ... } // Private (same for static and volatile). public: ... }; @endcode In real code, programmers will likely chose to declare this class as friend so to fully control public interfaces of their user-defined classes (this is not extensively done in the examples of this documentation only for brevity). This class is not intended to be directly used by programmers a part from being declared as @c friend (and that is why this class does not have any public member and it is not copyable). @warning Not declaring this class friend of user-defined classes will cause compiler errors on some compilers (e.g., MSVC) because the private members needed to check the contracts will not be accessible. On other compilers (e.g., GCC and CLang), the private access will instead fail SFINAE and no compiler error will be reported while invariants and subcontracting will be silently skipped at run-time. Therefore, programmers must make sure to either declare this class as friend or to always declare invariant functions and base types @c typedef as public members. @see @RefSect{advanced.access_specifiers, Access Specifiers} */ class access { // Non-copyable (see below). /** @cond */ private: // No public APIs (so users cannot use it directly by mistake). access(); // Should never be constructed (not even internally). ~access(); // No boost::noncopyable to avoid its overhead when contracts disabled. access(access&); access& operator=(access&); #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(has_base_types, BOOST_CONTRACT_BASES_TYPEDEF) template<class C> struct base_types_of { typedef typename C::BOOST_CONTRACT_BASES_TYPEDEF type; }; #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( has_static_invariant_f, BOOST_CONTRACT_STATIC_INVARIANT_FUNC) BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION( has_static_invariant_s, BOOST_CONTRACT_STATIC_INVARIANT_FUNC) template<class C> struct has_static_invariant : has_static_invariant_s<C, void, boost::mpl::vector<> > {}; template<class C> static void static_invariant() { C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC(); } template<class C> class static_invariant_addr { // Class so to pass it as tparam. typedef void (*func_ptr)(); public: static func_ptr apply() { return &C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC; } }; BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( has_invariant_f, BOOST_CONTRACT_INVARIANT_FUNC) BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION( has_invariant_s, BOOST_CONTRACT_INVARIANT_FUNC) template<class C> struct has_cv_invariant : has_invariant_f<C, void, boost::mpl::vector<>, boost::function_types::cv_qualified> {}; template<class C> struct has_const_invariant : has_invariant_f<C, void, boost::mpl:: vector<>, boost::function_types::const_qualified> {}; template<class C> static void cv_invariant(C const volatile* obj) { BOOST_CONTRACT_DETAIL_DEBUG(obj); obj->BOOST_CONTRACT_INVARIANT_FUNC(); } template<class C> static void const_invariant(C const* obj) { BOOST_CONTRACT_DETAIL_DEBUG(obj); obj->BOOST_CONTRACT_INVARIANT_FUNC(); } #endif // Friends (used to limit library's public API). // NOTE: Using friends here and in all other places in this library // does not increase compilation times (I experimented replacing all // friends with public and got the same compilation times). #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, /* is_friend = */ 1, OO, RR, FF, CC, AArgs); BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1, OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs) #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS template<typename RR, class CC> friend class boost::contract::detail::cond_inv; #endif /** @endcond */ }; } } // namespace #endif // #include guard assert.hpp 0000644 00000014137 15125525375 0006576 0 ustar 00 #ifndef BOOST_CONTRACT_ASSERT_HPP_ #define BOOST_CONTRACT_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 /** @file Assert contract conditions. */ #include <boost/contract/core/config.hpp> #include <boost/contract/detail/noop.hpp> #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Preferred way to assert contract conditions. Any exception thrown from within a contract (preconditions, postconditions, exception guarantees, old value copies at body, class invariants, etc.) is interpreted by this library as a contract failure. Therefore, users can program contract assertions manually throwing an exception when an asserted condition is checked to be @c false (this library will then call the appropriate contract failure handler @RefFunc{boost::contract::precondition_failure}, etc.). However, it is preferred to use this macro because it expands to code that throws @RefClass{boost::contract::assertion_failure} with the correct assertion file name (using <c>__FILE__</c>), line number (using <c>__LINE__</c>), and asserted condition code so to produce informative error messages (C++11 <c>__func__</c> is not used here because in most cases it will simply expand to the internal compiler name of the lambda function used to program the contract conditions adding no specificity to the error message). @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined by this library. @see @RefSect{tutorial.preconditions, Preconditions}, @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exceptions Guarantees}, @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param cond Boolean contract condition to check. (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_ASSERT((cond)) will always work.) */ // This must be an expression (a trivial one so the compiler can optimize it // away). It cannot an empty code block `{}`, etc. otherwise code like // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL. #define BOOST_CONTRACT_ASSERT(cond) #elif !defined(BOOST_CONTRACT_NO_ALL) #include <boost/contract/detail/assert.hpp> #define BOOST_CONTRACT_ASSERT(cond) \ BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */ #else // This must be an expression (a trivial one so the compiler can optimize it // away). It cannot an empty code block `{}`, etc. otherwise code like // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL. #define BOOST_CONTRACT_ASSERT(cond) \ BOOST_CONTRACT_DETAIL_NOOP #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Preferred way to assert contract conditions that are computationally expensive, at least compared to the computational cost of executing the function body. The asserted condition will always be compiled and validated syntactically, but it will not be checked at run-time unless @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default). This macro is defined by code equivalent to: @code #ifdef BOOST_CONTRACT_AUDITS #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_ASSERT(cond) #else #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_ASSERT(true || cond) #endif @endcode @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined by this library. If there is a need, programmers are free to implement their own assertion levels defining macros similar to the one above. @see @RefSect{extras.assertion_levels, Assertion Levels}, @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param cond Boolean contract condition to check. (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.) */ #define BOOST_CONTRACT_ASSERT_AUDIT(cond) #elif defined(BOOST_CONTRACT_AUDITS) #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_ASSERT(cond) #else #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif /** Preferred way to document in the code contract conditions that are computationally prohibitive, at least compared to the computational cost of executing the function body. The asserted condition will always be compiled and validated syntactically, but it will never be checked at run-time. This macro is defined by code equivalent to: @code #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ BOOST_CONTRACT_ASSERT(true || cond) @endcode @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined by this library. If there is a need, programmers are free to implement their own assertion levels defining macros similar to the one above. @see @RefSect{extras.assertion_levels, Assertion Levels}, @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param cond Boolean contract condition to check. (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis and @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.) */ #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif // #include guard constructor.hpp 0000644 00000007336 15125525375 0007665 0 ustar 00 #ifndef BOOST_CONTRACT_CONSTRUCTOR_HPP_ #define BOOST_CONTRACT_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 /** @file Program contracts for constructors. */ #include <boost/contract/core/config.hpp> #include <boost/contract/core/specify.hpp> #include <boost/contract/core/access.hpp> #include <boost/contract/core/constructor_precondition.hpp> #if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include <boost/contract/detail/operation/constructor.hpp> #endif namespace boost { namespace contract { /** Program contracts for constructors. This is used to specify postconditions, exception guarantees, old value copies at body, and check class invariants for constructors (see @RefClass{boost::contract::constructor_precondition} to specify preconditions for constructors): @code class u { friend class boost::contract:access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: u(...) { boost::contract::old_ptr<old_type> old_var; boost::contract::check c = boost::contract::constructor(this) // No `.precondition` (use `constructor_precondition` instead). .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Constructor body. } ... }; @endcode For optimization, this can be omitted for constructors that do not have postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.constructors, Constructors} @param obj The object @c this from the scope of the enclosing constructor declaring the contract. (Constructors check all class invariants, including static and volatile invariants, see @RefSect{tutorial.class_invariants, Class Invariants} and @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam Class The type of the class containing the constructor declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the constructor body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template<class Class> specify_old_postcondition_except<> constructor(Class* obj) { // Must #if also on ..._PRECONDITIONS here because specify_... is generic. #if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) return specify_old_postcondition_except<>( new boost::contract::detail::constructor<Class>(obj)); #else return specify_old_postcondition_except<>(); #endif } } } // namespace #endif // #include guard
| ver. 1.6 |
Github
|
.
| PHP 8.2.30 | ??????????? ?????????: 0.06 |
proxy
|
phpinfo
|
???????????