casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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>
33 
34 
35 namespace 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 
128 template<class t> class assert_ {
129 public:
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
int Int
Definition: aipstype.h:50
assert_(const void *ptr, const char *msg)
Definition: Assert.h:134
Utility class for Assert macros.
Definition: Assert.h:128
void null()
A no-op, but it keeps g++ from complaining about &quot;variable not used&quot; errors.
Definition: Assert.h:143
assert_(int expr, const char *msg)
Definition: Assert.h:131