OGLplus  (0.59.0) a C++ wrapper for rendering APIs

offset_ptr.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_MEMORY_OFFSET_PTR_HPP
10 #define EAGINE_MEMORY_OFFSET_PTR_HPP
11 
12 #include "../assert.hpp"
13 #include "../extract.hpp"
14 #include "../type_identity.hpp"
15 #include "address.hpp"
16 
17 namespace eagine::memory {
18 //------------------------------------------------------------------------------
19 // basic_offset_ptr
20 //------------------------------------------------------------------------------
23 template <typename Pointee, typename OffsetType>
25 public:
28 
31 
33  using offset_type = OffsetType;
34 
36  using pointer = Pointee*;
37 
39  using const_pointer = std::add_const_t<Pointee>*;
40 
42  using reference = Pointee&;
43 
45  using const_reference = std::add_const_t<Pointee>&;
46 
49  constexpr basic_offset_ptr() noexcept = default;
50 
51  ~basic_offset_ptr() noexcept = default;
52 
54  explicit constexpr basic_offset_ptr(offset_type offs) noexcept
55  : _offs{offs} {}
56 
58  explicit constexpr basic_offset_ptr(address addr) noexcept
59  : _offs{_get_offs(addr)} {}
60 
62  basic_offset_ptr(Pointee* ptr) noexcept
63  : _offs{_get_offs(ptr)} {}
64 
66  basic_offset_ptr(const basic_offset_ptr& that) noexcept
67  : _offs{_get_offs(that)} {}
68 
71  : _offs{_get_offs(that)} {}
72 
74  template <typename P, typename O>
75  using enable_if_convertible = std::enable_if<
76  std::is_convertible_v<O, OffsetType> &&
77  std::is_convertible_v<P*, Pointee*>>;
78 
79  template <typename P, typename O>
80  using enable_if_different = std::enable_if<
81  !std::is_same_v<O, OffsetType> && !std::is_same_v<P, Pointee>>;
82 
84  template <
85  typename P,
86  typename O,
87  typename = enable_if_convertible<P, O>,
88  typename = enable_if_different<P, O>>
90  : _offs{_get_offs(that)} {}
91 
93  // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
94  auto operator=(const basic_offset_ptr& that) noexcept -> basic_offset_ptr& {
95  if(this != std::addressof(that)) {
96  _offs = _get_offs(that);
97  }
98  return *this;
99  }
100 
102  auto operator=(basic_offset_ptr&& that) noexcept -> basic_offset_ptr& {
103  _offs = _get_offs(that);
104  return *this;
105  }
106 
108  auto reset(Pointee* ptr) noexcept -> auto& {
109  return *this = basic_offset_ptr(ptr);
110  }
111 
113  auto reset(address adr) noexcept -> auto& {
114  return *this = basic_offset_ptr(adr);
115  }
116 
118  constexpr auto is_null() const noexcept -> bool {
119  return _offs == offset_type(0);
120  }
121 
124  explicit constexpr operator bool() const noexcept {
125  return !is_null();
126  }
127 
129  constexpr auto offset() const noexcept -> offset_type {
130  return _offs;
131  }
132 
134  auto addr() noexcept -> address {
135  return is_null() ? address() : address(_this_addr(), _offs);
136  }
137 
139  constexpr auto addr() const noexcept -> const_address {
140  return is_null() ? address() : address(_this_addr(), _offs);
141  }
142 
144  auto data() noexcept -> pointer {
145  return static_cast<pointer>(addr());
146  }
147 
149  constexpr auto data() const noexcept -> const_pointer {
150  return static_cast<const_pointer>(addr());
151  }
152 
155  auto get() noexcept -> pointer {
156  return data();
157  }
158 
161  constexpr auto get() const noexcept -> const_pointer {
162  return data();
163  }
164 
167  operator pointer() noexcept {
168  return get();
169  }
170 
173  constexpr operator const_pointer() const noexcept {
174  return get();
175  }
176 
178  auto operator*() noexcept -> reference {
179  EAGINE_ASSERT(!is_null());
180  return *get();
181  }
182 
184  constexpr auto operator*() const noexcept -> const_reference {
185  EAGINE_ASSERT(!is_null());
186  return *get();
187  }
188 
190  auto operator->() noexcept -> pointer {
191  EAGINE_ASSERT(!is_null());
192  return get();
193  }
194 
196  constexpr auto operator->() const noexcept -> const_pointer {
197  EAGINE_ASSERT(!is_null());
198  return get();
199  }
200 
202  auto operator++() noexcept -> auto& {
203  return *this = basic_offset_ptr(get() + 1);
204  }
205 
207  auto operator--() noexcept -> auto& {
208  return *this = basic_offset_ptr(get() - 1);
209  }
210 
212  auto operator[](offset_type index) noexcept -> reference {
213  EAGINE_ASSERT(!is_null());
214  return get()[index];
215  }
216 
218  constexpr auto operator[](offset_type index) const noexcept
219  -> const_reference {
220  EAGINE_ASSERT(!is_null());
221  return get()[index];
222  }
223 
224 private:
225  static_assert(std::is_signed_v<offset_type>);
226 
227  offset_type _offs = {0};
228  using _rawptr = typename address::pointer;
229 
230  template <typename P, typename O>
231  static auto _that_addr(const basic_offset_ptr<P, O>& that) {
232  return address(_rawptr(&that));
233  }
234 
235  auto _this_addr() const noexcept {
236  return _that_addr(*this);
237  }
238 
239  auto _get_offs(address addr) noexcept -> offset_type {
240  return addr ? addr - _this_addr() : 0;
241  }
242 
243  auto _get_offs(Pointee* ptr) noexcept {
244  return _get_offs(address(ptr));
245  }
246 
247  template <typename P, typename O>
248  auto _get_offs(const basic_offset_ptr<P, O>& that) noexcept -> offset_type {
249  return that.is_null() ? offset_type(0)
250  : limit_cast<offset_type>(that.offset()) +
251  _get_offs(_that_addr(that));
252  }
253 };
254 //------------------------------------------------------------------------------
255 // extract
256 //------------------------------------------------------------------------------
259 template <typename P, typename O>
260 static constexpr auto extract(basic_offset_ptr<P, O> ptr) noexcept -> P& {
261  return EAGINE_CONSTEXPR_ASSERT(!ptr.is_null(), ptr.get());
262 }
263 //------------------------------------------------------------------------------
265 template <typename P, typename O>
266 static constexpr auto
267 extract_or(basic_offset_ptr<P, O> ptr, P& fallback) noexcept -> P& {
268  return ptr.is_null() ? fallback : ptr.get();
269 }
270 //------------------------------------------------------------------------------
272 template <typename P, typename O, typename F>
273 static constexpr auto extract_or(basic_offset_ptr<P, O> ptr, P& fallback)
274  -> std::enable_if_t<std::is_convertible_v<F, P>, P> {
275  return ptr.is_null() ? P{std::forward<F>(fallback)} : ptr.get();
276 }
277 //------------------------------------------------------------------------------
278 // rebind_pointer
279 //------------------------------------------------------------------------------
280 template <typename Ptr, typename U>
281 struct rebind_pointer;
282 //------------------------------------------------------------------------------
283 template <typename T, typename O, typename U>
284 struct rebind_pointer<basic_offset_ptr<T, O>, U>
285  : type_identity<basic_offset_ptr<U, O>> {};
286 //------------------------------------------------------------------------------
289 template <typename P, typename O>
290 static constexpr auto as_address(basic_offset_ptr<P, O> op) noexcept
292  return op.addr();
293 }
294 //------------------------------------------------------------------------------
297 template <typename Pointee>
299 //------------------------------------------------------------------------------
302 template <typename Pointee>
304 //------------------------------------------------------------------------------
305 } // namespace eagine::memory
306 
307 #endif // EAGINE_MEMORY_OFFSET_PTR_HPP
OffsetType offset_type
The offset type.
Definition: offset_ptr.hpp:33
auto reset(address adr) noexcept -> auto &
Point this pointer to another address.
Definition: offset_ptr.hpp:113
Class for handling memory addresses as integer values.
Definition: address.hpp:23
auto operator=(const basic_offset_ptr &that) noexcept -> basic_offset_ptr &
Copy assignment operator.
Definition: offset_ptr.hpp:94
const shader_source_header * pointer
The non-const pointer type.
Definition: offset_ptr.hpp:36
basic_offset_ptr(const basic_offset_ptr< P, O > &that) noexcept
Conversion copy constructor.
Definition: offset_ptr.hpp:89
basic_offset_ptr(Pointee *ptr) noexcept
Construction from a pointer.
Definition: offset_ptr.hpp:62
auto get() noexcept -> pointer
Returns the stored pointer. Alias for data().
Definition: offset_ptr.hpp:155
constexpr basic_offset_ptr(address addr) noexcept
Construction from a memory address.
Definition: offset_ptr.hpp:58
auto operator++() noexcept -> auto &
Pointer arithmentic increment.
Definition: offset_ptr.hpp:202
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
Basic offset pointer class template.
Definition: offset_ptr.hpp:24
constexpr auto addr() const noexcept -> const_address
Returns the pointed-to address.
Definition: offset_ptr.hpp:139
auto operator[](offset_type index) noexcept -> reference
Pointer array subscript operator.
Definition: offset_ptr.hpp:212
constexpr auto data() const noexcept -> const_pointer
Returns the stored pointer.
Definition: offset_ptr.hpp:149
basic_address< std::is_const_v< Pointee > > address
The non-const address types.
Definition: offset_ptr.hpp:27
static constexpr auto limit_cast(Src value) noexcept -> std::enable_if_t< std::is_convertible_v< Src, Dst >, Dst >
Casts value to Dst type if the value fits in that type.
Definition: is_within_limits.hpp:133
static constexpr auto as_address(basic_offset_ptr< P, O > op) noexcept -> basic_address< std::is_const_v< P >>
Converts basic_offset_ptr into basic_address.
Definition: offset_ptr.hpp:290
basic_offset_ptr(const basic_offset_ptr &that) noexcept
Copy constructor.
Definition: offset_ptr.hpp:66
std::conditional_t< IsConst, const void *, void * > pointer
The associated untyped pointer type.
Definition: address.hpp:26
constexpr basic_offset_ptr() noexcept=default
Default constructor.
const shader_source_header & reference
The non-const reference type.
Definition: offset_ptr.hpp:42
std::add_const_t< const shader_source_header > & const_reference
The const reference type.
Definition: offset_ptr.hpp:45
auto operator=(basic_offset_ptr &&that) noexcept -> basic_offset_ptr &
Move assignment operator.
Definition: offset_ptr.hpp:102
auto operator--() noexcept -> auto &
Pointer arithmentic decrement.
Definition: offset_ptr.hpp:207
auto reset(Pointee *ptr) noexcept -> auto &
Point this pointer to another pointee.
Definition: offset_ptr.hpp:108
constexpr auto get() const noexcept -> const_pointer
Returns the stored pointer. Alias for data().
Definition: offset_ptr.hpp:161
static constexpr auto extract_or(basic_offset_ptr< P, O > ptr, P &fallback) noexcept -> P &
Overload of extract_or for basic_offset_ptr.
Definition: offset_ptr.hpp:267
auto addr() noexcept -> address
Returns the pointed-to address.
Definition: offset_ptr.hpp:134
constexpr auto is_null() const noexcept -> bool
Indicates that the pointer is null.
Definition: offset_ptr.hpp:118
basic_offset_ptr(basic_offset_ptr &&that) noexcept
Move constructor.
Definition: offset_ptr.hpp:70
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
constexpr auto operator*() const noexcept -> const_reference
Dereferences this pointer.
Definition: offset_ptr.hpp:184
auto operator->() noexcept -> pointer
Dereferences this pointer.
Definition: offset_ptr.hpp:190
std::add_const_t< const shader_source_header > * const_pointer
The const pointer type.
Definition: offset_ptr.hpp:39
std::enable_if< std::is_convertible_v< O, OffsetType > &&std::is_convertible_v< P *, Pointee * > > enable_if_convertible
Enabled if basic_offset_ptr<P, O> is compatible with this.
Definition: offset_ptr.hpp:77
auto operator*() noexcept -> reference
Dereferences this pointer.
Definition: offset_ptr.hpp:178
constexpr auto operator[](offset_type index) const noexcept -> const_reference
Pointer array subscript operator.
Definition: offset_ptr.hpp:218
auto data() noexcept -> pointer
Returns the stored pointer.
Definition: offset_ptr.hpp:144
constexpr auto offset() const noexcept -> offset_type
Returns the byte offset value.
Definition: offset_ptr.hpp:129
constexpr auto operator->() const noexcept -> const_pointer
Dereferences this pointer.
Definition: offset_ptr.hpp:196

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).