1 #ifndef CONSTRAINED_VALUE_HPP___ 2 #define CONSTRAINED_VALUE_HPP___ 3 4 /* Copyright (c) 2002,2003 CrystalClear Software, Inc. 5 * Use, modification and distribution is subject to the 6 * Boost Software License, Version 1.0. (See accompanying 7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 8 * Author: Jeff Garland 9 * $Date$ 10 */ 11 12 #include <exception> 13 #include <stdexcept> 14 #include <boost/config.hpp> 15 #include <boost/throw_exception.hpp> 16 #include <boost/mpl/if.hpp> 17 #include <boost/type_traits/is_base_of.hpp> 18 19 namespace boost { 20 21 //! Namespace containing constrained_value template and types 22 namespace CV { 23 //! Represent a min or max violation type 24 enum violation_enum {min_violation, max_violation}; 25 26 //! A template to specify a constrained basic value type 27 /*! This template provides a quick way to generate 28 * an integer type with a constrained range. The type 29 * provides for the ability to specify the min, max, and 30 * and error handling policy. 31 * 32 * <b>value policies</b> 33 * A class that provides the range limits via the min and 34 * max functions as well as a function on_error that 35 * determines how errors are handled. A common strategy 36 * would be to assert or throw and exception. The on_error 37 * is passed both the current value and the new value that 38 * is in error. 39 * 40 */ 41 template<class value_policies> 42 class BOOST_SYMBOL_VISIBLE constrained_value { 43 public: 44 typedef typename value_policies::value_type value_type; 45 // typedef except_type exception_type; constrained_value(value_type value)46 constrained_value(value_type value) : value_((min)()) 47 { 48 assign(value); 49 } operator =(value_type v)50 constrained_value& operator=(value_type v) 51 { 52 assign(v); 53 return *this; 54 } 55 //! Return the max allowed value (traits method) BOOST_PREVENT_MACRO_SUBSTITUTION()56 static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} 57 //! Return the min allowed value (traits method) BOOST_PREVENT_MACRO_SUBSTITUTION()58 static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} 59 //! Coerce into the representation type operator value_type() const60 operator value_type() const {return value_;} 61 protected: 62 value_type value_; 63 private: assign(value_type value)64 void assign(value_type value) 65 { 66 //adding 1 below gets rid of a compiler warning which occurs when the 67 //min_value is 0 and the type is unsigned.... 68 if (value+1 < (min)()+1) { 69 value_policies::on_error(value_, value, min_violation); 70 return; 71 } 72 if (value > (max)()) { 73 value_policies::on_error(value_, value, max_violation); 74 return; 75 } 76 value_ = value; 77 } 78 }; 79 80 //! Template to shortcut the constrained_value policy creation process 81 template<typename rep_type, rep_type min_value, 82 rep_type max_value, class exception_type> 83 class BOOST_SYMBOL_VISIBLE simple_exception_policy 84 { 85 struct BOOST_SYMBOL_VISIBLE exception_wrapper : public exception_type 86 { 87 // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode, 88 // we'll have to provide a way to acquire std::exception from the exception being thrown. 89 // However, we cannot derive from it, since it would make it interceptable by this class, 90 // which might not be what the user wanted. operator std::out_of_rangeboost::CV::simple_exception_policy::exception_wrapper91 operator std::out_of_range () const 92 { 93 // TODO: Make the message more descriptive by using arguments to on_error 94 return std::out_of_range("constrained value boundary has been violated"); 95 } 96 }; 97 98 typedef typename mpl::if_< 99 is_base_of< std::exception, exception_type >, 100 exception_type, 101 exception_wrapper 102 >::type actual_exception_type; 103 104 public: 105 typedef rep_type value_type; BOOST_PREVENT_MACRO_SUBSTITUTION()106 static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } BOOST_PREVENT_MACRO_SUBSTITUTION()107 static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } on_error(rep_type,rep_type,violation_enum)108 static void on_error(rep_type, rep_type, violation_enum) 109 { 110 boost::throw_exception(actual_exception_type()); 111 } 112 }; 113 114 115 116 } } //namespace CV 117 118 119 120 121 #endif 122