Lbug C++ API
Loading...
Searching...
No Matches
int128_t.h
Go to the documentation of this file.
1// =========================================================================================
2// This int128 implementtaion got
3
4// =========================================================================================
5#pragma once
6
7#include <cstdint>
8#include <functional>
9#include <string>
10
11#include "api.h"
12#include "overflow.h"
13
14namespace lbug {
15namespace common {
16
18struct uint128_t;
19
20// System representation for int128_t.
22 uint64_t low;
23 int64_t high;
24
25 int128_t() noexcept = default;
26 int128_t(int64_t value); // NOLINT: Allow implicit conversion from numeric values
27 int128_t(int32_t value); // NOLINT: Allow implicit conversion from numeric values
28 int128_t(int16_t value); // NOLINT: Allow implicit conversion from numeric values
29 int128_t(int8_t value); // NOLINT: Allow implicit conversion from numeric values
30 int128_t(uint64_t value); // NOLINT: Allow implicit conversion from numeric values
31 int128_t(uint32_t value); // NOLINT: Allow implicit conversion from numeric values
32 int128_t(uint16_t value); // NOLINT: Allow implicit conversion from numeric values
33 int128_t(uint8_t value); // NOLINT: Allow implicit conversion from numeric values
34 int128_t(double value); // NOLINT: Allow implicit conversion from numeric values
35 int128_t(float value); // NOLINT: Allow implicit conversion from numeric values
36
37 constexpr int128_t(uint64_t low, int64_t high) noexcept : low(low), high(high) {}
38
39 constexpr int128_t(const int128_t&) noexcept = default;
40 constexpr int128_t(int128_t&&) noexcept = default;
41 int128_t& operator=(const int128_t&) noexcept = default;
42 int128_t& operator=(int128_t&&) noexcept = default;
43
44 int128_t operator-() const;
45
46 // inplace arithmetic operators
47 int128_t& operator+=(const int128_t& rhs);
48 int128_t& operator*=(const int128_t& rhs);
49 int128_t& operator|=(const int128_t& rhs);
50 int128_t& operator&=(const int128_t& rhs);
51
52 // cast operators
53 explicit operator int64_t() const;
54 explicit operator int32_t() const;
55 explicit operator int16_t() const;
56 explicit operator int8_t() const;
57 explicit operator uint64_t() const;
58 explicit operator uint32_t() const;
59 explicit operator uint16_t() const;
60 explicit operator uint8_t() const;
61 explicit operator double() const;
62 explicit operator float() const;
63
64 explicit operator uint128_t() const;
65};
66
67// arithmetic operators
68LBUG_API int128_t operator+(const int128_t& lhs, const int128_t& rhs);
69LBUG_API int128_t operator-(const int128_t& lhs, const int128_t& rhs);
70LBUG_API int128_t operator*(const int128_t& lhs, const int128_t& rhs);
71LBUG_API int128_t operator/(const int128_t& lhs, const int128_t& rhs);
72LBUG_API int128_t operator%(const int128_t& lhs, const int128_t& rhs);
73LBUG_API int128_t operator^(const int128_t& lhs, const int128_t& rhs);
74LBUG_API int128_t operator&(const int128_t& lhs, const int128_t& rhs);
75LBUG_API int128_t operator~(const int128_t& val);
76LBUG_API int128_t operator|(const int128_t& lhs, const int128_t& rhs);
77LBUG_API int128_t operator<<(const int128_t& lhs, int amount);
78LBUG_API int128_t operator>>(const int128_t& lhs, int amount);
79
80// comparison operators
81LBUG_API bool operator==(const int128_t& lhs, const int128_t& rhs);
82LBUG_API bool operator!=(const int128_t& lhs, const int128_t& rhs);
83LBUG_API bool operator>(const int128_t& lhs, const int128_t& rhs);
84LBUG_API bool operator>=(const int128_t& lhs, const int128_t& rhs);
85LBUG_API bool operator<(const int128_t& lhs, const int128_t& rhs);
86LBUG_API bool operator<=(const int128_t& lhs, const int128_t& rhs);
87
88class Int128_t {
89public:
90 static std::string toString(int128_t input);
91
92 template<class T>
93 static bool tryCast(int128_t input, T& result);
94
95 template<class T>
96 static T cast(int128_t input) {
97 T result;
98 tryCast(input, result);
99 return result;
100 }
101
102 template<class T>
103 static bool tryCastTo(T value, int128_t& result);
104
105 template<class T>
106 static int128_t castTo(T value) {
107 int128_t result{};
108 if (!tryCastTo(value, result)) {
109 throw common::OverflowException("INT128 is out of range");
110 }
111 return result;
112 }
113
114 // negate
115 static void negateInPlace(int128_t& input) {
116 if (input.high == INT64_MIN && input.low == 0) {
117 throw common::OverflowException("INT128 is out of range: cannot negate INT128_MIN");
118 }
119 input.low = UINT64_MAX + 1 - input.low;
120 input.high = -input.high - 1 + (input.low == 0);
121 }
122
123 static int128_t negate(int128_t input) {
124 negateInPlace(input);
125 return input;
126 }
127
128 static bool tryMultiply(int128_t lhs, int128_t rhs, int128_t& result);
129
130 static int128_t Add(int128_t lhs, int128_t rhs);
131 static int128_t Sub(int128_t lhs, int128_t rhs);
132 static int128_t Mul(int128_t lhs, int128_t rhs);
133 static int128_t Div(int128_t lhs, int128_t rhs);
134 static int128_t Mod(int128_t lhs, int128_t rhs);
135 static int128_t Xor(int128_t lhs, int128_t rhs);
136 static int128_t LeftShift(int128_t lhs, int amount);
137 static int128_t RightShift(int128_t lhs, int amount);
141
142 static int128_t divMod(int128_t lhs, int128_t rhs, int128_t& remainder);
143 static int128_t divModPositive(int128_t lhs, uint64_t rhs, uint64_t& remainder);
144
145 static bool addInPlace(int128_t& lhs, int128_t rhs);
146 static bool subInPlace(int128_t& lhs, int128_t rhs);
147
148 // comparison operators
149 static bool equals(int128_t lhs, int128_t rhs) {
150 return lhs.low == rhs.low && lhs.high == rhs.high;
151 }
152
153 static bool notEquals(int128_t lhs, int128_t rhs) {
154 return lhs.low != rhs.low || lhs.high != rhs.high;
155 }
156
157 static bool greaterThan(int128_t lhs, int128_t rhs) {
158 return (lhs.high > rhs.high) || (lhs.high == rhs.high && lhs.low > rhs.low);
159 }
160
161 static bool greaterThanOrEquals(int128_t lhs, int128_t rhs) {
162 return (lhs.high > rhs.high) || (lhs.high == rhs.high && lhs.low >= rhs.low);
163 }
164
165 static bool lessThan(int128_t lhs, int128_t rhs) {
166 return (lhs.high < rhs.high) || (lhs.high == rhs.high && lhs.low < rhs.low);
167 }
168
169 static bool lessThanOrEquals(int128_t lhs, int128_t rhs) {
170 return (lhs.high < rhs.high) || (lhs.high == rhs.high && lhs.low <= rhs.low);
171 }
172};
173
174template<>
175bool Int128_t::tryCast(int128_t input, int8_t& result);
176template<>
177bool Int128_t::tryCast(int128_t input, int16_t& result);
178template<>
179bool Int128_t::tryCast(int128_t input, int32_t& result);
180template<>
181bool Int128_t::tryCast(int128_t input, int64_t& result);
182template<>
183bool Int128_t::tryCast(int128_t input, uint8_t& result);
184template<>
185bool Int128_t::tryCast(int128_t input, uint16_t& result);
186template<>
187bool Int128_t::tryCast(int128_t input, uint32_t& result);
188template<>
189bool Int128_t::tryCast(int128_t input, uint64_t& result);
190template<>
191bool Int128_t::tryCast(int128_t input, uint128_t& result); // signed to unsigned
192template<>
193bool Int128_t::tryCast(int128_t input, float& result);
194template<>
195bool Int128_t::tryCast(int128_t input, double& result);
196template<>
197bool Int128_t::tryCast(int128_t input, long double& result);
198
199template<>
200bool Int128_t::tryCastTo(int8_t value, int128_t& result);
201template<>
202bool Int128_t::tryCastTo(int16_t value, int128_t& result);
203template<>
204bool Int128_t::tryCastTo(int32_t value, int128_t& result);
205template<>
206bool Int128_t::tryCastTo(int64_t value, int128_t& result);
207template<>
208bool Int128_t::tryCastTo(uint8_t value, int128_t& result);
209template<>
210bool Int128_t::tryCastTo(uint16_t value, int128_t& result);
211template<>
212bool Int128_t::tryCastTo(uint32_t value, int128_t& result);
213template<>
214bool Int128_t::tryCastTo(uint64_t value, int128_t& result);
215template<>
217template<>
218bool Int128_t::tryCastTo(float value, int128_t& result);
219template<>
220bool Int128_t::tryCastTo(double value, int128_t& result);
221template<>
222bool Int128_t::tryCastTo(long double value, int128_t& result);
223
224} // namespace common
225} // namespace lbug
226
227template<>
228struct std::hash<lbug::common::int128_t> {
229 std::size_t operator()(const lbug::common::int128_t& v) const noexcept;
230};
#define LBUG_API
Definition api.h:25
Definition int128_t.h:88
static bool addInPlace(int128_t &lhs, int128_t rhs)
static bool tryCastTo(T value, int128_t &result)
static bool equals(int128_t lhs, int128_t rhs)
Definition int128_t.h:149
static int128_t Sub(int128_t lhs, int128_t rhs)
static int128_t Xor(int128_t lhs, int128_t rhs)
static bool subInPlace(int128_t &lhs, int128_t rhs)
static int128_t Add(int128_t lhs, int128_t rhs)
static int128_t divMod(int128_t lhs, int128_t rhs, int128_t &remainder)
static int128_t divModPositive(int128_t lhs, uint64_t rhs, uint64_t &remainder)
static int128_t Mod(int128_t lhs, int128_t rhs)
static int128_t BinaryAnd(int128_t lhs, int128_t rhs)
static int128_t LeftShift(int128_t lhs, int amount)
static int128_t negate(int128_t input)
Definition int128_t.h:123
static int128_t castTo(T value)
Definition int128_t.h:106
static bool tryCast(int128_t input, T &result)
static bool greaterThan(int128_t lhs, int128_t rhs)
Definition int128_t.h:157
static T cast(int128_t input)
Definition int128_t.h:96
static int128_t BinaryNot(int128_t val)
static int128_t Mul(int128_t lhs, int128_t rhs)
static int128_t BinaryOr(int128_t lhs, int128_t rhs)
static bool tryMultiply(int128_t lhs, int128_t rhs, int128_t &result)
static void negateInPlace(int128_t &input)
Definition int128_t.h:115
static bool lessThanOrEquals(int128_t lhs, int128_t rhs)
Definition int128_t.h:169
static bool notEquals(int128_t lhs, int128_t rhs)
Definition int128_t.h:153
static bool greaterThanOrEquals(int128_t lhs, int128_t rhs)
Definition int128_t.h:161
static int128_t Div(int128_t lhs, int128_t rhs)
static int128_t RightShift(int128_t lhs, int amount)
static bool lessThan(int128_t lhs, int128_t rhs)
Definition int128_t.h:165
static std::string toString(int128_t input)
Definition overflow.h:9
Definition array_utils.h:7
struct LBUG_API int128_t
Definition int128_t.h:17
Definition array_utils.h:7
Definition int128_t.h:21
uint64_t low
Definition int128_t.h:22
constexpr int128_t(const int128_t &) noexcept=default
int128_t() noexcept=default
int64_t high
Definition int128_t.h:23
constexpr int128_t(int128_t &&) noexcept=default
Definition uint128_t.h:15
std::size_t operator()(const lbug::common::int128_t &v) const noexcept