SheafSystem  0.0.0.0
assert_contract.h
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Include file for some libSheaf specific extensions to assert.h
19 
20 // @issue These macros are not named with any unique prefix to avoid name clashes.
21 
22 #ifndef ASSERT_CONTRACT_H
23 #define ASSERT_CONTRACT_H
24 
25 #ifndef SHEAF_DLL_SPEC_H
26 #include "SheafSystem/sheaf_dll_spec.h"
27 #endif
28 
29 
30 namespace sheaf
31 {
32 
37  SHEAF_DLL_SPEC void check_contract(bool xcond, const char* xmsg, const char* xfunction_name, const char* xfile, int xline);
38 
39 // ///
40 // /// Tests condition xcond and throws exception if false;
41 // /// exception message includes xmsg, file name xfile, and line number xline.
42 // ///
43 // SHEAF_DLL_SPEC void check_contract(bool xcond, const char* xmsg, const char* xfile, int xline);
44 
49  SHEAF_DLL_SPEC void check_contract(bool xcond,
50  const char* xcond_msg,
51  int xi,
52  const char* xi_msg,
53  const char* xfile,
54  int xline);
55 
56 // ///
57 // /// Tests condition xcond for index xi and throws exception if false;
58 // /// exception message includes xcond_msg, xi_msg, file name xfile, and line number xline.
59 // ///
60 // SHEAF_DLL_SPEC void check_contract(bool xcond,
61 // const char* xcond_msg,
62 // int xi,
63 // const char* xi_msg,
64 // const char* xfile,
65 // int xline);
66 
72  SHEAF_DLL_SPEC void check_contract(bool xcond,
73  const char* xcond_msg,
74  int xi,
75  const char* xi_msg,
76  const char* xfunction_name,
77  const char* xfile,
78  int xline);
79 
80 // ///
81 // /// Throws exception for existential quantification failure.
82 // ///
83 // SHEAF_DLL_SPEC void post_there_exists_failed(const char* xcond_msg,
84 // int xi,
85 // const char* xi_msg,
86 // int xmin,
87 // int xub,
88 // const char* xfile,
89 // int xline);
90 
94  SHEAF_DLL_SPEC void post_there_exists_failed(const char* xcond_msg,
95  int xi,
96  const char* xi_msg,
97  int xmin,
98  int xub,
99  const char* xfunction_name,
100  const char* xfile,
101  int xline);
102 
106  SHEAF_DLL_SPEC void post_unimplemented(const char* xcond_msg, const char* xfunction_name, const char* xfile, int xline);
107 
108 } // end namespace sheaf
109 
110 #ifndef NDEBUG
111 // ===========================================================
112 // CONTRACTS ON
113 // ===========================================================
114 
117 
118 // Assert condition x.
119 
120 #define dbc_assert(x) sheaf::check_contract((x), #x, __FUNCTION__, __FILE__, __LINE__)
121 
122 // Assert condition x for case specified by int xi.
123 
124 #define dbc_assert_for_i(x, xi) sheaf::check_contract((x), #x, (xi), #xi, __FUNCTION__, __FILE__, __LINE__)
125 
126 // "Universal" quantification of condition xcondition
127 // for int interval [xi_min, xi_ub). Xcondition should depend on int xi,
128 
129 #define dbc_assert_for_all(xi, xi_min, xi_ub, xcondition) \
130 { for(int xi = (xi_min); xi < (xi_ub); ++xi) dbc_assert_for_i((xcondition), xi); }
131 
132 // "Universal" quantification of condition xcondition
133 // for values specified by xinit, xtest, and xincrement.
134 // Xcondition should depend on variable declared in xinit.
135 
136 #define dbc_assert_for_range(xinit, xtest, xincrement, xcondition) \
137 { xinit; while(xtest) { dbc_assert(xcondition); xincrement; } }
138 
139 // "Universal" quatification of condition xcondition
140 // for values specified by xinit, xtest, xincrement, and xfinalize.
141 // Xcondition should depend on variable declared in xinit.
142 
143 #define dbc_assert_for_iterator(xinit, xtest, xincrement, xcondition, xfinalize) \
144 { xinit; while(xtest) { dbc_assert(xcondition); xincrement; } xfinalize; }
145 
146 // "Existential" quantification of condition xcondition
147 // for int interval [xi_min, xi_ub).
148 // Xcondition should depend on int xi,
149 
150 #define dbc_assert_there_exists(xi, xi_min, xi_ub, xcondition) \
151 { \
152  for(int xi = (xi_min); xi < (xi_ub) && !(xcondition); ++xi) \
153  { \
154  if(xi == ((xi_ub)-1)) \
155  { \
156  sheaf::post_there_exists_failed(#xcondition, xi, #xi, (xi_min), (xi_ub), __FUNCTION__, __FILE__, __LINE__); \
157  } \
158  } \
159 }
160 
161 // General assertion.
162 
163 #define assertion(x) dbc_assert(x)
164 
165 // "Old" variable declaration x;
166 
167 #define define_old_variable(x) x
168 
169 // Arbitrary code fragment x.
170 
171 #define if_contract(x) x
172 
173 // Precondition clause.
174 
175 #define require(x) dbc_assert(x)
176 #define require_for_all(i, i_min, i_ub, condition) dbc_assert_for_all(i, i_min, i_ub, condition)
177 #define require_for_range(init, test, increment, condition) dbc_assert_for_range(init, test, increment, condition)
178 #define require_for_iterator(init, test, increment, condition, finalize) dbc_assert_for_iterator(init, test, increment, condition, finalize);
179 #define require_there_exists(i, i_min, i_ub, condition) dbc_assert_there_exists(i, i_min, i_ub, condition)
180 
181 // Postcondition clause.
182 
183 #define ensure(x) dbc_assert(x)
184 #define ensure_for_all(i, i_min, i_ub, condition) dbc_assert_for_all(i, i_min, i_ub, condition)
185 #define ensure_for_range(init, test, increment, condition) dbc_assert_for_range(init, test, increment, condition)
186 #define ensure_for_iterator(init, test, increment, condition, finalize) dbc_assert_for_iterator(init, test, increment, condition, finalize);
187 #define ensure_there_exists(i, i_min, i_ub, condition) dbc_assert_there_exists(i, i_min, i_ub, condition)
188 
189 // Invariant clauses.
190 
191 #define invariance(x) dbc_assert(x)
192 #define invariance_for_all(i, i_min, i_ub, condition) dbc_assert_for_all(i, i_min, i_ub, condition)
193 #define invariance_for_range(init, test, increment, condition) dbc_assert_for_range(init, test, increment, condition)
194 #define invariance_for_iterator(init, test, increment, condition, finalize) dbc_assert_for_iterator(init, test, increment, condition, finalize);
195 #define invariance_there_exists(i, i_min, i_ub, condition) dbc_assert_there_exists(i, i_min, i_ub, condition)
196 
197 // ===========================================================
198 // END CONTRACTS ON
199 // ===========================================================
200 #else
201 // ===========================================================
202 // CONTRACTS OFF
203 // ===========================================================
204 
205 #define assertion(x)
206 #define define_old_variable(x)
207 #define if_contract(x)
208 #define require(x)
209 #define require_for_all(i, i_min, i_ub, condition)
210 #define require_for_range(init, test, increment, condition)
211 #define require_for_iterator(init, test, increment, condition, finalize)
212 #define require_there_exists(i, i_min, i_ub, condition)
213 #define ensure(x)
214 #define ensure_for_all(i, i_min, i_ub, condition)
215 #define ensure_for_range(init, test, increment, condition)
216 #define ensure_for_iterator(init, test, increment, condition, finalize)
217 #define ensure_there_exists(i, i_min, i_ub, condition)
218 #define invariance(x)
219 #define invariance_for_all(i, i_min, i_ub, condition)
220 #define invariance_for_range(init, test, increment, condition)
221 #define invariance_for_iterator(init, test, increment, condition, finalize)
222 #define invariance_there_exists(i, i_min, i_ub, condition)
223 
224 // ===========================================================
225 // END CONTRACTS OFF
226 // ===========================================================
227 #endif // NDEBUG
228 
229 // Indicates that function is "conceptually abstract" and intended
230 // to be implemented in descendants, but a stub has been implemented
231 // in the current class in order to define the contract. Equivalent
232 // to the "is deferred" syntax in Eiffel.
233 
234 #define is_abstract() sheaf::post_unimplemented("is abstract", __FUNCTION__, __FILE__, __LINE__)
235 
236 // Indicates that function is not implemented.
237 
238 #define not_implemented() sheaf::post_unimplemented("not implemented", __FUNCTION__, __FILE__, __LINE__)
239 
240 // Some macros for inserting "comment" assertions
241 // These allow construction of assertions that aren't executable,
242 // or that we don't want executed because they are redundant.
243 // These nevertheless look just like assertions and can be extracted
244 // by any tool that we build to extract assertions (e.g. an equivalent
245 // of the Eiffel short tool.)
246 
247 #define unexecutable(x) true
248 #define precondition_of(x) true
249 #define postcondition_of(x) true
250 
251 // Every function should have as a postcondition exactly one of
252 // ensure(is_basic_query());
253 // or
254 // ensure(is_derived_query());
255 // or
256 // ensure(invariant());
257 // See "Design by Contract, by Example", by Richard Mitchell
258 // and Jim McKim for the definitions of basic and derived queries.
259 // As used here, the term query refers to a function that does not
260 // change the state of the object, but merely returns a value, and
261 // therefore cannot affect the value of invariant().
262 
263 #define is_basic_query true
264 #define is_derived_query true
265 
266 
267 #endif // ifndef ASSERT_CONTRACT_H
SHEAF_DLL_SPEC void post_there_exists_failed(const char *xcond_msg, int xi, const char *xi_msg, int xmin, int xub, const char *xfunction_name, const char *xfile, int xline)
Throws exception for existential quantification failure.
Namespace for the sheaves component of the sheaf system.
SHEAF_DLL_SPEC void check_contract(bool xcond, const char *xmsg, const char *xfunction_name, const char *xfile, int xline)
Tests condition xcond and throws exception if false; exception message includes xmsg, file name xfile, and line number xline.
SHEAF_DLL_SPEC void post_unimplemented(const char *xcond_msg, const char *xfunction_name, const char *xfile, int xline)
Throws exception for attempt to invoke is_abstract or not implemented.