assert.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #ifndef BOOST_CONTRACT_ASSERT_HPP_
  2. #define BOOST_CONTRACT_ASSERT_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. Assert contract conditions.
  9. */
  10. #include <boost/contract/core/config.hpp>
  11. #include <boost/contract/detail/noop.hpp>
  12. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  13. /**
  14. Preferred way to assert contract conditions.
  15. Any exception thrown from within a contract (preconditions, postconditions,
  16. exception guarantees, old value copies at body, class invariants, etc.) is
  17. interpreted by this library as a contract failure.
  18. Therefore, users can program contract assertions manually throwing an
  19. exception when an asserted condition is checked to be @c false (this
  20. library will then call the appropriate contract failure handler
  21. @RefFunc{boost::contract::precondition_failure}, etc.).
  22. However, it is preferred to use this macro because it expands to
  23. code that throws @RefClass{boost::contract::assertion_failure} with the
  24. correct assertion file name (using <c>__FILE__</c>), line number (using
  25. <c>__LINE__</c>), and asserted condition code so to produce informative
  26. error messages.
  27. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
  28. and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
  29. predefined by this library.
  30. @see @RefSect{tutorial.preconditions, Preconditions},
  31. @RefSect{tutorial.postconditions, Postconditions},
  32. @RefSect{tutorial.exception_guarantees, Exceptions Guarantees},
  33. @RefSect{tutorial.class_invariants, Class Invariants}
  34. @param cond Boolean contract condition to check.
  35. (This is not a variadic macro parameter so any comma it might
  36. contain must be protected by round parenthesis,
  37. @c BOOST_CONTRACT_ASSERT((cond)) will always work.)
  38. */
  39. // This must be an expression (a trivial one so the compiler can optimize it
  40. // away). It cannot an empty code block `{}`, etc. otherwise code like
  41. // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
  42. #define BOOST_CONTRACT_ASSERT(cond)
  43. #elif !defined(BOOST_CONTRACT_NO_ALL)
  44. #include <boost/contract/detail/assert.hpp>
  45. #define BOOST_CONTRACT_ASSERT(cond) \
  46. BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */
  47. #else
  48. // This must be an expression (a trivial one so the compiler can optimize it
  49. // away). It cannot an empty code block `{}`, etc. otherwise code like
  50. // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
  51. #define BOOST_CONTRACT_ASSERT(cond) \
  52. BOOST_CONTRACT_DETAIL_NOOP
  53. #endif
  54. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  55. /**
  56. Preferred way to assert contract conditions that are computationally
  57. expensive, at least compared to the cost of executing the function body.
  58. The asserted condition will always be compiled and validated syntactically,
  59. but it will not be checked at run-time unless
  60. @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default).
  61. This macro is defined by code equivalent to:
  62. @code
  63. #ifdef BOOST_CONTRACT_AUDITS
  64. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  65. BOOST_CONTRACT_ASSERT(cond)
  66. #else
  67. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  68. BOOST_CONTRACT_ASSERT(true || cond)
  69. #endif
  70. @endcode
  71. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
  72. and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
  73. predefined by this library.
  74. If there is a need, programmers are free to implement their own assertion
  75. levels defining macros similar to the one above.
  76. @see @RefSect{extras.assertion_levels, Assertion Levels}
  77. @param cond Boolean contract condition to check.
  78. (This is not a variadic macro parameter so any comma it might
  79. contain must be protected by round parenthesis,
  80. @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.)
  81. */
  82. #define BOOST_CONTRACT_ASSERT_AUDIT(cond)
  83. #elif defined(BOOST_CONTRACT_AUDITS)
  84. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  85. BOOST_CONTRACT_ASSERT(cond)
  86. #else
  87. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  88. BOOST_CONTRACT_DETAIL_NOEVAL(cond)
  89. #endif
  90. /**
  91. Preferred way to assert contract conditions that are computationally
  92. prohibitive, at least compared to the cost of executing the function body.
  93. The asserted condition will always be compiled and validated syntactically, but
  94. it will never be checked at run-time.
  95. This macro is defined by code equivalent to:
  96. @code
  97. #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
  98. BOOST_CONTRACT_ASSERT(true || cond)
  99. @endcode
  100. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and
  101. @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined
  102. by this library.
  103. If there is a need, programmers are free to implement their own assertion levels
  104. defining macros similar to the one above.
  105. @see @RefSect{extras.assertion_levels, Assertion Levels}
  106. @param cond Boolean contract condition to check.
  107. (This is not a variadic macro parameter so any comma it might
  108. contain must be protected by round parenthesis,
  109. @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.)
  110. */
  111. #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
  112. BOOST_CONTRACT_DETAIL_NOEVAL(cond)
  113. #endif // #include guard