inkcpp
Loading...
Searching...
No Matches
story_ptr.h
1/* Copyright (c) 2024 Julian Benda
2 *
3 * This file is part of inkCPP which is released under MIT license.
4 * See file LICENSE.txt or go to
5 * https://github.com/JBenda/inkcpp for full license details.
6 */
7#pragma once
8
9#include "system.h"
10
11namespace ink::runtime
12{
13namespace internal
14{
16 struct ref_block {
17 ref_block()
18 : references(0)
19 , valid(true)
20 {
21 }
22
23 size_t references;
24 bool valid;
25
26 static void remove_reference(ref_block*&);
27 };
28
30 class story_ptr_base
31 {
32 protected:
34 story_ptr_base(internal::ref_block* story);
36 story_ptr_base(internal::ref_block* story, internal::ref_block* instance);
38 story_ptr_base(const story_ptr_base&);
39
40 story_ptr_base& operator=(const story_ptr_base&) = delete;
41
43 void add_reference();
47 bool remove_reference();
48
50 void set(const story_ptr_base& other);
51
53 inline bool is_valid() const
54 {
55 return _story_block != nullptr && _instance_block != nullptr && _story_block->valid
56 && _instance_block->valid;
57 }
58
60 inline bool is_story_valid() const { return _story_block != nullptr && _story_block->valid; }
61
62 private:
63 // reference block for the parent story
64 ref_block* _story_block;
65
66 // reference block for this pointer
67 ref_block* _instance_block;
68 };
69} // namespace internal
70
83template<typename T>
84class story_ptr : public internal::story_ptr_base
85{
86public:
90 story_ptr(T* ptr, internal::ref_block* story)
91 : story_ptr_base(story)
92 , _ptr(ptr)
93 {
94 add_reference();
95 }
96
100 template<typename U>
101 story_ptr(T* ptr, const story_ptr<U>& other)
102 : story_ptr_base(other)
103 , _ptr(ptr)
104 {
105 add_reference();
106 }
107
111 story_ptr(T* ptr)
112 : story_ptr_base(nullptr, nullptr)
113 , _ptr(nullptr)
114 {
115 inkAssert(ptr == nullptr, "can not create story_ptr from existing pointer!");
116 }
117
118 // null constructor
119 story_ptr()
120 : story_ptr_base(nullptr, nullptr)
121 , _ptr(nullptr)
122 {
123 }
124
125 // destructor
126 ~story_ptr();
127
128 // == copy methods ==
132 story_ptr(const story_ptr<T>& oth);
136 story_ptr<T>& operator=(const story_ptr<T>& oth);
137
138 // == casting ==
142 template<typename U>
144 {
145 // if cast fails, return null
146#ifdef INK_ENABLE_RTTI
147 U* casted = dynamic_cast<U*>(_ptr);
148#else
149 U* casted = reinterpret_cast<U*>(_ptr);
150#endif
151 if (casted == nullptr)
152 return nullptr;
153
154 // create new pointer with casted value but same instance blocks
155 return story_ptr<U>(casted, *this);
156 }
157
158 // == equality ==
160 inline bool operator==(const story_ptr<T>& other) { return _ptr == other._ptr; }
161
162 // == validity ==
164 bool is_valid() const { return story_ptr_base::is_valid() && _ptr; }
165
167 inline operator bool() const { return is_valid(); }
168
169 // === dereference operators ==
173 inline T* get() { return is_valid() ? _ptr : nullptr; }
174
178 inline const T* get() const { return is_valid() ? _ptr : nullptr; }
179
181 inline T* operator->() { return get(); }
182
184 inline const T* operator->() const { return get(); }
185
187 inline T& operator*() { return *get(); }
188
190 inline const T& operator*() const { return *get(); }
191
192private:
193 T* _ptr;
194};
195
196template<typename T>
197story_ptr<T>::~story_ptr()
198{
199 if (remove_reference()) {
200 delete _ptr;
201 _ptr = nullptr;
202 }
203}
204
205template<typename T>
207 : story_ptr_base(other)
208 , _ptr(other._ptr)
209{
210 add_reference();
211}
212
213template<typename T>
215{
216 // Clear out any old data
217 if (remove_reference()) {
218 delete _ptr;
219 _ptr = nullptr;
220 }
221
222 // Set pointers
223 set(other);
224 _ptr = other._ptr;
225
226 // initialize
227 add_reference();
228
229 // return reference to self
230 return *this;
231}
232} // namespace ink::runtime
Pointer wrapper to an object whose lifetime is tied to a story object.
Definition story_ptr.h:85
const T * get() const
access value as ptr
Definition story_ptr.h:178
T * get()
access value as ptr
Definition story_ptr.h:173
bool operator==(const story_ptr< T > &other)
implement operator==
Definition story_ptr.h:160
T * operator->()
implement operator->
Definition story_ptr.h:181
story_ptr(T *ptr)
pointer constructor.
Definition story_ptr.h:111
bool is_valid() const
checks if optional contains a value
Definition story_ptr.h:164
story_ptr< U > cast()
pointer cast while keeping ref count
Definition story_ptr.h:143
T & operator*()
implement operator*
Definition story_ptr.h:187
const T & operator*() const
implement operator*
Definition story_ptr.h:190
story_ptr< T > & operator=(const story_ptr< T > &oth)
copy assigment operator
Definition story_ptr.h:214
const T * operator->() const
implement operator->
Definition story_ptr.h:184
A loaded ink story.
Definition story.h:26
Contaning all modules and classes used for the inkles ink runtime.
Definition choice.h:13