portability/inf.hpp
#ifndef STLPLUS_INF
#define STLPLUS_INF
////////////////////////////////////////////////////////////////////////////////
// Author: Andy Rushton
// Copyright: (c) Southampton University 1999-2004
// (c) Andy Rushton 2004 onwards
// License: BSD License, see ../docs/license.html
// An infinite-precision integer class. This allows calculations on large
// integers to be performed without overflow.
// this class can throw the following exceptions:
// std::out_of_range
// std::overflow_error
// std::invalid_argument
// stlplus::divide_by_zero // why doesn't std have this?
// all of these are derivations of the baseclass:
// std::logic_error
// So you can catch all of them by catching the baseclass
// Warning: inf was never intended to be fast, it is just for programs which
// need a bit of infinite-precision integer arithmetic. For high-performance
// processing, use the Gnu Multi-Precision (GMP) library. The inf type is just
// easier to integrate and is already ported to all platforms and compilers
// that STLplus is ported to.
////////////////////////////////////////////////////////////////////////////////
#include "portability_fixes.hpp"
#include "portability_exceptions.hpp"
#include <string>
#include <iostream>
////////////////////////////////////////////////////////////////////////////////
namespace stlplus
{
////////////////////////////////////////////////////////////////////////////////
class inf
{
public:
//////////////////////////////////////////////////////////////////////////////
// constructors and assignments initialise the inf
// the void constructor initialises to zero, the others initialise to the
// value of the C integer type or the text value contained in the string
inf(void);
explicit inf(short);
explicit inf(unsigned short);
explicit inf(int);
explicit inf(unsigned);
explicit inf(long);
explicit inf(unsigned long);
// exceptions: std::invalid_argument
explicit inf(const std::string&) ;
inf(const inf&);
~inf(void);
// assignments with equivalent behaviour to the constructors
inf& operator = (short);
inf& operator = (unsigned short);
inf& operator = (int);
inf& operator = (unsigned);
inf& operator = (long);
inf& operator = (unsigned long);
// exceptions: std::invalid_argument
inf& operator = (const std::string&) ;
inf& operator = (const inf&);
//////////////////////////////////////////////////////////////////////////////
// conversions back to the C types
// truncate: controls the behaviour when the value is too long for the result
// true: truncate the value
// false: throw an exception
// exceptions: std::overflow_error
short to_short(bool truncate = true) const ;
// exceptions: std::overflow_error
unsigned short to_unsigned_short(bool truncate = true) const ;
// exceptions: std::overflow_error
int to_int(bool truncate = true) const ;
// exceptions: std::overflow_error
unsigned to_unsigned(bool truncate = true) const ;
// exceptions: std::overflow_error
long to_long(bool truncate = true) const ;
// exceptions: std::overflow_error
unsigned long to_unsigned_long(bool truncate = true) const ;
//////////////////////////////////////////////////////////////////////////////
// bitwise manipulation
void resize(unsigned bits);
void reduce(void);
// the number of significant bits in the value
unsigned bits (void) const;
unsigned size (void) const;
// the number of bits that can be accessed by the bit() method (=bits() rounded up to the next byte)
unsigned indexable_bits(void) const;
// exceptions: std::out_of_range
bool bit (unsigned index) const ;
// exceptions: std::out_of_range
bool operator [] (unsigned index) const ;
// exceptions: std::out_of_range
void set (unsigned index) ;
// exceptions: std::out_of_range
void clear (unsigned index) ;
// exceptions: std::out_of_range
void preset (unsigned index, bool value) ;
// exceptions: std::out_of_range
inf slice(unsigned low, unsigned high) const ;
//////////////////////////////////////////////////////////////////////////////
// tests for common values or ranges
bool negative (void) const;
bool natural (void) const;
bool positive (void) const;
bool zero (void) const;
bool non_zero (void) const;
// tests used in if(i) and if(!i)
// operator bool (void) const;
bool operator ! (void) const;
//////////////////////////////////////////////////////////////////////////////
// comparisons
bool operator == (const inf&) const;
bool operator != (const inf&) const;
bool operator < (const inf&) const;
bool operator <= (const inf&) const;
bool operator > (const inf&) const;
bool operator >= (const inf&) const;
//////////////////////////////////////////////////////////////////////////////
// bitwise logic operations
inf& invert (void);
inf operator ~ (void) const;
inf& operator &= (const inf&);
inf operator & (const inf&) const;
inf& operator |= (const inf&);
inf operator | (const inf&) const;
inf& operator ^= (const inf&);
inf operator ^ (const inf&) const;
inf& operator <<= (unsigned shift);
inf operator << (unsigned shift) const;
inf& operator >>= (unsigned shift);
inf operator >> (unsigned shift) const;
//////////////////////////////////////////////////////////////////////////////
// arithmetic operations
inf& negate (void);
inf operator - (void) const;
inf& abs(void);
friend inf abs(const inf&);
inf& operator += (const inf&);
inf operator + (const inf&) const;
inf& operator -= (const inf&);
inf operator - (const inf&) const;
inf& operator *= (const inf&);
inf operator * (const inf&) const;
// exceptions: divide_by_zero
inf& operator /= (const inf&) ;
// exceptions: divide_by_zero
inf operator / (const inf&) const ;
// exceptions: divide_by_zero
inf& operator %= (const inf&) ;
// exceptions: divide_by_zero
inf operator % (const inf&) const ;
// combined division operator - returns the result pair(quotient,remainder) in one go
// exceptions: divide_by_zero
std::pair<inf,inf> divide(const inf&) const ;
//////////////////////////////////////////////////////////////////////////////
// pre- and post- increment and decrement
inf& operator ++ (void);
inf operator ++ (int);
inf& operator -- (void);
inf operator -- (int);
//////////////////////////////////////////////////////////////////////////////
// string representation and I/O
std::string image_debug(void) const;
// conversion to a string representation
// radix must be 10, 2, 8 or 16
// exceptions: std::invalid_argument
std::string to_string(unsigned radix = 10) const;
// conversion from a string
// radix == 0 - radix is deduced from the input - assumed 10 unless number is prefixed by 0b, 0 or 0x
// however, you can specify the radix to be 10, 2, 8 or 16 to force that interpretation
// exceptions: std::invalid_argument
inf& from_string(const std::string&, unsigned radix = 0);
//////////////////////////////////////////////////////////////////////////////
private:
std::string m_data;
public:
const std::string& get_bytes(void) const;
void set_bytes(const std::string&);
};
////////////////////////////////////////////////////////////////////////////////
// redefine friends for gcc v4.1
inf abs(const inf&);
////////////////////////////////////////////////////////////////////////////////
std::ostream& operator << (std::ostream&, const inf&);
std::istream& operator >> (std::istream&, inf&);
////////////////////////////////////////////////////////////////////////////////
} // end namespace stlplus
#endif