При работе с датами и временем часто возникает необходимость ограничить целые значения диапазоном допустимых значений (т.е для секунд в минуте — от 0 до 59, для часов в сутках от 0 до 23, для дней в году — от 0 до 365). Вместо того чтобы каждый раз проверять эти значения при их передаче в функцию, предпочтительной является их автоматическая проверка с помощью перегруженного оператора присвоения. Так как имеется очень большое количество таких типов, следует реализовать один тип, который сможет работать с подобной проверкой для различных числовых диапазонов. Пример 5.10 представляет реализацию шаблона класса ConstrаinedValue, который облегчает задание диапазона целых чисел и определение других ограниченных типов.

Пример 5.10. constrained_value.hpp

#ifndef CONSTRAINED_VALUE_HPP

#define CONSTRAINED_VALUE_HPP

#include

#include

using namespace std;

template

struct ConstrainedValue {

public:

 // открытые typedef

 typedef typename Policy_T policy_type;

 typedef typename Policy_T::value_type value_type;

 typedef ConstrainedValue self;

 // конструктор по умолчанию

 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; }

 // использует функцию присвоения, определенную политикой

 void assign(const value_type& x) {

  Policy_T::assign(m, x);

 }

 // операции присвоения

 self& operator=(const value_type& x) { assign(x); return *this; }

 self& operator+=(const value_type& x) { assign(m + x) return *this; }

 self& operator-=(const value_type& x) { assign(m - x) return *this; }

 self& operator*=(const value_type& x) { assign(m * x); return *this; }

 self& operator/=(const value_type& x) { assign(m / x); return *this; }

 self& operator%=(const value_type& x) { assign(m % x); return *this; }

 self& operator>>=(int x) { assign(m >> x); return *this; }

 self& operator<<=(int x) { assign(m << x); return *this; }

 // унарные операторы

 self operator-() { return self(-m); }

 self operator+() { return self(-m); }

 self operator!() { return self(!m); }

 self operator~() { return self(~m); }

 // бинарные операторы

 friend self operator+(self x, const value_type& y) { return x += y; }

 friend self operator-(self x, const value_type& y) { return x -= y; }

 friend self operator*(self x, const value_type& y) { return x *= y; }

 friend self operator/{self x, const value_type& y) { return x /= y; }

 friend self operator%(self x, const value_type& y) { return x %= y; }

 friend self operator+(const value_type& y, self x) { return x += y; }

 friend self operator-(const value_type& y, self x) { return x -= y; }

 friend self operator*(const value_type& y, self x) { return x *= y; }

 friend self operator/(const value_type& y, self x) { return x /= y; }

 friend self operator%(const value_type& y, self x) { return x %= y; }

 friend self operator>>(self x, int y) { return x >>= y; }

Перейти на страницу:

Похожие книги