65struct is_allowed_id_repr<std::uint16_t> : std::true_type {};
67struct is_allowed_id_repr<std::uint32_t> : std::true_type {};
69struct is_allowed_id_repr<std::uint64_t> : std::true_type {};
71struct is_allowed_id_repr<std::string> : std::true_type {};
75struct is_allowed_id_repr<::ulid::Ulid> : std::true_type {};
82concept AllowedIdRepr = is_allowed_id_repr<std::remove_cvref_t<T>>::value;
88 { Tag::name } -> std::convertible_to<std::string_view>;
94concept StdToStringable =
requires(
const T& v) {
95 { std::to_string(v) } -> std::convertible_to<std::string>;
105template <
class Tag, AllowedIdRepr Repr>
108 using tag_type = Tag;
109 using repr_type = Repr;
116 requires(!std::default_initializable<Repr>)
119 requires std::default_initializable<Repr>
125 requires std::constructible_from<Repr, U&&> && (!std::is_same_v<std::remove_cvref_t<U>,
Id>)
126 explicit
Id(U&& u) : value_(std::forward<U>(u)) {}
129 explicit Id(std::string_view sv)
130 requires std::is_same_v<Repr, std::string>
133 [[nodiscard]]
const Repr& value() const& noexcept {
136 [[nodiscard]] Repr& value() &
noexcept {
139 [[nodiscard]] Repr&& value() &&
noexcept {
140 return std::move(value_);
143 [[nodiscard]]
auto operator<=>(
const Id&)
const =
default;
144 [[nodiscard]]
bool operator==(
const Id&)
const =
default;
153using Uint8Id = Id<Tag, std::uint8_t>;
155using Uint16Id = Id<Tag, std::uint16_t>;
157using Uint32Id = Id<Tag, std::uint32_t>;
159using Uint64Id = Id<Tag, std::uint64_t>;
162using StringId = Id<Tag, std::string>;
166using UlidId = Id<Tag, ::ulid::Ulid>;
174struct is_id : std::false_type {};
176template <
class Tag,
class Repr>
177struct is_id<Id<Tag, Repr>> : std::true_type {};
180inline constexpr bool is_id_v = is_id<std::remove_cvref_t<T>>::value;
185concept IdType = is_id_v<T>;
190template <
class Tag,
class Repr>
196template <
class Tag,
class Repr>
197 requires std::is_same_v<Repr, std::string>
203template <
class Tag,
class Repr>
204 requires(!std::is_same_v<Repr, std::string>) && detail::StdToStringable<Repr>
206 return std::to_string(
id.value());
211template <
class Tag,
class Repr>
212 requires std::is_same_v<Repr, ::ulid::Ulid>
213[[nodiscard]] std::string to_string(
const Id<Tag, Repr>&
id) {
214 return id.value().string();
220template <
class Tag,
class Repr>
223 std::string out{std::string_view{Tag::name}};
232template <
class Tag,
class Repr>
233std::ostream& operator<<(std::ostream& os,
const Id<Tag, Repr>&
id) {
234 return os << to_string(
id);
246template <
class Tag,
class Repr>
247 requires requires(
const Repr& r) {
248 { std::hash<Repr>{}(r) } -> std::convertible_to<std::size_t>;
250struct std::hash<comms::Id<Tag, Repr>> {
252 return std::hash<Repr>{}(
id.value());
259template <
class Tag,
class Repr,
class Char>
260struct std::formatter<comms::Id<Tag, Repr>, Char> : std::formatter<Repr, Char> {
261 template <
class FormatContext>
263 return std::formatter<Repr, Char>::format(
id.value(), ctx);
278#define COMMONS_DEFINE_ID_TAG(Name, NameStr) \
280 [[maybe_unused]] static constexpr ::std::string_view name = NameStr; \
283#define COMMONS_DEFINE_UINT8_ID(Name, NameStr) \
284 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
285 using Name = ::comms::Uint8Id<Name##Tag>
287#define COMMONS_DEFINE_UINT16_ID(Name, NameStr) \
288 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
289 using Name = ::comms::Uint16Id<Name##Tag>
291#define COMMONS_DEFINE_UINT32_ID(Name, NameStr) \
292 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
293 using Name = ::comms::Uint32Id<Name##Tag>
295#define COMMONS_DEFINE_UINT64_ID(Name, NameStr) \
296 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
297 using Name = ::comms::Uint64Id<Name##Tag>
299#define COMMONS_DEFINE_STRING_ID(Name, NameStr) \
300 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
301 using Name = ::comms::StringId<Name##Tag>
304#define COMMONS_DEFINE_ULID_ID(Name, NameStr) \
305 COMMONS_DEFINE_ID_TAG(Name, NameStr); \
306 using Name = ::comms::UlidId<Name##Tag>
Strong-typed identifier: a Repr value tagged with a phantom Tag.
Definition id.hpp:106
Id(std::string_view sv)
Convenience for StringId<Tag>: build directly from a string_view.
Definition id.hpp:129
Id()=delete
Default-construct the underlying Repr when it is itself default-initializable; otherwise the construc...
std::string to_string(const Color &c)
Color as its canonical hex string (#RRGGBB, or #RRGGBBAA when not opaque).
Definition color.hpp:1388
Concept form of is_allowed_id_repr.
Definition id.hpp:82
A tag exposing a static constexpr std::string_view name, used by display_string and the COMMONS_DEFIN...
Definition id.hpp:87
Central feature-gate header for Commons' optional integrations.
const Repr & to_underlying(const Id< Tag, Repr > &id) noexcept
Returns the underlying representation by const reference.
Definition id.hpp:191
std::string display_string(const Id< Tag, Repr > &id)
Tag::name + "/" + to_string(id) for a NamedIdTag, just to_string(id) otherwise.
Definition id.hpp:221
Trait selecting the representations allowed inside Id<Tag, Repr>.
Definition id.hpp:60
Fixed-width numeric aliases shared across the C++ libraries.