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 static void expectAtLeastOneField(const char* name, const Span<uint16_t>& fields);
37 [[noreturn]] static void throwNonNativeField(const char* variantName, const char* fieldName);
38 [[noreturn]] static void throwInvalidFieldIndex(const char* variantName, uint16_t index);
39 [[nodiscard]] static std::tuple<const char*, const Var*> getTypeAndValue(const Var& var,
41};
42
44template <typename T>
46{
47 static constexpr bool available = true;
48
49 template <std::size_t index>
50 [[nodiscard]] static bool tryPrintField(std::ostream& out, const char* typeName, const T& val, bool requiresNewline);
51
52protected:
53 template <std::size_t index>
54 [[nodiscard]] static bool assignFieldByName(const char* currentType,
55 const char* expectedTypeLong,
56 const char* expectedTypeShort,
57 const char* expectedAliasTypeShort,
58 const Var& fieldValue,
59 T& val);
60
61 template <std::size_t index>
62 static void assignField(const Var& fieldValue, T& val);
63
64 template <std::size_t index>
65 [[nodiscard]] static bool getFieldSerializedSize(const T& val, uint32_t key, uint32_t& result);
66
67 template <std::size_t index>
68 [[nodiscard]] static bool tryWriteField(OutputStream& out, const T& val, uint32_t key);
69
70 template <std::size_t index>
71 static void readField(InputStream& in, T& val);
72
73 template <std::size_t index>
74 [[nodiscard]] static bool tryFieldValueToVariant(const T& val, Var& var, std::shared_ptr<Var> valueVar, uint32_t key);
75};
76
78
79//----------------------------------------------------------------------------------------------------------------------
80// Inline implementation
81//----------------------------------------------------------------------------------------------------------------------
82
83template <typename T>
84template <std::size_t index>
85inline void VariantTraitsBase<T>::assignField(const Var& fieldValue, T& val)
86{
87 using F = std::variant_alternative_t<index, T>;
88 F fieldVal {};
89 VariantTraits<F>::variantToValue(fieldValue, fieldVal);
90 val.template emplace<index>(std::move(fieldVal));
91}
92
93template <typename T>
94template <std::size_t index>
95inline bool VariantTraitsBase<T>::assignFieldByName(const char* currentType,
96 const char* expectedTypeLong,
97 const char* expectedTypeShort,
98 const char* expectedAliasTypeShort,
99 const Var& fieldValue,
100 T& val)
101{
102 if (strcmp(currentType, expectedTypeShort) == 0U || strcmp(currentType, expectedTypeLong) == 0U ||
103 (expectedAliasTypeShort != nullptr && strcmp(currentType, expectedAliasTypeShort) == 0U))
104 {
105 assignField<index>(fieldValue, val);
106 return true;
107 }
108 return false;
109}
110
111template <typename T>
112template <std::size_t index>
113inline bool VariantTraitsBase<T>::getFieldSerializedSize(const T& val, uint32_t key, uint32_t& result)
114{
115 using F = std::variant_alternative_t<index, T>;
116 if (val.index() == index)
117 {
118 result =
120 return true;
121 }
122 return false;
123}
124
125template <typename T>
126template <std::size_t index>
127inline bool VariantTraitsBase<T>::tryWriteField(OutputStream& out, const T& val, uint32_t key)
128{
129 using F = std::variant_alternative_t<index, T>;
130 if (val.index() == index)
131 {
132 out.writeUInt32(key);
133 SerializationTraits<F>::write(out, std::get<index>(val));
134 return true;
135 }
136 return false;
137}
138
139template <typename T>
140template <std::size_t index>
142{
143 using F = std::variant_alternative_t<index, T>;
144 F fieldVal;
145 SerializationTraits<F>::read(in, fieldVal);
146 val.template emplace<index>(std::move(fieldVal));
147}
148
149template <typename T>
150template <std::size_t index>
152 Var& var,
153 std::shared_ptr<Var> valueVar,
154 uint32_t key)
155{
156 using F = std::variant_alternative_t<index, T>;
157 if (val.index() == index)
158 {
159 VariantTraits<F>::valueToVariant(std::get<index>(val), *valueVar);
160 var = KeyedVar {key, std::move(valueVar)};
161 return true;
162 }
163 return false;
164}
165
166template <typename T>
167template <std::size_t index>
168inline bool VariantTraitsBase<T>::tryPrintField(std::ostream& out,
169 const char* typeName,
170 const T& val,
171 bool requiresNewline)
172{
173 if (val.index() == index)
174 {
175 out.setf(std::ios::left, std::ios::adjustfield);
176 const auto indent = std::setw(static_cast<int>(out.width() + 2U));
177 out << indent << ' ' << "type: " << typeName << "\n";
178
179 if (auto valPtr = std::get_if<index>(&val); valPtr)
180 {
181 if (requiresNewline)
182 {
183 out << indent << ' ' << "value:\n" << indent << *valPtr;
184 }
185 else
186 {
187 out << indent << ' ' << "value: " << *valPtr;
188 }
189 }
190 return true;
191 }
192 return false;
193}
194
195} // namespace sen
196
197#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 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:46
static bool assignFieldByName(const char *currentType, const char *expectedTypeLong, const char *expectedTypeShort, const char *expectedAliasTypeShort, const Var &fieldValue, T &val)
Definition variant_traits.h:95
static bool tryWriteField(OutputStream &out, const T &val, uint32_t key)
Definition variant_traits.h:127
static void readField(InputStream &in, T &val)
Definition variant_traits.h:141
static constexpr bool available
Definition variant_traits.h:47
static bool tryPrintField(std::ostream &out, const char *typeName, const T &val, bool requiresNewline)
Definition variant_traits.h:168
static bool tryFieldValueToVariant(const T &val, Var &var, std::shared_ptr< Var > valueVar, uint32_t key)
Definition variant_traits.h:151
static bool getFieldSerializedSize(const T &val, uint32_t key, uint32_t &result)
Definition variant_traits.h:113
static void assignField(const Var &fieldValue, T &val)
Definition variant_traits.h:85