32namespace morph::model {
42 (std::integral<K> && !std::same_as<std::remove_cv_t<K>,
bool>) || std::same_as<std::remove_cv_t<K>, std::string>;
63 { key.hasValue() } -> std::convertible_to<bool>;
65 requires RawModelKey<std::remove_cvref_t<
decltype(*key)>>;
66 requires requires(std::remove_cvref_t<
decltype(*key)> raw) { K{std::move(raw)}; };
80template <WrappedModelKey K>
81using UnwrappedKeyOf = std::remove_cvref_t<decltype(*std::declval<const K&>())>;
93template <
typename Model>
100concept SelfDeclaredKey =
requires {
typename M::PrimaryKey; } && ModelKey<typename M::PrimaryKey>;
105 requires {
typename ModelKeyTraits<M>::PrimaryKey; } && ModelKey<typename ModelKeyTraits<M>::PrimaryKey>;
120concept KeyedModel = detail::SelfDeclaredKey<M> || detail::DeducedKey<M>;
131template <SelfDeclaredKey M>
134 using type = M::PrimaryKey;
141template <KeyedModel M>
167 if (!key.hasValue()) {
168 throw std::runtime_error(
"primary key is empty: a strong id with no value names no model instance");
171 }
else if constexpr (std::same_as<std::remove_cv_t<K>, std::string>) {
174 return std::to_string(key);
193 }
else if constexpr (std::same_as<std::remove_cv_t<K>, std::string>) {
194 return std::string{text};
201 auto [ptr, errc] = std::from_chars(text.data(), text.data() + text.size(), value);
202 const auto*
const last = text.data() + text.size();
203 if (errc != std::errc{} || ptr != last) {
204 throw std::runtime_error(
"invalid primary key encoding: '" + std::string{text} +
"'");
217template <
typename Action>
235template <
typename V,
typename C>
236struct MemberType<V C::*> {
243using MemberTypeOf = MemberType<std::remove_cv_t<T>>::type;
292#define BRIDGE_MODEL_KEY(M, A, MEMBER) \
294 struct morph::model::ActionKeyTraits<A> { \
295 static constexpr bool hasKey = true; \
296 static constexpr bool fromResult = false; \
297 static std::string key(const A& action) { return morph::model::keyToString(action.*MEMBER); } \
300 struct morph::model::ModelKeyTraits<M> { \
301 using PrimaryKey = morph::model::detail::MemberTypeOf<decltype(MEMBER)>; \
317#define BRIDGE_KEY_FROM(A, MEMBER) \
319 struct morph::model::ActionKeyTraits<A> { \
320 static constexpr bool hasKey = true; \
321 static constexpr bool fromResult = false; \
322 static std::string key(const A& action) { return morph::model::keyToString(action.*MEMBER); } \
337#define BRIDGE_MODEL_KEY_FROM_RESULT(M, A, MEMBER) \
339 struct morph::model::ActionKeyTraits<A> { \
340 static constexpr bool hasKey = true; \
341 static constexpr bool fromResult = true; \
342 template <typename R> \
343 static std::string keyOfResult(const R& result) { \
344 return morph::model::keyToString(result.*MEMBER); \
348 struct morph::model::ModelKeyTraits<M> { \
349 using PrimaryKey = morph::model::detail::MemberTypeOf<decltype(MEMBER)>; \
362#define BRIDGE_KEY_FROM_RESULT(A, MEMBER) \
364 struct morph::model::ActionKeyTraits<A> { \
365 static constexpr bool hasKey = true; \
366 static constexpr bool fromResult = true; \
367 template <typename R> \
368 static std::string keyOfResult(const R& result) { \
369 return morph::model::keyToString(result.*MEMBER); \
Satisfied by model types that have a primary key, however it was named.
Key types a model may declare as its PrimaryKey.
Key types that are themselves a wire-encodable scalar.
Key types that wrap a RawModelKey — the ladder's strong ids.
detail::KeyTypeOf< M >::type PrimaryKeyOf
The primary key type of a keyed model.
K keyFromString(std::string_view text)
Decodes a primary key from its canonical wire string.
std::string keyToString(const K &key)
Encodes a primary key as its canonical wire string.
Declares where an action's model key comes from.
static constexpr bool fromResult
Whether the key comes from the action's result rather than its payload.
static constexpr bool hasKey
Whether this action carries or establishes its model's key.
The key type of a model, when one has been declared for it.