5.6. Defining Constrained Value Types
Problem
You want self-validating numerical types to represents numbers with a limited range of valid values such as hours of a day or minutes of an hour.
Solution
When working with dates and times, frequently you will want values that are integers
with a limited range of valid values (i.e., 0 to 59 for seconds of a minute, 0 to 23 for
hours of a day, 0 to 365 for days of a year). Rather than checking these values every time
they are passed to a function, you would probably prefer to have them validated
automatically by overloading the assignment operator. Since there are so many of these
types, it is preferable to implement a single type that can handle this kind of validation
for different numerical ranges. Example
5-10 presents a ConstrainedValue template
class implementation that makes it easy to define ranged integers and other constrained
value types.
Example 5-10. constrained_value.hpp
#ifndef CONSTRAINED_VALUE_HPP #define CONSTRAINED_VALUE_HPP #include <cstdlib> #include <iostream> using namespace std; template<class Policy_T> struct ConstrainedValue { public: // public typedefs typedef typename Policy_T policy_type; typedef typename Policy_T::value_type value_type; typedef ConstrainedValue self; // default constructor ConstrainedValue() : m(Policy_T::default_value) { } ConstrainedValue(const self& x) : m(x.m) { } ConstrainedValue(const value_type& x) { Policy_T::assign(m, x); } operator value_type() const { return m; } // uses the policy ...