| #ifndef CONSTRAINED_VALUE_HPP___ |
| #define CONSTRAINED_VALUE_HPP___ |
| |
| /* Copyright (c) 2002,2003 CrystalClear Software, Inc. |
| * Use, modification and distribution is subject to the |
| * Boost Software License, Version 1.0. (See accompanying |
| * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) |
| * Author: Jeff Garland |
| * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $ |
| */ |
| |
| #include <exception> |
| #include <stdexcept> |
| #include <boost/config.hpp> |
| #include <boost/throw_exception.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/type_traits/is_base_of.hpp> |
| |
| namespace boost { |
| |
| //! Namespace containing constrained_value template and types |
| namespace CV { |
| //! Represent a min or max violation type |
| enum violation_enum {min_violation, max_violation}; |
| |
| //! A template to specify a constrained basic value type |
| /*! This template provides a quick way to generate |
| * an integer type with a constrained range. The type |
| * provides for the ability to specify the min, max, and |
| * and error handling policy. |
| * |
| * <b>value policies</b> |
| * A class that provides the range limits via the min and |
| * max functions as well as a function on_error that |
| * determines how errors are handled. A common strategy |
| * would be to assert or throw and exception. The on_error |
| * is passed both the current value and the new value that |
| * is in error. |
| * |
| */ |
| template<class value_policies> |
| class constrained_value { |
| public: |
| typedef typename value_policies::value_type value_type; |
| // typedef except_type exception_type; |
| constrained_value(value_type value) : value_((min)()) |
| { |
| assign(value); |
| } |
| constrained_value& operator=(value_type v) |
| { |
| assign(v); |
| return *this; |
| } |
| //! Return the max allowed value (traits method) |
| static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} |
| //! Return the min allowed value (traits method) |
| static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} |
| //! Coerce into the representation type |
| operator value_type() const {return value_;} |
| protected: |
| value_type value_; |
| private: |
| void assign(value_type value) |
| { |
| //adding 1 below gets rid of a compiler warning which occurs when the |
| //min_value is 0 and the type is unsigned.... |
| if (value+1 < (min)()+1) { |
| value_policies::on_error(value_, value, min_violation); |
| return; |
| } |
| if (value > (max)()) { |
| value_policies::on_error(value_, value, max_violation); |
| return; |
| } |
| value_ = value; |
| } |
| }; |
| |
| //! Template to shortcut the constrained_value policy creation process |
| template<typename rep_type, rep_type min_value, |
| rep_type max_value, class exception_type> |
| class simple_exception_policy |
| { |
| struct exception_wrapper : public exception_type |
| { |
| // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode, |
| // we'll have to provide a way to acquire std::exception from the exception being thrown. |
| // However, we cannot derive from it, since it would make it interceptable by this class, |
| // which might not be what the user wanted. |
| operator std::out_of_range () const |
| { |
| // TODO: Make the message more descriptive by using arguments to on_error |
| return std::out_of_range("constrained value boundary has been violated"); |
| } |
| }; |
| |
| typedef typename mpl::if_< |
| is_base_of< std::exception, exception_type >, |
| exception_type, |
| exception_wrapper |
| >::type actual_exception_type; |
| |
| public: |
| typedef rep_type value_type; |
| static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } |
| static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } |
| static void on_error(rep_type, rep_type, violation_enum) |
| { |
| boost::throw_exception(actual_exception_type()); |
| } |
| }; |
| |
| |
| |
| } } //namespace CV |
| |
| |
| |
| |
| #endif |