#pragma once #include template struct pointer_wrapper{ static_assert(std::is_object_v, "T must be an object type"); pointer_wrapper() noexcept = default; explicit pointer_wrapper(T* p) noexcept : ptr(p) {} explicit pointer_wrapper(T&& x) noexcept { T& ref = std::forward(x); ptr = std::addressof(ref); } T& get() const noexcept { return *ptr; } auto operator->() const noexcept { return ptr; } operator T&() const noexcept { return *ptr; } T copy() const noexcept { return *ptr; } auto raw() const noexcept -> T* { return ptr; } operator bool() const noexcept { return ptr != nullptr; } void clear() noexcept { ptr = nullptr; } private: T* ptr{nullptr}; }; template auto make_pointer_wrapper(T* p) noexcept -> pointer_wrapper { return pointer_wrapper(p); } template auto make_pointer_wrapper(T& x) noexcept -> pointer_wrapper { return pointer_wrapper(x); }