CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cppad_assert.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_CPPAD_ASSERT_HPP
2 # define CPPAD_CORE_CPPAD_ASSERT_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 /*!
16 \file cppad_assert.hpp
17 Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
18 */
19 
20 /*
21 -------------------------------------------------------------------------------
22 $begin cppad_assert$$
23 $spell
24  CppAD
25  exp
26  const
27  bool
28 $$
29 
30 
31 $section CppAD Assertions During Execution$$
32 $mindex assert macro CPPAD_ASSERT_KNOWN CPPAD_ASSERT_UNKNOWN$$
33 
34 $head Syntax$$
35 $codei%CPPAD_ASSERT_KNOWN(%exp%, %msg%)
36 %$$
37 $codei%CPPAD_ASSERT_UNKNOWN(%exp%)%$$
38 
39 
40 $head Purpose$$
41 These CppAD macros are used to detect and report errors.
42 They are documented here because they correspond to the C++
43 source code that the error is reported at.
44 
45 $head NDEBUG$$
46 If the preprocessor symbol
47 $cref/NDEBUG/Faq/Speed/NDEBUG/$$ is defined,
48 these macros do nothing; i.e., they are optimized out.
49 
50 $head Restriction$$
51 The CppAD user should not uses these macros.
52 You can however write your own macros that do not begin with $code CPPAD$$
53 and that call the $cref/CppAD error handler/ErrorHandler/$$.
54 
55 $head Known$$
56 The $code CPPAD_ASSERT_KNOWN$$ macro is used to check for an error
57 with a known cause.
58 For example, many CppAD routines uses these macros
59 to make sure their arguments conform to their specifications.
60 
61 $head Unknown$$
62 The $code CPPAD_ASSERT_UNKNOWN$$ macro is used to check that the
63 CppAD internal data structures conform as expected.
64 If this is not the case, CppAD does not know why the error has
65 occurred; for example, the user may have written past the end
66 of an allocated array.
67 
68 $head Exp$$
69 The argument $icode exp$$ is a C++ source code expression
70 that results in a $code bool$$ value that should be true.
71 If it is false, an error has occurred.
72 This expression may be execute any number of times
73 (including zero times) so it must have not side effects.
74 
75 $head Msg$$
76 The argument $icode msg$$ has prototype
77 $codei%
78  const char *%msg%
79 %$$
80 and contains a $code '\0'$$ terminated character string.
81 This string is a description of the error
82 corresponding to $icode exp$$ being false.
83 
84 $head Error Handler$$
85 These macros use the
86 $cref/CppAD error handler/ErrorHandler/$$ to report errors.
87 This error handler can be replaced by the user.
88 
89 $end
90 ------------------------------------------------------------------------------
91 */
92 
93 # include <cassert>
94 # include <iostream>
96 
97 /*!
98 \def CPPAD_ASSERT_KNOWN(exp, msg)
99 Check that \a exp is true, if not print \a msg and terminate execution.
100 
101 The C++ expression \a exp is expected to be true.
102 If it is false,
103 the CppAD use has made an error that is described by \a msg.
104 If the preprocessor symbol \a NDEBUG is not defined,
105 and \a exp is false,
106 this macro will report the source code line number at
107 which this expected result occurred.
108 In addition, it will print the specified error message \a msg.
109 */
110 # ifdef NDEBUG
111 # define CPPAD_ASSERT_KNOWN(exp, msg) // do nothing
112 # else
113 # define CPPAD_ASSERT_KNOWN(exp, msg) \
114 { if( ! ( exp ) ) \
115  CppAD::ErrorHandler::Call( \
116  true , \
117  __LINE__ , \
118  __FILE__ , \
119  #exp , \
120  msg ); \
121 }
122 # endif
123 
124 /*!
125 \def CPPAD_ASSERT_UNKNOWN(exp)
126 Check that \a exp is true, if not terminate execution.
127 
128 The C++ expression \a exp is expected to be true.
129 If it is false,
130 CppAD has detected an error but does not know the cause of the error.
131 If the preprocessor symbol \a NDEBUG is not defined,
132 and \a exp is false,
133 this macro will report the source code line number at
134 which this expected result occurred.
135 */
136 # ifdef NDEBUG
137 # define CPPAD_ASSERT_UNKNOWN(exp) // do nothing
138 # else
139 # define CPPAD_ASSERT_UNKNOWN(exp) \
140 { if( ! ( exp ) ) \
141  CppAD::ErrorHandler::Call( \
142  false , \
143  __LINE__ , \
144  __FILE__ , \
145  #exp , \
146  "" ); \
147 }
148 # endif
149 
150 /*!
151 \def CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)
152 Check that operator \a op has the specified number of of arguments and results.
153 
154 If \a NDEBUG is not defined and either the number of arguments
155 or the number of results are not as expected,
156 execution is terminated and the source code line number is reported.
157 */
158 # define CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res) \
159  CPPAD_ASSERT_UNKNOWN( NumArg(op) == n_arg ) \
160  CPPAD_ASSERT_UNKNOWN( NumRes(op) == n_res )
161 
162 /*!
163 \def CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
164 Check that the first call to a routine is not during parallel execution mode.
165 
166 If \c NDEBUG is defined, this macro has no effect
167 (not even the definition of (\c assert_first_call).
168 Otherwise, the variable
169 \code
170  static bool assert_first_call
171 \endcode
172 is defined and if the first call is executed in parallel mode,
173 execution is terminated and the source code line number is reported.
174 */
175 # ifdef NDEBUG
176 # define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
177 # else
178 # define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL \
179  static bool assert_first_call = true; \
180  if( assert_first_call ) \
181  { CPPAD_ASSERT_KNOWN( \
182  ! (CppAD::thread_alloc::in_parallel() ), \
183  "In parallel mode and parallel_setup has not been called." \
184  ); \
185  assert_first_call = false; \
186  }
187 # endif
188 
189 # endif