Created by Scott Robert Ladd at Coyote Gulch Productions.
00001 //--------------------------------------------------------------------- 00002 // Algorithmic Conjurings @ http://www.coyotegulch.com 00003 // 00004 // validator.h (libevocosm) 00005 // 00006 // Templatized validation and constraint enforcement functions. 00007 //--------------------------------------------------------------------- 00008 // 00009 // Copyright 2004, 2005, 2006, 2007 Scott Robert Ladd 00010 // 00011 // This program is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU General Public License as published by 00013 // the Free Software Foundation; either version 2 of the License, or 00014 // (at your option) any later version. 00015 // 00016 // This program is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU General Public License 00022 // along with this program; if not, write to the 00023 // Free Software Foundation, Inc. 00024 // 59 Temple Place - Suite 330 00025 // Boston, MA 02111-1307, USA. 00026 // 00027 //----------------------------------------------------------------------- 00028 // 00029 // For more information on this software package, please visit 00030 // Scott's web site, Coyote Gulch Productions, at: 00031 // 00032 // http://www.coyotegulch.com 00033 // 00034 //----------------------------------------------------------------------- 00035 00036 #if !defined(LIBEVOCOSM_VALIDATOR_H) 00037 #define LIBEVOCOSM_VALIDATOR_H 00038 00039 #include <sstream> 00040 #include <stdexcept> 00041 #include <typeinfo> 00042 00043 namespace libevocosm 00044 { 00045 using std::stringstream; 00046 using std::string; 00047 using std::runtime_error; 00048 00050 00058 template <typename Type> 00059 class validation_error : public runtime_error 00060 { 00061 private: 00062 static string build_error_string(const Type & object, 00063 const string & details) 00064 { 00065 stringstream message; 00066 00067 message << "validation error: " 00068 << typeid(object).name() << " " << object 00069 << details; 00070 00071 return message.str(); 00072 } 00073 00074 public: 00076 00087 validation_error(const Type & object, 00088 const string & details = string()) 00089 : runtime_error(build_error_string(object,details)) 00090 { 00091 // nada 00092 } 00093 }; 00094 00096 00104 template <typename Type> 00105 void validate_equals(const Type & object, 00106 const Type & constraint, 00107 const string & message = string()) 00108 { 00109 if (object != constraint) 00110 { 00111 stringstream details; 00112 details << " must equal " << constraint << " " << message; 00113 throw validation_error<Type>(object,details.str()); 00114 } 00115 } 00116 00118 00126 template <typename Type> 00127 void validate_not(const Type & object, 00128 const Type & constraint, 00129 const string & message = string()) 00130 { 00131 if (object == constraint) 00132 { 00133 stringstream details; 00134 details << " must not equal " << constraint << " " << message; 00135 throw validation_error<Type>(object,details.str()); 00136 } 00137 } 00138 00140 00148 template <typename Type> 00149 void validate_less(const Type & object, 00150 const Type & constraint, 00151 const string & message = string()) 00152 { 00153 if (object >= constraint) 00154 { 00155 stringstream details; 00156 details << " must be less than " << constraint << " " << message; 00157 throw validation_error<Type>(object,details.str()); 00158 } 00159 } 00160 00162 00170 template <typename Type> 00171 void validate_less_eq(const Type & object, 00172 const Type & constraint, 00173 const string & message = string()) 00174 { 00175 if (object > constraint) 00176 { 00177 stringstream details; 00178 details << " must be less than " << constraint << " " << message; 00179 throw validation_error<Type>(object,details.str()); 00180 } 00181 } 00182 00184 00192 template <typename Type> 00193 void validate_greater(const Type & object, 00194 const Type & constraint, 00195 const string & message = string()) 00196 { 00197 if (object <= constraint) 00198 { 00199 stringstream details; 00200 details << " must be greater than " << constraint << " " << message; 00201 throw validation_error<Type>(object,details.str()); 00202 } 00203 } 00204 00206 00214 template <typename Type> 00215 void validate_greater_eq(const Type & object, 00216 const Type & constraint, 00217 const string & message = string()) 00218 { 00219 if (object < constraint) 00220 { 00221 stringstream details; 00222 details << " must be greater than " << constraint << " " << message; 00223 throw validation_error<Type>(object,details.str()); 00224 } 00225 } 00226 00228 00239 template <typename Type> 00240 void validate_range(const Type & object, 00241 const Type & low_bound, 00242 const Type & high_bound, 00243 const string & message = string()) 00244 { 00245 if ((object < low_bound) || (object > high_bound)) 00246 { 00247 stringstream details; 00248 details << " must be between " << low_bound << " and " 00249 << high_bound << " " << message; 00250 throw validation_error<Type>(object,details.str()); 00251 } 00252 } 00253 00255 00266 template <typename Type, typename Predicate> 00267 void validate_with(const Type & object, 00268 const Predicate & constraint, 00269 const string & message = string()) 00270 { 00271 if (!constraint(object)) 00272 { 00273 stringstream details; 00274 details << " failed test " << typeid(constraint).name() << " " << message; 00275 throw validation_error<Type>(object,details.str()); 00276 } 00277 } 00278 00280 00286 template <typename Type> 00287 void enforce_lower_limit(Type & object, 00288 const Type & low_value) 00289 { 00290 if (object < low_value) 00291 object = low_value; 00292 } 00293 00295 00301 template <typename Type> 00302 void enforce_upper_limit(Type & object, 00303 const Type & high_value) 00304 { 00305 if (object > high_value) 00306 object = high_value; 00307 } 00308 00310 00319 template <typename Type> 00320 void enforce_range(Type & object, 00321 const Type & low_value, 00322 const Type & high_value) 00323 { 00324 if (object < low_value) 00325 object = low_value; 00326 else if (object > high_value) 00327 object = high_value; 00328 } 00329 00331 00340 inline string build_location_string(const char * filename, long line_no) 00341 { 00342 stringstream text; 00343 text << "in " << filename << ", line " << line_no; 00344 return text.str(); 00345 } 00346 } 00347 00348 // These macros allow validation to be included on a per-compile basis, based on the settings 00349 // of the DEBUG and NDEBUG preprocessor macros. 00350 #if defined(_DEBUG) && !defined(NDEBUG) 00351 #define LIBEVOCOSM_VALIDATE_EQUALS(object,constraint,details) libevocosm::validate_equals(object,constraint,details) 00352 #define LIBEVOCOSM_VALIDATE_NOT(object,constraint,details) libevocosm::validate_not(object,constraint,details) 00353 #define LIBEVOCOSM_VALIDATE_LESS(object,constraint,details) libevocosm::validate_less(object,constraint,details) 00354 #define LIBEVOCOSM_VALIDATE_LESS_EQ(object,constraint,details) libevocosm::validate_less_eq(object,constraint,details) 00355 #define LIBEVOCOSM_VALIDATE_GREATER(object,constraint,details) libevocosm::validate_greater(object,constraint,details) 00356 #define LIBEVOCOSM_VALIDATE_GREATER_EQ(object,constraint,details) libevocosm::validate_greater_eq(object,constraint,details) 00357 #define LIBEVOCOSM_VALIDATE_RANGE(object,low_bound,high_bound,details) libevocosm::validate_range(object,low_bound,high_bound,details) 00358 #define LIBEVOCOSM_VALIDATE_WITH(object,constraint,details) libevocosm::validate_with(object,constraint,details) 00359 #define LIBEVOCOSM_LOCATION libevocosm::build_location_string(__FILE__,__LINE__) 00360 #else 00361 #define LIBEVOCOSM_VALIDATE_EQUALS(object,constraint,details) 00362 #define LIBEVOCOSM_VALIDATE_NOT(object,constraint,details) 00363 #define LIBEVOCOSM_VALIDATE_LESS(object,constraint,details) 00364 #define LIBEVOCOSM_VALIDATE_LESS_EQ(object,constraint,details) 00365 #define LIBEVOCOSM_VALIDATE_GREATER(object,constraint,details) 00366 #define LIBEVOCOSM_VALIDATE_GREATER_EQ(object,constraint,details) 00367 #define LIBEVOCOSM_VALIDATE_RANGE(object,low_bound,high_bound,details) 00368 #define LIBEVOCOSM_VALIDATE_WITH(object,constraint,details) 00369 #define LIBEVOCOSM_LOCATION std::string() 00370 #endif 00371 00372 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.