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