commons 0.1.5
Header-only C++23 library of common/shared types for the C++ libraries
Loading...
Searching...
No Matches
id.hpp File Reference

A strong-typed identifier — comms::Id<Tag, Repr> — that wraps an allowed representation in a phantom Tag so that ids of different kinds cannot be mixed. More...

#include <commons/config.hpp>
#include <commons/types.hpp>
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <format>
#include <functional>
#include <ostream>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
Include dependency graph for id.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  comms::is_allowed_id_repr< T >
 Trait selecting the representations allowed inside Id<Tag, Repr>. More...
 
class  comms::Id< Tag, Repr >
 Strong-typed identifier: a Repr value tagged with a phantom Tag. More...
 
struct  std::hash< comms::Id< Tag, Repr > >
 Hash an Id through its underlying representation. More...
 
struct  std::formatter< comms::Id< Tag, Repr >, Char >
 Forward formatting to the underlying Repr's formatter. More...
 

Concepts

concept  comms::AllowedIdRepr
 Concept form of is_allowed_id_repr.
 
concept  comms::NamedIdTag
 A tag exposing a static constexpr std::string_view name, used by display_string and the COMMONS_DEFINE_*_ID macros.
 

Macros

#define COMMONS_DEFINE_ID_TAG(Name, NameStr)
 Emit a tag type Name##Tag with static constexpr std::string_view name.
 

Functions

template<class Tag , class Repr >
const Repr & comms::to_underlying (const Id< Tag, Repr > &id) noexcept
 Returns the underlying representation by const reference.
 
template<class Tag , class Repr >
requires std::is_same_v<Repr, std::string>
std::string comms::to_string (const Id< Tag, Repr > &id)
 Id<Tag, std::string> — return the value itself.
 
template<class Tag , class Repr >
requires (!std::is_same_v<Repr, std::string>) && detail::StdToStringable<Repr>
std::string comms::to_string (const Id< Tag, Repr > &id)
 Id<Tag, uintN_t> — delegate to std::to_string.
 
template<class Tag , class Repr >
std::string comms::display_string (const Id< Tag, Repr > &id)
 Tag::name + "/" + to_string(id) for a NamedIdTag, just to_string(id) otherwise.
 

Detailed Description

A strong-typed identifier — comms::Id<Tag, Repr> — that wraps an allowed representation in a phantom Tag so that ids of different kinds cannot be mixed.

The allowed representations are deliberately narrow: the four unsigned fixed-width integer types (std::uint8_t / 16 / 32 / 64), std::string, and — gated by COMMONS_WITH_ULIDulid::Ulid. Any other representation fails the AllowedIdRepr concept at the point of use.

A Tag is any type. If it exposes a static constexpr std::string_view name member, display_string(id) prefixes the representation with that name (user/42), and the COMMONS_DEFINE_*_ID macros generate exactly that shape. Without a name, display_string falls back to the bare representation.

Serialization (in commons/json.hpp, gated by COMMONS_WITH_NLOHMANN_JSON): an Id travels as its inner Repr's natural JSON (a number for the uint reprs, a string for std::string, and — when ULID is also on — the ULID string for ulid::Ulid).

Text output (always available): to_string, operator<<, and std::format all emit the inner representation. The std::formatter specialization inherits from std::formatter<Repr>, so any format spec that the underlying type accepts (e.g. "{:#x}" for the uint reprs) works transparently.

Macro Definition Documentation

◆ COMMONS_DEFINE_ID_TAG

#define COMMONS_DEFINE_ID_TAG (   Name,
  NameStr 
)
Value:
struct Name##Tag { \
[[maybe_unused]] static constexpr ::std::string_view name = NameStr; \
}

Emit a tag type Name##Tag with static constexpr std::string_view name.

[[maybe_unused]] on name keeps the macro quiet at use sites that only rely on it indirectly through display_string (never odr-used).