15 static VarInt &make(
void *space,
char size);
18 VarInt(
const VarInt &other) =
delete;
20 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
21 VarInt &operator=(T other) {
22 *
reinterpret_cast<T *
>(bytes()) = other;
26 VarInt &operator=(
const VarInt &other);
28 char *bytes() {
return &size_ + 1; };
29 const char *bytes()
const {
return &size_ + 1; };
31 char size()
const {
return size_; }
33 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
35 return *
reinterpret_cast<const T *
>(bytes());
38 bool operator==(
const VarInt &other)
const;
39 bool operator!=(
const VarInt &other)
const;
41 bool operator<(
const VarInt &other)
const;
42 bool operator<=(
const VarInt &other)
const;
43 bool operator>(
const VarInt &other)
const;
44 bool operator>=(
const VarInt &other)
const;
46 bool high_bit()
const;
48 bool negative()
const;
51 bool too_positive()
const;
54 bool too_negative()
const;
56 VarInt &operator+=(
const VarInt &other);
57 bool add_overflow(
const VarInt &other);
59 template <
typename T> VarInt &operator+=(T other);
60 template <
typename T> VarInt &operator*=(T other);
62 template <
typename T>
bool add_overflow(T other);
63 template <
typename T>
bool mul_overflow(T other);
70 void positive_limit();
71 void negative_limit();
72 void unsigned_limit();
83 template <
char Size>
class BigInt :
public VarInt {
87 BigInt() : VarInt(Size) {}
89 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
90 BigInt &operator=(T other) {
91 static_assert(
sizeof(T) == Size,
"incorrect size");
92 return static_cast<BigInt &
>(VarInt::operator=(other));
95 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
96 BigInt(T other) : VarInt(Size) {
97 static_assert(
sizeof(T) == Size,
"incorrect size");
102 template <
typename T> VarInt &VarInt::operator+=(T other) {
107 template <
typename T> VarInt &VarInt::operator*=(T other) {
112 template <
typename T>
bool VarInt::add_overflow(T other) {
113 unsigned char carry = 0;
115 const auto *r_bytes =
reinterpret_cast<const char *
>(&other);
116 for (i = 0; i <
sizeof(T); ++i)
117 bytes()[i] = __builtin_addcb(bytes()[0], r_bytes[i], carry, &carry);
118 for (; i < size_; ++i)
119 bytes()[i] = __builtin_addcb(bytes()[i], 0, carry, &carry);
123 template <
typename T>
bool VarInt::mul_overflow(T other) {
124 char space[
sizeof(VarInt) + size_];
125 auto &p = *
new (space) VarInt(size_);
127 bool overflow =
false;
131 overflow |= p.add_overflow(*
this);
136 overflow |= shl_overflow();
144 #endif // not _VARINT_H_