22 #include <type_traits> 37 struct is_integral<random_iterator::uint128_t> : std::true_type {};
39 struct is_unsigned<random_iterator::uint128_t> : std::true_type {};
61 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
67 #ifdef __LITTLE_ENDIAN__ 72 if (std::is_signed<T>::value) {
73 if (rhs < T(0)) { UPPER = -1; }
77 template <
typename S,
typename T,
78 typename =
typename std::enable_if<
79 std::is_integral<S>::value && std::is_integral<T>::value,
void>::type>
80 uint128_t(
const S& upper_rhs,
const T& lower_rhs)
85 #ifdef __LITTLE_ENDIAN__ 100 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
101 inline uint128_t& operator=(
const T& rhs) {
104 if (std::is_signed<T>::value) {
105 if (rhs < T(0)) { UPPER = -1; }
113 inline operator bool()
const;
114 inline operator uint8_t()
const;
115 inline operator uint16_t()
const;
116 inline operator uint32_t()
const;
117 inline operator uint64_t()
const;
124 template <
typename T,
125 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
126 inline uint128_t operator&(
const T& rhs)
const {
127 return uint128_t(0, LOWER & (uint64_t)rhs);
132 template <
typename T,
133 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
134 inline uint128_t& operator&=(
const T& rhs) {
142 template <
typename T,
143 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
144 inline uint128_t operator|(
const T& rhs)
const {
145 return uint128_t(UPPER, LOWER | (uint64_t)rhs);
150 template <
typename T,
151 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
152 inline uint128_t& operator|=(
const T& rhs) {
153 LOWER |= (uint64_t)rhs;
159 template <
typename T,
160 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
161 inline uint128_t operator^(
const T& rhs)
const {
162 return uint128_t(UPPER, LOWER ^ (uint64_t)rhs);
167 template <
typename T,
168 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
169 inline uint128_t& operator^=(
const T& rhs) {
170 LOWER ^= (uint64_t)rhs;
179 template <
typename T,
180 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
187 template <
typename T,
188 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
189 inline uint128_t& operator<<=(
const T& rhs) {
196 template <
typename T,
197 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
198 inline uint128_t operator>>(
const T& rhs)
const {
204 template <
typename T,
205 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
206 inline uint128_t& operator>>=(
const T& rhs) {
212 inline bool operator!()
const;
213 inline bool operator&&(
const uint128_t& rhs)
const;
214 inline bool operator||(
const uint128_t& rhs)
const;
216 template <
typename T,
217 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
218 inline bool operator&&(
const T& rhs)
const {
219 return static_cast<bool>(*
this && rhs);
222 template <
typename T,
223 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
224 inline bool operator||(
const T& rhs)
const {
225 return static_cast<bool>(*
this || rhs);
229 inline bool operator==(
const uint128_t& rhs)
const;
231 template <
typename T,
232 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
233 inline bool operator==(
const T& rhs)
const {
234 return (!UPPER && (LOWER == (uint64_t)rhs));
239 template <
typename T,
240 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
242 return (UPPER | (LOWER != (uint64_t)rhs));
247 template <
typename T,
248 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
249 inline bool operator>(
const T& rhs)
const {
250 return (UPPER || (LOWER > (uint64_t)rhs));
255 template <
typename T,
256 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
257 inline bool operator<(
const T& rhs)
const {
258 return (!UPPER) ? (LOWER < (uint64_t)rhs) :
false;
263 template <
typename T,
264 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
266 return ((*
this > rhs) | (*
this == rhs));
271 template <
typename T,
272 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
274 return ((*
this < rhs) | (*
this == rhs));
280 template <
typename T,
281 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
283 return uint128_t(UPPER + ((LOWER + (uint64_t)rhs) < LOWER), LOWER + (uint64_t)rhs);
288 template <
typename T,
289 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
296 template <
typename T,
297 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
299 return uint128_t((uint64_t)(UPPER - ((LOWER - rhs) > LOWER)),
300 (uint64_t)(LOWER - rhs));
305 template <
typename T,
306 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
313 template <
typename T,
314 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
321 template <
typename T,
322 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
329 template <
typename T,
330 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
337 template <
typename T,
338 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
345 template <
typename T,
346 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
347 inline uint128_t operator%(
const T& rhs)
const {
353 template <
typename T,
354 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
355 inline uint128_t& operator%=(
const T& rhs) {
374 inline uint64_t upper()
const;
375 inline uint64_t lower()
const;
378 inline uint8_t bits()
const;
384 inline std::string str(uint8_t base = 10,
const unsigned int& len = 0)
const;
387 std::pair<uint128_t, uint128_t> divmod(
const uint128_t& lhs,
389 void init(
const char* s);
390 void _init_hex(
const char* s);
391 void _init_dec(
const char* s);
392 void _init_oct(
const char* s);
394 #if defined(__powerpc64__) || defined(__x86_64__) 398 asm(
"mulhdu %3\n\t" :
"=a"(z.LOWER),
"=d"(z.UPPER) :
"%0"(x.LOWER),
"rm"(y.LOWER));
400 asm(
"mulq %3\n\t" :
"=a"(z.LOWER),
"=d"(z.UPPER) :
"%0"(x.LOWER),
"rm"(y.LOWER));
402 z.UPPER += (x.UPPER * y.LOWER) + (x.LOWER * y.UPPER);
407 #ifdef __BIG_ENDIAN__ 408 uint64_t UPPER, LOWER;
410 #ifdef __LITTLE_ENDIAN__ 411 uint64_t LOWER, UPPER;
419 template <
typename T,
420 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
425 template <
typename T,
426 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
427 inline T& operator&=(T& lhs,
const uint128_t& rhs) {
428 return lhs =
static_cast<T
>(rhs & lhs);
431 template <
typename T,
432 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
437 template <
typename T,
438 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
439 inline T& operator|=(T& lhs,
const uint128_t& rhs) {
440 return lhs =
static_cast<T
>(rhs | lhs);
443 template <
typename T,
444 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
449 template <
typename T,
450 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
451 inline T& operator^=(T& lhs,
const uint128_t& rhs) {
452 return lhs =
static_cast<T
>(rhs ^ lhs);
466 template <
typename T,
467 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
468 inline T& operator<<=(T& lhs,
const uint128_t& rhs) {
469 return lhs =
static_cast<T
>(
uint128_t(lhs) << rhs);
482 template <
typename T,
483 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
484 inline T& operator>>=(T& lhs,
const uint128_t& rhs) {
485 return lhs =
static_cast<T
>(
uint128_t(lhs) >> rhs);
489 template <
typename T,
490 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
491 inline bool operator==(
const T& lhs,
const uint128_t& rhs) {
492 return (!rhs.upper() && ((uint64_t)lhs == rhs.lower()));
495 template <
typename T,
496 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
498 return (rhs.upper() | ((uint64_t)lhs != rhs.lower()));
501 template <
typename T,
502 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
504 return (!rhs.upper()) && ((uint64_t)lhs > rhs.lower());
507 template <
typename T,
508 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
510 if (rhs.upper()) {
return true; }
511 return ((uint64_t)lhs < rhs.lower());
514 template <
typename T,
515 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
517 if (rhs.upper()) {
return false; }
518 return ((uint64_t)lhs >= rhs.lower());
521 template <
typename T,
522 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
524 if (rhs.upper()) {
return true; }
525 return ((uint64_t)lhs <= rhs.lower());
529 template <
typename T,
530 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
535 template <
typename T,
536 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
538 return lhs =
static_cast<T
>(rhs + lhs);
541 template <
typename T,
542 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
547 template <
typename T,
548 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
550 return lhs =
static_cast<T
>(-(rhs - lhs));
553 template <
typename T,
554 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
559 template <
typename T,
560 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
562 return lhs =
static_cast<T
>(rhs * lhs);
565 template <
typename T,
566 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
571 template <
typename T,
572 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
574 return lhs =
static_cast<T
>(
uint128_t(lhs) / rhs);
577 template <
typename T,
578 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
583 template <
typename T,
584 typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
585 inline T& operator%=(T& lhs,
const uint128_t& rhs) {
586 return lhs =
static_cast<T
>(
uint128_t(lhs) % rhs);
594 #include "uint128.inl"
constexpr bool operator<(quantity< D, X > const &x, quantity< D, Y > const &y)
less-than.
constexpr quantity< D, X > operator-(quantity< D, X > const &x)
constexpr quantity< D, detail::PromoteMul< X, Y > > operator*(quantity< D, X > const &x, const Y &y)
quan * num
constexpr quantity< D, detail::PromoteMul< X, Y > > operator/(quantity< D, X > const &x, const Y &y)
quan / num
constexpr bool operator>=(quantity< D, X > const &x, quantity< D, Y > const &y)
greater-equal.
constexpr bool operator<=(quantity< D, X > const &x, quantity< D, Y > const &y)
less-equal.
constexpr quantity< D, X > operator+(quantity< D, X > const &x)
std::ostream & operator<<(std::ostream &, corsika::Code)
Code output operator.
constexpr bool operator!=(quantity< D, X > const &x, quantity< D, Y > const &y)
inequality.
constexpr quantity< D, X > & operator-=(quantity< D, X > &x, quantity< D, Y > const &y)
quan -= quan
constexpr quantity< D, X > & operator*=(quantity< D, X > &x, const Y &y)
quan *= num
constexpr quantity< D, X > & operator+=(quantity< D, X > &x, quantity< D, Y > const &y)
quan += quan
constexpr bool operator>(quantity< D, X > const &x, quantity< D, Y > const &y)
greater-than.
constexpr quantity< D, X > & operator/=(quantity< D, X > &x, const Y &y)
quan /= num