18 template<
typename,
typename>
19 friend class UnderlyingType;
22 struct ConstructorAccess {
23 explicit ConstructorAccess(
int) {}
26 template<
typename R = U>
28 return reinterpret_cast<R *
>(&resource);
31 template<
typename R = U>
32 auto get()
const noexcept {
33 return reinterpret_cast<const R *
>(&resource);
36 template<
typename R,
typename... P>
37 auto get(UnderlyingType<P...> &other)
noexcept {
38 return reinterpret_cast<R *
>(&other.resource);
42 explicit UnderlyingType(ConstructorAccess, std::shared_ptr<Loop> ref) noexcept
43 : pLoop{std::move(ref)}, resource{} {}
45 UnderlyingType(
const UnderlyingType &) =
delete;
46 UnderlyingType(UnderlyingType &&) =
delete;
48 virtual ~UnderlyingType() {
49 static_assert(std::is_base_of_v<UnderlyingType<T, U>, T>);
52 UnderlyingType &operator=(
const UnderlyingType &) =
delete;
53 UnderlyingType &operator=(UnderlyingType &&) =
delete;
60 template<
typename... Args>
61 static std::shared_ptr<T>
create(Args &&...args) {
62 return std::make_shared<T>(ConstructorAccess{0}, std::forward<Args>(args)...);
88 const U *
raw() const noexcept {
108 return const_cast<U *
>(
const_cast<const UnderlyingType *
>(
this)->raw());
112 std::shared_ptr<Loop> pLoop;