Sen API
Sen Libraries
Loading...
Searching...
No Matches
type.h
Go to the documentation of this file.
1// === type.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_TYPE_H
9#define SEN_CORE_META_TYPE_H
10
11// sen
20
21// std
22#include <cassert>
23#include <cstddef>
24#include <functional>
25#include <memory>
26#include <optional>
27#include <string_view>
28#include <type_traits>
29#include <variant>
30
31namespace sen
32{
33
36
38struct MemberHash: public StrongType<uint32_t, MemberHash>
39{
40 using StrongType<uint32_t, MemberHash>::StrongType;
41};
42
43template <>
44struct ShouldBePassedByValue<MemberHash>: std::true_type
45{
46};
47
48template <>
49struct impl::hash<MemberHash>
50{
51 inline u32 operator()(const ::sen::MemberHash& x) const noexcept { return hashIntegral(x.get()); }
52};
53
55enum class TransportMode : uint8_t
56{
57 unicast = 0U,
58 multicast = 1U,
59 confirmed = 2U,
60};
61
62// forward declarations
63struct Var;
64
70class Type
71{
72public: // special members
73 SEN_NOCOPY_NOMOVE(Type)
74
75public:
76 virtual ~Type() = default;
77
78public:
80 [[nodiscard]] virtual std::string_view getName() const noexcept = 0;
81
83 [[nodiscard]] virtual std::string_view getDescription() const noexcept = 0;
84
86 virtual void accept(FullTypeVisitor& tv) const = 0;
87
89 [[nodiscard]] virtual bool isBounded() const noexcept = 0;
90
92 [[nodiscard]] MemberHash getHash() const noexcept;
93
94public:
96 static Result<void, std::string> validateLowerCaseName(std::string_view name);
97
99 static Result<void, std::string> validateTypeName(std::string_view name);
100
101public:
102 // Declaration of:
103 //
104 // bool isX() const noexcept;
105 // virtual const X* asX() const noexcept;
106 //
107 // Where X is defined for all supported types. It returns a valid
108 // pointer if the subclass is of type X.
109
110 // native types
113 DECL_IS_TYPE_FUNC(BoolType)
117 DECL_IS_TYPE_FUNC(Float32Type)
118 DECL_IS_TYPE_FUNC(Float64Type)
119 DECL_IS_TYPE_FUNC(StringType)
120 DECL_IS_TYPE_FUNC(UInt8Type)
121 DECL_IS_TYPE_FUNC(Int16Type)
122 DECL_IS_TYPE_FUNC(UInt16Type)
123 DECL_IS_TYPE_FUNC(Int32Type)
124 DECL_IS_TYPE_FUNC(UInt32Type)
125 DECL_IS_TYPE_FUNC(Int64Type)
126 DECL_IS_TYPE_FUNC(UInt64Type)
129
130 // custom types
135 DECL_IS_TYPE_FUNC(ClassType)
140
141public:
142 [[nodiscard]] virtual bool equals(const Type& other) const noexcept = 0;
143
145 friend bool operator==(const Type& lhs, const Type& rhs) { return lhs.equals(rhs); }
146
148 friend bool operator!=(const Type& lhs, const Type& rhs) { return !lhs.equals(rhs); }
149
150protected:
151 explicit Type(MemberHash hash) noexcept;
152
153private:
154 MemberHash hash_;
155};
156
160template <typename SenTypeType>
161class TypeHandle final
162{
163 using RawPtrType = SenTypeType*;
164 using ManagedPtrType = std::shared_ptr<SenTypeType>;
165 using StorageType = std::variant<RawPtrType, ManagedPtrType>;
166
167private:
168 template <typename T>
169 explicit TypeHandle(T* type): type_(type)
170 {
171 SEN_ASSERT(type != nullptr && "handles should not be to nullptrs");
172 }
173
174public:
175 template <typename T>
177
178 template <
179 typename ArgT,
180 typename... ArgTypes,
181 std::enable_if_t<std::negation_v<sen::std_util::IsInstantiationOf<TypeHandle, std::decay_t<ArgT>>>, bool> = true>
182 // NOLINTNEXTLINE(hicpp-explicit-conversions): implicit conversion wanted here
183 TypeHandle(ArgT&& arg, ArgTypes&&... args)
184 : type_(std::make_shared<SenTypeType>(std::forward<ArgT>(arg), std::forward<ArgTypes>(args)...))
185 {
186 }
187
188 template <typename T>
189 // NOLINTNEXTLINE(hicpp-explicit-conversions): implicit conversion wanted here
190 TypeHandle(std::shared_ptr<T> type): type_(std::move(type))
191 {
192 SEN_ASSERT(std::get<ManagedPtrType>(type_).get() != nullptr && "Handles should not be to nullptrs");
193 }
194
195 template <typename OtherSenTypeType>
196 // NOLINTNEXTLINE(hicpp-explicit-conversions): implicit conversion wanted here
198 : type_(std::visit(sen::Overloaded {[](OtherSenTypeType* ptr) -> StorageType { return {ptr}; },
199 [](std::shared_ptr<OtherSenTypeType> sharedPtr) -> StorageType
200 { return {std::move(sharedPtr)}; }},
201 otherHandle.type_))
202 {
203 }
204
205 template <typename OtherSenTypeType>
206 // NOLINTNEXTLINE(hicpp-explicit-conversions): implicit conversion wanted here
208 : type_(std::visit(sen::Overloaded {[](OtherSenTypeType* ptr) -> StorageType { return {ptr}; },
209 [](std::shared_ptr<OtherSenTypeType> sharedPtr) -> StorageType
210 { return {std::move(sharedPtr)}; }},
211 otherHandle.type_))
212 {
213 }
214
215 SenTypeType& operator*() { return *type(); }
216 const SenTypeType& operator*() const { return *type(); }
217
218 SenTypeType* operator->() { return type(); }
219 const SenTypeType* operator->() const { return type(); }
220
221 SenTypeType* type()
222 {
223 if (std::holds_alternative<ManagedPtrType>(type_))
224 {
225 return std::get<ManagedPtrType>(type_).get();
226 }
227
228 return std::get<RawPtrType>(type_);
229 }
230
231 const SenTypeType* type() const
232 {
233 if (std::holds_alternative<ManagedPtrType>(type_))
234 {
235 return std::get<ManagedPtrType>(type_).get();
236 }
237
238 return std::get<RawPtrType>(type_);
239 }
240
241 //===--------------------------------------------------===//
242 // Comparisons
243 //===--------------------------------------------------===//
244 template <typename U>
245 friend bool operator==(const TypeHandle& lhs, const TypeHandle<U>& rhs)
246 {
247 return *lhs == *rhs;
248 }
249 friend bool operator==(const TypeHandle& lhs, const Type& rhs) { return *lhs == rhs; }
250 friend bool operator==(const Type& lhs, const TypeHandle& rhs) { return lhs == *rhs; }
251
252 template <typename U>
253 friend bool operator!=(const TypeHandle& lhs, const TypeHandle<U>& rhs)
254 {
255 return *lhs != *rhs;
256 }
257 friend bool operator!=(const TypeHandle& lhs, const Type& rhs) { return *lhs != rhs; }
258 friend bool operator!=(const Type& lhs, const TypeHandle& rhs) { return lhs != *rhs; }
259
260private:
261 StorageType type_;
262
263 template <typename T>
264 friend class TypeHandle;
265
266 template <typename T, typename U>
267 friend std::optional<TypeHandle<T>> dynamicTypeHandleCast(const TypeHandle<U>&);
268};
269
270template <typename T>
271TypeHandle(std::shared_ptr<T> type) -> TypeHandle<T>;
272
280template <typename T>
282{ // explicit factory function to prevent accidental creation/convertion from a type *
283 return TypeHandle<T> {typePtr};
284}
285
287template <typename T, typename U>
288std::optional<TypeHandle<T>> dynamicTypeHandleCast(const TypeHandle<U>& handle)
289{
290 // Note: Implemented as non-member functions to mirror the design of *_pointer_cast
291
292 // Handle managed ptr
293 if (std::holds_alternative<typename TypeHandle<U>::ManagedPtrType>(handle.type_))
294 {
295 if (auto convertedSharedPtr = std::dynamic_pointer_cast<typename TypeHandle<T>::ManagedPtrType::element_type>(
296 std::get<typename TypeHandle<U>::ManagedPtrType>(handle.type_)))
297 {
298 return {TypeHandle(std::move(convertedSharedPtr))};
299 }
300
301 return std::nullopt;
302 }
303
304 // Handle unmanaged raw ptr
305 if (auto convertedPtr =
306 dynamic_cast<typename TypeHandle<T>::RawPtrType>(std::get<typename TypeHandle<U>::RawPtrType>(handle.type_)))
307 {
308 return {sen::makeNonOwningTypeHandle(convertedPtr)};
309 }
310
311 return std::nullopt;
312}
313
315template <typename T>
316using ConstSharedPtr = std::shared_ptr<const T>;
317
318template <typename T = Type>
320
321template <typename T = Type>
322using MaybeConstTypeHandle = std::optional<ConstTypeHandle<T>>;
323
325
326} // namespace sen
327
328namespace std
329{
330
331template <typename Type>
332struct hash<sen::TypeHandle<Type>> // NOLINT(cert-dcl58-cpp): specializing std::hash is allowed
333{
334 size_t operator()(const sen::TypeHandle<Type>& typeHandle) const noexcept { return typeHandle->getHash().get(); }
335};
336
337} // namespace std
338
339//----------------------------------------------------------------------------------------------------------------------
340// Inline implementation
341//----------------------------------------------------------------------------------------------------------------------
342
343#undef DECL_IS_TYPE_FUNC
344
348#define SEN_META_TYPE(classname) \
349public: \
350 SEN_NOCOPY_NOMOVE(classname) \
351 \
352public: \
353 void accept(FullTypeVisitor& tv) const override { tv.apply(*this); } \
354 \
355 [[nodiscard]] const classname* as##classname() const noexcept override { return this; } \
356 \
357private:
358
359namespace std
360{
361
362template <>
363struct hash<::sen::MemberHash>
364{
365 size_t operator()(const ::sen::MemberHash& x) const noexcept
366 {
367 return std::hash<::sen::MemberHash::ValueType>()(x.get());
368 }
369};
370
371} // namespace std
372
373#endif // SEN_CORE_META_TYPE_H
The following macros implement a replacement of assert that is connected to the overall fault handlin...
Here we define a set of template meta-programming helpers to let the compiler take some decisions bas...
Represents an aliased type.
Definition alias_type.h:56
Represents a user-defined type.
Definition custom_type.h:23
Represents a sen::Duration (a time duration).
Definition time_types.h:28
Represents an enumeration.
Definition enum_type.h:84
A Visitor for constant types. This class is based on the GoF Visitor design pattern....
Definition type_visitor.h:28
Represents an integral numeric type.
Definition native_types.h:80
Represents a native (built-in) type that can be created on the stack or sent in a message.
Definition native_types.h:35
Represents a numeric native type.
Definition native_types.h:45
Represents an optional type.
Definition optional_type.h:56
Represents a quantity.
Definition quantity_type.h:76
Represents a floating point numeric type.
Definition native_types.h:90
Result<T, E> is a template type that can be used to return and propagate errors. The intent is to rep...
Definition result.h:135
Represents a sequence type.
Definition sequence_type.h:67
CRTP class that wraps T to make it a strong type.
Definition strong_type.h:72
Represents a structure type.
Definition struct_type.h:96
Represents a sen::TimeStamp (a point in time).
Definition time_types.h:48
Handle around a type that, by default, ensures the lifetime of the underlying type.
Definition type.h:162
SenTypeType * operator->()
Definition type.h:218
const SenTypeType & operator*() const
Definition type.h:216
friend std::optional< TypeHandle< T > > dynamicTypeHandleCast(const TypeHandle< U > &)
Definition type.h:288
friend bool operator!=(const Type &lhs, const TypeHandle &rhs)
Definition type.h:258
TypeHandle(std::shared_ptr< T > type)
Definition type.h:190
const SenTypeType * operator->() const
Definition type.h:219
TypeHandle(const TypeHandle< OtherSenTypeType > &otherHandle)
Definition type.h:197
const SenTypeType * type() const
Definition type.h:231
friend class TypeHandle
Definition type.h:264
SenTypeType * type()
Definition type.h:221
friend bool operator!=(const TypeHandle &lhs, const Type &rhs)
Definition type.h:257
TypeHandle(ArgT &&arg, ArgTypes &&... args)
Definition type.h:183
friend bool operator==(const TypeHandle &lhs, const TypeHandle< U > &rhs)
Definition type.h:245
friend bool operator!=(const TypeHandle &lhs, const TypeHandle< U > &rhs)
Definition type.h:253
friend bool operator==(const TypeHandle &lhs, const Type &rhs)
Definition type.h:249
SenTypeType & operator*()
Definition type.h:215
friend bool operator==(const Type &lhs, const TypeHandle &rhs)
Definition type.h:250
friend TypeHandle< T > makeNonOwningTypeHandle(T *type)
Definition type.h:281
TypeHandle(TypeHandle< OtherSenTypeType > &&otherHandle)
Definition type.h:207
Represents a type that can be used to define variables and arguments for methods or functions....
Definition type.h:71
static Result< void, std::string > validateTypeName(std::string_view name)
Checks that a upper case name (used for type names) is valid.
virtual std::string_view getName() const noexcept=0
The type name.
virtual bool isBounded() const noexcept=0
True if values of this type have a bounded memory footprint (do not grow or shrink).
virtual void accept(FullTypeVisitor &tv) const =0
Accepts a type visitor.
Type(MemberHash hash) noexcept
friend bool operator!=(const Type &lhs, const Type &rhs)
Returns true if the lhs type is not the same as the rhs type.
Definition type.h:148
virtual std::string_view getDescription() const noexcept=0
The type documentation.
virtual bool equals(const Type &other) const noexcept=0
virtual ~Type()=default
static Result< void, std::string > validateLowerCaseName(std::string_view name)
Checks that a lower case name (used for fields, enums, etc) is valid.
MemberHash getHash() const noexcept
Returns the unique hash computed for the type at compile time.
Represents a variant type.
Definition variant_type.h:75
Used for indicating that no result value is provided.
Definition native_types.h:150
#define SEN_ASSERT(expr)
Checks an intermediate result produced by a procedure (not an input or output). NOLINTNEXTLINE.
Definition assert.h:39
std::shared_ptr< const T > ConstSharedPtr
Utility typedef.
Definition type.h:316
TypeHandle< T > makeNonOwningTypeHandle(T *typePtr)
Creates a non-owning type handle from a type pointer.
Definition type.h:281
std::optional< ConstTypeHandle< T > > MaybeConstTypeHandle
Definition type.h:322
TypeHandle< const T > ConstTypeHandle
Definition type.h:319
TransportMode
How to transport information.
Definition type.h:56
@ multicast
Directed to all receivers, unreliable, unordered, no congestion control.
Definition type.h:58
@ confirmed
Directed to each receiver, reliable, ordered, with congestion control, relatively heavyweight.
Definition type.h:59
@ unicast
Directed to each receiver, unreliable, unordered, no congestion control.
Definition type.h:57
uint32_t u32
Definition numbers.h:25
This file contains functions related to hashing and compression. This is mainly used by Sen internals...
Definition assert.h:17
STL namespace.
The hash of a member.
Definition type.h:39
Helper type for std::variant lambda visitors.
Definition class_helpers.h:170
Utility to indicate that your class wants to be passed by value in some of the library calls.
Definition class_helpers.h:34
size_t operator()(const sen::TypeHandle< Type > &typeHandle) const noexcept
Definition type.h:334
size_t operator()(const ::sen::MemberHash &x) const noexcept
Definition type.h:365
#define DECL_IS_TYPE_FUNC(type_name)
Definition type_impl.h:12