Line data Source code
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; 46 0 : constrained_value(value_type value) : value_((min)()) 47 : { 48 0 : assign(value); 49 : } 50 : constrained_value& operator=(value_type v) 51 : { 52 : assign(v); 53 : return *this; 54 : } 55 : //! Return the max allowed value (traits method) 56 0 : static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} 57 : //! Return the min allowed value (traits method) 58 0 : static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} 59 : //! Coerce into the representation type 60 0 : operator value_type() const {return value_;} 61 : protected: 62 : value_type value_; 63 : private: 64 0 : 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 0 : if (value+1 < (min)()+1) { 69 0 : value_policies::on_error(value_, value, min_violation); 70 : return; 71 : } 72 0 : if (value > (max)()) { 73 0 : value_policies::on_error(value_, value, max_violation); 74 : return; 75 : } 76 0 : 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. 91 : 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; 106 0 : static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } 107 0 : static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } 108 0 : static void on_error(rep_type, rep_type, violation_enum) 109 : { 110 0 : boost::throw_exception(actual_exception_type()); 111 : } 112 : }; 113 : 114 : 115 : 116 : } } //namespace CV 117 : 118 : 119 : 120 : 121 : #endif