Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


validator.h
00001 /*
00002     Evocosm is a C++ framework for implementing evolutionary algorithms.
00003 
00004     Copyright 2011 Scott Robert Ladd. All rights reserved.
00005 
00006     Evocosm is user-supported open source software. Its continued development is dependent
00007     on financial support from the community. You can provide funding by visiting the Evocosm
00008     website at:
00009 
00010         http://www.coyotegulch.com
00011 
00012     You may license Evocosm in one of two fashions:
00013 
00014     1) Simplified BSD License (FreeBSD License)
00015 
00016     Redistribution and use in source and binary forms, with or without modification, are
00017     permitted provided that the following conditions are met:
00018 
00019     1.  Redistributions of source code must retain the above copyright notice, this list of
00020         conditions and the following disclaimer.
00021 
00022     2.  Redistributions in binary form must reproduce the above copyright notice, this list
00023         of conditions and the following disclaimer in the documentation and/or other materials
00024         provided with the distribution.
00025 
00026     THIS SOFTWARE IS PROVIDED BY SCOTT ROBERT LADD ``AS IS'' AND ANY EXPRESS OR IMPLIED
00027     WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00028     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SCOTT ROBERT LADD OR
00029     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00030     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00032     ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00033     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00034     ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 
00036     The views and conclusions contained in the software and documentation are those of the
00037     authors and should not be interpreted as representing official policies, either expressed
00038     or implied, of Scott Robert Ladd.
00039 
00040     2) Closed-Source Proprietary License
00041 
00042     If your project is a closed-source or proprietary project, the Simplified BSD License may
00043     not be appropriate or desirable. In such cases, contact the Evocosm copyright holder to
00044     arrange your purchase of an appropriate license.
00045 
00046     The author can be contacted at:
00047 
00048           scott.ladd@coyotegulch.com
00049           scott.ladd@gmail.com
00050           http:www.coyotegulch.com
00051 */
00052 
00053 #if !defined(LIBEVOCOSM_VALIDATOR_H)
00054 #define LIBEVOCOSM_VALIDATOR_H
00055 
00056 #include <sstream>
00057 #include <stdexcept>
00058 #include <typeinfo>
00059 
00060 namespace libevocosm
00061 {
00062     using std::stringstream;
00063     using std::string;
00064     using std::runtime_error;
00065 
00067 
00075     template <typename Type>
00076     class validation_error : public runtime_error
00077     {
00078     private:
00079         static string build_error_string(const Type & object,
00080                                          const string & details)
00081         {
00082             stringstream message;
00083 
00084             message << "validation error: "
00085                     << typeid(object).name() << " " << object
00086                     << details;
00087 
00088             return message.str();
00089         }
00090 
00091     public:
00093 
00104         validation_error(const Type & object,
00105                          const string & details = string())
00106             : runtime_error(build_error_string(object,details))
00107         {
00108             // nada
00109         }
00110     };
00111 
00113 
00121     template <typename Type>
00122     void validate_equals(const Type & object,
00123                          const Type & constraint,
00124                          const string & message = string())
00125     {
00126         if (object != constraint)
00127         {
00128             stringstream details;
00129             details << " must equal " << constraint << " " << message;
00130             throw validation_error<Type>(object,details.str());
00131         }
00132     }
00133 
00135 
00143     template <typename Type>
00144     void validate_not(const Type & object,
00145                       const Type & constraint,
00146                       const string & message = string())
00147     {
00148         if (object == constraint)
00149         {
00150             stringstream details;
00151             details << " must not equal " << constraint << " " << message;
00152             throw validation_error<Type>(object,details.str());
00153         }
00154     }
00155 
00157 
00165     template <typename Type>
00166     void validate_less(const Type & object,
00167                       const Type & constraint,
00168                       const string & message = string())
00169     {
00170         if (object >= constraint)
00171         {
00172             stringstream details;
00173             details << " must be less than " << constraint << " " << message;
00174             throw validation_error<Type>(object,details.str());
00175         }
00176     }
00177 
00179 
00187     template <typename Type>
00188     void validate_less_eq(const Type & object,
00189                           const Type & constraint,
00190                           const string & message = string())
00191     {
00192         if (object > constraint)
00193         {
00194             stringstream details;
00195             details << " must be less than " << constraint << " " << message;
00196             throw validation_error<Type>(object,details.str());
00197         }
00198     }
00199 
00201 
00209     template <typename Type>
00210     void validate_greater(const Type & object,
00211                       const Type & constraint,
00212                       const string & message = string())
00213     {
00214         if (object <= constraint)
00215         {
00216             stringstream details;
00217             details << " must be greater than " << constraint << " " << message;
00218             throw validation_error<Type>(object,details.str());
00219         }
00220     }
00221 
00223 
00231     template <typename Type>
00232     void validate_greater_eq(const Type & object,
00233                       const Type & constraint,
00234                       const string & message = string())
00235     {
00236         if (object < constraint)
00237         {
00238             stringstream details;
00239             details << " must be greater than " << constraint << " " << message;
00240             throw validation_error<Type>(object,details.str());
00241         }
00242     }
00243 
00245 
00256     template <typename Type>
00257     void validate_range(const Type & object,
00258                         const Type & low_bound,
00259                         const Type & high_bound,
00260                         const string & message = string())
00261     {
00262         if ((object < low_bound) || (object > high_bound))
00263         {
00264             stringstream details;
00265             details << " must be between " << low_bound << " and "
00266                     << high_bound << " " << message;
00267             throw validation_error<Type>(object,details.str());
00268         }
00269     }
00270 
00272 
00283     template <typename Type, typename Predicate>
00284     void validate_with(const Type & object,
00285                        const Predicate & constraint,
00286                        const string & message = string())
00287     {
00288         if (!constraint(object))
00289         {
00290             stringstream details;
00291             details << " failed test " << typeid(constraint).name() << " " << message;
00292             throw validation_error<Type>(object,details.str());
00293         }
00294     }
00295 
00297 
00303     template <typename Type>
00304     void enforce_lower_limit(Type & object,
00305                              const Type & low_value)
00306     {
00307         if (object < low_value)
00308             object = low_value;
00309     }
00310 
00312 
00318     template <typename Type>
00319     void enforce_upper_limit(Type & object,
00320                             const Type & high_value)
00321     {
00322         if (object > high_value)
00323             object = high_value;
00324     }
00325 
00327 
00333     template <typename Type>
00334     void enforce_index(Type & object,
00335                         const Type & array_length)
00336     {
00337         if (object >= array_length)
00338             object = array_length - 1;
00339 
00340         if (object < 0)
00341             object = 0;
00342     }
00343 
00345 
00354     template <typename Type>
00355     void enforce_range(Type & object,
00356                        const Type & low_value,
00357                        const Type & high_value)
00358     {
00359         if (object < low_value)
00360             object = low_value;
00361         else if (object > high_value)
00362             object = high_value;
00363     }
00364 
00366 
00375     inline string build_location_string(const char * filename, long line_no)
00376     {
00377         stringstream text;
00378         text << "in " << filename << ", line " << line_no;
00379         return text.str();
00380     }
00381 }
00382 
00383 // These macros allow validation to be included on a per-compile basis, based on the settings
00384 // of the DEBUG and NDEBUG preprocessor macros.
00385 #if defined(_DEBUG) && !defined(NDEBUG)
00386 #define LIBEVOCOSM_VALIDATE_EQUALS(object,constraint,details) libevocosm::validate_equals(object,constraint,details)
00387 #define LIBEVOCOSM_VALIDATE_NOT(object,constraint,details) libevocosm::validate_not(object,constraint,details)
00388 #define LIBEVOCOSM_VALIDATE_LESS(object,constraint,details) libevocosm::validate_less(object,constraint,details)
00389 #define LIBEVOCOSM_VALIDATE_LESS_EQ(object,constraint,details) libevocosm::validate_less_eq(object,constraint,details)
00390 #define LIBEVOCOSM_VALIDATE_GREATER(object,constraint,details) libevocosm::validate_greater(object,constraint,details)
00391 #define LIBEVOCOSM_VALIDATE_GREATER_EQ(object,constraint,details) libevocosm::validate_greater_eq(object,constraint,details)
00392 #define LIBEVOCOSM_VALIDATE_RANGE(object,low_bound,high_bound,details) libevocosm::validate_range(object,low_bound,high_bound,details)
00393 #define LIBEVOCOSM_VALIDATE_WITH(object,constraint,details) libevocosm::validate_with(object,constraint,details)
00394 #define LIBEVOCOSM_LOCATION libevocosm::build_location_string(__FILE__,__LINE__)
00395 #else
00396 #define LIBEVOCOSM_VALIDATE_EQUALS(object,constraint,details)
00397 #define LIBEVOCOSM_VALIDATE_NOT(object,constraint,details)
00398 #define LIBEVOCOSM_VALIDATE_LESS(object,constraint,details)
00399 #define LIBEVOCOSM_VALIDATE_LESS_EQ(object,constraint,details)
00400 #define LIBEVOCOSM_VALIDATE_GREATER(object,constraint,details)
00401 #define LIBEVOCOSM_VALIDATE_GREATER_EQ(object,constraint,details)
00402 #define LIBEVOCOSM_VALIDATE_RANGE(object,low_bound,high_bound,details)
00403 #define LIBEVOCOSM_VALIDATE_WITH(object,constraint,details)
00404 #define LIBEVOCOSM_LOCATION std::string()
00405 #endif
00406 
00407 #endif

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