open62541pp 0.18.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 IsRegistered : std::false_type {};
36
37template <typename T>
38struct IsRegistered<T, std::void_t<decltype(TypeRegistry<T>{})>> : std::true_type {};
39
40} // namespace detail
41
42template <typename T>
43const UA_DataType& getDataType() noexcept {
44 using ValueType = typename std::remove_cv_t<T>;
45 static_assert(
46 detail::IsRegistered<ValueType>::value,
47 "The provided template type is not registered. "
48 "Specify the data type manually or add a template specialization for TypeRegistry."
49 );
51}
52
53/* ---------------------------------- Template specializations ---------------------------------- */
54
55// NOLINTNEXTLINE
56#define UAPP_TYPEREGISTRY_NATIVE(NativeType, typeIndex) \
57 template <> \
58 struct TypeRegistry<NativeType> { \
59 static const auto& getDataType() noexcept { \
60 return UA_TYPES[typeIndex]; \
61 } \
62 };
63
64// builtin types
65// @cond HIDDEN_SYMBOLS
66UAPP_TYPEREGISTRY_NATIVE(UA_Boolean, UA_TYPES_BOOLEAN)
70UAPP_TYPEREGISTRY_NATIVE(UA_UInt16, UA_TYPES_UINT16)
72UAPP_TYPEREGISTRY_NATIVE(UA_UInt32, UA_TYPES_UINT32)
74UAPP_TYPEREGISTRY_NATIVE(UA_UInt64, UA_TYPES_UINT64)
76UAPP_TYPEREGISTRY_NATIVE(UA_Double, UA_TYPES_DOUBLE)
77// UAPP_TYPEREGISTRY_NATIVE(UA_String, UA_TYPES_STRING) // manual implementation below
78// UAPP_TYPEREGISTRY_NATIVE(UA_DateTime, UA_TYPES_DATETIME) // alias for int64_t
80// UAPP_TYPEREGISTRY_NATIVE(UA_ByteString, UA_TYPES_BYTESTRING) // alias for UA_String
81// UAPP_TYPEREGISTRY_NATIVE(UA_XmlElement, UA_TYPES_XMLELEMENT) // alias for UA_String
82UAPP_TYPEREGISTRY_NATIVE(UA_NodeId, UA_TYPES_NODEID)
83UAPP_TYPEREGISTRY_NATIVE(UA_ExpandedNodeId, UA_TYPES_EXPANDEDNODEID)
84// UAPP_TYPEREGISTRY_NATIVE(UA_StatusCode, UA_TYPES_STATUSCODE) // alias for uint32_t
85UAPP_TYPEREGISTRY_NATIVE(UA_QualifiedName, UA_TYPES_QUALIFIEDNAME)
86UAPP_TYPEREGISTRY_NATIVE(UA_LocalizedText, UA_TYPES_LOCALIZEDTEXT)
87UAPP_TYPEREGISTRY_NATIVE(UA_ExtensionObject, UA_TYPES_EXTENSIONOBJECT)
88UAPP_TYPEREGISTRY_NATIVE(UA_DataValue, UA_TYPES_DATAVALUE)
89UAPP_TYPEREGISTRY_NATIVE(UA_Variant, UA_TYPES_VARIANT)
90UAPP_TYPEREGISTRY_NATIVE(UA_DiagnosticInfo, UA_TYPES_DIAGNOSTICINFO)
91
92template <>
93struct TypeRegistry<UA_String> {
94 static_assert(std::is_same_v<UA_String, UA_ByteString>);
95 static_assert(std::is_same_v<UA_String, UA_XmlElement>);
96
97 template <typename... Ts>
98 static const auto& getDataType([[maybe_unused]] Ts... args) noexcept {
99 static_assert(
100 detail::AlwaysFalse<Ts...>::value,
101 "Data type of UA_String is ambiguous (alias for UA_ByteString and UA_XmlElement). "
102 "Please specify data type manually."
103 );
104 }
105};
106
107// @endcond
108
109} // namespace opcua
static UA_LogCategory const char va_list args
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