Sen API
Sen Libraries
Loading...
Searching...
No Matches
variant_traits.h
Go to the documentation of this file.
1// === variant_traits.h ================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_META_VARIANT_TRAITS_H
9#define SEN_CORE_META_VARIANT_TRAITS_H
10
11// sen
12#include "sen/core/base/span.h"
17#include "sen/core/meta/type.h"
19
20// std
21#include <cstring>
22#include <iomanip>
23#include <tuple>
24
25namespace sen
26{
27
28struct Var;
29
32
34{
35protected:
36 [[noreturn]] static void throwEmptyStructError(const char* name);
37 static void expectAtLeastOneField(const char* name, const Span<uint16_t>& fields);
38 [[noreturn]] static void throwNonNativeField(const char* variantName, const char* fieldName);
39 [[noreturn]] static void throwInvalidFieldIndex(const char* variantName, uint16_t index);
40 [[nodiscard]] static std::tuple<const char*, const Var*> getTypeAndValue(const Var& var,
42};
43
45template <typename T>
47{
48 static constexpr bool available = true;
49
50 template <std::size_t index>
51 [[nodiscard]] static bool tryPrintField(std::ostream& out, const char* typeName, const T& val, bool requiresNewline);
52
53protected:
54 template <std::size_t index>
55 [[nodiscard]] static bool assignFieldByName(const char* currentType,
56 const char* expectedTypeLong,
57 const char* expectedTypeShort,
58 const char* expectedAliasTypeShort,
59 const Var& fieldValue,
60 T& val);
61
62 template <std::size_t index>
63 static void assignField(const Var& fieldValue, T& val);
64
65 template <std::size_t index>
66 [[nodiscard]] static bool getFieldSerializedSize(const T& val, uint32_t key, uint32_t& result);
67
68 template <std::size_t index>
69 [[nodiscard]] static bool tryWriteField(OutputStream& out, const T& val, uint32_t key);
70
71 template <std::size_t index>
72 static void readField(InputStream& in, T& val);
73
74 template <std::size_t index>
75 [[nodiscard]] static bool tryFieldValueToVariant(const T& val, Var& var, std::shared_ptr<Var> valueVar, uint32_t key);
76};
77
79
80//----------------------------------------------------------------------------------------------------------------------
81// Inline implementation
82//----------------------------------------------------------------------------------------------------------------------
83
84template <typename T>
85template <std::size_t index>
86inline void VariantTraitsBase<T>::assignField(const Var& fieldValue, T& val)
87{
88 using F = std::variant_alternative_t<index, T>;
89 F fieldVal {};
90 VariantTraits<F>::variantToValue(fieldValue, fieldVal);
91 val.template emplace<index>(std::move(fieldVal));
92}
93
94template <typename T>
95template <std::size_t index>
96inline bool VariantTraitsBase<T>::assignFieldByName(const char* currentType,
97 const char* expectedTypeLong,
98 const char* expectedTypeShort,
99 const char* expectedAliasTypeShort,
100 const Var& fieldValue,
101 T& val)
102{
103 if (strcmp(currentType, expectedTypeShort) == 0U || strcmp(currentType, expectedTypeLong) == 0U ||
104 (expectedAliasTypeShort != nullptr && strcmp(currentType, expectedAliasTypeShort) == 0U))
105 {
106 assignField<index>(fieldValue, val);
107 return true;
108 }
109 return false;
110}
111
112template <typename T>
113template <std::size_t index>
114inline bool VariantTraitsBase<T>::getFieldSerializedSize(const T& val, uint32_t key, uint32_t& result)
115{
116 using F = std::variant_alternative_t<index, T>;
117 if (val.index() == index)
118 {
119 result =
121 return true;
122 }
123 return false;
124}
125
126template <typename T>
127template <std::size_t index>
128inline bool VariantTraitsBase<T>::tryWriteField(OutputStream& out, const T& val, uint32_t key)
129{
130 using F = std::variant_alternative_t<index, T>;
131 if (val.index() == index)
132 {
133 out.writeUInt32(key);
134 SerializationTraits<F>::write(out, std::get<index>(val));
135 return true;
136 }
137 return false;
138}
139
140template <typename T>
141template <std::size_t index>
143{
144 using F = std::variant_alternative_t<index, T>;
145 F fieldVal;
146 SerializationTraits<F>::read(in, fieldVal);
147 val.template emplace<index>(std::move(fieldVal));
148}
149
150template <typename T>
151template <std::size_t index>
153 Var& var,
154 std::shared_ptr<Var> valueVar,
155 uint32_t key)
156{
157 using F = std::variant_alternative_t<index, T>;
158 if (val.index() == index)
159 {
160 VariantTraits<F>::valueToVariant(std::get<index>(val), *valueVar);
161 var = KeyedVar {key, std::move(valueVar)};
162 return true;
163 }
164 return false;
165}
166
167template <typename T>
168template <std::size_t index>
169inline bool VariantTraitsBase<T>::tryPrintField(std::ostream& out,
170 const char* typeName,
171 const T& val,
172 bool requiresNewline)
173{
174 if (val.index() == index)
175 {
176 out.setf(std::ios::left, std::ios::adjustfield);
177 const auto indent = std::setw(static_cast<int>(out.width() + 2U));
178 out << indent << ' ' << "type: " << typeName << "\n";
179
180 if (auto valPtr = std::get_if<index>(&val); valPtr)
181 {
182 if (requiresNewline)
183 {
184 out << indent << ' ' << "value:\n" << indent << *valPtr;
185 }
186 else
187 {
188 out << indent << ' ' << "value: " << *valPtr;
189 }
190 }
191 return true;
192 }
193 return false;
194}
195
196} // namespace sen
197
198#endif // SEN_CORE_META_VARIANT_TRAITS_H
void writeUInt32(uint32_t val)
Definition output_stream.h:44
Contiguous view of elements of type T. Inspired by http://www.open-std.org/jtc1/sc22/wg21/docs/papers...
Definition span.h:34
InputStreamTemplate< LittleEndian > InputStream
Definition input_stream.h:84
Definition type_traits.h:47
Definition type_traits.h:34
std::tuple< uint32_t, std::shared_ptr< Var > > KeyedVar
A key-var tuple, to represent variants.
Definition var.h:110
TypeHandle< const T > ConstTypeHandle
Definition type.h:319
Definition assert.h:17
OutputStreamTemplate< LittleEndian > OutputStream
Definition output_stream.h:64
Can hold any supported value type. Wraps std::variant to allow recursion and implements some helpers.
Definition var.h:119
Definition variant_traits.h:34
static void throwNonNativeField(const char *variantName, const char *fieldName)
static void throwInvalidFieldIndex(const char *variantName, uint16_t index)
static void throwEmptyStructError(const char *name)
static void expectAtLeastOneField(const char *name, const Span< uint16_t > &fields)
static std::tuple< const char *, const Var * > getTypeAndValue(const Var &var, ConstTypeHandle< VariantType > meta)
Base class for variant traits.
Definition variant_traits.h:47
static bool assignFieldByName(const char *currentType, const char *expectedTypeLong, const char *expectedTypeShort, const char *expectedAliasTypeShort, const Var &fieldValue, T &val)
Definition variant_traits.h:96
static bool tryWriteField(OutputStream &out, const T &val, uint32_t key)
Definition variant_traits.h:128
static void readField(InputStream &in, T &val)
Definition variant_traits.h:142
static constexpr bool available
Definition variant_traits.h:48
static bool tryPrintField(std::ostream &out, const char *typeName, const T &val, bool requiresNewline)
Definition variant_traits.h:169
static bool tryFieldValueToVariant(const T &val, Var &var, std::shared_ptr< Var > valueVar, uint32_t key)
Definition variant_traits.h:152
static bool getFieldSerializedSize(const T &val, uint32_t key, uint32_t &result)
Definition variant_traits.h:114
static void assignField(const Var &fieldValue, T &val)
Definition variant_traits.h:86