max_args.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 max argument number for public function (with and without result).
  6. #include "../detail/oteststream.hpp"
  7. #include <boost/contract/public_function.hpp>
  8. #include <boost/contract/check.hpp>
  9. #include <boost/contract/base_types.hpp>
  10. #include <boost/contract/override.hpp>
  11. #include <boost/preprocessor/repetition/repeat.hpp>
  12. #include <boost/preprocessor/arithmetic/inc.hpp>
  13. #include <boost/preprocessor/control/expr_iif.hpp>
  14. #include <boost/preprocessor/cat.hpp>
  15. #include <boost/preprocessor/stringize.hpp>
  16. #include <boost/config.hpp>
  17. #include <boost/detail/lightweight_test.hpp>
  18. #include <sstream>
  19. boost::contract::test::detail::oteststream out;
  20. #if defined(BOOST_GCC)
  21. #pragma GCC diagnostic push
  22. #pragma GCC diagnostic ignored "-Wunused-parameter" // aN from macros.
  23. #elif defined(BOOST_CLANG)
  24. #pragma clang diagnostic push
  25. #pragma clang diagnostic ignored "-Wunused-parameter" // aN from macros.
  26. #endif
  27. #define BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_(z, n, unused) \
  28. int BOOST_PP_CAT(a, n) ,
  29. #define BOOST_CONTRACT_TEST_MAX_ARGS_COMMA_ARG_(z, n, unused) \
  30. , BOOST_PP_CAT(a, n)
  31. #define BOOST_CONTRACT_TEST_MAX_ARGS_N_(z, n, unused) \
  32. n
  33. struct b {
  34. static void static_invariant() { out << "b::static_inv" << std::endl; }
  35. void invariant() const { out << "b::inv" << std::endl; }
  36. #define BOOST_CONTRACT_TEST_MAX_ARGS_B_F_(z, n, unused) \
  37. virtual int BOOST_PP_CAT(f, n)( \
  38. BOOST_PP_REPEAT_ ## z( \
  39. n, BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_, ~) \
  40. boost::contract::virtual_* v = 0 \
  41. ) { \
  42. int result = 0; \
  43. boost::contract::check c = boost::contract::public_function( \
  44. v, result, this) \
  45. .precondition([] { \
  46. out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  47. "::pre" << std::endl; \
  48. }) \
  49. .old([] { \
  50. out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  51. "::old" << std::endl; \
  52. }) \
  53. .postcondition([] (int result) { \
  54. out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  55. "::post" << std::endl; \
  56. }) \
  57. ; \
  58. out << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  59. "::body" << std::endl; \
  60. return result; \
  61. }
  62. BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
  63. BOOST_CONTRACT_TEST_MAX_ARGS_B_F_, ~)
  64. };
  65. struct a
  66. #define BASES public b
  67. : BASES
  68. {
  69. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  70. #undef BASES
  71. static void static_invariant() { out << "a::static_inv" << std::endl; }
  72. void invariant() const { out << "a::inv" << std::endl; }
  73. #define BOOST_CONTRACT_TEST_MAX_ARGS_A_F_(z, n, unused) \
  74. int BOOST_PP_CAT(f, n)( \
  75. BOOST_PP_REPEAT_ ## z( \
  76. n, BOOST_CONTRACT_TEST_MAX_ARGS_PARAM_COMMA_, ~) \
  77. boost::contract::virtual_* v = 0 \
  78. ) /* override */ { \
  79. int result = 0; \
  80. boost::contract::check c = boost::contract::public_function< \
  81. BOOST_PP_CAT(override_, BOOST_PP_CAT(f, n)) \
  82. >( \
  83. v, result, &a::BOOST_PP_CAT(f, n), this \
  84. BOOST_PP_REPEAT_ ## z( \
  85. n, BOOST_CONTRACT_TEST_MAX_ARGS_COMMA_ARG_, ~) \
  86. ) \
  87. .precondition([] { \
  88. out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  89. "::pre" << std::endl; \
  90. }) \
  91. .old([] { \
  92. out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  93. "::old" << std::endl; \
  94. }) \
  95. .postcondition([] (int result) { \
  96. out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  97. "::post" << std::endl; \
  98. }) \
  99. ; \
  100. out << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  101. "::body" << std::endl; \
  102. return result; \
  103. } \
  104. BOOST_CONTRACT_OVERRIDE(BOOST_PP_CAT(f, n))
  105. BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
  106. BOOST_CONTRACT_TEST_MAX_ARGS_A_F_, ~)
  107. };
  108. #if defined(BOOST_GCC)
  109. #pragma GCC diagnostic pop
  110. #elif defined(BOOST_CLANG)
  111. #pragma clang diagnostic pop
  112. #endif
  113. int main() {
  114. std::ostringstream ok;
  115. a aa;
  116. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  117. #define BOOST_CONTRACT_TEST_entry_inv 1
  118. #else
  119. #define BOOST_CONTRACT_TEST_entry_inv 0
  120. #endif
  121. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  122. #define BOOST_CONTRACT_TEST_pre 1
  123. #else
  124. #define BOOST_CONTRACT_TEST_pre 0
  125. #endif
  126. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  127. #define BOOST_CONTRACT_TEST_exit_inv 1
  128. #else
  129. #define BOOST_CONTRACT_TEST_exit_inv 0
  130. #endif
  131. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  132. #define BOOST_CONTRACT_TEST_post 1
  133. #else
  134. #define BOOST_CONTRACT_TEST_post 0
  135. #endif
  136. #ifndef BOOST_CONTRACT_NO_OLDS
  137. #define BOOST_CONTRACT_TEST_old 1
  138. #else
  139. #define BOOST_CONTRACT_TEST_old 0
  140. #endif
  141. #define BOOST_CONTRACT_TEST_MAX_ARGS_TEST_(z, n, unused) \
  142. out.str(""); \
  143. aa.BOOST_PP_CAT(f, n)(BOOST_PP_ENUM_ ## z( \
  144. n, BOOST_CONTRACT_TEST_MAX_ARGS_N_, ~)); \
  145. ok.str(""); ok \
  146. BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_entry_inv, \
  147. << "b::static_inv\n" \
  148. << "b::inv\n"\
  149. << "a::static_inv\n" \
  150. << "a::inv\n" \
  151. ) \
  152. BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_pre, \
  153. << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  154. "::pre\n" \
  155. ) \
  156. BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_old, \
  157. << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  158. "::old\n" \
  159. << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  160. "::old\n" \
  161. ) \
  162. << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << "::body\n" \
  163. BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_exit_inv, \
  164. << "b::static_inv\n" \
  165. << "b::inv\n"\
  166. << "a::static_inv\n" \
  167. << "a::inv\n" \
  168. ) \
  169. BOOST_PP_EXPR_IIF(BOOST_CONTRACT_TEST_post, \
  170. << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  171. "::old\n" \
  172. << "b::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  173. "::post\n" \
  174. << "a::" << BOOST_PP_STRINGIZE(BOOST_PP_CAT(f, n)) << \
  175. "::post\n" \
  176. ) \
  177. ; \
  178. BOOST_TEST(out.eq(ok.str()));
  179. BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
  180. BOOST_CONTRACT_TEST_MAX_ARGS_TEST_, ~)
  181. #undef BOOST_CONTRACT_TEST_entry_inv
  182. #undef BOOST_CONTRACT_TEST_pre
  183. #undef BOOST_CONTRACT_TEST_exit_inv
  184. #undef BOOST_CONTRACT_TEST_post
  185. #undef BOOST_CONTRACT_TEST_old
  186. return boost::report_errors();
  187. }