20 static_assert(std::is_integral_v<T>,
"Expecting tagged_id to be an integral");
21 static_assert(std::is_unsigned_v<T>,
"Expecting tagged_id to be an unsigned integer");
22 static_assert(Max < std::numeric_limits<T>::max(),
"Max must be at least one less than the maximum value of T");
26 constexpr static value_type max = Max;
27 constexpr static value_type invalid = max + 1;
28 constexpr static value_type mask =
static_cast<value_type
>((1ULL << std::bit_width(invalid)) - 1);
30 constexpr explicit tagged_id(
signed long long rhs) noexcept : value(narrow_cast<value_type>(rhs))
32 tt_axiom(value <= invalid);
34 constexpr explicit tagged_id(
signed long rhs) noexcept : value(narrow_cast<value_type>(rhs))
36 tt_axiom(value <= invalid);
38 constexpr explicit tagged_id(
signed int rhs) noexcept : value(narrow_cast<value_type>(rhs))
40 tt_axiom(value <= invalid);
42 constexpr explicit tagged_id(
signed short rhs) noexcept : value(narrow_cast<value_type>(rhs))
44 tt_axiom(value <= invalid);
46 constexpr explicit tagged_id(
signed char rhs) noexcept : value(narrow_cast<value_type>(rhs))
48 tt_axiom(value <= invalid);
50 constexpr explicit tagged_id(
unsigned long long rhs) noexcept : value(narrow_cast<value_type>(rhs))
52 tt_axiom(value <= invalid);
54 constexpr explicit tagged_id(
unsigned long rhs) noexcept : value(narrow_cast<value_type>(rhs))
56 tt_axiom(value <= invalid);
58 constexpr explicit tagged_id(
unsigned int rhs) noexcept : value(narrow_cast<value_type>(rhs))
60 tt_axiom(value <= invalid);
62 constexpr explicit tagged_id(
unsigned short rhs) noexcept : value(narrow_cast<value_type>(rhs))
64 tt_axiom(value <= invalid);
66 constexpr explicit tagged_id(
unsigned char rhs) noexcept : value(narrow_cast<value_type>(rhs))
68 tt_axiom(value <= invalid);
71 constexpr tagged_id &operator=(
signed long long rhs)
noexcept
73 value = narrow_cast<value_type>(rhs);
74 tt_axiom(value <= invalid);
77 constexpr tagged_id &operator=(
signed long rhs)
noexcept
79 value = narrow_cast<value_type>(rhs);
80 tt_axiom(value <= invalid);
83 constexpr tagged_id &operator=(
signed int rhs)
noexcept
85 value = narrow_cast<value_type>(rhs);
86 tt_axiom(value <= invalid);
89 constexpr tagged_id &operator=(
signed short rhs)
noexcept
91 value = narrow_cast<value_type>(rhs);
92 tt_axiom(value <= invalid);
95 constexpr tagged_id &operator=(
signed char rhs)
noexcept
97 value = narrow_cast<value_type>(rhs);
98 tt_axiom(value <= invalid);
101 constexpr tagged_id &operator=(
unsigned long long rhs)
noexcept
103 value = narrow_cast<value_type>(rhs);
104 tt_axiom(value <= invalid);
107 constexpr tagged_id &operator=(
unsigned long rhs)
noexcept
109 value = narrow_cast<value_type>(rhs);
110 tt_axiom(value <= invalid);
113 constexpr tagged_id &operator=(
unsigned int rhs)
noexcept
115 value = narrow_cast<value_type>(rhs);
116 tt_axiom(value <= invalid);
119 constexpr tagged_id &operator=(
unsigned short rhs)
noexcept
121 value = narrow_cast<value_type>(rhs);
122 tt_axiom(value <= invalid);
125 constexpr tagged_id &operator=(
unsigned char rhs)
noexcept
127 value = narrow_cast<value_type>(rhs);
128 tt_axiom(value <= invalid);
132 constexpr tagged_id() noexcept : value(invalid) {}
138 constexpr operator signed long long()
const noexcept
140 return narrow_cast<signed long long>(value);
142 constexpr operator signed long()
const noexcept
144 return narrow_cast<signed long>(value);
146 constexpr operator signed int()
const noexcept
148 return narrow_cast<signed int>(value);
150 constexpr operator signed short()
const noexcept
152 return narrow_cast<signed short>(value);
154 constexpr operator signed char()
const noexcept
156 return narrow_cast<signed char>(value);
158 constexpr operator unsigned long long()
const noexcept
160 return narrow_cast<unsigned long long>(value);
162 constexpr operator unsigned long()
const noexcept
164 return narrow_cast<unsigned long>(value);
166 constexpr operator unsigned int()
const noexcept
168 return narrow_cast<unsigned int>(value);
170 constexpr operator unsigned short()
const noexcept
172 return narrow_cast<unsigned short>(value);
174 constexpr operator unsigned char()
const noexcept
176 return narrow_cast<unsigned char>(value);
179 constexpr operator bool()
const noexcept
184 [[nodiscard]]
constexpr size_t hash()
const noexcept
189 [[nodiscard]]
constexpr friend bool operator==(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
191 return lhs.value == rhs.value;
193 [[nodiscard]]
constexpr friend bool operator!=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
195 return lhs.value != rhs.value;
197 [[nodiscard]]
constexpr friend bool operator<(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
199 return lhs.value < rhs.value;
201 [[nodiscard]]
constexpr friend bool operator>(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
203 return lhs.value > rhs.value;
205 [[nodiscard]]
constexpr friend bool operator<=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
207 return lhs.value <= rhs.value;
209 [[nodiscard]]
constexpr friend bool operator>=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept
211 return lhs.value >= rhs.value;
215 [[nodiscard]]
constexpr friend bool operator==(
tagged_id const &lhs, O
const &rhs)
noexcept
220 [[nodiscard]]
constexpr friend bool operator!=(
tagged_id const &lhs, O
const &rhs)
noexcept
225 [[nodiscard]]
constexpr friend bool operator<(
tagged_id const &lhs, O
const &rhs)
noexcept
230 [[nodiscard]]
constexpr friend bool operator>(
tagged_id const &lhs, O
const &rhs)
noexcept
235 [[nodiscard]]
constexpr friend bool operator<=(
tagged_id const &lhs, O
const &rhs)
noexcept
240 [[nodiscard]]
constexpr friend bool operator>=(
tagged_id const &lhs, O
const &rhs)
noexcept
245 [[nodiscard]]
constexpr friend bool operator==(O
const &lhs,
tagged_id const &rhs)
noexcept
250 [[nodiscard]]
constexpr friend bool operator!=(O
const &lhs,
tagged_id const &rhs)
noexcept
255 [[nodiscard]]
constexpr friend bool operator<(O
const &lhs,
tagged_id const &rhs)
noexcept
260 [[nodiscard]]
constexpr friend bool operator>(O
const &lhs,
tagged_id const &rhs)
noexcept
265 [[nodiscard]]
constexpr friend bool operator<=(O
const &lhs,
tagged_id const &rhs)
noexcept
270 [[nodiscard]]
constexpr friend bool operator>=(O
const &lhs,
tagged_id const &rhs)
noexcept
277 return std::format(
"{}:{}", Tag, rhs.value);
282 return lhs << to_string(rhs);