Iros
 
Loading...
Searching...
No Matches
rc.h
Go to the documentation of this file.
1#pragma once
2
7#include "di/util/immovable.h"
8#include "di/util/std_new.h"
14
15namespace di::vocab {
16struct RcTag {};
17
18template<typename T>
20
21template<typename T>
23private:
24 template<typename>
25 friend struct MakeRcFunction;
26
27public:
28 template<typename = void>
29 constexpr auto rc_from_this() {
30 return Rc<T>(static_cast<T*>(this), adopt_object);
31 }
32
33protected:
35
36private:
38 auto* base = static_cast<IntrusiveThreadUnsafeRefCount*>(pointer);
39 ++base->m_ref_count;
40 }
41
43 auto* base = static_cast<IntrusiveThreadUnsafeRefCount*>(pointer);
44 if (base->m_ref_count-- == 1) {
45 delete pointer;
46 }
47 }
48
49 template<typename... Args, typename R = meta::AllocatorResult<platform::DefaultAllocator, T*>>
50 constexpr static auto make(Args&&... args) -> R
51 requires(requires { new (std::nothrow) T(util::forward<Args>(args)...); })
52 {
53 if consteval {
54 return new T(util::forward<Args>(args)...);
55 }
56 auto* result = new (std::nothrow) T(util::forward<Args>(args)...);
57 if constexpr (concepts::FallibleAllocator<platform::DefaultAllocator>) {
58 if (!result) {
59 return vocab::Unexpected(platform::BasicError::NotEnoughMemory);
60 }
61 } else {
62 DI_ASSERT(result);
63 }
64 return result;
65 }
66
67 usize m_ref_count { 1 };
68};
69
70template<typename T>
72 template<typename... Args>
73 constexpr auto operator()(Args&&... args) const
74 requires(requires { IntrusiveThreadUnsafeRefCount<T>::make(util::forward<Args>(args)...); })
75 {
76 return vocab::as_fallible(IntrusiveThreadUnsafeRefCount<T>::make(util::forward<Args>(args)...)) %
77 [](T* pointer) {
78 return Rc<T>(pointer, retain_object);
79 } |
81 }
82};
83
84template<detail::IntrusivePtrValid<RcTag> T>
85constexpr inline auto make_rc = MakeRcFunction<T> {};
86}
87
88namespace di {
89using vocab::IntrusiveThreadUnsafeRefCount;
90using vocab::make_rc;
91using vocab::Rc;
92}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition intrusive_ptr.h:25
meta::LikeExpected< decltype(di::allocate(util::declval< Alloc & >(), 0, 0)), T > AllocatorResult
Definition allocator.h:25
size_t usize
Definition integers.h:33
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition lazy.h:165
constexpr auto adopt_object
Definition intrusive_ptr.h:22
constexpr auto as_fallible
Definition as_fallible.h:26
constexpr auto try_infallible
Definition try_infallible.h:31
constexpr auto make_rc
Definition rc.h:85
Unexpected(E &&) -> Unexpected< meta::UnwrapRefDecay< E > >
constexpr auto retain_object
Definition intrusive_ptr.h:17
IntrusivePtr< T, RcTag > Rc
Definition rc.h:19
Definition zstring_parser.h:9
Definition in_place_type.h:5
Definition immovable.h:4
constexpr friend void tag_invoke(types::Tag< intrusive_ptr_increment >, InPlaceType< RcTag >, T *pointer)
Definition rc.h:37
friend struct MakeRcFunction
Definition rc.h:25
constexpr friend void tag_invoke(types::Tag< intrusive_ptr_decrement >, InPlaceType< RcTag >, T *pointer)
Definition rc.h:42
constexpr auto rc_from_this()
Definition rc.h:29
Definition rc.h:71
constexpr auto operator()(Args &&... args) const
Definition rc.h:73
Definition rc.h:16