casacore
Loading...
Searching...
No Matches
Assert.h
Go to the documentation of this file.
1// # Assert.h: Throw exceptions when Assertions fail.
2// # Copyright (C) 1993,1994,1995,1999,2000,2002
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_ASSERT_H
27#define CASA_ASSERT_H
28
29#include <casacore/casa/aips.h>
30#include <casacore/casa/Exceptions/Error.h>
31
32namespace casacore { // # NAMESPACE CASACORE - BEGIN
33
34// <summary>Utility function for Assert macros.</summary>
35// <use visibility=export>
36// <reviewed reviewer="Friso Olnon" date="1995/03/13" tests="" demos="">
37// </reviewed>
38
39// <prerequisite>
40// <li> module <linkto module=Exceptions>Exceptions</linkto>
41// </prerequisite>
42
43// <etymology>
44// Templated function <src>assert_</src> is the basis for the macros
45// <src>DebugAssertExit</src>, <src>DebugAssert</src>,
46// <src>AlwaysAssertExit</src>, and <src>AlwaysAssert</src> which
47// form the "public interface" to the Assertion mechanism.
48// </etymology>
49
50// <synopsis>
51// The present Assertion mechanism uses the exception
52// handling mechanism to throw the errors when an Assertion
53// fails. It can be used in two ways:
54// <dl>
55// <dt> <src>DebugAssertExit(expr)</src>
56// <dt> <src>AlwaysAssertExit(expr)</src>
57// <dd> cause the program to abort if <src>expr</src> evaluates to false.
58// This form is intended for the <em>end users</em>
59// because presumabily at their level there is no way to recover
60// from errors.
61// <dt> <src>DebugAssert(expr, exception)</src>
62// <dt> <src>AlwaysAssert(expr, exception)</src>
63// <dd> throw the specified exception if the <src>expr</src> is false.
64// This form is designed to be used by <em>library
65// elements</em> because it actually raises an exception which
66// can be later caught in the regular way.
67// </dl>
68//
69// <note role=tip> <src>DebugAssertExit</src> and
70// <src>DebugAssert</src> are only invoked in
71// debug mode (i.e. when <src>AIPS_DEBUG</src> is defined); otherwise
72// they preprocess to null statements. <src>AlwaysAssertExit</src>
73// and <src>AlwaysAssert</src> are always invoked.
74// </note>
75//
76// </synopsis>
77
78// <example>
79// The implementation of the <linkto module=Arrays>Array classes</linkto>
80// contains many examples of the Assertion mechanism. The following
81// application of the Assertion mechanism is taken from the archive of
82// the aips2-workers@nrao.edu mail group (Brian Glendenning, 1994/03/23):
83//
84// I thought I'd readvertise a technique I use that helps me find
85// problems in the classes I write. I have found this to be an
86// EXTREMELY useful way of discovering bugs automatically (so the users
87// of your class don't have to manually).
88//
89// In your class, write an <src>ok()</src> member function that
90// returns a <src>Bool</src>. Allow for inheritance and make it a
91// virtual function (in fact, the derived class's <src>ok()</src> would
92// probably call the <src>ok()</src> from its parent, as well as doing
93// specific stuff for the derived class).
94//
95// Then in every member function, place a call to <src>ok()</src> in
96// an Assertion. Like this:
97// <srcblock>
98// DebugAssert(ok(), AipsError); // include aips/Assert.h in your .cc file
99// </srcblock>
100//
101// The second argument is the exception you want to throw.
102// <src>AipsError</src> will always do, although you can throw a
103// more particular one if you want to. This Assertion will not be in
104// production code -- i.e. if <src>AIPS_DEBUG</src> is not defined, the
105// above line will be a null statement. I place these lines at the entry
106// to all member functions (except I place them at the <em>end</em> of a
107// constructor!). (I normally don't put an Assertion in an inline
108// function).
109//
110// In the <src>ok()</src> function you should Assert a class's
111// invariants. This is more or less the same as Asserting that an
112// object's private and protected data are <em>consistent</em>. For
113// example, one of the simple tests I do in the array classes is Assert
114// that the number of elements (which I cache) is indeed equal to the
115// product of its shape (I do ~15 tests in the <src>ok()</src> for the
116// new <src>Array<T></src> class).
117// </example>
118
119// this templated function is called from Assert macros
120template <typename t>
121void assert_(bool expr, const char* msg, const char* file, int line);
122
123// These marcos are provided for use instead of simply using the
124// <src>assert_</src> function directly.
125//
126// <src>DebugAssert</src> and <src>AlwaysAssert</src> are designed to
127// be used by library elements because they actually raise an exception
128// which can later be later caught.
129// <src>DebugAssertExit</src> and <src>AlwaysAssertExit</src> are
130// intended to be used by the applications writer, because they cause an
131// <src>exit(0)</src>.
132
133#define AlwaysAssert(expr, exception) \
134 { \
135 casacore::assert_<exception>(static_cast<bool>(expr), "Failed AlwaysAssert " #expr, __FILE__, \
136 static_cast<int>(__LINE__)); \
137 }
138#define AlwaysAssertExit(expr) \
139 { \
140 casacore::assert_<casacore::AbortError>(static_cast<bool>(expr), \
141 "Unrecoverable AlwaysAssertExit: " #expr, __FILE__, \
142 static_cast<int>(__LINE__)); \
143 }
144
145#if defined(AIPS_DEBUG)
146
147#define DebugAssert(expr, exception) \
148 { \
149 casacore::assert_<exception>(static_cast<bool>(expr), "Failed Assertion: " #expr, __FILE__, \
150 static_cast<int>(__LINE__)); \
151 }
152#define DebugAssertExit(expr) \
153 { \
154 casacore::assert_<casacore::AbortError>(static_cast<bool>(expr), \
155 "Unrecoverable Assertion: " #expr, __FILE__, \
156 static_cast<int>(__LINE__)); \
157 }
158
159#else
160
161#define DebugAssert(expr, exception)
162#define DebugAssertExit(expr)
163
164#endif
165
166} // namespace casacore
167
168#ifndef CASACORE_NO_AUTO_TEMPLATES
169#include <casacore/casa/Utilities/Assert.tcc>
170#endif // # CASACORE_NO_AUTO_TEMPLATES
171#endif
void assert_(bool expr, const char *msg, const char *file, int line)
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28