You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
121 lines
3.9 KiB
121 lines
3.9 KiB
#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
|
|
|