Merge branch 'main' of feistymeow.org:feisty_meow
[feisty_meow.git] / basis / guards.h
1 #ifndef GUARDS_GROUP
2 #define GUARDS_GROUP
3
4 //////////////
5 // Name   : guards
6 // Author : Chris Koeritz
7 //////////////
8 // Copyright (c) 1989-$now By Author.  This program is free software; you can
9 // redistribute it and/or modify it under the terms of the GNU General Public
10 // License as published by the Free Software Foundation:
11 //     http://www.gnu.org/licenses/gpl.html
12 // or under the terms of the GNU Library license:
13 //     http://www.gnu.org/licenses/lgpl.html
14 // at your preference.  Those licenses describe your legal rights to this
15 // software, and no other rights or warranties apply.
16 // Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
17 //////////////
18
19 //! The guards collection helps in testing preconditions and reporting errors.
20 /*!
21   It also provides checking of boundary conditions, macros for causing
22   immediate program exit, and other sentinels for constructing preconditions
23   and postconditions.
24 */
25
26 namespace basis {
27
28 // forward declaration.
29 class astring;
30 class base_string;
31
32 //////////////
33
34 // simpler guards first...
35
36 //! Returns true if the value is within the range specified.
37 template <class contents>
38 bool in_range(const contents &value, const contents &low, const contents &high)
39 { return !( (high < low) || (value < low) || (value > high) ); }
40
41 //////////////
42
43 //! Verifies that "value" is between "low" and "high", inclusive.
44 /*! When the number is not in bounds, the function that is currently executing
45 returns the "to_return" default provided.  "to_return" can be empty for
46 functions that return void.  Note: it is also considered a failure for high to
47 be less than low. */
48 #define bounds_return(value, low, high, to_return) \
49     { if (!basis::in_range(value, low, high)) return to_return; }
50
51 //////////////
52
53 //! Verifies that "value" is between "low" and "high", inclusive.
54 /*! "Value" must be an object for which greater than and less than are defined.
55 The static_class_name() method and func definition are used to tag the
56 complaint that is emitted when problems are detected.  Note that if
57 CATCH_ERRORS is defined, then the program is _halted_ if the value is out
58 of bounds.  Otherwise, the "to_return" value is returned. */
59 #ifdef CATCH_ERRORS
60   #define bounds_halt(value, low, high, to_return) { \
61     if (((value) < (low)) || ((value) > (high))) { \
62       throw_error(basis::astring(static_class_name()), basis::astring(func), \
63           basis::astring("value ") + #value \
64           + " was not in range " + #low + " to " + #high \
65           + " at " + __WHERE__); \
66       return to_return; \
67     } \
68   }
69 #else
70   #define bounds_halt(a, b, c, d) bounds_return(a, b, c, d)
71 #endif
72
73 //////////////
74
75 //! writes a string "to_fill" in a nicely formatted manner using the class and function names.
76 void format_error(const base_string &class_name, const base_string &func_name,
77     const base_string &error_message, base_string &to_fill);
78
79 //! throws an error that incorporates the class name and function name.
80 void throw_error(const base_string &class_name, const base_string &func_name,
81     const base_string &error_message);
82
83 //! synonym method using astrings for easier char * handling.
84 void throw_error(const astring &class_name, const astring &func_name,
85     const astring &error_message);
86
87 //////////////
88
89 }  // namespace.
90
91 #endif
92