//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / COMMON
//
//File: moduloint.h
//
//Version: $Revision: 1.7 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/09/28 05:11:14 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      Class for integers using modulo arithmetic
//     This class implements integers that use modulo arithmetic.
//     User selects modulus as a constructor parameter. Most common
//     operators are defined for moduloIntegers, in binary operators
//     the other argument can be either moduloInteger or unsigned long.
//     NOTE: Some operators return unsigned long instead of class to
//     make them more practical to use.
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 
//
//

#ifndef __COMMON_MODULOINT_H__
#define __COMMON_MODULOINT_H__

#include <typeinfo>

class moduloInteger
{
    public:
        moduloInteger(unsigned long modulus_);
        moduloInteger(const moduloInteger &other_);
        virtual ~moduloInteger(void);

        unsigned long getValue(void) const;
        unsigned long getModulus(void) const;

        const moduloInteger &operator=(unsigned long value_);
        const moduloInteger &operator=(const moduloInteger &other_);
        int operator==(unsigned long value_) const;
        int operator==(const moduloInteger &other_) const;
        int operator!=(unsigned long value_) const;
        int operator!=(const moduloInteger &other_) const;
        int operator<(unsigned long value_) const;
        int operator<(const moduloInteger &other_) const;
        int operator>(unsigned long value_) const;
        int operator>(const moduloInteger &other_) const;
        int operator<=(unsigned long value_) const;
        int operator<=(const moduloInteger &other_) const;
        int operator>=(unsigned long value_) const;
        int operator>=(const moduloInteger &other_) const;
        unsigned long operator+(unsigned long value_) const;
        unsigned long operator+(const moduloInteger &other_) const;
        unsigned long operator-(unsigned long value_) const;
        unsigned long operator-(const moduloInteger &other_) const;
        unsigned long operator+=(unsigned long value_);
        unsigned long operator+=(const moduloInteger &other_);
        unsigned long operator-=(unsigned long value_);
        unsigned long operator-=(const moduloInteger &other_);
        unsigned long operator++(void);
        unsigned long operator--(void);
        unsigned long operator++(int);
        unsigned long operator--(int);

        static int compareWithBase(const moduloInteger &left_,
                                   const moduloInteger &right_,
                                   const moduloInteger &base_);
        
        friend unsigned long operator+(unsigned long lhs_,
                                       const moduloInteger &rhs_);
        friend unsigned long operator-(unsigned long lhs_,
                                       const moduloInteger &rhs_);
        friend int operator==(unsigned long lhs_,
                              const moduloInteger &rhs_);
        friend int operator!=(unsigned long lhs_,
                              const moduloInteger &rhs_);
        friend int operator<(unsigned long lhs_,
                             const moduloInteger &rhs_);
        friend int operator>(unsigned long lhs_,
                             const moduloInteger &rhs_);
        friend int operator<=(unsigned long lhs_,
                              const moduloInteger &rhs_);
        friend int operator>=(unsigned long lhs_,
                              const moduloInteger &rhs_);

    private:
        unsigned long _value;
        unsigned long _modulus;
};

#endif // __COMMON_MODULOINT_H__

