Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / date_time / constrained_value.hpp
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     constrained_value(value_type value) : value_((min)())
47     {
48       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     static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}
57     //! Return the min allowed value (traits method)
58     static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}
59     //! Coerce into the representation type
60     operator value_type() const {return value_;}
61   protected:
62     value_type value_;
63   private:
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.
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     static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }
107     static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; }
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