open62541pp 0.19.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
typeconverter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4
5namespace opcua {
6
7/**
8 * Type conversion from and to native types.
9 *
10 * Native types can be both `UA_*` types and wrapper classes (like `UA_Guid` and `Guid`).
11 * The `TypeConverter` is mainly used within the `Variant` class to set/get non-native types.
12 *
13 * Template specializations can be added for conversions of arbitrary types:
14 * @code
15 * namespace ::opcua {
16 * template <>
17 * struct TypeConverter<MyGuid> {
18 * using NativeType = UA_Guid;
19 * [[nodiscard]] static MyGuid fromNative(const UA_Guid& src) { ... }
20 * [[nodiscard]] static UA_Guid toNative(const MyGuid& src) { ... }
21 * };
22 * }
23 * @endcode
24 */
25template <typename T, typename Enable = void>
27
28/* -------------------------------------- Traits and helper ------------------------------------- */
29
30template <typename T, typename = void>
31struct IsConvertible : std::false_type {};
32
33template <typename T>
34struct IsConvertible<T, std::void_t<decltype(TypeConverter<T>{})>> : std::true_type {};
35
36namespace detail {
37
38template <typename T, typename = std::enable_if_t<IsConvertible<T>::value>>
39[[nodiscard]] constexpr T fromNative(const typename TypeConverter<T>::NativeType& src) {
40 using NativeType = typename TypeConverter<T>::NativeType;
41 if constexpr (std::is_invocable_r_v<T, decltype(TypeConverter<T>::fromNative), NativeType>) {
43 } else {
44 T dst{};
45 TypeConverter<T>::fromNative(src, dst);
46 return dst;
47 }
48}
49
50template <typename T, typename = std::enable_if_t<IsConvertible<T>::value>>
51[[nodiscard]] constexpr auto toNative(const T& src) -> typename TypeConverter<T>::NativeType {
52 using NativeType = typename TypeConverter<T>::NativeType;
53 if constexpr (std::is_invocable_r_v<NativeType, decltype(TypeConverter<T>::toNative), T>) {
54 return TypeConverter<T>::toNative(src);
55 } else {
56 NativeType dst{};
57 TypeConverter<T>::toNative(src, dst);
58 return dst;
59 }
60}
61
62} // namespace detail
63
64} // namespace opcua
Type conversion from and to native types.