6 #ifndef XENIUM_DETAIL_DELETABLE_OBJECT_HPP
7 #define XENIUM_DETAIL_DELETABLE_OBJECT_HPP
10 #include <type_traits>
14 #pragma warning(disable: 26495)
17 namespace xenium {
namespace reclamation {
namespace detail {
19 struct deletable_object
21 virtual void delete_self() = 0;
22 deletable_object* next =
nullptr;
24 virtual ~deletable_object() =
default;
27 inline void delete_objects(deletable_object*& list)
30 for (deletable_object* next =
nullptr; cur !=
nullptr; cur = next)
38 template <
class Derived,
class DeleterT,
class Base>
39 struct deletable_object_with_non_empty_deleter : Base
41 using Deleter = DeleterT;
42 virtual void delete_self()
override
44 Deleter& my_deleter =
reinterpret_cast<Deleter&
>(deleter_buffer);
45 Deleter deleter(std::move(my_deleter));
46 my_deleter.~Deleter();
48 deleter(
static_cast<Derived*
>(
this));
51 void set_deleter(Deleter deleter)
53 new (&deleter_buffer) Deleter(std::move(deleter));
57 using buffer =
typename std::aligned_storage<
sizeof(Deleter),
alignof(Deleter)>::type;
58 buffer deleter_buffer;
61 template <
class Derived,
class DeleterT,
class Base>
62 struct deletable_object_with_empty_deleter : Base
64 using Deleter = DeleterT;
65 virtual void delete_self()
override
67 static_assert(std::is_default_constructible<Deleter>::value,
"empty deleters must be default constructible");
69 deleter(
static_cast<Derived*
>(
this));
72 void set_deleter(Deleter ) {}
75 template <
class Derived,
class Deleter = std::default_delete<Derived>,
class Base = deletable_
object>
76 using deletable_object_impl = std::conditional_t<std::is_empty<Deleter>::value,
77 deletable_object_with_empty_deleter<Derived, Deleter, Base>,
78 deletable_object_with_non_empty_deleter<Derived, Deleter, Base>