91#if SIZEOF_OFF_T > SIZEOF_TIME_T
92#if SIZEOF_OFF_T > SIZEOF_SIZE_T
94 { limitint_from(a); };
97 { limitint_from(a); };
100#if SIZEOF_TIME_T > SIZEOF_SIZE_T
102 { limitint_from(a); };
105 { limitint_from(a); };
126 template <
class T>
limitint power(
const T & exponent)
const;
137 {
limitint ret = *
this; ++(*this);
return ret; };
139 {
limitint ret = *
this; --(*this);
return ret; };
141 {
return *
this += 1; };
143 {
return *
this -= 1; };
145 U_32 operator % (U_32 arg)
const;
150 template <
class T>
void unstack(T &v)
151 { limitint_unstack_to(v); }
156 unsigned char operator [] (
const limitint & position)
const;
159 bool is_zero()
const {
return field == 0; };
161 bool operator < (
const limitint &x)
const {
return field < x.field; };
162 bool operator == (
const limitint &x)
const {
return field == x.field; };
163 bool operator > (
const limitint &x)
const {
return field > x.field; };
164 bool operator <= (
const limitint &x)
const {
return field <= x.field; };
165 bool operator != (
const limitint &x)
const {
return field != x.field; };
166 bool operator >= (
const limitint &x)
const {
return field >= x.field; };
167 static bool is_system_big_endian();
169 B debug_get_max()
const {
return max_value; };
170 B debug_get_bytesize()
const {
return bytesize; };
171 B debug_get_field()
const {
return field; };
178 template <
class T>
void limitint_from(T a);
179 template <
class T> T max_val_of(T x);
180 template <
class T>
void limitint_unstack_to(T &a);
185 static const int TG = 4;
186 static const U_32 sizeof_field =
sizeof(B);
188 enum endian { big_endian, little_endian, not_initialized };
189 using group =
unsigned char[TG];
191 static endian used_endian;
192 static const U_I bytesize =
sizeof(B);
193 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
194 static U_8 zeroed_field[ZEROED_SIZE];
196 static void setup_endian();
204 template <
class B> limitint<B> operator - (
const limitint<B> &,
const limitint<B> &);
205 template <
class B>
inline limitint<B> operator - (
const limitint<B> & a, U_I b)
206 {
return a - limitint<B>(b); }
207 template <
class B> limitint<B> operator * (
const limitint<B> &,
const limitint<B> &);
208 template <
class B>
inline limitint<B> operator * (
const limitint<B> & a, U_I b)
209 {
return a * limitint<B>(b); }
210 template <
class B> limitint<B> operator / (
const limitint<B> &,
const limitint<B> &);
211 template <
class B> limitint<B> operator / (
const limitint<B> & a, U_I b)
212 {
return a / limitint<B>(b); }
213 template <
class B> limitint<B> operator % (
const limitint<B> &,
const limitint<B> &);
214 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit);
215 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit);
216 template <
class B> limitint<B>
operator << (
const limitint<B> & a, U_32 bit);
217 template <
class B> limitint<B>
operator << (
const limitint<B> & a,
const limitint<B> & bit);
218 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit);
219 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit);
220 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit);
221 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit);
222 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit);
223 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit);
225 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
231 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
233 euclide(a, limitint<B>(b), q, r);
236#ifndef INFININT_BASE_TYPE
237#error INFININT_BASE_TYPE not defined cannot instantiate template
239 using infinint = limitint<INFININT_BASE_TYPE>;
249 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
252 template <
class B> limitint<B>::limitint(proto_generic_file & x)
258 template <
class B>
void limitint<B>::build_from_file(proto_generic_file & x)
262 limitint<B> skip = 0;
263 char *ptr = (
char *)&field;
265 int_tools_bitfield bf;
269 lu = x.read((
char *)&a, 1);
272 throw Erange(
"limitint::build_from_file(proto_generic_file)", gettext(
"Reached end of file before all data could be read"));
281 int_tools_expand_byte(a, bf);
282 for(S_I i = 0; i < 8; ++i)
285 throw Erange(
"limitint::build_from_file(proto_generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
296 if(skip.field > bytesize)
300 lu = x.read(ptr, skip.field);
302 if(used_endian == not_initialized)
304 if(used_endian == little_endian)
305 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
307 field >>= (bytesize - skip.field)*8;
314 template <
class B>
void limitint<B>::dump(proto_generic_file & x)
const
318 unsigned char last_width;
321 unsigned char *ptr, *fin;
324 if(used_endian == not_initialized)
327 if(used_endian == little_endian)
330 ptr = (
unsigned char *)(&field) + (bytesize - 1);
331 fin = (
unsigned char *)(&field) - 1;
336 ptr = (
unsigned char *)(&field);
337 fin = (
unsigned char *)(&field) + bytesize;
340 while(ptr != fin && *ptr == 0)
351 euclide(width, (
const B)(TG), width, justification);
352 if(justification != 0)
356 euclide(width, (
const B)(8), width, pos);
360 last_width = 0x80 >> 7;
365 U_16 pos_s = (U_16)(0xFFFF & pos);
366 last_width = 0x80 >> (pos_s - 1);
372 if(width > ZEROED_SIZE)
374 x.write((
char *)zeroed_field, ZEROED_SIZE);
375 width -= ZEROED_SIZE;
379 x.write((
char *)zeroed_field, width);
385 x.write((
char *)&last_width, 1);
389 if(justification != 0)
391 justification = TG - justification;
392 if(justification > ZEROED_SIZE)
395 x.write((
char *)zeroed_field, justification);
400 x.write((
char *)zeroed_field, 1);
404 x.write((
char *)ptr, 1);
409 template<
class B> limitint<B> & limitint<B>::operator += (
const limitint & arg)
411 B res = field + arg.field;
412 if(res < field || res < arg.field)
420 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
422 if(field < arg.field)
423 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
432 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
434 static const B max_power = bytesize*8 - 1;
436 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
437 if(total > max_power)
444 total = field*arg.field;
445 if(field != 0 && arg.field != 0)
446 if(total < field || total < arg.field)
452 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
455 for(T count = 0; count < exponent; ++count)
461 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
464 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
470 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
473 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
479 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
481 if(bit >= sizeof_field*8)
488 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
494 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
496 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
502 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
504 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
510 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
516 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
522 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
528 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
530 return U_32(field % arg);
533 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
535 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
541 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
549 x = int_tools_rotate_right_one_bit(x);
556 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
562 static const T max_T = max_val_of(a);
565 if(field < (B)(step) && (T)(field) < step)
577 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
588 return limitint<B>(ret);
591 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
594 B index = position.field;
602 return (
unsigned char)(tmp & 0xFF);
605 template <
class B>
void limitint<B>::setup_endian()
608 used_endian = big_endian;
610 used_endian = little_endian;
612 (void)memset(zeroed_field, 0, ZEROED_SIZE);
616 template <
class B>
bool limitint<B>::is_system_big_endian()
618 if(used_endian == not_initialized)
627 case not_initialized:
639 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
647 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
655 template <
class B> limitint<B> operator * (
const limitint<B> & a,
const limitint<B> & b)
663 template <
class B> limitint<B> operator / (
const limitint<B> & a,
const limitint<B> & b)
671 template <
class B> limitint<B> operator % (
const limitint<B> & a,
const limitint<B> & b)
679 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit)
686 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
693 template <
class B> limitint<B>
operator << (
const limitint<B> & a, U_32 bit)
700 template <
class B> limitint<B>
operator << (
const limitint<B> & a,
const limitint<B> & bit)
707 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
714 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
721 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
728 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
735 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
742 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit)
ancestor class of generic_file
contains all the excetion class thrown by libdar
std::ostream & operator<<(std::ostream &ref, const infinint &arg)
specific << operator to use infinint in std::ostream
are defined here basic integer types that tend to be portable
include macro defined by the configure script and some specific additional ones
libdar namespace encapsulate all libdar symbols
bool integers_system_is_big_endian()
returns true if the system is big endian, false else
precursor class of generic_file used to avoid cyclic dependencies with storage and infinint