Crunch
A Message Definition Language for Getting Things Right
Loading...
Searching...
No Matches
crunch_messages.hpp
1#pragma once
2
3#include <concepts>
4#include <crunch/core/crunch_types.hpp>
5#include <crunch/fields/crunch_scalar.hpp>
6#include <crunch/fields/crunch_string.hpp>
7#include <crunch/messages/crunch_field.hpp>
8#include <tuple>
9#include <type_traits>
10#include <utility>
11
12namespace Crunch::messages {
13
14using Crunch::Error;
15using Crunch::FieldId;
17
26#define CRUNCH_MESSAGE_FIELDS(...) \
27 constexpr auto get_fields() const { return std::tie(__VA_ARGS__); } \
28 constexpr auto get_fields() { return std::tie(__VA_ARGS__); }
29
40// Reuse concepts from crunch_field.hpp
41using messages::HasCrunchMessageInterface;
42using messages::ValidElementType;
43
57template <typename T>
58concept ValidField =
59 messages::is_array_field_v<std::remove_cvref_t<T>> ||
60 messages::is_map_field_v<std::remove_cvref_t<T>> ||
61 (messages::is_field_v<std::remove_cvref_t<T>> &&
63
65
66template <typename Tuple>
67concept tuple_members_are_valid_fields = requires {
68 std::apply([]<typename... Ts>(Ts&&...)
69 requires(ValidField<Ts> && ...)
70 {},
71 std::declval<Tuple>());
72};
73
74template <FieldId... Ids>
75struct has_duplicates;
76
77template <>
78struct has_duplicates<> : std::false_type {};
79
80template <FieldId Head, FieldId... Tail>
81struct has_duplicates<Head, Tail...> {
82 static constexpr bool value =
83 ((Head == Tail) || ...) || has_duplicates<Tail...>::value;
84};
85
86template <typename Tuple>
87concept has_unique_field_ids =
88 []<std::size_t... Is>(std::index_sequence<Is...>) {
89 return !has_duplicates<std::remove_cvref_t<
90 std::tuple_element_t<Is, Tuple>>::field_id...>::value;
91 }(std::make_index_sequence<std::tuple_size_v<Tuple>>{});
92
93template <typename Message>
94concept HasConstexprValidate = requires(const Message& m) {
95 {
96 std::bool_constant<(Message{}.Validate(), true)>()
97 } -> std::same_as<std::true_type>;
98};
99
100template <typename Message>
101concept HasConstexprGetFields = requires {
102 {
103 std::bool_constant<(Message{}.get_fields(), true)>()
104 } -> std::same_as<std::true_type>;
105};
107
118template <typename Message>
120 std::regular<Message> && HasConstexprGetFields<Message> &&
122 tuple_members_are_valid_fields<decltype(Message{}.get_fields())> &&
123 has_unique_field_ids<decltype(Message{}.get_fields())> &&
124 HasConstexprValidate<Message>;
125
126} // namespace Crunch::messages
Concept ensuring a type is a fully valid CrunchMessage.
Definition: crunch_messages.hpp:119
Concept to detect if a type quacks like a Crunch Message.
Definition: crunch_field.hpp:226
Concept for valid element type in Array/Map. Must be a scalar, string, message, array,...
Definition: crunch_field.hpp:266
Concept checking if a type T is a valid field wrapper instance.
Definition: crunch_messages.hpp:58
int32_t FieldId
Unique identifier for a field within a Crunch message.
Definition: crunch_types.hpp:11
int32_t MessageId
Unique identifier for a message type.
Definition: crunch_types.hpp:25
Represents an error occurred during Crunch operations.
Definition: crunch_types.hpp:75