29 #ifndef REAL_INFININT_HPP
30 #define REAL_INFININT_HPP
32 #include "../my_config.h"
37 #include <sys/types.h>
48 #define ZEROED_SIZE 50
65 #if SIZEOF_OFF_T > SIZEOF_TIME_T
66 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
67 infinint(off_t a = 0) { infinint_from(a); };
69 infinint(
size_t a = 0) { infinint_from(a); };
72 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
73 infinint(time_t a = 0) { infinint_from(a); };
75 infinint(
size_t a = 0) { infinint_from(a); };
82 infinint(
infinint && ref) noexcept { field =
nullptr; move_from(std::move(ref)); };
84 infinint & operator = (
const infinint & ref) { detruit(); copy_from(ref);
return *
this; };
85 infinint & operator = (infinint && ref) noexcept { move_from(std::move(ref));
return *
this; }
87 ~infinint() { detruit(); };
89 void dump(proto_generic_file &x)
const;
90 void read(proto_generic_file &f) { detruit(); build_from_file(f); };
92 infinint & operator += (
const infinint & ref);
93 infinint & operator -= (
const infinint & ref);
94 infinint & operator *= (
unsigned char arg);
95 infinint & operator *= (
const infinint & ref);
96 template <
class T> infinint power(
const T & exponent)
const;
97 inline infinint & operator /= (
const infinint & ref);
98 inline infinint & operator %= (
const infinint & ref);
99 infinint & operator &= (
const infinint & ref);
100 infinint & operator |= (
const infinint & ref);
101 infinint & operator ^= (
const infinint & ref);
102 infinint & operator >>= (U_32 bit);
103 infinint & operator >>= (infinint bit);
104 infinint & operator <<= (U_32 bit);
105 infinint & operator <<= (infinint bit);
106 infinint operator ++(
int a)
107 { infinint ret = *
this; ++(*this);
return ret; };
108 infinint operator --(
int a)
109 { infinint ret = *
this; --(*this);
return ret; };
110 infinint & operator ++()
111 {
return *
this += 1; };
112 infinint & operator --()
113 {
return *
this -= 1; };
115 U_32 operator % (U_32 arg)
const
116 {
return modulo(arg); };
125 { infinint_unstack_to(v); }
144 static bool is_system_big_endian();
147 static constexpr
int TG = 4;
149 enum endian { big_endian, little_endian, not_initialized };
150 using group =
unsigned char[TG];
154 bool is_valid() const noexcept;
157 void copy_from(const
infinint & ref);
158 void move_from(
infinint && ref) noexcept { std::swap(field, ref.field); };
160 void make_at_least_as_wider_as(
const infinint & ref);
161 template <
class T>
void infinint_from(T a);
162 template <
class T> T max_val_of(T x);
163 template <
class T>
void infinint_unstack_to(T &a);
164 template <
class T> T modulo(T arg)
const;
165 signed int difference(
const infinint & b)
const;
170 static endian used_endian;
171 static U_8 zeroed_field[ZEROED_SIZE];
172 static void setup_endian();
176 #define OPERATOR(OP) inline bool operator OP (const infinint &a, const infinint &b) \
178 return a.difference(b) OP 0; \
188 infinint operator + (const infinint &, const infinint &);
189 infinint operator - (const infinint &, const infinint &);
190 infinint operator * (const infinint &, const infinint &);
191 infinint operator * (const infinint &, const
unsigned char);
192 infinint operator * (const
unsigned char, const infinint &);
193 infinint operator / (const infinint &, const infinint &);
194 infinint operator % (const infinint &, const infinint &);
195 infinint operator & (const infinint & a, const infinint & bit);
196 infinint operator | (const infinint & a, const infinint & bit);
197 infinint operator ^ (const infinint & a, const infinint & bit);
198 infinint operator >> (const infinint & a, U_32 bit);
199 infinint operator >> (const infinint & a, const infinint & bit);
200 infinint operator << (const infinint & a, U_32 bit);
201 infinint operator << (const infinint & a, const infinint & bit);
202 void euclide(infinint a, const infinint &b, infinint &q, infinint &r);
203 template <class T> inline
void euclide(T a, T b, T & q, T &r)
208 inline infinint & infinint::operator /= (
const infinint & ref)
214 inline infinint & infinint::operator %= (
const infinint & ref)
225 template <
class T> infinint infinint::power(
const T & exponent)
const
228 for(T count = 0; count < exponent; ++count)
234 template <
class T> T infinint::modulo(T arg)
const
236 infinint tmp = *
this % infinint(arg);
238 unsigned char *debut = (
unsigned char *)(&ret);
239 unsigned char *ptr = debut +
sizeof(T) - 1;
240 storage::iterator it = tmp.field->rbegin();
242 while(it != tmp.field->rend() && ptr >= debut)
251 while(it != tmp.field->rend())
258 if(used_endian == little_endian)
259 int_tools_swap_bytes(debut,
sizeof(T));
265 template <
class T>
void infinint::infinint_from(T a)
267 U_I size =
sizeof(a);
269 unsigned char *ptr, *fin;
271 if(used_endian == not_initialized)
274 if(used_endian == little_endian)
277 ptr = (
unsigned char *)(&a) + (size - 1);
278 fin = (
unsigned char *)(&a) - 1;
283 ptr = (
unsigned char *)(&a);
284 fin = (
unsigned char *)(&a) + size;
287 while(ptr != fin && *ptr == 0)
299 field =
new (std::nothrow) storage(size);
302 storage::iterator it = field->begin();
310 if(it != field->end())
314 throw Ememory(
"template infinint::infinint_from");
317 template <
class T> T infinint::max_val_of(T x)
325 x = int_tools_rotate_right_one_bit(x);
332 template <
class T>
void infinint::infinint_unstack_to(T & a)
337 static const T max_T = max_val_of(a);
338 infinint step = max_T - a;
343 unsigned char *debut = (
unsigned char *)&transfert;
344 unsigned char *ptr = debut +
sizeof(transfert) - 1;
345 storage::iterator it = field->rbegin();
347 while(ptr >= debut && it != field->rend())
354 if(used_endian == little_endian)
355 int_tools_swap_bytes(debut,
sizeof(transfert));
the arbitrary large positive integer class
ancestor class of generic_file
arbitrary large storage structure
unsigned char operator[](const infinint &position) const
return in little endian order the information byte storing the integer
void unstack(T &v)
convert infinint to standard interger types
infinint get_storage_size() const noexcept
it returns number of byte of information necessary to store the integer
infinint(proto_generic_file &x)
read an infinint from a file
are defined here basic integer types that tend to be portable
libdar namespace encapsulate all libdar symbols
precursor class of generic_file used to avoid cyclic dependencies with storage and infinint
contains a class that permits arbitrary large data storage