tagval 0.2.0
Modern C++23 header-only library of tagged values (open/closed enumerations with metadata)
Loading...
Searching...
No Matches
open_ended.hpp
Go to the documentation of this file.
1#pragma once
2
22
23#include <tagval/base.hpp>
24#include <tagval/entry.hpp>
25#include <tagval/error.hpp>
27#include <tagval/values.hpp>
28
29#include <commons/fixed_string.hpp>
30
31#include <concepts>
32#include <expected>
33#include <ranges>
34#include <string>
35#include <string_view>
36
37namespace tagval {
38
39namespace detail {
40
41template <typename T>
42concept HasValuesT = requires { typename T::values_t; };
43
44} // namespace detail
45
62template <comms::FixedString Id, typename Derived>
63class OpenEnded : public detail::HandleBase<Id, Derived> {
65
70 template <typename Self = Derived>
71 // NOLINTNEXTLINE(readability-identifier-naming)
72 inline static const bool values_t_seeded_ = [] {
73 if constexpr (detail::HasValuesT<Self>) {
74 for (constexpr auto ptrs = values_metadata_pointers<typename Self::values_t>();
75 const auto* p : ptrs) {
77 }
78 }
79 return true;
80 }();
81
82public:
83 using base_t::base_t;
84
88 template <typename E>
89 [[nodiscard]] static const Derived& value() noexcept {
90 static_assert(std::same_as<typename E::owner_t, Derived>,
91 "Entry type's owner must match this kind");
92 (void)values_t_seeded_<Derived>;
93 static const Derived h = base_t::make_handle(OpenEndedRegistry<Derived>::find(E::code));
94 return h;
95 }
96
101 [[nodiscard]] static auto all_values() noexcept {
102 (void)values_t_seeded_<Derived>;
104 std::views::transform(
105 [](const TagValMetadata* p) -> const TagValMetadata& { return *p; });
106 }
107
109 [[nodiscard]] static Derived of(std::string_view code) {
110 (void)values_t_seeded_<Derived>;
112 if (m == nullptr) {
113 std::string msg = "tagval: unknown code '";
114 msg.append(code);
115 msg += "' for kind '";
116 msg.append(Id.view());
117 msg += "'";
118 throw UnknownCodeError{msg};
119 }
120 return base_t::make_handle(m);
121 }
122
124 [[nodiscard]] static std::expected<Derived, ParseError> try_of(std::string_view code) noexcept {
125 (void)values_t_seeded_<Derived>;
127 if (m == nullptr) {
128 return std::unexpected(ParseError{.code = std::string{code}, .kind_id = Id.view()});
129 }
130 return base_t::make_handle(m);
131 }
132};
133
134} // namespace tagval
CRTP HandleBase used by ClosedEnded and OpenEnded.
Runtime list of metadata pointers for a single OpenEnded kind.
Definition openended_registry.hpp:27
static void add(const TagValMetadata *m)
Register a pinned metadata pointer.
Definition openended_registry.hpp:31
static std::span< const TagValMetadata *const > all() noexcept
Definition openended_registry.hpp:42
static const TagValMetadata * find(std::string_view code) noexcept
Definition openended_registry.hpp:46
CRTP base for tag-value kinds whose values are partly compile-time (Derived::values_t) and partly con...
Definition open_ended.hpp:63
static std::expected< Derived, ParseError > try_of(std::string_view code) noexcept
Look up a value by code. Returns ParseError on miss.
Definition open_ended.hpp:124
static auto all_values() noexcept
Range of TagValMetadata covering compile-time values_t entries (seeded lazily on first call) plus ext...
Definition open_ended.hpp:101
static Derived of(std::string_view code)
Look up a value by code. Throws UnknownCodeError on miss.
Definition open_ended.hpp:109
static const Derived & value() noexcept
Canonical handle for an entry.
Definition open_ended.hpp:89
Thrown by of() when a code is not present.
Definition error.hpp:19
CRTP handle.
Definition base.hpp:49
static Derived make_handle(const TagValMetadata *m) noexcept
Build a Derived handle from a stable metadata pointer.
Definition base.hpp:109
std::string_view code() const noexcept
Definition base.hpp:55
Definition open_ended.hpp:42
Compile-time Entry NTTP and the runtime-view TagValMetadata struct.
tagval exception types and ParseError record used by try_of().
Definition base.hpp:26
Per-Owner runtime registry used by OpenEnded kinds.
Returned via std::expected from try_of() when a code is not present.
Definition error.hpp:25
std::string code
The attempted code.
Definition error.hpp:26
Runtime view of an entry's metadata.
Definition entry.hpp:46
Compile-time list of Entry types for ClosedEnded kinds.