cond_post.hpp 2.9 KB

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