open62541pp 0.15.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
connection.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <memory>
5#include <type_traits>
6
7namespace opcua::detail {
8
9/**
10 * Helper base class to derive a wrapper (e.g. `Server&`) from its underlying connection.
11 * The single connection pointer member is the same as in the parent connection class. A custom
12 * deleter is provided to prevent circular dependencies and double deletion.
13 * Because the connection pointer is the first and single member of the wrapper class, the
14 * connection pointer and the wrapper class are pointer-interconvertible (standard-layout required).
15 */
16template <typename WrapperType>
18public:
19 static_assert(sizeof(WrapperType) == sizeof(std::unique_ptr<ConnectionBase>));
20
21 // unique_ptr<T> is standard layout but clang disagrees:
22 // https://github.com/llvm/llvm-project/issues/53021
23 // static_assert(std::is_standard_layout_v<WrapperType>);
24
25 ConnectionBase() noexcept
26 : connectionPtr_(this) {}
27
28 ~ConnectionBase() = default;
29
31 ConnectionBase(ConnectionBase&&) noexcept = delete;
32 ConnectionBase& operator=(const ConnectionBase&) = delete;
33 ConnectionBase& operator=(ConnectionBase&&) noexcept = delete;
34
35 [[nodiscard]] WrapperType* wrapperPtr() noexcept {
36 assert(connectionPtr_ != nullptr);
37 // NOLINTNEXTLINE(bugprone-casting-through-void)
38 return static_cast<WrapperType*>(static_cast<void*>(&connectionPtr_));
39 };
40
41 [[nodiscard]] WrapperType& wrapper() noexcept {
42 return *wrapperPtr();
43 }
44
45private:
46 struct NoDeleter {
47 constexpr void operator()(ConnectionBase* /* unused */) noexcept {};
48 };
49
50 std::unique_ptr<ConnectionBase, NoDeleter> connectionPtr_;
51};
52
53} // namespace opcua::detail
Helper base class to derive a wrapper (e.g.
ConnectionBase(ConnectionBase &&) noexcept=delete
WrapperType * wrapperPtr() noexcept
WrapperType & wrapper() noexcept
ConnectionBase(const ConnectionBase &)=delete