Sophie

Sophie

distrib > Mandriva > 2009.1 > x86_64 > by-pkgid > e447967e21fe00b997923c01e1eb38ae > files > 6

agave-debug-0.4.5-1mdv2008.1.x86_64.rpm

/*******************************************************************************
 *  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