casacore
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: aips2-request@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//# $Id$
27
28#ifndef CASA_ASSERT_H
29#define CASA_ASSERT_H
30
31#include <casacore/casa/aips.h>
32#include <casacore/casa/Exceptions/Error.h>
33
34
35namespace casacore { //# NAMESPACE CASACORE - BEGIN
36
37// <summary>Utility class for Assert macros.</summary>
38// <use visibility=export>
39// <reviewed reviewer="Friso Olnon" date="1995/03/13" tests="" demos="">
40// </reviewed>
41
42// <prerequisite>
43// <li> module <linkto module=Exceptions>Exceptions</linkto>
44// </prerequisite>
45
46// <etymology>
47// Templated class <src>assert_</src> is the basis for the macros
48// <src>DebugAssertExit</src>, <src>DebugAssert</src>,
49// <src>AlwaysAssertExit</src>, and <src>AlwaysAssert</src> which
50// form the "public interface" to the Assertion mechanism.
51// </etymology>
52
53// <synopsis>
54// The present Assertion mechanism uses the exception
55// handling mechanism to throw the errors when an Assertion
56// fails. It can be used in two ways:
57// <dl>
58// <dt> <src>DebugAssertExit(expr)</src>
59// <dt> <src>AlwaysAssertExit(expr)</src>
60// <dd> cause the program to abort if <src>expr</src> evaluates to a
61// null value. This form is intended for the <em>end users</em>
62// because presumabily at their level there is no way to recover
63// from errors.
64// <dt> <src>DebugAssert(expr, exception)</src>
65// <dt> <src>AlwaysAssert(expr, exception)</src>
66// <dd> throw the specified exception if the <src>expr</src> is
67// null. This form is designed to be used by <em>library
68// elements</em> because it actually raises an exception which
69// can be later caught in the regular way.
70// </dl>
71//
72// <note role=tip> <src>DebugAssertExit</src> and
73// <src>DebugAssert</src> are only invoked in
74// debug mode (i.e. when <src>AIPS_DEBUG</src> is defined); otherwise
75// they preprocess to null statements. <src>AlwaysAssertExit</src>
76// and <src>AlwaysAssert</src> are always invoked.
77// </note>
78//
79// <note role=tip> Class <src>assert_</src> is internal to the
80// Assertion mechanism and should be undocumented. However,
81// documenting the class is the only way to document this mechanism,
82// which for the rest consists of preprocessor macros.
83// </note>
84//
85// </synopsis>
86
87// <example>
88// The implementation of the <linkto module=Arrays>Array classes</linkto>
89// contains many examples of the Assertion mechanism. The following
90// application of the Assertion mechanism is taken from the archive of
91// the aips2-workers@nrao.edu mail group (Brian Glendenning, 1994/03/23):
92//
93// I thought I'd readvertise a technique I use that helps me find
94// problems in the classes I write. I have found this to be an
95// EXTREMELY useful way of discovering bugs automatically (so the users
96// of your class don't have to manually).
97//
98// In your class, write an <src>ok()</src> member function that
99// returns a <src>Bool</src>. Allow for inheritance and make it a
100// virtual function (in fact, the derived class's <src>ok()</src> would
101// probably call the <src>ok()</src> from its parent, as well as doing
102// specific stuff for the derived class).
103//
104// Then in every member function, place a call to <src>ok()</src> in
105// an Assertion. Like this:
106// <srcblock>
107// DebugAssert(ok(), AipsError); // include aips/Assert.h in your .cc file
108// </srcblock>
109//
110// The second argument is the exception you want to throw.
111// <src>AipsError</src> will always do, although you can throw a
112// more particular one if you want to. This Assertion will not be in
113// production code -- i.e. if <src>AIPS_DEBUG</src> is not defined, the
114// above line will be a null statement. I place these lines at the entry
115// to all member functions (except I place them at the <em>end</em> of a
116// constructor!). (I normally don't put an Assertion in an inline
117// function).
118//
119// In the <src>ok()</src> function you should Assert a class's
120// invariants. This is more or less the same as Asserting that an
121// object's private and protected data are <em>consistent</em>. For
122// example, one of the simple tests I do in the array classes is Assert
123// that the number of elements (which I cache) is indeed equal to the
124// product of its shape (I do ~15 tests in the <src>ok()</src> for the
125// new <src>Array<T></src> class).
126// </example>
127
128template<class t> class assert_ {
129public:
130 // <group>
131 assert_(int expr, const char *msg) {
132 if (! expr) throw(t(msg));
133 }
134 assert_(const void *ptr, const char *msg) {
135 if (! ptr) throw(t(msg));
136 }
137 assert_(int expr, const char *msg, const char* file, Int line);
138 assert_(const void *ptr, const char *msg, const char* file, Int line);
139 // </group>
140
141 // A no-op, but it keeps g++ from complaining about "variable not used"
142 // errors
143 void null() {}
144};
145
146// These marcos are provided for use instead of simply using the
147// constructors of <src>assert_</src> to allow addition of line
148// numbers and file name in the future.
149//
150// <src>DebugAssert</src> and <src>AlwaysAssert</src> are designed to
151// be used by library elements because they actually raise an exception
152// which can later be later caught.
153// <src>DebugAssertExit</src> and <src>AlwaysAssertExit</src> are
154// intended to be used by the applications writer, because they cause an
155// <src>exit(0)</src>.
156
157#define AlwaysAssert(expr, exception) \
158 {casacore::assert_<exception > dummy_(expr, "Failed AlwaysAssert " #expr,__FILE__,(casacore::Int)__LINE__); dummy_.null(); }
159#define AlwaysAssertExit(expr) \
160 {casacore::assert_<casacore::AbortError> dummy_(expr, "Unrecoverable AlwaysAssertExit: " #expr,__FILE__,(casacore::Int)__LINE__); dummy_.null();}
161
162#if defined(AIPS_DEBUG)
163
164//# The backslashes below have spaces after them to make the egcs
165// compiler happy # (otherwise it thinks they are multiline //
166// comments). If ever uncommented # the spaces should be removed.
167
168// #define DebugAssert(expr, exception)
169// (assert_<exception > (expr, "Failed Assertion: " #expr))
170// #define Assert(expr)
171// (assert_<AbortError> (expr, "Unrecoverable Assertion: " #expr))
172
173// #define DebugAssert(expr, exception)
174// (assert_<exception > (expr, "Failed Assertion: " #expr,__FILE__,(Int)__LINE__))
175// #define Assert(expr)
176// (assert_<AbortError> (expr, "Unrecoverable Assertion: " #expr,__FILE__,(Int)__LINE__))
177
178#define DebugAssert(expr, exception) \
179 {casacore::assert_<exception > dummy_(expr, "Failed Assertion: " #expr,__FILE__,(casacore::Int)__LINE__); dummy_.null();}
180#define DebugAssertExit(expr) \
181 {casacore::assert_<casacore::AbortError> dummy_(expr, "Unrecoverable Assertion: " #expr,__FILE__,(casacore::Int)__LINE__); dummy_.null();}
182
183#else
184
185#define DebugAssert(expr, exception)
186#define DebugAssertExit(expr)
187
188#endif
189
190
191} //# NAMESPACE CASACORE - END
192
193#ifndef CASACORE_NO_AUTO_TEMPLATES
194#include <casacore/casa/Utilities/Assert.tcc>
195#endif //# CASACORE_NO_AUTO_TEMPLATES
196#endif
void null()
A no-op, but it keeps g++ from complaining about "variable not used" errors.
Definition: Assert.h:143
assert_(const void *ptr, const char *msg)
Definition: Assert.h:134
assert_(int expr, const char *msg)
Definition: Assert.h:131
assert_(int expr, const char *msg, const char *file, Int line)
assert_(const void *ptr, const char *msg, const char *file, Int line)
this file contains all the compiler specific defines
Definition: mainpage.dox:28
int Int
Definition: aipstype.h:50