| 1 | #pragma once |
|---|---|
| 2 | |
| 3 | #include <nn/util/util_BitUtil.h> |
| 4 | #include "nn/types.h" |
| 5 | |
| 6 | namespace nn::util { |
| 7 | |
| 8 | class BytePtr { |
| 9 | public: |
| 10 | explicit BytePtr(void* ptr) : m_Ptr(ptr) {} |
| 11 | BytePtr(void* ptr, ptrdiff_t offset) : BytePtr(ptr) { Advance(offset); } |
| 12 | |
| 13 | void Reset(void* ptr) { m_Ptr = ptr; } |
| 14 | |
| 15 | void* Get() const { return m_Ptr; } |
| 16 | |
| 17 | template <typename T> |
| 18 | T* Get() const { |
| 19 | return static_cast<T*>(Get()); |
| 20 | } |
| 21 | |
| 22 | BytePtr& Advance(ptrdiff_t offset) { |
| 23 | m_Ptr = Get<char>() + offset; |
| 24 | return *this; |
| 25 | } |
| 26 | |
| 27 | ptrdiff_t Distance(const void* other) const { |
| 28 | return static_cast<const char*>(other) - Get<char>(); |
| 29 | } |
| 30 | |
| 31 | // TODO |
| 32 | bool IsAligned(size_t alignment) const; |
| 33 | |
| 34 | BytePtr& AlignUp(size_t alignment) { |
| 35 | uintptr_t& ptr = reinterpret_cast<uintptr_t&>(m_Ptr); |
| 36 | ptr = align_up(x: ptr, align: alignment); |
| 37 | return *this; |
| 38 | } |
| 39 | |
| 40 | BytePtr& AlignDown(size_t alignment); |
| 41 | |
| 42 | BytePtr& operator+=(ptrdiff_t offset) { return Advance(offset); } |
| 43 | BytePtr& operator-=(ptrdiff_t offset) { return Advance(offset: -offset); } |
| 44 | |
| 45 | BytePtr operator+(ptrdiff_t offset) const { return BytePtr(*this) += offset; } |
| 46 | BytePtr operator-(ptrdiff_t offset) const { return BytePtr(*this) -= offset; } |
| 47 | |
| 48 | BytePtr operator++(int) { return BytePtr(*this) + 1; } |
| 49 | BytePtr& operator++() { return Advance(offset: 1); } |
| 50 | |
| 51 | BytePtr operator--(int) { return BytePtr(*this) - 1; } |
| 52 | BytePtr& operator--() { return Advance(offset: -1); } |
| 53 | |
| 54 | private: |
| 55 | void* m_Ptr; |
| 56 | }; |
| 57 | |
| 58 | class ConstBytePtr { |
| 59 | public: |
| 60 | explicit ConstBytePtr(const void* ptr) : m_Ptr(ptr) {} |
| 61 | ConstBytePtr(const BytePtr&); |
| 62 | ConstBytePtr(const void* ptr, ptrdiff_t offset) : ConstBytePtr(ptr) { Advance(offset); } |
| 63 | |
| 64 | void Reset(const void*); |
| 65 | |
| 66 | const void* Get() const { return m_Ptr; } |
| 67 | |
| 68 | template <typename T> |
| 69 | const T* Get() const { |
| 70 | return static_cast<const T*>(Get()); |
| 71 | } |
| 72 | |
| 73 | ConstBytePtr& Advance(ptrdiff_t offset) { |
| 74 | m_Ptr = Get<char>() + offset; |
| 75 | return *this; |
| 76 | } |
| 77 | |
| 78 | ptrdiff_t Distance(const void* ptr) const { |
| 79 | return static_cast<const char*>(ptr) - Get<char>(); |
| 80 | } |
| 81 | |
| 82 | bool IsAligned(size_t) const; |
| 83 | ConstBytePtr& AlignUp(size_t); |
| 84 | ConstBytePtr& AlignDown(size_t); |
| 85 | ConstBytePtr& operator+=(ptrdiff_t); |
| 86 | ConstBytePtr& operator-=(ptrdiff_t); |
| 87 | ConstBytePtr operator+(ptrdiff_t) const; |
| 88 | ConstBytePtr operator-(ptrdiff_t) const; |
| 89 | ConstBytePtr operator++(int); |
| 90 | ConstBytePtr& operator++(); |
| 91 | ConstBytePtr operator--(int); |
| 92 | ConstBytePtr& operator--(); |
| 93 | |
| 94 | private: |
| 95 | const void* m_Ptr; |
| 96 | }; |
| 97 | |
| 98 | } // namespace nn::util |
| 99 |