constructor.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #ifndef BOOST_CONTRACT_CONSTRUCTOR_HPP_
  2. #define BOOST_CONTRACT_CONSTRUCTOR_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 constructors.
  9. */
  10. #include <boost/contract/core/config.hpp>
  11. #include <boost/contract/core/specify.hpp>
  12. #include <boost/contract/core/access.hpp>
  13. #include <boost/contract/core/constructor_precondition.hpp>
  14. #if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
  15. !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
  16. defined(BOOST_CONTRACT_STATIC_LINK)
  17. #include <boost/contract/detail/operation/constructor.hpp>
  18. #endif
  19. namespace boost { namespace contract {
  20. /**
  21. Program contracts for constructors.
  22. This is used to specify postconditions, exception guarantees, old value copies
  23. at body, and check class invariants for constructors (see
  24. @RefClass{boost::contract::constructor_precondition} to specify preconditions
  25. for constructors):
  26. @code
  27. class u {
  28. friend class boost::contract:access;
  29. void invariant() const { // Optional (as for static and volatile).
  30. BOOST_CONTRACT_ASSERT(...);
  31. ...
  32. }
  33. public:
  34. u(...) {
  35. boost::contract::old_ptr<old_type> old_var;
  36. boost::contract::check c = boost::contract::constructor(this)
  37. // No `.precondition` (use `constructor_precondition` instead).
  38. .old([&] { // Optional.
  39. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  40. ...
  41. })
  42. .postcondition([&] { // Optional.
  43. BOOST_CONTRACT_ASSERT(...);
  44. ...
  45. })
  46. .except([&] { // Optional.
  47. BOOST_CONTRACT_ASSERT(...);
  48. ...
  49. })
  50. ;
  51. ... // Constructor body.
  52. }
  53. ...
  54. };
  55. @endcode
  56. For optimization, this can be omitted for constructors that do not have
  57. postconditions and exception guarantees, within classes that have no invariants.
  58. @see @RefSect{tutorial.constructors, Constructors}
  59. @param obj The object @c this from the scope of the enclosing constructor
  60. declaring the contract.
  61. (Constructors check all class invariants, including static and
  62. volatile invariants, see @RefSect{tutorial.class_invariants,
  63. Class Invariants} and
  64. @RefSect{extras.volatile_public_functions,
  65. Volatile Public Functions}).
  66. @tparam Class The type of the class containing the constructor declaring the
  67. contract.
  68. (Usually this template parameter is automatically deduced by C++
  69. and it does not need to be explicitly specified by programmers.)
  70. @return The result of this function must be assigned to a variable of type
  71. @RefClass{boost::contract::check} declared explicitly (i.e., without
  72. using C++11 @c auto declarations) and locally just before the code of
  73. the constructor body (otherwise this library will generate a run-time
  74. error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
  75. */
  76. template<class Class>
  77. specify_old_postcondition_except<> constructor(Class* obj) {
  78. // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
  79. #if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
  80. !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
  81. defined(BOOST_CONTRACT_STATIC_LINK)
  82. return specify_old_postcondition_except<>(
  83. new boost::contract::detail::constructor<Class>(obj));
  84. #else
  85. return specify_old_postcondition_except<>();
  86. #endif
  87. }
  88. } } // namespace
  89. #endif // #include guard