//////////////////////////////////////////////////////////////////////////////
// $Id: Byte.h,v 1.1.1.1 2003/09/15 16:37:52 nthiery Exp $
// Name:	Byte.h
// Purpose:	Class Byte for very small non negative integers
//		(User interface)
// Author:	Nicolas M. Thiéry <nthiery@mines.edu>
// Created:	2000/08
// Copyright:	LGPL
//////////////////////////////////////////////////////////////////////////////

// Specifications:
//  - a Byte can hold any integer value in the range 0,...,255
//  - integer arithmetic works as usual, as long as there is no overflow
//  - no range checks!
//
// Implementation:
//  - Typically just a wrapper around unsigned char, with automatic
//    conversions and redefinition of << and >>.

#ifndef GLIP_BYTE_H
#define GLIP_BYTE_H

#include <iostream>

namespace GLIP {
  
  class ByteBinOp;		// Implementation with binary operators
  class ByteConv;		// Implementation with implicit conversions
  				// See Stroustrup's Book, Ch. 11.4
  
  typedef ByteConv Byte;	// Unless specific problem, use Byte

  // Implementation
  
  class ByteBinOp {
  private:
    typedef ByteBinOp Byte;
    unsigned char c;
  public:
    
    // Constructors and operators for automagic conversions 

    explicit ByteBinOp(unsigned char c_=0) : c(c_) {};
    
    operator unsigned char() const { return c; };
    
    Byte& operator =  (int c_) { c=c_;   return *this; }

    // Input/output operators
    // Those are (hopefully) the only operations where Byte's and
    // unsigned char's have different behaviour.

    friend std::istream& operator >> (std::istream &i, Byte &b) {
      int v;
      i >> v;
      b.c=v;
      return i;
    }
    friend std::ostream& operator << (std::ostream &o, Byte b) {
      return o << int(b.c);
    }

    // Usual arithmetic operators (members)
    
    Byte& operator += (Byte b) { c+=b.c; return *this; }
    Byte& operator -= (Byte b) { c-=b.c; return *this; }
    Byte& operator *= (Byte b) { c*=b.c; return *this; }
    Byte& operator /= (Byte b) { c/=b.c; return *this; }
    Byte& operator %= (Byte b) { c%=b.c; return *this; }

    // Should unary '+' return a Byte or Byte& ?
    Byte  operator +  ()       { return Byte(c);       }
    // Unary '-' shall not be defined! 
    
    Byte& operator ++ ()       { ++c;    return *this; }
    Byte& operator -- ()       { --c;    return *this; }

    Byte  operator ++ (int)    { return Byte(c++);     }
    Byte  operator -- (int)    { return Byte(c--);     }

    // Other usual arithmetic binary operators (non members)
    
    friend bool operator ==(Byte b1, Byte b2) { return b1.c==b2.c;}
    friend bool operator !=(Byte b1, Byte b2) { return b1.c!=b2.c;}

    friend bool operator < (Byte b1, Byte b2) { return b1.c< b2.c;}
    friend bool operator > (Byte b1, Byte b2) { return b1.c> b2.c;}
    friend bool operator <=(Byte b1, Byte b2) { return b1.c<=b2.c;}
    friend bool operator >=(Byte b1, Byte b2) { return b1.c>=b2.c;}

    friend Byte operator + (Byte b1, Byte b2) { return Byte(b1.c+b2.c); }
    friend Byte operator - (Byte b1, Byte b2) { return Byte(b1.c-b2.c); }
    friend Byte operator * (Byte b1, Byte b2) { return Byte(b1.c*b2.c); }
    friend Byte operator / (Byte b1, Byte b2) { return Byte(b1.c/b2.c); }
    friend Byte operator % (Byte b1, Byte b2) { return Byte(b1.c%b2.c); }

  };

  class ByteConv {
  private:
    typedef ByteConv Byte;
    unsigned char c;
    void assign(int i) { /*range check*/ c=i; };
  public:
    
    // Constructors and operators for automagic conversions 

    ByteConv         (int i=0) { assign(i);                 };
    Byte& operator = (int i)   { assign(i);   return *this; }
    operator int() const { return c; };
    // Input/output operators
    // Those are (hopefully) the only operations where Byte's and
    // unsigned char's have different behaviour.

    friend std::istream& operator >> (std::istream &i, Byte &b) {
      int v;
      i >> v;
      b.c=v;
      return i;
    }
    friend std::ostream& operator << (std::ostream &o, Byte b) {
      return o << int(b.c);
    }

    // Usual arithmetic operators (members)
    
    Byte& operator += (Byte b) { c+=b.c; return *this; }
    Byte& operator -= (Byte b) { c-=b.c; return *this; }
    Byte& operator *= (Byte b) { c*=b.c; return *this; }
    Byte& operator /= (Byte b) { c/=b.c; return *this; }
    Byte& operator %= (Byte b) { c%=b.c; return *this; }

    // Should unary '+' return a Byte or Byte& ?
    Byte  operator +  ()       { return Byte(c);       }
    // Unary '-' shall not be defined! 
    
    Byte& operator ++ ()       { ++c;    return *this; }
    Byte& operator -- ()       { --c;    return *this; }

    Byte  operator ++ (int)    { return Byte(c++);     }
    Byte  operator -- (int)    { return Byte(c--);     }

  };
  
}	// namespace GLIP

#endif	/* GLIP_BYTE_H */

// Local Variables: 
// mode: c++
// End: 
