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

address.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_MEMORY_ADDRESS_HPP
10 #define EAGINE_MEMORY_ADDRESS_HPP
11 
12 #include "../assert.hpp"
13 #include "../types.hpp"
14 #include "align.hpp"
15 #include <cstddef>
16 #include <type_traits>
17 
18 namespace eagine::memory {
19 //------------------------------------------------------------------------------
22 template <bool IsConst>
24 public:
26  using pointer = std::conditional_t<IsConst, const void*, void*>;
27 
29  using byte_pointer = std::conditional_t<IsConst, const byte*, byte*>;
30 
31  ~basic_address() noexcept = default;
32 
34  constexpr basic_address() noexcept = default;
35 
37  constexpr basic_address(basic_address&&) noexcept = default;
38 
40  constexpr auto operator=(basic_address&&) noexcept
41  -> basic_address& = default;
42 
44  constexpr basic_address(const basic_address&) noexcept = default;
45 
47  constexpr auto operator=(const basic_address&) noexcept
48  -> basic_address& = default;
49 
51  constexpr explicit basic_address(std::nullptr_t) noexcept {}
52 
54  constexpr explicit basic_address(std::intptr_t addr) noexcept
55  : _addr(reinterpret_cast<pointer>(addr)) {}
56 
58  constexpr explicit basic_address(pointer addr) noexcept
59  : _addr(addr) {}
60 
61  template <
62  typename Int,
63  typename = std::enable_if_t<
64  std::is_integral_v<Int> && std::is_convertible_v<Int, std::ptrdiff_t>>>
65  constexpr basic_address(basic_address that, Int offs) noexcept
66  : _addr(that.ptr() + offs) {}
67 
68  template <bool IsConst2, typename = std::enable_if_t<IsConst && !IsConst2>>
69  constexpr basic_address(basic_address<IsConst2> a) noexcept
70  : _addr(pointer(a)) {}
71 
73  constexpr auto is_null() const noexcept {
74  return _addr == nullptr;
75  }
76 
79  constexpr explicit operator bool() const noexcept {
80  return !is_null();
81  }
82 
86  constexpr auto ptr() const noexcept {
87  return static_cast<byte_pointer>(_addr);
88  }
89 
93  constexpr auto get() const noexcept {
94  return _addr;
95  }
96 
99  constexpr explicit operator pointer() const noexcept {
100  return _addr;
101  }
102 
107  template <
108  typename T,
109  typename =
110  std::enable_if_t<!std::is_void_v<T> && (std::is_const_v<T> || !IsConst)>>
111  constexpr explicit operator T*() const noexcept {
112  return EAGINE_CONSTEXPR_ASSERT(
113  is_aligned_as<T>(), static_cast<T*>(_addr));
114  }
115 
119  constexpr auto value() const noexcept {
120  return reinterpret_cast<std::intptr_t>(_addr);
121  }
122 
126  constexpr auto misalignment(span_size_t alignment) const noexcept {
127  return memory::misalignment(value(), alignment);
128  }
129 
133  constexpr auto is_aligned_to(span_size_t alignment) const noexcept {
134  return memory::is_aligned_to(value(), alignment);
135  }
136 
140  template <typename T>
141  constexpr auto is_aligned_as(type_identity<T> tid = {}) const noexcept {
142  return memory::is_aligned_as<T>(value(), tid);
143  }
144 
146  constexpr friend auto operator==(basic_address a, basic_address b) noexcept {
147  return a.ptr() == b.ptr();
148  }
149 
151  constexpr friend auto operator!=(basic_address a, basic_address b) noexcept {
152  return a.ptr() != b.ptr();
153  }
154 
156  constexpr friend auto operator<(basic_address a, basic_address b) noexcept {
157  return a.ptr() < b.ptr();
158  }
159 
161  constexpr friend auto operator<=(basic_address a, basic_address b) noexcept {
162  return a.ptr() <= b.ptr();
163  }
164 
166  constexpr friend auto operator>(basic_address a, basic_address b) noexcept {
167  return a.ptr() > b.ptr();
168  }
169 
171  constexpr friend auto operator>=(basic_address a, basic_address b) noexcept {
172  return a.ptr() >= b.ptr();
173  }
174 
176  constexpr friend auto operator-(basic_address a, basic_address b) noexcept
177  -> std::ptrdiff_t {
178  return a.ptr() - b.ptr();
179  }
180 
182  constexpr friend auto operator+(basic_address a, std::ptrdiff_t o) noexcept
183  -> basic_address {
184  return {a, o};
185  }
186 
188  constexpr friend auto operator-(basic_address a, std::ptrdiff_t o) noexcept
189  -> basic_address {
190  return {a, -o};
191  }
192 
193 private:
194  pointer _addr{nullptr};
195 };
196 //------------------------------------------------------------------------------
200 
204 //------------------------------------------------------------------------------
207 template <typename T>
208 static constexpr auto as_address(T* addr) noexcept {
209  return basic_address<std::is_const_v<T>>(addr);
210 }
211 //------------------------------------------------------------------------------
214 static constexpr auto
215 misalignment(const_address addr, span_size_t alignment) noexcept {
216  return addr.misalignment(alignment);
217 }
218 //------------------------------------------------------------------------------
221 static constexpr auto
222 misalignment(const void* ptr, span_size_t alignment) noexcept {
223  return misalignment(as_address(ptr), alignment);
224 }
225 //------------------------------------------------------------------------------
228 static constexpr auto
229 is_aligned_to(const_address addr, span_size_t alignment) noexcept {
230  return addr.is_aligned_to(alignment);
231 }
232 //------------------------------------------------------------------------------
235 static constexpr auto
236 is_aligned_to(const void* ptr, span_size_t alignment) noexcept {
237  return is_aligned_to(as_address(ptr), alignment);
238 }
239 //------------------------------------------------------------------------------
242 template <typename T>
243 static constexpr auto
244 is_aligned_as(const_address addr, type_identity<T> tid = {}) noexcept {
245  return addr.is_aligned_as(tid);
246 }
247 //------------------------------------------------------------------------------
248 static constexpr auto
249 align_up_offs(span_size_t align, span_size_t misalign) noexcept {
250  return (misalign ? align - misalign : 0);
251 }
252 //------------------------------------------------------------------------------
253 template <bool IsConst>
254 static constexpr auto align_up_by(
255  basic_address<IsConst> addr,
256  span_size_t offs,
257  span_size_t max) noexcept {
258  return EAGINE_CONSTEXPR_ASSERT(
259  (offs <= max), basic_address<IsConst>(addr, offs));
260 }
261 //------------------------------------------------------------------------------
265 template <bool IsConst>
266 static constexpr auto align_up(
268  span_size_t align,
269  span_size_t max) noexcept -> basic_address<IsConst> {
270  return align_up_by(
271  addr, align_up_offs(align, misalignment(addr, align)), max);
272 }
273 //------------------------------------------------------------------------------
274 static constexpr auto
275 align_down_offs(span_size_t, span_size_t misalign) noexcept {
276  return misalign;
277 }
278 //------------------------------------------------------------------------------
279 template <bool IsConst>
280 static constexpr auto align_down_by(
281  basic_address<IsConst> addr,
282  span_size_t offs,
283  span_size_t max) noexcept {
284  return EAGINE_CONSTEXPR_ASSERT(
285  (offs <= max), basic_address<IsConst>(addr, -offs));
286 }
287 //------------------------------------------------------------------------------
291 template <bool IsConst>
292 static constexpr auto align_down(
294  span_size_t align,
295  span_size_t max) noexcept -> basic_address<IsConst> {
296 
297  return align_down_by(
298  addr, align_down_offs(align, misalignment(addr, align)), max);
299 }
300 //------------------------------------------------------------------------------
303 template <bool IsConst>
304 static constexpr auto
306  return align_down(addr, align, addr.value());
307 }
308 //------------------------------------------------------------------------------
311 static inline auto align_down(const byte* ptr, span_size_t align)
312  -> const byte* {
313  return align_down(const_address(ptr), align).ptr();
314 }
315 //------------------------------------------------------------------------------
319 template <typename T>
320 static constexpr auto align_up_to(
321  basic_address<std::is_const_v<T>> addr,
322  type_identity<T> = {},
323  span_size_t align = span_align_of<T>(),
324  span_size_t max = span_size_of<T>()) noexcept {
325 
326  if(align < span_align_of<T>()) {
327  align = span_align_of<T>();
328  }
329 
330  return static_cast<T*>(align_up(addr, align, max));
331 }
332 //------------------------------------------------------------------------------
336 template <typename T>
337 static constexpr auto align_down_to(
338  basic_address<std::is_const_v<T>> addr,
339  type_identity<T> = {},
340  span_size_t align = span_align_of<T>(),
341  span_size_t max = span_size_of<T>()) noexcept {
342  if(align < span_align_of<T>()) {
343  align = span_align_of<T>();
344  }
345 
346  return static_cast<T*>(align_down(addr, align, max));
347 }
348 //------------------------------------------------------------------------------
349 } // namespace eagine::memory
350 
351 #endif // EAGINE_MEMORY_ADDRESS_HPP
constexpr basic_address(pointer addr) noexcept
Construction from untyped pointer type.
Definition: address.hpp:58
static constexpr auto align_up_to(basic_address< std::is_const_v< T >> addr, type_identity< T >={}, span_size_t align=span_align_of< T >(), span_size_t max=span_size_of< T >()) noexcept
Aligns a memory address up to the required alignment of type T.
Definition: address.hpp:320
Class for handling memory addresses as integer values.
Definition: address.hpp:23
constexpr basic_address(std::intptr_t addr) noexcept
Construction from signed integer type.
Definition: address.hpp:54
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
constexpr friend auto operator<=(basic_address a, basic_address b) noexcept
Less-equal comparison.
Definition: address.hpp:161
constexpr auto is_aligned_as(type_identity< T > tid={}) const noexcept
Indicates if this address is aligned to the alignment or type T.
Definition: address.hpp:141
static constexpr auto as_address(T *addr) noexcept
Casts a pointer to basic_address.
Definition: address.hpp:208
constexpr auto get() const noexcept
Returns the untyped pointer for this address.
Definition: address.hpp:93
static constexpr auto is_aligned_as(const_address addr, type_identity< T > tid={}) noexcept
Indicates if a memory address aligned as the specified type T.
Definition: address.hpp:244
constexpr friend auto operator+(basic_address a, std::ptrdiff_t o) noexcept -> basic_address
Byte offset addition.
Definition: address.hpp:182
constexpr friend auto operator<(basic_address a, basic_address b) noexcept
Less-than comparison.
Definition: address.hpp:156
constexpr auto misalignment(span_size_t alignment) const noexcept
Returns the misalignment of this address to the specified alignment.
Definition: address.hpp:126
constexpr auto value() const noexcept
Returns this address as an signed integer.
Definition: address.hpp:119
constexpr friend auto operator-(basic_address a, std::ptrdiff_t o) noexcept -> basic_address
Byte offset subtraction.
Definition: address.hpp:188
std::conditional_t< IsConst, const void *, void * > pointer
The associated untyped pointer type.
Definition: address.hpp:26
constexpr friend auto operator>=(basic_address a, basic_address b) noexcept
Greater-equal comparison.
Definition: address.hpp:171
static constexpr auto is_aligned_to(const void *ptr, span_size_t alignment) noexcept
Indicates if a pointer is aligned to the specified alignment.
Definition: address.hpp:236
static constexpr auto align_up(basic_address< IsConst > addr, span_size_t align, span_size_t max) noexcept -> basic_address< IsConst >
Aligns a memory address up to the specified alignment.
Definition: address.hpp:266
basic_address< true > const_address
Type alias for const memory address values.
Definition: address.hpp:199
constexpr basic_address() noexcept=default
Default constructor.
constexpr friend auto operator==(basic_address a, basic_address b) noexcept
Equality comparison.
Definition: address.hpp:146
static constexpr auto align_down_to(basic_address< std::is_const_v< T >> addr, type_identity< T >={}, span_size_t align=span_align_of< T >(), span_size_t max=span_size_of< T >()) noexcept
Aligns a memory address down to the required alignment of type T.
Definition: address.hpp:337
static constexpr auto misalignment(const void *ptr, span_size_t alignment) noexcept
Returns the misalignment of a pointer to the specified alignment.
Definition: address.hpp:222
static auto align_down(const byte *ptr, span_size_t align) -> const byte *
Aligns a byte pointer down to the specified alignment.
Definition: address.hpp:311
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
constexpr friend auto operator-(basic_address a, basic_address b) noexcept -> std::ptrdiff_t
Byte difference between two addresses.
Definition: address.hpp:176
constexpr friend auto operator>(basic_address a, basic_address b) noexcept
Greater-than comparison.
Definition: address.hpp:166
std::conditional_t< IsConst, const byte *, byte * > byte_pointer
The associated byte pointer type.
Definition: address.hpp:29
constexpr auto is_aligned_to(span_size_t alignment) const noexcept
Indicates if this address is aligned to the specified alignment.
Definition: address.hpp:133
constexpr auto is_null() const noexcept
Indicates if the stored address is null.
Definition: address.hpp:73
constexpr friend auto operator!=(basic_address a, basic_address b) noexcept
Non-equality comparison.
Definition: address.hpp:151
constexpr auto ptr() const noexcept
Returns the byte pointer for this address.
Definition: address.hpp:86

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