function.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #ifndef BOOST_CONTRACT_FUNCTION_HPP_
  2. #define BOOST_CONTRACT_FUNCTION_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. /** @file
  8. Program contracts for (non-public) functions.
  9. */
  10. #include <boost/contract/core/config.hpp>
  11. #include <boost/contract/core/specify.hpp>
  12. #if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
  13. !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
  14. defined(BOOST_CONTRACT_STATIC_LINK)
  15. #include <boost/contract/detail/operation/function.hpp>
  16. #endif
  17. namespace boost { namespace contract {
  18. /**
  19. Program contracts for non-member, private and protected functions.
  20. This is used to specify preconditions, postconditions, exception guarantees, and
  21. old value copies at body for non-member, private and protected functions (these
  22. functions never check class invariants, see
  23. @RefSect{contract_programming_overview.function_calls, Function Calls}):
  24. @code
  25. void f(...) {
  26. boost::contract::old_ptr<old_type> old_var;
  27. boost::contract::check c = boost::contract::function()
  28. .precondition([&] { // Optional.
  29. BOOST_CONTRACT_ASSERT(...);
  30. ...
  31. })
  32. .old([&] { // Optional.
  33. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  34. ...
  35. })
  36. .postcondition([&] { // Optional.
  37. BOOST_CONTRACT_ASSERT(...);
  38. ...
  39. })
  40. .except([&] { // Optional.
  41. BOOST_CONTRACT_ASSERT(...);
  42. ...
  43. })
  44. ;
  45. ... // Function body.
  46. }
  47. @endcode
  48. This can be used also to program contracts in implementation code for lambda
  49. functions, loops, and arbitrary blocks of code.
  50. For optimization, this can be omitted for code that does not have preconditions,
  51. postconditions, and exception guarantees.
  52. @see @RefSect{tutorial.non_member_functions, Non-Member Functions},
  53. @RefSect{advanced.private_and_protected_functions,
  54. Private and Protected Functions},
  55. @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__,
  56. Lambdas\, Loops\, Code Blocks}
  57. @return The result of this function must be assigned to a variable of type
  58. @RefClass{boost::contract::check} declared explicitly (i.e., without
  59. using C++11 @c auto declarations) and locally just before the code of
  60. the function body (otherwise this library will generate a run-time
  61. error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
  62. */
  63. inline specify_precondition_old_postcondition_except<> function() {
  64. // Must #if also on ..._INVARIANTS here because specify_... is generic.
  65. #if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
  66. !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
  67. defined(BOOST_CONTRACT_STATIC_LINK)
  68. return specify_precondition_old_postcondition_except<>(
  69. new boost::contract::detail::function());
  70. #else
  71. return specify_precondition_old_postcondition_except<>();
  72. #endif
  73. }
  74. } } // namespace
  75. #endif // #include guard