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/type_traits/conditional.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 BOOST_CXX14_CONSTEXPR constrained_value(value_type value) : value_((min)()) 47 { 48 assign(value); 49 } operator =(value_type v)50 BOOST_CXX14_CONSTEXPR constrained_value& operator=(value_type v) 51 { 52 assign(v); 53 return *this; 54 } 55 //! Return the max allowed value (traits method) 56 static BOOST_CONSTEXPR value_type BOOST_PREVENT_MACRO_SUBSTITUTION()57 max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} 58 59 //! Return the min allowed value (traits method) 60 static BOOST_CONSTEXPR value_type BOOST_PREVENT_MACRO_SUBSTITUTION()61 min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} 62 63 //! Coerce into the representation type operator value_type() const64 BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;} 65 protected: 66 value_type value_; 67 private: assign(value_type value)68 BOOST_CXX14_CONSTEXPR void assign(value_type value) 69 { 70 //adding 1 below gets rid of a compiler warning which occurs when the 71 //min_value is 0 and the type is unsigned.... 72 if (value+1 < (min)()+1) { 73 value_policies::on_error(value_, value, min_violation); 74 return; 75 } 76 if (value > (max)()) { 77 value_policies::on_error(value_, value, max_violation); 78 return; 79 } 80 value_ = value; 81 } 82 }; 83 84 //! Template to shortcut the constrained_value policy creation process 85 template<typename rep_type, rep_type min_value, 86 rep_type max_value, class exception_type> 87 class BOOST_SYMBOL_VISIBLE simple_exception_policy 88 { 89 struct BOOST_SYMBOL_VISIBLE exception_wrapper : public exception_type 90 { 91 // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode, 92 // we'll have to provide a way to acquire std::exception from the exception being thrown. 93 // However, we cannot derive from it, since it would make it interceptable by this class, 94 // which might not be what the user wanted. operator std::out_of_rangeboost::CV::simple_exception_policy::exception_wrapper95 operator std::out_of_range () const 96 { 97 // TODO: Make the message more descriptive by using arguments to on_error 98 return std::out_of_range("constrained value boundary has been violated"); 99 } 100 }; 101 102 typedef typename conditional< 103 is_base_of< std::exception, exception_type >::value, 104 exception_type, 105 exception_wrapper 106 >::type actual_exception_type; 107 108 public: 109 typedef rep_type value_type; 110 static BOOST_CONSTEXPR rep_type BOOST_PREVENT_MACRO_SUBSTITUTION()111 min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } 112 113 static BOOST_CONSTEXPR rep_type BOOST_PREVENT_MACRO_SUBSTITUTION()114 max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } 115 on_error(rep_type,rep_type,violation_enum)116 static void on_error(rep_type, rep_type, violation_enum) 117 { 118 boost::throw_exception(actual_exception_type()); 119 } 120 }; 121 122 123 124 } } //namespace CV 125 126 127 128 129 #endif 130