// Copyright (C) 2003 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_BIGINT_KERNEl_C_ #define DLIB_BIGINT_KERNEl_C_ #include "bigint_kernel_abstract.h" #include "../algs.h" #include "../assert.h" #include namespace dlib { // ---------------------------------------------------------------------------------------- template < typename bigint_base > class bigint_kernel_c { bigint_base data; explicit bigint_kernel_c ( const bigint_base& item ) : data(item) {} public: bigint_kernel_c ( ); bigint_kernel_c ( uint32 value ); bigint_kernel_c ( const bigint_kernel_c& item ); ~bigint_kernel_c ( ); const bigint_kernel_c operator+ ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator+= ( const bigint_kernel_c& rhs ); const bigint_kernel_c operator- ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator-= ( const bigint_kernel_c& rhs ); const bigint_kernel_c operator* ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator*= ( const bigint_kernel_c& rhs ); const bigint_kernel_c operator/ ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator/= ( const bigint_kernel_c& rhs ); const bigint_kernel_c operator% ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator%= ( const bigint_kernel_c& rhs ); bool operator < ( const bigint_kernel_c& rhs ) const; bool operator == ( const bigint_kernel_c& rhs ) const; bigint_kernel_c& operator= ( const bigint_kernel_c& rhs ); template friend std::ostream& operator<< ( std::ostream& out, const bigint_kernel_c& rhs ); template friend std::istream& operator>> ( std::istream& in, bigint_kernel_c& rhs ); bigint_kernel_c& operator++ ( ); const bigint_kernel_c operator++ ( int ); bigint_kernel_c& operator-- ( ); const bigint_kernel_c operator-- ( int ); template friend const bigint_kernel_c operator+ ( uint16 lhs, const bigint_kernel_c& rhs ); template friend const bigint_kernel_c operator+ ( const bigint_kernel_c& lhs, uint16 rhs ); bigint_kernel_c& operator+= ( uint16 rhs ); template friend const bigint_kernel_c operator- ( uint16 lhs, const bigint_kernel_c& rhs ); template friend const bigint_kernel_c operator- ( const bigint_kernel_c& lhs, uint16 rhs ); bigint_kernel_c& operator-= ( uint16 rhs ); template friend const bigint_kernel_c operator* ( uint16 lhs, const bigint_kernel_c& rhs ); template friend const bigint_kernel_c operator* ( const bigint_kernel_c& lhs, uint16 rhs ); bigint_kernel_c& operator*= ( uint16 rhs ); template friend const bigint_kernel_c operator/ ( uint16 lhs, const bigint_kernel_c& rhs ); template friend const bigint_kernel_c operator/ ( const bigint_kernel_c& lhs, uint16 rhs ); bigint_kernel_c& operator/= ( uint16 rhs ); template friend const bigint_kernel_c operator% ( uint16 lhs, const bigint_kernel_c& rhs ); template friend const bigint_kernel_c operator% ( const bigint_kernel_c& lhs, uint16 rhs ); bigint_kernel_c& operator%= ( uint16 rhs ); template friend bool operator < ( uint16 lhs, const bigint_kernel_c& rhs ); template friend bool operator < ( const bigint_kernel_c& lhs, uint16 rhs ); template friend bool operator == ( const bigint_kernel_c& lhs, uint16 rhs ); template friend bool operator == ( uint16 lhs, const bigint_kernel_c& rhs ); bigint_kernel_c& operator= ( uint16 rhs ); void swap ( bigint_kernel_c& item ) { data.swap(item.data); } }; template < typename bigint_base > void swap ( bigint_kernel_c& a, bigint_kernel_c& b ) { a.swap(b); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > inline void serialize ( const bigint_kernel_c& item, std::ostream& out ) { std::ios::fmtflags oldflags = out.flags(); out.flags(); out << item << ' '; out.flags(oldflags); if (!out) throw serialization_error("Error serializing object of type bigint_kernel_c"); } template < typename bigint_base > inline void deserialize ( bigint_kernel_c& item, std::istream& in ) { std::ios::fmtflags oldflags = in.flags(); in.flags(); in >> item; in.flags(oldflags); if (in.get() != ' ') { item = 0; throw serialization_error("Error deserializing object of type bigint_kernel_c"); } } // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // member function definitions // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c:: bigint_kernel_c ( ) {} // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c:: bigint_kernel_c ( uint32 value ) : data(value) { // make sure requires clause is not broken DLIB_CASSERT( value <= 0xFFFFFFFF , "\tbigint::bigint(uint16)" << "\n\t value must be <= (2^32)-1" << "\n\tthis: " << this << "\n\tvalue: " << value ); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c:: bigint_kernel_c ( const bigint_kernel_c& item ) : data(item.data) {} // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c:: ~bigint_kernel_c ( ) {} // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator+ ( const bigint_kernel_c& rhs ) const { return bigint_kernel_c(data + rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator+= ( const bigint_kernel_c& rhs ) { data += rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator- ( const bigint_kernel_c& rhs ) const { // make sure requires clause is not broken DLIB_CASSERT( !(*this < rhs), "\tconst bigint bigint::operator-(const bigint&)" << "\n\t *this should not be less than rhs" << "\n\tthis: " << this << "\n\t*this: " << *this << "\n\trhs: " << rhs ); // call the real function return bigint_kernel_c(data-rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator-= ( const bigint_kernel_c& rhs ) { // make sure requires clause is not broken DLIB_CASSERT( !(*this < rhs), "\tbigint& bigint::operator-=(const bigint&)" << "\n\t *this should not be less than rhs" << "\n\tthis: " << this << "\n\t*this: " << *this << "\n\trhs: " << rhs ); // call the real function data -= rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator* ( const bigint_kernel_c& rhs ) const { return bigint_kernel_c(data * rhs.data ); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator*= ( const bigint_kernel_c& rhs ) { data *= rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator/ ( const bigint_kernel_c& rhs ) const { //make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0), "\tconst bigint bigint::operator/(const bigint&)" << "\n\t can't divide by zero" << "\n\tthis: " << this ); // call the real function return bigint_kernel_c(data/rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator/= ( const bigint_kernel_c& rhs ) { // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0), "\tbigint& bigint::operator/=(const bigint&)" << "\n\t can't divide by zero" << "\n\tthis: " << this ); // call the real function data /= rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator% ( const bigint_kernel_c& rhs ) const { // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0), "\tconst bigint bigint::operator%(const bigint&)" << "\n\t can't divide by zero" << "\n\tthis: " << this ); // call the real function return bigint_kernel_c(data%rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator%= ( const bigint_kernel_c& rhs ) { // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0), "\tbigint& bigint::operator%=(const bigint&)" << "\n\t can't divide by zero" << "\n\tthis: " << this ); // call the real function data %= rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool bigint_kernel_c:: operator < ( const bigint_kernel_c& rhs ) const { return data < rhs.data; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool bigint_kernel_c:: operator == ( const bigint_kernel_c& rhs ) const { return data == rhs.data; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator= ( const bigint_kernel_c& rhs ) { data = rhs.data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > std::ostream& operator<< ( std::ostream& out, const bigint_kernel_c& rhs ) { out << rhs.data; return out; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > std::istream& operator>> ( std::istream& in, bigint_kernel_c& rhs ) { in >> rhs.data; return in; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator++ ( ) { ++data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator++ ( int ) { return bigint_kernel_c(data++); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator-- ( ) { // make sure requires clause is not broken DLIB_CASSERT( !(*this == 0), "\tbigint& bigint::operator--()" << "\n\t *this to subtract from *this it must not be zero to begin with" << "\n\tthis: " << this ); // call the real function --data; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c bigint_kernel_c:: operator-- ( int ) { // make sure requires clause is not broken DLIB_CASSERT( !(*this == 0), "\tconst bigint bigint::operator--(int)" << "\n\t *this to subtract from *this it must not be zero to begin with" << "\n\tthis: " << this ); // call the real function return bigint_kernel_c(data--); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator+ ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( lhs <= 65535, "\tconst bigint operator+(uint16, const bigint&)" << "\n\t lhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return bigint_kernel_c(static_cast(lhs)+rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator+ ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tconst bigint operator+(const bigint&, uint16)" << "\n\t rhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return bigint_kernel_c(lhs.data+static_cast(rhs)); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator+= ( uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tbigint& bigint::operator+=(uint16)" << "\n\t rhs must be <= 65535" << "\n\tthis: " << this << "\n\t*this: " << *this << "\n\trhs: " << rhs ); data += rhs; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator- ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( !(static_cast(lhs) < rhs) && lhs <= 65535, "\tconst bigint operator-(uint16,const bigint&)" << "\n\t lhs must be greater than or equal to rhs and lhs <= 65535" << "\n\tlhs: " << lhs << "\n\trhs: " << rhs << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs ); // call the real function return bigint_kernel_c(static_cast(lhs)-rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator- ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( !(lhs < static_cast(rhs)) && rhs <= 65535, "\tconst bigint operator-(const bigint&,uint16)" << "\n\t lhs must be greater than or equal to rhs and rhs <= 65535" << "\n\tlhs: " << lhs << "\n\trhs: " << rhs << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs ); // call the real function return bigint_kernel_c(lhs.data-static_cast(rhs)); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator-= ( uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( !(*this < static_cast(rhs)) && rhs <= 65535, "\tbigint& bigint::operator-=(uint16)" << "\n\t *this must not be less than rhs and rhs <= 65535" << "\n\tthis: " << this << "\n\t*this: " << *this << "\n\trhs: " << rhs ); // call the real function data -= static_cast(rhs); return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator* ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( lhs <= 65535, "\tconst bigint operator*(uint16, const bigint&)" << "\n\t lhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return bigint_kernel_c(lhs*rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator* ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tconst bigint operator*(const bigint&, uint16)" << "\n\t rhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return bigint_kernel_c(lhs.data*rhs); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator*= ( uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\t bigint bigint::operator*=(uint16)" << "\n\t rhs must be <= 65535" << "\n\tthis: " << this << "\n\t*this: " << *this << "\n\trhs: " << rhs ); data *= static_cast(rhs); return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator/ ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && lhs <= 65535, "\tconst bigint operator/(uint16,const bigint&)" << "\n\t you can't divide by zero and lhs <= 65535" << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs << "\n\tlhs: " << lhs ); // call the real function return bigint_kernel_c(lhs/rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator/ ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && rhs <= 65535, "\tconst bigint operator/(const bigint&,uint16)" << "\n\t you can't divide by zero and rhs <= 65535" << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs << "\n\trhs: " << rhs ); // call the real function return bigint_kernel_c(lhs.data/static_cast(rhs)); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator/= ( uint16 rhs ) { // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && static_cast(rhs) <= 65535, "\tbigint& bigint::operator/=(uint16)" << "\n\t you can't divide by zero and rhs must be <= 65535" << "\n\tthis: " << this << "\n\trhs: " << rhs ); // call the real function data /= rhs; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator% ( uint16 lhs, const bigint_kernel_c& rhs ) { // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && static_cast(lhs) <= 65535, "\tconst bigint operator%(uint16,const bigint&)" << "\n\t you can't divide by zero and lhs must be <= 65535" << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs << "\n\tlhs: " << lhs ); // call the real function return bigint_kernel_c(lhs%rhs.data); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > const bigint_kernel_c operator% ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && rhs <= 65535, "\tconst bigint operator%(const bigint&,uint16)" << "\n\t you can't divide by zero and rhs must be <= 65535" << "\n\t&lhs: " << &lhs << "\n\t&rhs: " << &rhs << "\n\trhs: " << rhs ); // call the real function return bigint_kernel_c(lhs.data%static_cast(rhs)); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator%= ( uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( !(rhs == 0) && rhs <= 65535, "\tbigint& bigint::operator%=(uint16)" << "\n\t you can't divide by zero and rhs must be <= 65535" << "\n\tthis: " << this << "\n\trhs: " << rhs ); // call the real function data %= rhs; return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool operator < ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( lhs <= 65535, "\tbool operator<(uint16, const bigint&)" << "\n\t lhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return static_cast(lhs) < rhs.data; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool operator < ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tbool operator<(const bigint&, uint16)" << "\n\t rhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return lhs.data < static_cast(rhs); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool operator == ( const bigint_kernel_c& lhs, uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tbool operator==(const bigint&, uint16)" << "\n\t rhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return lhs.data == static_cast(rhs); } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bool operator == ( uint16 l, const bigint_kernel_c& rhs ) { uint32 lhs = l; // make sure requires clause is not broken DLIB_CASSERT( lhs <= 65535, "\tbool operator==(uint16, const bigint&)" << "\n\t lhs must be <= 65535" << "\n\trhs: " << rhs << "\n\tlhs: " << lhs ); return static_cast(lhs) == rhs.data; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > bigint_kernel_c& bigint_kernel_c:: operator= ( uint16 r ) { uint32 rhs = r; // make sure requires clause is not broken DLIB_CASSERT( rhs <= 65535, "\tbigint bigint::operator=(uint16)" << "\n\t rhs must be <= 65535" << "\n\t*this: " << *this << "\n\tthis: " << this << "\n\tlhs: " << rhs ); data = static_cast(rhs); return *this; } // ---------------------------------------------------------------------------------------- template < typename bigint_base > inline bool operator> (const bigint_kernel_c& a, const bigint_kernel_c& b) { return b < a; } template < typename bigint_base > inline bool operator!= (const bigint_kernel_c& a, const bigint_kernel_c& b) { return !(a == b); } template < typename bigint_base > inline bool operator<= (const bigint_kernel_c& a, const bigint_kernel_c& b) { return !(b < a); } template < typename bigint_base > inline bool operator>= (const bigint_kernel_c& a, const bigint_kernel_c& b) { return !(a < b); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_BIGINT_KERNEl_C_