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