CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
OffsetPtr.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
12#include <iterator>
13#include <type_traits>
14
15namespace CeresEngine {
16
17 template<class RawPointer, class OffsetType> class OffsetPointerCaster;
18
19 template<class T, class OffsetType> class OffsetPointerCaster<T*, OffsetType> {
20 private:
22
23 public:
24 explicit OffsetPointerCaster(OffsetType offset) : mOffset(offset) {}
25 explicit OffsetPointerCaster(const volatile T* p) : mOffset(static_cast<OffsetType>(reinterpret_cast<std::intptr_t>(p))) {}
26
27 [[nodiscard]] OffsetType offset() const { return mOffset; }
28 [[nodiscard]] T* pointer() const { return reinterpret_cast<T*>(static_cast<std::intptr_t>(mOffset)); }
29 };
30
31 template<class OffsetType> OffsetType offset_ptr_offset(const volatile void* ptr, const volatile void* thisPtr) {
33 // NOTE: offset == 1 && ptr != 0 is not legal for this pointer
34 if(!ptr) {
35 return 1;
36 }
37 OffsetType offset = static_cast<OffsetType>(caster_t(ptr).offset() - caster_t(thisPtr).offset());
38 CE_ASSERT(offset != 1);
39 return offset;
40 }
41
42 template<class OffsetType> OffsetType offset_ptr_offset_from_other(const volatile void* thisPtr, const volatile void* otherPtr, OffsetType otherOffset) {
44 if(otherOffset == 1) {
45 return 1;
46 }
47 OffsetType offset = static_cast<OffsetType>(caster_t(otherPtr).offset() - caster_t(thisPtr).offset() + otherOffset);
48 CE_ASSERT(offset != 1);
49 return offset;
50 }
51
52 template<class OffsetType> void* offset_ptr_raw_pointer(const volatile void* thisPtr, OffsetType offset) {
54 if(offset == 1) {
55 return nullptr;
56 }
57 return caster_t(caster_t(thisPtr).offset() + offset).pointer();
58 }
59
64 template<typename PointedType, class DifferenceType = std::ptrdiff_t, class OffsetType = std::intptr_t, std::size_t OffsetAlignment = alignof(OffsetType)>
65 class OffsetPtr {
66 // static_assert(sizeof(OffsetType) >= sizeof(uintptr_t));
67 // static_assert(std::is_integral_v<OffsetType> && std::is_unsigned_v<OffsetType>);
68
69 private:
70 static constexpr OffsetType nullOffset = 1;
72
73 public: // C++ container concept
76 using reference = typename std::add_lvalue_reference_t<PointedType>;
77 using value_type = std::remove_cv_t<PointedType>;
78 using difference_type = DifferenceType;
79 using iterator_category = std::random_access_iterator_tag;
81
83
84 public:
86
89
91 template<typename T>
94
97
99 template<typename T2>
103
105 OffsetPtr& operator=(const pointer from) noexcept {
107 return *this;
108 }
109
111 OffsetPtr& operator=(const OffsetPtr& ptr) noexcept {
112 mOffset = offset_ptr_offset_from_other(this, &ptr, ptr.mOffset);
113 return *this;
114 }
115
117 template<class T2>
118 OffsetPtr& operator=(const OffsetPtr<T2, DifferenceType, OffsetType, OffsetAlignment>& ptr) noexcept requires std::is_convertible_v<T2*, PointedType*> {
119 mOffset = offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this);
120 }
121
123 ~OffsetPtr() = default;
124
125 private:
127 struct const_cast_tag {};
130
132 template<class T2, class P2, class O2, std::size_t A2>
135
136 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
138
140 template<class T2, class P2, class O2, std::size_t A2>
143
144 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
146
148 template<class T2, class P2, class O2, std::size_t A2>
151
152 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
154
156 template<class T2, class P2, class O2, std::size_t A2>
159
160 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
162
163 public:
166
169
172
176
179 pointer* ptr = get();
180 return ptr[idx];
181 }
182
184 inline void reset() noexcept { *this = nullptr; }
185
186 public:
188 inline OffsetPtr& operator+=(difference_type offset) noexcept {
189 mOffset += offset * sizeof(PointedType);
190 return *this;
191 }
192
194 inline OffsetPtr& operator-=(difference_type offset) noexcept {
195 mOffset -= offset * sizeof(PointedType);
196 return *this;
197 }
198
200 inline OffsetPtr& operator++(void) noexcept {
201 mOffset += sizeof(PointedType);
202 return *this;
203 }
204
206 inline OffsetPtr operator++(int) noexcept {
207 OffsetPtr tmp(*this);
208 mOffset += sizeof(PointedType);
209 return tmp;
210 }
211
213 inline OffsetPtr& operator--(void) noexcept {
214 mOffset -= sizeof(PointedType);
215 return *this;
216 }
217
219 inline OffsetPtr operator--(int) noexcept {
220 OffsetPtr tmp(*this);
221 mOffset -= sizeof(PointedType);
222 return tmp;
223 }
224
228 [[nodiscard]] explicit operator bool() const noexcept { return mOffset != nullOffset; }
229
232
233 public:
236 [[nodiscard]] inline static OffsetPtr pointer_to(reference r) noexcept { return OffsetPtr(&r); }
237
239 inline friend OffsetPtr operator+(difference_type diff, OffsetPtr right) noexcept {
240 right += diff;
241 return right;
242 }
243
245 inline friend OffsetPtr operator+(OffsetPtr left, difference_type diff) noexcept {
246 left += diff;
247 return left;
248 }
249
251 inline friend OffsetPtr operator-(OffsetPtr left, difference_type diff) noexcept {
252 left -= diff;
253 return left;
254 }
255
257 inline friend OffsetPtr operator-(difference_type diff, OffsetPtr right) noexcept {
258 right -= diff;
259 return right;
260 }
261
263 inline friend difference_type operator-(const OffsetPtr& pt, const OffsetPtr& pt2) noexcept { return difference_type(pt.get() - pt2.get()); }
264
266 [[nodiscard]] inline friend bool operator==(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() == pt2.get(); }
267
269 [[nodiscard]] inline friend bool operator!=(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() != pt2.get(); }
270
272 [[nodiscard]] inline friend bool operator<(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() < pt2.get(); }
273
275 [[nodiscard]] inline friend bool operator<=(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() <= pt2.get(); }
276
278 [[nodiscard]] inline friend bool operator>(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() > pt2.get(); }
279
281 [[nodiscard]] inline friend bool operator>=(const OffsetPtr& pt1, const OffsetPtr& pt2) noexcept { return pt1.get() >= pt2.get(); }
282
284 [[nodiscard]] inline friend bool operator==(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 == pt2.get(); }
285
287 [[nodiscard]] inline friend bool operator!=(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 != pt2.get(); }
288
290 [[nodiscard]] inline friend bool operator<(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 < pt2.get(); }
291
293 [[nodiscard]] inline friend bool operator<=(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 <= pt2.get(); }
294
296 [[nodiscard]] inline friend bool operator>(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 > pt2.get(); }
297
299 [[nodiscard]] inline friend bool operator>=(pointer pt1, const OffsetPtr& pt2) noexcept { return pt1 >= pt2.get(); }
300
302 [[nodiscard]] inline friend bool operator==(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() == pt2; }
303
305 [[nodiscard]] inline friend bool operator!=(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() != pt2; }
306
308 [[nodiscard]] inline friend bool operator<(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() < pt2; }
309
311 [[nodiscard]] inline friend bool operator<=(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() <= pt2; }
312
314 [[nodiscard]] inline friend bool operator>(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() > pt2; }
315
317 [[nodiscard]] inline friend bool operator>=(const OffsetPtr& pt1, pointer pt2) noexcept { return pt1.get() >= pt2; }
318
320 inline friend void swap(OffsetPtr& left, OffsetPtr& right) noexcept {
321 pointer ptr = right.get();
322 right = left;
323 left = ptr;
324 }
325 };
326
328 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
332
334 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
338
340 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
344
346 template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
350
351} // namespace CeresEngine
352
353template<typename PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
354struct std::hash<CeresEngine::OffsetPtr<PointedType, DifferenceType, OffsetType, OffsetAlignment>> {
356 [[nodiscard]] size_t operator()(const T& value) const noexcept { return std::hash<PointedType*>{}(value.get()); }
357};
#define CE_ASSERT(...)
Definition Macros.hpp:323
#define CE_EXPLICIT(EXPR)
Definition Macros.hpp:413
OffsetType mOffset
Definition OffsetPtr.hpp:21
OffsetType offset() const
Definition OffsetPtr.hpp:27
OffsetPointerCaster(OffsetType offset)
Definition OffsetPtr.hpp:24
T * pointer() const
Definition OffsetPtr.hpp:28
OffsetPointerCaster(const volatile T *p)
Definition OffsetPtr.hpp:25
Definition OffsetPtr.hpp:17
A special pointer that stores the pointer as an offset of the pointee to the OffsetPtr instance itsel...
Definition OffsetPtr.hpp:65
friend bool operator!=(const OffsetPtr &pt1, pointer pt2) noexcept
Checks if two pointers point to the same object.
Definition OffsetPtr.hpp:305
friend bool operator==(const OffsetPtr &pt1, pointer pt2) noexcept
Definition OffsetPtr.hpp:302
pointer get() const noexcept
Obtains raw pointer from offset.
Definition OffsetPtr.hpp:165
friend bool operator==(pointer pt1, const OffsetPtr &pt2) noexcept
Definition OffsetPtr.hpp:284
OffsetPtr operator--(int) noexcept
Postfix increment operator. Decrements the pointer by 1.
Definition OffsetPtr.hpp:219
OffsetType mOffset
Definition OffsetPtr.hpp:71
friend OffsetPtr operator-(difference_type diff, OffsetPtr right) noexcept
Definition OffsetPtr.hpp:257
OffsetPtr & operator=(const OffsetPtr< T2, DifferenceType, OffsetType, OffsetAlignment > &ptr) noexcept
Assigns the OffsetPtr by copying another.
Definition OffsetPtr.hpp:118
friend OffsetPtr< T1, P1, O1, A1 > static_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of static_cast between pointers.
Definition OffsetPtr.hpp:329
friend bool operator>=(pointer pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator>=.
Definition OffsetPtr.hpp:299
OffsetPtr & operator--(void) noexcept
Prefix increment operator. Decrements the pointer by 1.
Definition OffsetPtr.hpp:213
friend OffsetPtr operator+(OffsetPtr left, difference_type diff) noexcept
Definition OffsetPtr.hpp:245
friend bool operator<(const OffsetPtr &pt1, pointer pt2) noexcept
Compares two pointers using operator<.
Definition OffsetPtr.hpp:308
friend bool operator<=(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator<=.
Definition OffsetPtr.hpp:275
pointer operator->() const noexcept
Implements the pointer-like -> operator. It can return 0 pointer.
Definition OffsetPtr.hpp:171
OffsetPtr() noexcept=default
friend bool operator>(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator>.
Definition OffsetPtr.hpp:278
friend bool operator!=(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Checks if two pointers point to the same object.
Definition OffsetPtr.hpp:269
static OffsetPtr pointer_to(reference r) noexcept
Creates a new OffsetPtr from a raw pointer.
Definition OffsetPtr.hpp:236
OffsetType offset_type
Definition OffsetPtr.hpp:80
static constexpr OffsetType nullOffset
Definition OffsetPtr.hpp:70
friend OffsetPtr< T1, P1, O1, A1 > const_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of const_cast between pointers.
Definition OffsetPtr.hpp:335
friend void swap(OffsetPtr &left, OffsetPtr &right) noexcept
Swaps left and right pointers.
Definition OffsetPtr.hpp:320
friend bool operator!=(pointer pt1, const OffsetPtr &pt2) noexcept
Checks if two pointers point to the same object.
Definition OffsetPtr.hpp:287
OffsetPtr & operator-=(difference_type offset) noexcept
Decrements the pointer by the given offset.
Definition OffsetPtr.hpp:194
friend bool operator==(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Definition OffsetPtr.hpp:266
OffsetPtr operator++(int) noexcept
Postfix increment operator. Increments the pointer by 1.
Definition OffsetPtr.hpp:206
friend OffsetPtr< T1, P1, O1, A1 > reinterpret_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of reinterpret_cast between pointers.
Definition OffsetPtr.hpp:347
friend bool operator<=(const OffsetPtr &pt1, pointer pt2) noexcept
Compares two pointers using operator<=.
Definition OffsetPtr.hpp:311
std::random_access_iterator_tag iterator_category
Definition OffsetPtr.hpp:79
friend bool operator>=(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator>=.
Definition OffsetPtr.hpp:281
OffsetPtr & operator++(void) noexcept
Prefix increment operator. Increments the pointer by 1.
Definition OffsetPtr.hpp:200
friend bool operator>(pointer pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator>.
Definition OffsetPtr.hpp:296
typename std::add_lvalue_reference_t< PointedType > reference
Definition OffsetPtr.hpp:76
reference operator*() const noexcept
Implements the dereferencing operator, if it is nullptr, behavior is undefined.
Definition OffsetPtr.hpp:175
offset_type getOffset() const noexcept
Obtains the internal offset of the pointer.
Definition OffsetPtr.hpp:168
friend bool operator<(pointer pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator<.
Definition OffsetPtr.hpp:290
DifferenceType difference_type
Definition OffsetPtr.hpp:78
friend bool operator<=(pointer pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator<=.
Definition OffsetPtr.hpp:293
void reset() noexcept
Resets the pointer and sets it to nullptr.
Definition OffsetPtr.hpp:184
PointedType * pointer
Definition OffsetPtr.hpp:75
friend difference_type operator-(const OffsetPtr &pt, const OffsetPtr &pt2) noexcept
Definition OffsetPtr.hpp:263
friend bool operator>(const OffsetPtr &pt1, pointer pt2) noexcept
Compares two pointers using operator>.
Definition OffsetPtr.hpp:314
friend OffsetPtr operator+(difference_type diff, OffsetPtr right) noexcept
Definition OffsetPtr.hpp:239
std::remove_cv_t< PointedType > value_type
Definition OffsetPtr.hpp:77
friend bool operator>=(const OffsetPtr &pt1, pointer pt2) noexcept
Compares two pointers using operator>=.
Definition OffsetPtr.hpp:317
~OffsetPtr()=default
Default destructor.
reference operator[](difference_type idx) const noexcept
Implements the indexing operator.
Definition OffsetPtr.hpp:178
OffsetPtr & operator+=(difference_type offset) noexcept
Increments the pointer by the given offset.
Definition OffsetPtr.hpp:188
PointedType element_type
Definition OffsetPtr.hpp:74
OffsetPtr & operator=(const OffsetPtr &ptr) noexcept
Assigns the OffsetPtr by copying another.
Definition OffsetPtr.hpp:111
friend bool operator<(const OffsetPtr &pt1, const OffsetPtr &pt2) noexcept
Compares two pointers using operator<.
Definition OffsetPtr.hpp:272
OffsetPtr & operator=(const pointer from) noexcept
Assigns the OffsetPtr from a raw pointer.
Definition OffsetPtr.hpp:105
bool operator!() const noexcept
Checks if the pointer is nullptr.
Definition OffsetPtr.hpp:231
friend OffsetPtr operator-(OffsetPtr left, difference_type diff) noexcept
Definition OffsetPtr.hpp:251
friend OffsetPtr< T1, P1, O1, A1 > dynamic_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of dynamic_cast between pointers.
Definition OffsetPtr.hpp:341
Definition Application.hpp:19
OffsetPtr< T1, P1, O1, A1 > reinterpret_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of reinterpret_cast between pointers.
Definition OffsetPtr.hpp:347
OffsetType offset_ptr_offset(const volatile void *ptr, const volatile void *thisPtr)
Definition OffsetPtr.hpp:31
OffsetPtr< T1, P1, O1, A1 > dynamic_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of dynamic_cast between pointers.
Definition OffsetPtr.hpp:341
OffsetPtr< T1, P1, O1, A1 > const_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of const_cast between pointers.
Definition OffsetPtr.hpp:335
OffsetType offset_ptr_offset_from_other(const volatile void *thisPtr, const volatile void *otherPtr, OffsetType otherOffset)
Definition OffsetPtr.hpp:42
OffsetPtr< T1, P1, O1, A1 > static_pointer_cast(const OffsetPtr< T2, P2, O2, A2 > &r) noexcept
Simulation of static_cast between pointers.
Definition OffsetPtr.hpp:329
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
void * offset_ptr_raw_pointer(const volatile void *thisPtr, OffsetType offset)
Definition OffsetPtr.hpp:52
Definition Span.hpp:668
Definition OffsetPtr.hpp:127
Definition OffsetPtr.hpp:128
Definition OffsetPtr.hpp:126