no_macro.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 without BOOST_CONTRACT_OLD macro.
  6. #ifndef BOOST_CONTRACT_TEST_OLD_PTR_TYPE
  7. #error "must define BOOST_CONTRACT_TEST_OLD_PTR_TYPE"
  8. #endif
  9. #include "../detail/oteststream.hpp"
  10. #include "../detail/counter.hpp"
  11. #include <boost/contract/function.hpp>
  12. #include <boost/contract/public_function.hpp>
  13. #include <boost/contract/base_types.hpp>
  14. #include <boost/contract/override.hpp>
  15. #include <boost/contract/assert.hpp>
  16. #include <boost/contract/old.hpp>
  17. #include <boost/contract/check.hpp>
  18. #include <boost/detail/lightweight_test.hpp>
  19. #include <cassert>
  20. boost::contract::test::detail::oteststream out;
  21. struct i_tag; typedef boost::contract::test::detail::counter<i_tag, int> i_type;
  22. struct j_tag; typedef boost::contract::test::detail::counter<j_tag, int> j_type;
  23. struct b {
  24. virtual void swap(i_type& i, j_type& j, boost::contract::virtual_* v = 0);
  25. };
  26. void b::swap(i_type& i, j_type& j, boost::contract::virtual_* v) {
  27. BOOST_CONTRACT_TEST_OLD_PTR_TYPE<i_type> old_i = boost::contract::make_old(
  28. v, boost::contract::copy_old(v) ?
  29. i_type::eval(i)
  30. :
  31. boost::contract::null_old()
  32. );
  33. BOOST_CONTRACT_TEST_OLD_PTR_TYPE<j_type> old_j;
  34. boost::contract::check c = boost::contract::public_function(v, this)
  35. .precondition([&] {
  36. out << "b::swap::pre" << std::endl;
  37. BOOST_CONTRACT_ASSERT(i.value != j.value);
  38. })
  39. .old([&] {
  40. out << "b::swap::old" << std::endl;
  41. old_j = boost::contract::make_old(v, boost::contract::copy_old(v) ?
  42. j_type::eval(j) : boost::contract::null_old());
  43. })
  44. .postcondition([&] {
  45. out << "b::swap::post" << std::endl;
  46. BOOST_CONTRACT_ASSERT(i.value == old_j->value);
  47. BOOST_CONTRACT_ASSERT(j.value == old_i->value);
  48. })
  49. ;
  50. assert(false);
  51. }
  52. struct a
  53. #define BASES public b
  54. : BASES
  55. {
  56. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  57. #undef BASES
  58. void swap(i_type& i, j_type& j, boost::contract::virtual_* v = 0)
  59. /* override */ {
  60. boost::contract::check c = boost::contract::public_function<
  61. override_swap>(v, &a::swap, this, i, j);
  62. out << "a::swap::body" << std::endl;
  63. int t = i.value;
  64. i.value = j.value;
  65. j.value = t;
  66. }
  67. BOOST_CONTRACT_OVERRIDE(swap)
  68. };
  69. struct x_tag;
  70. typedef boost::contract::test::detail::counter<x_tag, char> x_type;
  71. struct y_tag;
  72. typedef boost::contract::test::detail::counter<y_tag, char> y_type;
  73. void swap(x_type& x, y_type& y) {
  74. BOOST_CONTRACT_TEST_OLD_PTR_TYPE<x_type> old_x = boost::contract::make_old(
  75. boost::contract::copy_old() ?
  76. x_type::eval(x)
  77. :
  78. boost::contract::null_old()
  79. );
  80. BOOST_CONTRACT_TEST_OLD_PTR_TYPE<y_type> old_y;
  81. boost::contract::check c = boost::contract::function()
  82. .precondition([&] {
  83. out << "swap::pre" << std::endl;
  84. BOOST_CONTRACT_ASSERT(x.value != y.value);
  85. })
  86. .old([&] {
  87. out << "swap::old" << std::endl;
  88. old_y = boost::contract::make_old(boost::contract::copy_old() ?
  89. y_type::eval(y) : boost::contract::null_old());
  90. })
  91. .postcondition([&] {
  92. out << "swap::post" << std::endl;
  93. BOOST_CONTRACT_ASSERT(x.value == old_y->value);
  94. BOOST_CONTRACT_ASSERT(y.value == old_x->value);
  95. })
  96. ;
  97. out << "swap::body" << std::endl;
  98. char t = x.value;
  99. x.value = y.value;
  100. y.value = t;
  101. }
  102. int main() {
  103. std::ostringstream ok;
  104. out.str("");
  105. x_type x; x.value = 'a';
  106. y_type y; y.value = 'b';
  107. swap(x, y);
  108. ok.str(""); ok
  109. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  110. << "swap::pre" << std::endl
  111. #endif
  112. #ifndef BOOST_CONTRACT_NO_OLDS
  113. << "swap::old" << std::endl
  114. #endif
  115. << "swap::body" << std::endl
  116. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  117. << "swap::post" << std::endl
  118. #endif
  119. ;
  120. BOOST_TEST(out.eq(ok.str()));
  121. #ifndef BOOST_CONTRACT_NO_OLDS
  122. #define BOOST_CONTRACT_TEST_old 1u
  123. #else
  124. #define BOOST_CONTRACT_TEST_old 0u
  125. #endif
  126. BOOST_TEST_EQ(x.value, 'b');
  127. BOOST_TEST_EQ(x.copies(), BOOST_CONTRACT_TEST_old);
  128. BOOST_TEST_EQ(x.evals(), BOOST_CONTRACT_TEST_old);
  129. BOOST_TEST_EQ(x.ctors(), x.dtors() + 1); // 1 for local var.
  130. BOOST_TEST_EQ(y.value, 'a');
  131. BOOST_TEST_EQ(y.copies(), BOOST_CONTRACT_TEST_old);
  132. BOOST_TEST_EQ(y.evals(), BOOST_CONTRACT_TEST_old);
  133. BOOST_TEST_EQ(y.ctors(), y.dtors() + 1); // 1 for local var.
  134. a aa;
  135. i_type i; i.value = 1;
  136. j_type j; j.value = 2;
  137. out.str("");
  138. aa.swap(i, j);
  139. ok.str(""); ok
  140. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  141. << "b::swap::pre" << std::endl
  142. #endif
  143. #ifndef BOOST_CONTRACT_NO_OLDS
  144. << "b::swap::old" << std::endl
  145. #endif
  146. << "a::swap::body" << std::endl
  147. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  148. << "b::swap::old" << std::endl
  149. << "b::swap::post" << std::endl
  150. #endif
  151. ;
  152. BOOST_TEST(out.eq(ok.str()));
  153. BOOST_TEST_EQ(i.value, 2);
  154. BOOST_TEST_EQ(i.copies(), BOOST_CONTRACT_TEST_old);
  155. BOOST_TEST_EQ(i.evals(), BOOST_CONTRACT_TEST_old);
  156. BOOST_TEST_EQ(i.ctors(), i.dtors() + 1); // 1 for local var.
  157. BOOST_TEST_EQ(j.value, 1);
  158. BOOST_TEST_EQ(j.copies(), BOOST_CONTRACT_TEST_old);
  159. BOOST_TEST_EQ(j.evals(), BOOST_CONTRACT_TEST_old);
  160. BOOST_TEST_EQ(j.ctors(), j.dtors() + 1); // 1 for local var.
  161. #undef BOOST_CONTRACT_TEST_old
  162. return boost::report_errors();
  163. }