libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


validator.h

00001 //---------------------------------------------------------------------
00002 //  Algorithmic Conjurings @ http://www.coyotegulch.com
00003 //
00004 //  validator.h (libcoyotl)
00005 //
00006 //  Templatized validation and constraint enforcement functions.
00007 //---------------------------------------------------------------------
00008 //
00009 //  Copyright 1990-2005 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(LIBCOYOTL_VALIDATOR_H)
00037 #define LIBCOYOTL_VALIDATOR_H
00038 
00039 #include <sstream>
00040 #include <stdexcept>
00041 #include <typeinfo>
00042 
00043 namespace libcoyotl
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 LIBCOYOTL_VALIDATE_EQUALS(object,constraint,details) libcoyotl::validate_equals(object,constraint,details)
00352 #define LIBCOYOTL_VALIDATE_NOT(object,constraint,details) libcoyotl::validate_not(object,constraint,details)
00353 #define LIBCOYOTL_VALIDATE_LESS(object,constraint,details) libcoyotl::validate_less(object,constraint,details)
00354 #define LIBCOYOTL_VALIDATE_LESS_EQ(object,constraint,details) libcoyotl::validate_less_eq(object,constraint,details)
00355 #define LIBCOYOTL_VALIDATE_GREATER(object,constraint,details) libcoyotl::validate_greater(object,constraint,details)
00356 #define LIBCOYOTL_VALIDATE_GREATER_EQ(object,constraint,details) libcoyotl::validate_greater_eq(object,constraint,details)
00357 #define LIBCOYOTL_VALIDATE_RANGE(object,low_bound,high_bound,details) libcoyotl::validate_range(object,low_bound,high_bound,details)
00358 #define LIBCOYOTL_VALIDATE_WITH(object,constraint,details) libcoyotl::validate_with(object,constraint,details)
00359 #define LIBCOYOTL_LOCATION libcoyotl::build_location_string(__FILE__,__LINE__)
00360 #else
00361 #define LIBCOYOTL_VALIDATE_EQUALS(object,constraint,details)
00362 #define LIBCOYOTL_VALIDATE_NOT(object,constraint,details)
00363 #define LIBCOYOTL_VALIDATE_LESS(object,constraint,details)
00364 #define LIBCOYOTL_VALIDATE_LESS_EQ(object,constraint,details)
00365 #define LIBCOYOTL_VALIDATE_GREATER(object,constraint,details)
00366 #define LIBCOYOTL_VALIDATE_GREATER_EQ(object,constraint,details)
00367 #define LIBCOYOTL_VALIDATE_RANGE(object,low_bound,high_bound,details)
00368 #define LIBCOYOTL_VALIDATE_WITH(object,constraint,details)
00369 #define LIBCOYOTL_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.