/******************************************************************************* * PROJECT: GNOME Colorscheme * * AUTHOR: Hubert Matthews * * Copyright (c) 2005 Hubert Matthews * * License: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * *******************************************************************************/ #ifndef __GCS_CHECKED_INT_H #define __GCS_CHECKED_INT_H #include <stdexcept> namespace gcs { /** A policy function for CheckedInt that throws an out-of-range exception * when the value tries to exceed the defined limits */ template <int low, int high> class OutOfBoundsThrower { public: static int RangeCheck(int newVal) { if (newVal < low || newVal > high) { throw std::out_of_range("RangeCheck failed"); } return newVal; } }; /** A policy function for CheckedInt that makes the value wrap around from * the beginning when the value tries to exceed the defined limits */ template <int low, int high> class ModularArithmetic { public: static int RangeCheck(int newVal) { while (newVal >= high) { newVal -= high - low; } while (newVal < low) { newVal += high - low; } return newVal; } }; /** A policy function for CheckedInt that pegs the value at the high or low * limit when the value tries to exceed the defined limits */ template <int low, int high> class SaturatedArithmetic { public: static int RangeCheck(int newVal) { if (newVal > high) { newVal = high; } else if (newVal < low) { newVal = low; } return newVal; } }; /** A range-check integer type * * The upper and lower limit can be defined, as well as the behavior when * the limits are exceeded */ template <int low, int high, template <int, int> class ValueChecker = OutOfBoundsThrower> class CheckedInt : protected ValueChecker<low, high> { public: int value; explicit CheckedInt(int i = low) : value(this->RangeCheck(i)) {} CheckedInt& operator+=(int incr) { value = this->RangeCheck(value + incr); return *this; } CheckedInt& operator++() { *this += 1; return *this; } const CheckedInt operator++(int) { CheckedInt temp(*this); ++*this; return temp; } CheckedInt& operator-=(int incr) { *this += - incr; return *this; } inline operator int() const { return value; } CheckedInt& operator=(int i) { value = this->RangeCheck(i); return *this; } const CheckedInt operator+(const CheckedInt & other) const { return CheckedInt(*this) += other; } CheckedInt& operator*=(int incr) { value = this->RangeCheck(value * incr); return *this; } }; } // namespace gcs #endif // __GCS_CHECKED_INT_H