12#ifndef MORTON_WIDE_UINT_HPP
13#define MORTON_WIDE_UINT_HPP
24#if defined(__SIZEOF_INT128__)
25#define MORTON_HAS_INT128 1
31#if defined(MORTON_HAS_INT128)
45template <std::
size_t W>
47 static_assert(W >= 2,
"use a built-in integer for <= 64 bits");
48 std::array<std::uint64_t, W>
w{};
53 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T> && (sizeof(T) <= 8)>>
54 MORTON_HD constexpr w
ide_u
int(T v) : w{} {
55 w[0] = std::u
int64_t(static_cast<std::make_
unsigned_t<T>>(v));
58#if defined(MORTON_HAS_INT128)
60 MORTON_HD constexpr w
ide_u
int(u
int128_t v) : w{} {
61 w[0] = std::u
int64_t(v);
63 w[1] = std::uint64_t(v >> 64);
68 template <std::
size_t W2,
typename = std::enable_if_t<W2 != W>>
70 for (std::size_t i = 0; i < W && i < W2; ++i)
74 MORTON_HD explicit constexpr operator std::uint64_t()
const {
return w[0]; }
75#if defined(MORTON_HAS_INT128)
83 MORTON_HD explicit constexpr operator bool()
const {
84 for (std::size_t i = 0; i < W; ++i)
93 for (std::size_t i = 0; i < W; ++i)
98 for (std::size_t i = 0; i < W; ++i)
103 for (std::size_t i = 0; i < W; ++i)
108 for (std::size_t i = 0; i < W; ++i)
119 const unsigned ws = s / 64, bs = s % 64;
120 for (
int i =
int(W) - 1; i >= 0; --i) {
121 const int src = i - int(ws);
124 v = w[std::size_t(src)] << bs;
125 if (bs && src - 1 >= 0)
126 v |= w[std::size_t(src - 1)] >> (64 - bs);
128 r.
w[std::size_t(i)] = v;
134 const unsigned ws = s / 64, bs = s % 64;
135 for (std::size_t i = 0; i < W; ++i) {
136 const std::size_t src = i + ws;
140 if (bs && src + 1 < W)
141 v |= w[src + 1] << (64 - bs);
153 std::uint64_t carry = 0;
154 for (std::size_t i = 0; i < W; ++i) {
155 std::uint64_t s1 = a.
w[i] + b.
w[i];
156 std::uint64_t c1 = (s1 < a.
w[i]) ? 1u : 0u;
157 std::uint64_t s2 = s1 + carry;
158 std::uint64_t c2 = (s2 < s1) ? 1u : 0u;
166 std::uint64_t borrow = 0;
167 for (std::size_t i = 0; i < W; ++i) {
168 std::uint64_t d1 = a.
w[i] - b.
w[i];
169 std::uint64_t b1 = (a.
w[i] < b.
w[i]) ? 1u : 0u;
170 std::uint64_t d2 = d1 - borrow;
171 std::uint64_t b2 = (d1 < borrow) ? 1u : 0u;
182 for (std::size_t i = 0; i < W; ++i)
183 if (a.
w[i] != b.
w[i])
191 for (std::size_t i = W; i-- > 0;) {
192 if (a.
w[i] != b.
w[i])
193 return a.
w[i] < b.
w[i];
The MORTON_HD host/device function marker, shared by every core header.
#define MORTON_HD
Definition hd.hpp:27
unsigned __int128 uint128_t
The built-in 128-bit unsigned, used for 65..128-bit codes.
Definition wide_uint.hpp:39
Fixed-width unsigned integer of.
Definition wide_uint.hpp:46
friend MORTON_HD constexpr bool operator>=(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:203
friend MORTON_HD constexpr wide_uint operator+(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:151
MORTON_HD constexpr wide_uint & operator<<=(unsigned s)
Definition wide_uint.hpp:147
MORTON_HD constexpr wide_uint & operator&=(const wide_uint &o)
Definition wide_uint.hpp:97
friend MORTON_HD constexpr bool operator<(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:190
std::array< std::uint64_t, W > w
Words, little-endian: w[0] is least significant.
Definition wide_uint.hpp:48
friend MORTON_HD constexpr wide_uint operator-(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:164
friend MORTON_HD constexpr wide_uint operator|(wide_uint a, const wide_uint &b)
Definition wide_uint.hpp:113
MORTON_HD constexpr wide_uint & operator++()
Definition wide_uint.hpp:177
friend MORTON_HD constexpr bool operator!=(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:187
friend MORTON_HD constexpr bool operator>(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:197
friend MORTON_HD constexpr bool operator<=(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:200
MORTON_HD constexpr wide_uint(const wide_uint< W2 > &o)
Definition wide_uint.hpp:69
friend MORTON_HD constexpr bool operator==(const wide_uint &a, const wide_uint &b)
Definition wide_uint.hpp:181
MORTON_HD constexpr wide_uint & operator|=(const wide_uint &o)
Definition wide_uint.hpp:102
MORTON_HD constexpr wide_uint operator<<(unsigned s) const
Definition wide_uint.hpp:117
MORTON_HD constexpr wide_uint operator~() const
Definition wide_uint.hpp:91
MORTON_HD constexpr wide_uint & operator>>=(unsigned s)
Definition wide_uint.hpp:148
MORTON_HD constexpr wide_uint & operator^=(const wide_uint &o)
Definition wide_uint.hpp:107
friend MORTON_HD constexpr wide_uint operator&(wide_uint a, const wide_uint &b)
Definition wide_uint.hpp:112
MORTON_HD constexpr wide_uint operator>>(unsigned s) const
Definition wide_uint.hpp:132
MORTON_HD constexpr wide_uint()=default
MORTON_HD constexpr wide_uint & operator--()
Definition wide_uint.hpp:178
friend MORTON_HD constexpr wide_uint operator^(wide_uint a, const wide_uint &b)
Definition wide_uint.hpp:114