mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
unsharable_shared_ptr.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
6
7
8namespace m {
9
21template<typename T>
22struct unsharable_shared_ptr : public std::shared_ptr<T>
23{
24 template<typename To, typename From> friend unsharable_shared_ptr<To> cast(unsharable_shared_ptr<From>);
25 template<typename To, typename From> friend unsharable_shared_ptr<To> as(unsharable_shared_ptr<From>);
26
27 using super = std::shared_ptr<T>;
28 /* Must not add `using super::super` or `super::operator=` since this would allow construction or assignment from
29 * a `std::shared_ptr` which we want to prevent because a custom deleter might not be set. Instead, explicitly
30 * implement the desired methods by delegating to the superclass and delete the undesired methods. */
31
32 private:
36 using deleter_func_type = void(*)(const void*);
37 static void default_deleter(const void *ptr) { delete (T*) ptr; }
38 static void noop_deleter(const void*) { }
39
40 public:
41 template<typename Y>
43
45 explicit unsharable_shared_ptr(std::nullptr_t) : super(nullptr) { }
46
49
50 template<typename Y>
52 template<typename Y>
54
55 template<typename Y>
56 unsharable_shared_ptr(const std::shared_ptr<Y>&) = delete; // delete since custom deleter might not be set
57 private:
58 /* Conceptually deleted, since custom deleter might not be set but must be possible for befriended `cast()` and
59 * `as()`. */
60 template<typename Y>
61 unsharable_shared_ptr(std::shared_ptr<Y> &&ptr) : super(std::move(ptr)) { }
62
63 public:
66
67 template<typename Y>
68 unsharable_shared_ptr & operator=(const unsharable_shared_ptr<Y> &ptr) { super::operator=(ptr); return *this; }
69 template<typename Y>
70 unsharable_shared_ptr & operator=(unsharable_shared_ptr<Y> &&ptr) { super::operator=(std::move(ptr)); return *this; }
71
72 template<typename Y>
73 unsharable_shared_ptr & operator=(const std::shared_ptr<Y>&) = delete; // delete since custom deleter might not be set
74 template<typename Y>
75 unsharable_shared_ptr & operator=(std::shared_ptr<Y>&&) = delete; // delete since custom deleter might not be set
76
84 std::unique_ptr<T> exclusive_shared_to_unique() {
85 if (super::use_count() == 0) return nullptr; // nothing to unshare
86 if (super::use_count() > 1) throw m::invalid_state{"not exclusive"};
87 *std::get_deleter<deleter_func_type>(static_cast<super>(*this)) = &unsharable_shared_ptr::noop_deleter;
88 std::unique_ptr<T> uptr{super::get()};
89 super::reset(); // this will *not* delete the referenced object
90 M_insist(super::get() == nullptr);
91 return uptr;
92 }
93};
94
95template<typename T, typename... Args>
97{
98 return unsharable_shared_ptr<T>{new T(std::forward<Args>(args)...)};
99}
100
101}
struct @5 args
#define M_insist(...)
Definition: macro.hpp:129
‍mutable namespace
Definition: Backend.hpp:10
unsharable_shared_ptr< T > make_unsharable_shared(Args &&... args)
T(x)
STL namespace.
Signals that an object was in an invalid state when a method was invoked.
Definition: exception.hpp:31
This class extends std::shared_ptr to allow for unsharing an exclusively held object and thereby conv...
void(*)(const void *) deleter_func_type
‍custom deleter type; use function pointer instead of reference due to clang-17 issue; use const void...
unsharable_shared_ptr(const unsharable_shared_ptr< Y > &ptr)
unsharable_shared_ptr & operator=(const std::shared_ptr< Y > &)=delete
friend unsharable_shared_ptr< To > as(unsharable_shared_ptr< From >)
static void noop_deleter(const void *)
unsharable_shared_ptr & operator=(unsharable_shared_ptr< Y > &&ptr)
static void default_deleter(const void *ptr)
std::unique_ptr< T > exclusive_shared_to_unique()
Converts (and thereby moves) the exclusively held object from this unsharable_shared_ptr to a std::un...
unsharable_shared_ptr & operator=(unsharable_shared_ptr &&)=default
unsharable_shared_ptr & operator=(const unsharable_shared_ptr< Y > &ptr)
friend unsharable_shared_ptr< To > cast(unsharable_shared_ptr< From >)
unsharable_shared_ptr(unsharable_shared_ptr &&)=default
unsharable_shared_ptr(const unsharable_shared_ptr &)=default
unsharable_shared_ptr(const std::shared_ptr< Y > &)=delete
unsharable_shared_ptr & operator=(std::shared_ptr< Y > &&)=delete
unsharable_shared_ptr(unsharable_shared_ptr< Y > &&ptr)
unsharable_shared_ptr(std::shared_ptr< Y > &&ptr)
unsharable_shared_ptr & operator=(const unsharable_shared_ptr &)=default