libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


validator.h
1//---------------------------------------------------------------------
2// Algorithmic Conjurings @ http://www.coyotegulch.com
3//
4// validator.h (libcoyotl)
5//
6// Templatized validation and constraint enforcement functions.
7//---------------------------------------------------------------------
8//
9// Copyright 1990-2005 Scott Robert Ladd
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the
23// Free Software Foundation, Inc.
24// 59 Temple Place - Suite 330
25// Boston, MA 02111-1307, USA.
26//
27//-----------------------------------------------------------------------
28//
29// For more information on this software package, please visit
30// Scott's web site, Coyote Gulch Productions, at:
31//
32// http://www.coyotegulch.com
33//
34//-----------------------------------------------------------------------
35
36#if !defined(LIBCOYOTL_VALIDATOR_H)
37#define LIBCOYOTL_VALIDATOR_H
38
39#include <sstream>
40#include <stdexcept>
41#include <typeinfo>
42
43namespace libcoyotl
44{
45 using std::stringstream;
46 using std::string;
47 using std::runtime_error;
48
50
58 template <typename Type>
59 class validation_error : public runtime_error
60 {
61 private:
62 static string build_error_string(const Type & object,
63 const string & details)
64 {
65 stringstream message;
66
67 message << "validation error: "
68 << typeid(object).name() << " " << object
69 << details;
70
71 return message.str();
72 }
73
74 public:
76
87 validation_error(const Type & object,
88 const string & details = string())
89 : runtime_error(build_error_string(object,details))
90 {
91 // nada
92 }
93 };
94
96
104 template <typename Type>
105 void validate_equals(const Type & object,
106 const Type & constraint,
107 const string & message = string())
108 {
109 if (object != constraint)
110 {
111 stringstream details;
112 details << " must equal " << constraint << " " << message;
113 throw validation_error<Type>(object,details.str());
114 }
115 }
116
118
126 template <typename Type>
127 void validate_not(const Type & object,
128 const Type & constraint,
129 const string & message = string())
130 {
131 if (object == constraint)
132 {
133 stringstream details;
134 details << " must not equal " << constraint << " " << message;
135 throw validation_error<Type>(object,details.str());
136 }
137 }
138
140
148 template <typename Type>
149 void validate_less(const Type & object,
150 const Type & constraint,
151 const string & message = string())
152 {
153 if (object >= constraint)
154 {
155 stringstream details;
156 details << " must be less than " << constraint << " " << message;
157 throw validation_error<Type>(object,details.str());
158 }
159 }
160
162
170 template <typename Type>
171 void validate_less_eq(const Type & object,
172 const Type & constraint,
173 const string & message = string())
174 {
175 if (object > constraint)
176 {
177 stringstream details;
178 details << " must be less than " << constraint << " " << message;
179 throw validation_error<Type>(object,details.str());
180 }
181 }
182
184
192 template <typename Type>
193 void validate_greater(const Type & object,
194 const Type & constraint,
195 const string & message = string())
196 {
197 if (object <= constraint)
198 {
199 stringstream details;
200 details << " must be greater than " << constraint << " " << message;
201 throw validation_error<Type>(object,details.str());
202 }
203 }
204
206
214 template <typename Type>
215 void validate_greater_eq(const Type & object,
216 const Type & constraint,
217 const string & message = string())
218 {
219 if (object < constraint)
220 {
221 stringstream details;
222 details << " must be greater than " << constraint << " " << message;
223 throw validation_error<Type>(object,details.str());
224 }
225 }
226
228
239 template <typename Type>
240 void validate_range(const Type & object,
241 const Type & low_bound,
242 const Type & high_bound,
243 const string & message = string())
244 {
245 if ((object < low_bound) || (object > high_bound))
246 {
247 stringstream details;
248 details << " must be between " << low_bound << " and "
249 << high_bound << " " << message;
250 throw validation_error<Type>(object,details.str());
251 }
252 }
253
255
266 template <typename Type, typename Predicate>
267 void validate_with(const Type & object,
268 const Predicate & constraint,
269 const string & message = string())
270 {
271 if (!constraint(object))
272 {
273 stringstream details;
274 details << " failed test " << typeid(constraint).name() << " " << message;
275 throw validation_error<Type>(object,details.str());
276 }
277 }
278
280
286 template <typename Type>
287 void enforce_lower_limit(Type & object,
288 const Type & low_value)
289 {
290 if (object < low_value)
291 object = low_value;
292 }
293
295
301 template <typename Type>
302 void enforce_upper_limit(Type & object,
303 const Type & high_value)
304 {
305 if (object > high_value)
306 object = high_value;
307 }
308
310
319 template <typename Type>
320 void enforce_range(Type & object,
321 const Type & low_value,
322 const Type & high_value)
323 {
324 if (object < low_value)
325 object = low_value;
326 else if (object > high_value)
327 object = high_value;
328 }
329
331
340 inline string build_location_string(const char * filename, long line_no)
341 {
342 stringstream text;
343 text << "in " << filename << ", line " << line_no;
344 return text.str();
345 }
346}
347
348// These macros allow validation to be included on a per-compile basis, based on the settings
349// of the DEBUG and NDEBUG preprocessor macros.
350#if defined(_DEBUG) && !defined(NDEBUG)
351#define LIBCOYOTL_VALIDATE_EQUALS(object,constraint,details) libcoyotl::validate_equals(object,constraint,details)
352#define LIBCOYOTL_VALIDATE_NOT(object,constraint,details) libcoyotl::validate_not(object,constraint,details)
353#define LIBCOYOTL_VALIDATE_LESS(object,constraint,details) libcoyotl::validate_less(object,constraint,details)
354#define LIBCOYOTL_VALIDATE_LESS_EQ(object,constraint,details) libcoyotl::validate_less_eq(object,constraint,details)
355#define LIBCOYOTL_VALIDATE_GREATER(object,constraint,details) libcoyotl::validate_greater(object,constraint,details)
356#define LIBCOYOTL_VALIDATE_GREATER_EQ(object,constraint,details) libcoyotl::validate_greater_eq(object,constraint,details)
357#define LIBCOYOTL_VALIDATE_RANGE(object,low_bound,high_bound,details) libcoyotl::validate_range(object,low_bound,high_bound,details)
358#define LIBCOYOTL_VALIDATE_WITH(object,constraint,details) libcoyotl::validate_with(object,constraint,details)
359#define LIBCOYOTL_LOCATION libcoyotl::build_location_string(__FILE__,__LINE__)
360#else
361#define LIBCOYOTL_VALIDATE_EQUALS(object,constraint,details)
362#define LIBCOYOTL_VALIDATE_NOT(object,constraint,details)
363#define LIBCOYOTL_VALIDATE_LESS(object,constraint,details)
364#define LIBCOYOTL_VALIDATE_LESS_EQ(object,constraint,details)
365#define LIBCOYOTL_VALIDATE_GREATER(object,constraint,details)
366#define LIBCOYOTL_VALIDATE_GREATER_EQ(object,constraint,details)
367#define LIBCOYOTL_VALIDATE_RANGE(object,low_bound,high_bound,details)
368#define LIBCOYOTL_VALIDATE_WITH(object,constraint,details)
369#define LIBCOYOTL_LOCATION std::string()
370#endif
371
372#endif
A STL-compatible array class.
Definition array.h:73
Standard validation exception.
Definition validator.h:60
validation_error(const Type &object, const string &details=string())
Constructor.
Definition validator.h:87

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.