if_copyable_macro.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright (C) 2008-2018 Lorenzo Caminiti
  2. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  3. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  4. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  5. // Test old values of non-copyable types (using macro interface).
  6. #include "if_copyable.hpp"
  7. #include "../detail/unprotected_commas.hpp"
  8. #include <boost/contract_macro.hpp>
  9. #include <boost/noncopyable.hpp>
  10. #include <boost/detail/lightweight_test.hpp>
  11. unsigned old_checks;
  12. template<typename T>
  13. struct b {
  14. virtual void next(T& x, boost::contract::virtual_* v = 0) {
  15. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(
  16. typename boost::contract::test::detail::unprotected_commas<T, void,
  17. void>::type1
  18. )(
  19. (boost::contract::test::detail::unprotected_commas<void, void,
  20. void>::same(v)),
  21. old_x,
  22. (boost::contract::test::detail::unprotected_commas<void, void,
  23. void>::same(x))
  24. );
  25. BOOST_CONTRACT_PUBLIC_FUNCTION(
  26. boost::contract::test::detail::unprotected_commas<void, void,
  27. void>::same(v),
  28. boost::contract::test::detail::unprotected_commas<void, void,
  29. void>::same(this)
  30. )
  31. BOOST_CONTRACT_POSTCONDITION([&] {
  32. boost::contract::test::detail::unprotected_commas<
  33. void, void, void>::call();
  34. if(old_x) {
  35. BOOST_CONTRACT_ASSERT(x == *old_x + T(1));
  36. ++old_checks;
  37. }
  38. })
  39. ;
  40. ++x;
  41. }
  42. BOOST_CONTRACT_OVERRIDE(next)
  43. };
  44. template<typename T>
  45. struct a
  46. #define BASES public b<T>
  47. : BASES
  48. {
  49. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  50. #undef BASES
  51. virtual void next(T& x, boost::contract::virtual_* v = 0) /* override */ {
  52. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(
  53. typename boost::contract::test::detail::unprotected_commas<T, void,
  54. void>::type1
  55. )(
  56. (boost::contract::test::detail::unprotected_commas<void, void,
  57. void>::same(v)),
  58. old_x,
  59. (boost::contract::test::detail::unprotected_commas<void, void,
  60. void>::same(x))
  61. );
  62. BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(
  63. typename boost::contract::test::detail::unprotected_commas<
  64. override_next, void, void>::type1
  65. )(
  66. boost::contract::test::detail::unprotected_commas<void, void,
  67. void>::same(v),
  68. &a::next,
  69. boost::contract::test::detail::unprotected_commas<void, void,
  70. void>::same(this),
  71. boost::contract::test::detail::unprotected_commas<void, void,
  72. void>::same(x)
  73. )
  74. BOOST_CONTRACT_POSTCONDITION([&] {
  75. boost::contract::test::detail::unprotected_commas<
  76. void, void, void>::call();
  77. if(old_x) {
  78. BOOST_CONTRACT_ASSERT(x == *old_x + T(1));
  79. ++old_checks;
  80. }
  81. })
  82. ;
  83. ++x;
  84. }
  85. BOOST_CONTRACT_OVERRIDE(next)
  86. };
  87. template<typename T>
  88. void next(T& x) {
  89. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(
  90. typename boost::contract::test::detail::unprotected_commas<T, void,
  91. void>::type1
  92. )(
  93. old_x,
  94. (boost::contract::test::detail::unprotected_commas<void, void,
  95. void>::same(x))
  96. );
  97. BOOST_CONTRACT_FUNCTION()
  98. BOOST_CONTRACT_POSTCONDITION([&] {
  99. boost::contract::test::detail::unprotected_commas<void, void, void>
  100. ::call();
  101. if(old_x) {
  102. BOOST_CONTRACT_ASSERT(x == *old_x + T(1));
  103. ++old_checks;
  104. }
  105. })
  106. ;
  107. ++x;
  108. }
  109. int main() {
  110. int i = 1; // Test built-in copyable type.
  111. cp c(1); // Test custom copyable type.
  112. ncp n(1); // Test non-copyable type.
  113. // Test free functions (old values without `v`).
  114. unsigned cnt =
  115. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  116. 1
  117. #else
  118. 0
  119. #endif
  120. ;
  121. old_checks = 0;
  122. next(i);
  123. BOOST_TEST_EQ(old_checks, cnt);
  124. old_checks = 0;
  125. next(c);
  126. BOOST_TEST_EQ(old_checks, cnt);
  127. old_checks = 0;
  128. next(n);
  129. BOOST_TEST_EQ(old_checks, 0u);
  130. // Test virtual functions (old values with `v`).
  131. cnt =
  132. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  133. 2
  134. #else
  135. 0
  136. #endif
  137. ;
  138. a<int> ai;
  139. old_checks = 0;
  140. ai.next(i);
  141. BOOST_TEST_EQ(old_checks, cnt);
  142. a<cp> ac;
  143. old_checks = 0;
  144. ac.next(c);
  145. BOOST_TEST_EQ(old_checks, cnt);
  146. a<ncp> an;
  147. old_checks = 0;
  148. an.next(n);
  149. BOOST_TEST_EQ(old_checks, 0u);
  150. return boost::report_errors();
  151. }