assert.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 (C++11 <c>__func__</c> is not used here because in most cases
  27. it will simply expand to the internal compiler name of the lambda function
  28. used to program the contract conditions adding no specificity to the error
  29. message).
  30. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
  31. and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
  32. predefined by this library.
  33. @see @RefSect{tutorial.preconditions, Preconditions},
  34. @RefSect{tutorial.postconditions, Postconditions},
  35. @RefSect{tutorial.exception_guarantees, Exceptions Guarantees},
  36. @RefSect{tutorial.class_invariants, Class Invariants},
  37. @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
  38. @param cond Boolean contract condition to check.
  39. (This is not a variadic macro parameter so any comma it might
  40. contain must be protected by round parenthesis and
  41. @c BOOST_CONTRACT_ASSERT((cond)) will always work.)
  42. */
  43. // This must be an expression (a trivial one so the compiler can optimize it
  44. // away). It cannot an empty code block `{}`, etc. otherwise code like
  45. // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
  46. #define BOOST_CONTRACT_ASSERT(cond)
  47. #elif !defined(BOOST_CONTRACT_NO_ALL)
  48. #include <boost/contract/detail/assert.hpp>
  49. #define BOOST_CONTRACT_ASSERT(cond) \
  50. BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */
  51. #else
  52. // This must be an expression (a trivial one so the compiler can optimize it
  53. // away). It cannot an empty code block `{}`, etc. otherwise code like
  54. // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
  55. #define BOOST_CONTRACT_ASSERT(cond) \
  56. BOOST_CONTRACT_DETAIL_NOOP
  57. #endif
  58. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  59. /**
  60. Preferred way to assert contract conditions that are computationally
  61. expensive, at least compared to the computational cost of executing the
  62. function body.
  63. The asserted condition will always be compiled and validated syntactically,
  64. but it will not be checked at run-time unless
  65. @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default).
  66. This macro is defined by code equivalent to:
  67. @code
  68. #ifdef BOOST_CONTRACT_AUDITS
  69. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  70. BOOST_CONTRACT_ASSERT(cond)
  71. #else
  72. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  73. BOOST_CONTRACT_ASSERT(true || cond)
  74. #endif
  75. @endcode
  76. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
  77. and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
  78. predefined by this library.
  79. If there is a need, programmers are free to implement their own assertion
  80. levels defining macros similar to the one above.
  81. @see @RefSect{extras.assertion_levels, Assertion Levels},
  82. @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
  83. @param cond Boolean contract condition to check.
  84. (This is not a variadic macro parameter so any comma it might
  85. contain must be protected by round parenthesis and
  86. @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.)
  87. */
  88. #define BOOST_CONTRACT_ASSERT_AUDIT(cond)
  89. #elif defined(BOOST_CONTRACT_AUDITS)
  90. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  91. BOOST_CONTRACT_ASSERT(cond)
  92. #else
  93. #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
  94. BOOST_CONTRACT_DETAIL_NOEVAL(cond)
  95. #endif
  96. /**
  97. Preferred way to document in the code contract conditions that are
  98. computationally prohibitive, at least compared to the computational cost of
  99. executing the function body.
  100. The asserted condition will always be compiled and validated syntactically, but
  101. it will never be checked at run-time.
  102. This macro is defined by code equivalent to:
  103. @code
  104. #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
  105. BOOST_CONTRACT_ASSERT(true || cond)
  106. @endcode
  107. @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and
  108. @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined
  109. by this library.
  110. If there is a need, programmers are free to implement their own assertion levels
  111. defining macros similar to the one above.
  112. @see @RefSect{extras.assertion_levels, Assertion Levels},
  113. @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
  114. @param cond Boolean contract condition to check.
  115. (This is not a variadic macro parameter so any comma it might
  116. contain must be protected by round parenthesis and
  117. @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.)
  118. */
  119. #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
  120. BOOST_CONTRACT_DETAIL_NOEVAL(cond)
  121. #endif // #include guard