open62541pp 0.17.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
typewrapper.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4#include <utility> // exchange, swap
5
6#include "open62541pp/common.hpp" // TypeIndex
11
12namespace opcua {
13
14/**
15 * Template base class to wrap `UA_*` type objects that require manual memory management.
16 *
17 * Provides a zero-cost abstraction to wrap C API objects and automatically delete them upon
18 * destruction.
19 *
20 * @warning No virtual constructor is defined; do not implement a destructor in derived classes.
21 * @ingroup Wrapper
22 */
23template <typename T, TypeIndex Index>
24class TypeWrapper : public Wrapper<T> {
25public:
26 static_assert(Index < UA_TYPES_COUNT);
27
28 constexpr TypeWrapper() noexcept = default;
29
30 /// Constructor with native object (deep copy).
31 explicit constexpr TypeWrapper(const T& native)
32 : Wrapper<T>(detail::copy(native, UA_TYPES[Index])) {}
33
34 /// Constructor with native object (move rvalue).
35 constexpr TypeWrapper(T&& native) noexcept // NOLINT
36 : Wrapper<T>(std::exchange(native, {})) {}
37
39 clear();
40 };
41
42 /// Copy constructor (deep copy).
43 constexpr TypeWrapper(const TypeWrapper& other)
44 : Wrapper<T>(detail::copy(other.native(), UA_TYPES[Index])) {}
45
46 /// Move constructor.
47 constexpr TypeWrapper(TypeWrapper&& other) noexcept
48 : Wrapper<T>(std::exchange(other.native(), {})) {}
49
50 /// Copy assignment (deep copy).
51 constexpr TypeWrapper& operator=(const TypeWrapper& other) {
52 if (this != &other) {
53 clear();
54 this->native() = detail::copy(other.native(), UA_TYPES[Index]);
55 }
56 return *this;
57 }
58
59 /// Copy assignment with native object (deep copy).
60 constexpr TypeWrapper& operator=(const T& native) {
61 if (&this->native() != &native) {
62 clear();
63 this->native() = detail::copy(native, UA_TYPES[Index]);
64 }
65 return *this;
66 }
67
68 /// Move assignment.
69 constexpr TypeWrapper& operator=(TypeWrapper&& other) noexcept {
70 if (this != &other) {
71 clear();
72 this->native() = std::exchange(other.native(), {});
73 }
74 return *this;
75 }
76
77 /// Move assignment with native object.
78 constexpr TypeWrapper& operator=(T&& native) noexcept { // NOLINT
79 if (&this->native() != &native) {
80 clear();
81 this->native() = std::exchange(native, {});
82 }
83 return *this;
84 }
85
86 /// Get type as type index of the ::UA_TYPES array.
87 static constexpr TypeIndex typeIndex() {
88 return Index;
89 }
90
91protected:
92 constexpr void clear() noexcept {
93 detail::clear(this->native(), UA_TYPES[Index]);
94 }
95};
96
97/* -------------------------------------------- Trait ------------------------------------------- */
98
99namespace detail {
100
101template <typename T>
102struct IsTypeWrapper {
103 // https://stackoverflow.com/a/51910887
104 template <typename U, TypeIndex Index>
105 static std::true_type check(const TypeWrapper<U, Index>&);
106
107 static std::false_type check(...);
108
109 using type = decltype(check(std::declval<T&>())); // NOLINT, false positive?
110 static constexpr bool value = type::value;
111};
112
113template <typename T>
114constexpr bool isTypeWrapper = IsTypeWrapper<T>::value;
115
116} // namespace detail
117
118/* --------------------------------- TypeRegistry specialization -------------------------------- */
119
120template <typename T>
121struct TypeRegistry<T, std::enable_if_t<detail::isTypeWrapper<T>>> {
122 static const UA_DataType& getDataType() noexcept {
123 return UA_TYPES[T::typeIndex()];
124 }
125};
126
127} // namespace opcua
Template base class to wrap UA_* type objects that require manual memory management.
constexpr TypeWrapper & operator=(TypeWrapper &&other) noexcept
Move assignment.
constexpr TypeWrapper(T &&native) noexcept
Constructor with native object (move rvalue).
constexpr TypeWrapper(TypeWrapper &&other) noexcept
Move constructor.
constexpr TypeWrapper & operator=(T &&native) noexcept
Move assignment with native object.
constexpr TypeWrapper & operator=(const TypeWrapper &other)
Copy assignment (deep copy).
constexpr TypeWrapper() noexcept=default
constexpr TypeWrapper & operator=(const T &native)
Copy assignment with native object (deep copy).
constexpr void clear() noexcept
static constexpr TypeIndex typeIndex()
Get type as type index of the UA_TYPES array.
constexpr TypeWrapper(const TypeWrapper &other)
Copy constructor (deep copy).
Template base class to wrap native objects.
Definition wrapper.hpp:33
constexpr const T & native() const noexcept
Definition wrapper.hpp:102
constexpr Wrapper() noexcept=default
uint16_t TypeIndex
Type index of the UA_TYPES array.
Definition common.hpp:21
const UA_DataType UA_TYPES[191]
#define UA_TYPES_COUNT