open62541pp 0.16.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
typeregistry.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4
6#include "open62541pp/detail/traits.hpp" // AlwaysFalse
7
8namespace opcua {
9
10/**
11 * Type registry.
12 *
13 * The type registry is used to derive the corresponding `UA_DataType` object from template types.
14 *
15 * Custom data types can be registered with template specializations:
16 * @code
17 * namespace ::opcua {
18 * template <>
19 * struct TypeRegistry<MyCustomType> {
20 * static const UA_DataType& getDataType() noexcept {
21 * // ...
22 * }
23 * };
24 * }
25 * @endcode
26 */
27template <typename T, typename Enabled = void>
29
30/* -------------------------------------- Traits and helper ------------------------------------- */
31
32namespace detail {
33
34template <typename T, typename = void>
35struct IsRegisteredType : std::false_type {};
36
37template <typename T>
38struct IsRegisteredType<T, std::void_t<decltype(TypeRegistry<T>{})>> : std::true_type {};
39
40template <typename T>
42
43} // namespace detail
44
45template <typename T>
46const UA_DataType& getDataType() noexcept {
47 using ValueType = typename std::remove_cv_t<T>;
48 static_assert(
50 "The provided template type is not registered. "
51 "Specify the data type manually or add a template specialization for TypeRegistry."
52 );
54}
55
56/* ---------------------------------- Template specializations ---------------------------------- */
57
58// NOLINTNEXTLINE
59#define UAPP_TYPEREGISTRY_NATIVE(NativeType, typeIndex) \
60 template <> \
61 struct TypeRegistry<NativeType> { \
62 static const auto& getDataType() noexcept { \
63 return UA_TYPES[typeIndex]; \
64 } \
65 };
66
67// builtin types
68// @cond HIDDEN_SYMBOLS
69UAPP_TYPEREGISTRY_NATIVE(UA_Boolean, UA_TYPES_BOOLEAN)
73UAPP_TYPEREGISTRY_NATIVE(UA_UInt16, UA_TYPES_UINT16)
75UAPP_TYPEREGISTRY_NATIVE(UA_UInt32, UA_TYPES_UINT32)
77UAPP_TYPEREGISTRY_NATIVE(UA_UInt64, UA_TYPES_UINT64)
79UAPP_TYPEREGISTRY_NATIVE(UA_Double, UA_TYPES_DOUBLE)
80// UAPP_TYPEREGISTRY_NATIVE(UA_String, UA_TYPES_STRING) // manual implementation below
81// UAPP_TYPEREGISTRY_NATIVE(UA_DateTime, UA_TYPES_DATETIME) // alias for int64_t
83// UAPP_TYPEREGISTRY_NATIVE(UA_ByteString, UA_TYPES_BYTESTRING) // alias for UA_String
84// UAPP_TYPEREGISTRY_NATIVE(UA_XmlElement, UA_TYPES_XMLELEMENT) // alias for UA_String
85UAPP_TYPEREGISTRY_NATIVE(UA_NodeId, UA_TYPES_NODEID)
86UAPP_TYPEREGISTRY_NATIVE(UA_ExpandedNodeId, UA_TYPES_EXPANDEDNODEID)
87// UAPP_TYPEREGISTRY_NATIVE(UA_StatusCode, UA_TYPES_STATUSCODE) // alias for uint32_t
88UAPP_TYPEREGISTRY_NATIVE(UA_QualifiedName, UA_TYPES_QUALIFIEDNAME)
89UAPP_TYPEREGISTRY_NATIVE(UA_LocalizedText, UA_TYPES_LOCALIZEDTEXT)
90UAPP_TYPEREGISTRY_NATIVE(UA_ExtensionObject, UA_TYPES_EXTENSIONOBJECT)
91UAPP_TYPEREGISTRY_NATIVE(UA_DataValue, UA_TYPES_DATAVALUE)
92UAPP_TYPEREGISTRY_NATIVE(UA_Variant, UA_TYPES_VARIANT)
93UAPP_TYPEREGISTRY_NATIVE(UA_DiagnosticInfo, UA_TYPES_DIAGNOSTICINFO)
94
95template <>
96struct TypeRegistry<UA_String> {
97 static_assert(std::is_same_v<UA_String, UA_ByteString>);
98 static_assert(std::is_same_v<UA_String, UA_XmlElement>);
99
100 template <typename... Ts>
101 static const auto& getDataType([[maybe_unused]] Ts... args) noexcept {
102 static_assert(
103 detail::AlwaysFalse<Ts...>::value,
104 "Data type of UA_String is ambiguous (alias for UA_ByteString and UA_XmlElement). "
105 "Please specify data type manually."
106 );
107 }
108};
109
110// @endcond
111
112} // namespace opcua
113
114// include template specializations for native types
static UA_LogCategory const char va_list args
constexpr bool isRegisteredType
const UA_DataType & getDataType() noexcept
#define UAPP_TYPEREGISTRY_NATIVE(NativeType, typeIndex)
int32_t UA_Int32
uint16_t UA_UInt16
int16_t UA_Int16
int8_t UA_SByte
uint32_t UA_UInt32
float UA_Float
double UA_Double
uint8_t UA_Byte
uint64_t UA_UInt64
int64_t UA_Int64