27 #include <type_traits>
51 struct raw_object_tag {};
55 impl* _impl =
nullptr;
64 deleter(raw_object_tag,
void*
object) noexcept
65 : _impl(from_raw_object(
object)) {}
78 explicit operator bool() const noexcept {
return bool(_impl); }
89 static bool is_raw_object(
impl* i) noexcept {
90 auto x =
reinterpret_cast<uintptr_t
>(i);
93 bool is_raw_object() const noexcept {
94 return is_raw_object(_impl);
96 static void* to_raw_object(
impl* i) noexcept {
97 auto x =
reinterpret_cast<uintptr_t
>(i);
98 return reinterpret_cast<void*
>(x & ~uintptr_t(1));
100 void* to_raw_object() const noexcept {
101 return to_raw_object(_impl);
103 impl* from_raw_object(
void*
object) noexcept {
104 auto x =
reinterpret_cast<uintptr_t
>(object);
105 return reinterpret_cast<impl*
>(x | 1);
110 struct deleter::impl {
120 if (is_raw_object()) {
121 std::free(to_raw_object());
124 if (_impl && --_impl->refs == 0) {
133 new (
this)
deleter(std::move(x));
139 template <
typename Deleter>
140 struct lambda_deleter_impl final : deleter::impl {
142 lambda_deleter_impl(deleter next, Deleter&& del)
143 :
impl(std::move(next)), del(std::move(del)) {}
144 virtual ~lambda_deleter_impl()
override { del(); }
147 template <
typename Object>
148 struct object_deleter_impl final : deleter::impl {
150 object_deleter_impl(deleter next, Object&& obj)
151 :
impl(std::move(next)), obj(std::move(obj)) {}
154 template <
typename Object>
156 object_deleter_impl<Object>* make_object_deleter_impl(deleter next, Object obj) {
157 return new object_deleter_impl<Object>(std::move(next), std::move(obj));
168 template <
typename Object>
171 return deleter(
new lambda_deleter_impl<Object>(std::move(next), std::move(o)));
179 template <
typename Object>
182 return make_deleter(
deleter(), std::move(o));
186 struct free_deleter_impl final : deleter::impl {
188 free_deleter_impl(
void* obj) :
impl(
deleter()), obj(obj) {}
189 virtual ~free_deleter_impl()
override { std::free(obj); }
199 if (is_raw_object()) {
200 _impl =
new free_deleter_impl(to_raw_object());
214 impl* next_impl = _impl;
217 if (next_impl == d._impl) {
220 if (is_raw_object(next_impl)) {
221 next_d->_impl = next_impl =
new free_deleter_impl(to_raw_object(next_impl));
224 if (next_impl->refs != 1) {
225 next_d->_impl = next_impl = make_object_deleter_impl(
deleter(next_impl), std::move(d));
229 next_d = &next_impl->next;
230 next_impl = next_d->_impl;
232 next_d->_impl = d._impl;
246 return deleter(deleter::raw_object_tag(), obj);
258 return make_deleter(std::move(next), [obj] ()
mutable { std::free(obj); });
263 template <
typename T>
267 return deleter{make_object_deleter_impl(
deleter(), std::move(obj))};
272 template <
typename T>
276 return deleter{make_object_deleter_impl(std::move(d), std::move(obj))};
Definition: deleter.hh:47
deleter() noexcept=default
Constructs an empty deleter that does nothing in its destructor.
deleter make_free_deleter(deleter next, void *obj)
Definition: deleter.hh:257
deleter make_object_deleter(T &&obj)
Definition: deleter.hh:266
void append(deleter d)
Definition: deleter.hh:210
deleter make_object_deleter(deleter d, T &&obj)
Definition: deleter.hh:275
deleter make_deleter(Object o)
Definition: deleter.hh:181
~deleter()
Destroys the deleter and carries out the encapsulated action.
Definition: deleter.hh:119
deleter share()
Definition: deleter.hh:195
deleter make_free_deleter(void *obj)
Definition: deleter.hh:242
deleter make_deleter(deleter next, Object o)
Definition: deleter.hh:170
holds the implementation parts of the metrics layer, do not use directly.
Seastar API namespace.
Definition: abort_on_ebadf.hh:24