1 2 #ifndef BOOST_CONTRACT_DETAIL_COND_POST_HPP_ 3 #define BOOST_CONTRACT_DETAIL_COND_POST_HPP_ 4 5 // Copyright (C) 2008-2018 Lorenzo Caminiti 6 // Distributed under the Boost Software License, Version 1.0 (see accompanying 7 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 8 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 9 10 #include <boost/contract/core/exception.hpp> 11 #include <boost/contract/core/config.hpp> 12 #include <boost/contract/detail/condition/cond_base.hpp> 13 #include <boost/contract/detail/none.hpp> 14 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 15 #include <boost/contract/detail/type_traits/optional.hpp> 16 #include <boost/optional.hpp> 17 #include <boost/function.hpp> 18 #include <boost/type_traits/remove_reference.hpp> 19 #include <boost/mpl/if.hpp> 20 #include <boost/preprocessor/facilities/empty.hpp> 21 #endif 22 23 /* PRIVATE */ 24 25 #define BOOST_CONTRACT_DETAIL_COND_POST_DEF_( \ 26 result_type, result_param, ftor_type, ftor_var, ftor_call) \ 27 public: \ 28 template<typename F> \ 29 void set_post(F const& f) { ftor_var = f; } \ 30 \ 31 protected: \ 32 void check_post(result_type const& result_param) { \ 33 if(failed()) return; \ 34 try { if(ftor_var) { ftor_call; } } \ 35 catch(...) { fail(&boost::contract::postcondition_failure); } \ 36 } \ 37 \ 38 private: \ 39 boost::function<ftor_type> ftor_var; /* Boost.Func for lambdas, etc. */ 40 41 /* CODE */ 42 43 namespace boost { namespace contract { namespace detail { 44 45 template<typename VR> 46 class cond_post : public cond_base { // Non-copyable base. 47 public: cond_post(boost::contract::from from)48 explicit cond_post(boost::contract::from from) : cond_base(from) {} 49 50 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 51 private: typedef typename boost::mpl::if_<is_optional<VR>, 52 boost::optional<typename boost::remove_reference<typename 53 optional_value_type<VR>::type>::type const&> const& 54 , 55 VR const& 56 >::type r_type; 57 58 BOOST_CONTRACT_DETAIL_COND_POST_DEF_( 59 r_type, 60 r, 61 void (r_type), 62 // Won't raise this error if NO_POST (for optimization). 63 BOOST_CONTRACT_ERROR_postcondition_result_parameter_required, 64 BOOST_CONTRACT_ERROR_postcondition_result_parameter_required(r) 65 ) 66 #endif 67 }; 68 69 template<> 70 class cond_post<none> : public cond_base { // Non-copyable base. 71 public: cond_post(boost::contract::from from)72 explicit cond_post(boost::contract::from from) : cond_base(from) {} 73 74 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 75 BOOST_CONTRACT_DETAIL_COND_POST_DEF_( 76 none, 77 /* r */ BOOST_PP_EMPTY(), 78 void (), 79 // Won't raise this error if NO_POST (for optimization). 80 BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed, 81 BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed() 82 ) 83 #endif 84 }; 85 86 } } } // namespace 87 88 #endif // #include guard 89 90