#pragma once #include #include #include namespace nkg { template [[nodiscard]] inline ptrdiff_t address_delta(ptr1_t ptr1, ptr2_t ptr2) noexcept { static_assert(std::is_pointer_v && std::is_pointer_v); return reinterpret_cast(ptr1) - reinterpret_cast(ptr2); } template [[nodiscard]] inline ptr_t address_offset(ptr_t ptr, ptrdiff_t off) noexcept { static_assert(std::is_pointer_v); return reinterpret_cast( const_cast( reinterpret_cast(ptr) + off ) ); } template [[nodiscard]] inline return_ptr_t address_offset_cast(ptr_t ptr, ptrdiff_t off) noexcept { static_assert(std::is_pointer_v && std::is_pointer_v); return reinterpret_cast(address_offset(ptr, off)); } template [[nodiscard]] inline bool is_address_in_range(ptr_t ptr, begin_ptr_t begin, end_ptr_t end) { static_assert(std::is_pointer_v && std::is_pointer_v && std::is_pointer_v); auto _ptr = reinterpret_cast(ptr); auto _begin = reinterpret_cast(begin); auto _end = reinterpret_cast(end); return _begin <= _ptr && _ptr < _end; } template [[nodiscard]] inline bool is_address_in_range(ptr_t ptr, base_ptr_t base, size_t size) { static_assert(std::is_pointer_v && std::is_pointer_v); return is_address_in_range(ptr, base, address_offset(base, size)); } template [[nodiscard]] inline bool is_address_in_range(ptr1_t ptr1, ptr2_t ptr2, begin_ptr_t begin, end_ptr_t end) { static_assert(std::is_pointer_v && std::is_pointer_v && std::is_pointer_v && std::is_pointer_v); auto _ptr1 = reinterpret_cast(ptr1); auto _ptr2 = reinterpret_cast(ptr2); auto _begin = reinterpret_cast(begin); auto _end = reinterpret_cast(end); return _begin <= _ptr1 && _ptr1 <= _ptr2 && _ptr2 <= _end; } template [[nodiscard]] inline bool is_address_in_range(ptr_t ptr, size_t size, begin_ptr_t begin, end_ptr_t end) { static_assert(std::is_pointer_v && std::is_pointer_v && std::is_pointer_v); return is_address_in_range(ptr, address_offset(ptr, size), begin, end); } template [[nodiscard]] inline bool is_address_in_range(ptr1_t ptr1, ptr2_t ptr2, base_ptr_t base, size_t size) { static_assert(std::is_pointer_v && std::is_pointer_v && std::is_pointer_v); return is_address_in_range(ptr1, ptr2, base, address_offset(base, size)); } template [[nodiscard]] inline bool is_address_in_range(ptr_t p, size_t s, base_ptr_t base, size_t size) { static_assert(std::is_pointer_v); static_assert(std::is_pointer_v); return is_address_in_range(p, address_offset(p, s), base, address_offset(base, size)); } // template // [[nodiscard]] // inline __ReadType AddressRead(__PtrType p) noexcept { // static_assert(std::is_trivial_v<__ReadType> && std::is_standard_layout_v<__ReadType>); // static_assert(std::is_pointer_v<__PtrType>); // return *reinterpret_cast(p); // } // // template // [[nodiscard]] // inline __ReadType AddressRead(__PtrType p, ptrdiff_t offset) noexcept { // static_assert(std::is_trivial_v<__ReadType> && std::is_standard_layout_v<__ReadType>); // static_assert(std::is_pointer_v<__PtrType>); // return *reinterpret_cast( // reinterpret_cast(p) + offset // ); // } // // template // [[nodiscard]] // inline __ReadType AddressRead(__PtrType p, size_t scale, ptrdiff_t index) noexcept { // static_assert(std::is_trivial_v<__ReadType> && std::is_standard_layout_v<__ReadType>); // static_assert(std::is_pointer_v<__PtrType>); // return *reinterpret_cast( // reinterpret_cast(p) + scale * index // ); // } // // template // inline void AddressWrite(__PtrType p, const __WriteType& value) noexcept { // static_assert(std::is_trivial_v<__WriteType> && std::is_standard_layout_v<__WriteType>); // static_assert(std::is_pointer_v<__PtrType>); // *reinterpret_cast(p) = value; // } // // template // inline void AddressWrite(__PtrType p, ptrdiff_t offset, const __WriteType& value) noexcept { // static_assert(std::is_trivial_v<__WriteType> && std::is_standard_layout_v<__WriteType>); // static_assert(std::is_pointer_v<__PtrType>); // *reinterpret_cast( // reinterpret_cast(p) + offset // ) = value; // } // // template // inline void AddressWrite(__PtrType p, size_t scale, ptrdiff_t index, const __WriteType& value) noexcept { // static_assert(std::is_trivial_v<__WriteType> && std::is_standard_layout_v<__WriteType>); // static_assert(std::is_pointer_v<__PtrType>); // *reinterpret_cast( // reinterpret_cast(p) + scale * index // ) = value; // } }