X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fstlplus%2Fportability%2Finf.hpp;fp=src%2Fstlplus%2Fportability%2Finf.hpp;h=f28541af6bf9ce7083ffb4f7b26aeb9c8f807321;hb=6b0a0d0efafe34d48ab344fca3b479553bd4e62c;hp=0000000000000000000000000000000000000000;hpb=85783316365181491a3e3c0c63659972477cebba;p=chaz%2Fyoink diff --git a/src/stlplus/portability/inf.hpp b/src/stlplus/portability/inf.hpp new file mode 100644 index 0000000..f28541a --- /dev/null +++ b/src/stlplus/portability/inf.hpp @@ -0,0 +1,228 @@ +#ifndef STLPLUS_INF +#define STLPLUS_INF +//////////////////////////////////////////////////////////////////////////////// + +// Author: Andy Rushton +// Copyright: (c) Southampton University 1999-2004 +// (c) Andy Rushton 2004-2009 +// 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 +#include + +//////////////////////////////////////////////////////////////////////////////// + +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); + explicit inf(const std::string&) throw(std::invalid_argument); + 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); + inf& operator = (const std::string&) throw(std::invalid_argument); + 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 + + short to_short(bool truncate = true) const throw(std::overflow_error); + unsigned short to_unsigned_short(bool truncate = true) const throw(std::overflow_error); + + int to_int(bool truncate = true) const throw(std::overflow_error); + unsigned to_unsigned(bool truncate = true) const throw(std::overflow_error); + + long to_long(bool truncate = true) const throw(std::overflow_error); + unsigned long to_unsigned_long(bool truncate = true) const throw(std::overflow_error); + + ////////////////////////////////////////////////////////////////////////////// + // 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; + + bool bit (unsigned index) const throw(std::out_of_range); + bool operator [] (unsigned index) const throw(std::out_of_range); + + void set (unsigned index) throw(std::out_of_range); + void clear (unsigned index) throw(std::out_of_range); + void preset (unsigned index, bool value) throw(std::out_of_range); + + inf slice(unsigned low, unsigned high) const throw(std::out_of_range); + + ////////////////////////////////////////////////////////////////////////////// + // 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; + + inf& operator /= (const inf&) throw(divide_by_zero); + inf operator / (const inf&) const throw(divide_by_zero); + + inf& operator %= (const inf&) throw(divide_by_zero); + inf operator % (const inf&) const throw(divide_by_zero); + + // combined division operator - returns the result pair(quotient,remainder) in one go + std::pair divide(const inf&) const throw(divide_by_zero); + + ////////////////////////////////////////////////////////////////////////////// + // 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 + std::string to_string(unsigned radix = 10) const + throw(std::invalid_argument); + + // 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 + inf& from_string(const std::string&, unsigned radix = 0) + throw(std::invalid_argument); + + ////////////////////////////////////////////////////////////////////////////// + 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