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)) { tt_axiom(value <= invalid); }
31 constexpr explicit tagged_id(
signed long rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
32 constexpr explicit tagged_id(
signed int rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
33 constexpr explicit tagged_id(
signed short rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
34 constexpr explicit tagged_id(
signed char rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
35 constexpr explicit tagged_id(
unsigned long long rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
36 constexpr explicit tagged_id(
unsigned long rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
37 constexpr explicit tagged_id(
unsigned int rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
38 constexpr explicit tagged_id(
unsigned short rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
39 constexpr explicit tagged_id(
unsigned char rhs) noexcept : value(narrow_cast<value_type>(rhs)) { tt_axiom(value <= invalid); }
41 constexpr tagged_id &operator=(
signed long long rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
42 constexpr tagged_id &operator=(
signed long rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
43 constexpr tagged_id &operator=(
signed int rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
44 constexpr tagged_id &operator=(
signed short rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
45 constexpr tagged_id &operator=(
signed char rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
46 constexpr tagged_id &operator=(
unsigned long long rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
47 constexpr tagged_id &operator=(
unsigned long rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
48 constexpr tagged_id &operator=(
unsigned int rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
49 constexpr tagged_id &operator=(
unsigned short rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
50 constexpr tagged_id &operator=(
unsigned char rhs)
noexcept { value = narrow_cast<value_type>(rhs); tt_axiom(value <= invalid);
return *
this; }
52 constexpr tagged_id() noexcept : value(invalid) {}
58 constexpr operator signed long long ()
const noexcept {
return narrow_cast<signed long long>(value); }
59 constexpr operator signed long ()
const noexcept {
return narrow_cast<signed long>(value); }
60 constexpr operator signed int ()
const noexcept {
return narrow_cast<signed int>(value); }
61 constexpr operator signed short ()
const noexcept {
return narrow_cast<signed short>(value); }
62 constexpr operator signed char ()
const noexcept {
return narrow_cast<signed char>(value); }
63 constexpr operator unsigned long long ()
const noexcept {
return narrow_cast<unsigned long long>(value); }
64 constexpr operator unsigned long ()
const noexcept {
return narrow_cast<unsigned long>(value); }
65 constexpr operator unsigned int ()
const noexcept {
return narrow_cast<unsigned int>(value); }
66 constexpr operator unsigned short ()
const noexcept {
return narrow_cast<unsigned short>(value); }
67 constexpr operator unsigned char ()
const noexcept {
return narrow_cast<unsigned char>(value); }
69 constexpr operator bool ()
const noexcept {
return value <= max; }
73 [[nodiscard]]
constexpr friend bool operator==(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value == rhs.value; }
74 [[nodiscard]]
constexpr friend bool operator!=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value != rhs.value; }
75 [[nodiscard]]
constexpr friend bool operator<(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value < rhs.value; }
76 [[nodiscard]]
constexpr friend bool operator>(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value > rhs.value; }
77 [[nodiscard]]
constexpr friend bool operator<=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value <= rhs.value; }
78 [[nodiscard]]
constexpr friend bool operator>=(
tagged_id const &lhs,
tagged_id const &rhs)
noexcept {
return lhs.value >= rhs.value; }
80 template<
typename O> [[nodiscard]]
constexpr friend bool operator==(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs ==
tagged_id{rhs}; }
81 template<
typename O> [[nodiscard]]
constexpr friend bool operator!=(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs !=
tagged_id{rhs}; }
82 template<
typename O> [[nodiscard]]
constexpr friend bool operator<(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs <
tagged_id{rhs}; }
83 template<
typename O> [[nodiscard]]
constexpr friend bool operator>(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs >
tagged_id{rhs}; }
84 template<
typename O> [[nodiscard]]
constexpr friend bool operator<=(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs <=
tagged_id{rhs}; }
85 template<
typename O> [[nodiscard]]
constexpr friend bool operator>=(
tagged_id const &lhs, O
const &rhs)
noexcept {
return lhs >=
tagged_id{rhs}; }
86 template<
typename O> [[nodiscard]]
constexpr friend bool operator==(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} == rhs; }
87 template<
typename O> [[nodiscard]]
constexpr friend bool operator!=(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} != rhs; }
88 template<
typename O> [[nodiscard]]
constexpr friend bool operator<(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} < rhs; }
89 template<
typename O> [[nodiscard]]
constexpr friend bool operator>(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} > rhs; }
90 template<
typename O> [[nodiscard]]
constexpr friend bool operator<=(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} <= rhs; }
91 template<
typename O> [[nodiscard]]
constexpr friend bool operator>=(O
const &lhs,
tagged_id const &rhs)
noexcept {
return tagged_id{lhs} >= rhs; }
94 return fmt::format(
"{}:{}", Tag, rhs.value);
98 return lhs << to_string(rhs);