From d1a9aab8593ca4ca9f238df3b79fb02b3d5ebc1c Mon Sep 17 00:00:00 2001 From: Brett Date: Mon, 9 Dec 2024 16:00:08 -0500 Subject: [PATCH] make byte functions more concise --- CMakeLists.txt | 2 +- include/blt/std/memory_util.h | 352 +++++++++++++++++----------------- libraries/parallel-hashmap | 2 +- 3 files changed, 182 insertions(+), 174 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 955cd41..3ce8a83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 2.1.11) +set(BLT_VERSION 2.1.12) set(BLT_TARGET BLT) diff --git a/include/blt/std/memory_util.h b/include/blt/std/memory_util.h index 0985253..5e50bc0 100644 --- a/include/blt/std/memory_util.h +++ b/include/blt/std/memory_util.h @@ -27,30 +27,30 @@ #include #if defined(__clang__) || defined(__llvm__) || defined(__GNUC__) || defined(__GNUG__) - - #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(WIN32) - - #include - - #define SWAP16(val) bswap_16(val) - #define SWAP32(val) bswap_32(val) - #define SWAP64(val) bswap_64(val) - #else + +#if (defined(__GNUC__) || defined(__GNUG__)) && !defined(WIN32) + +#include + +#define SWAP16(val) bswap_16(val) +#define SWAP32(val) bswap_32(val) +#define SWAP64(val) bswap_64(val) +#else #define SWAP16(val) __builtin_bswap16(val) #define SWAP32(val) __builtin_bswap32(val) #define SWAP64(val) __builtin_bswap64(val) - #endif - - - #if __cplusplus >= 202002L - +#endif + + +#if __cplusplus >= 202002L + #include #define ENDIAN_LOOKUP(little_endian) (std::endian::native == std::endian::little && !little_endian) || \ (std::endian::native == std::endian::big && little_endian) - #else - #define ENDIAN_LOOKUP(little_endian) !little_endian - #endif +#else +#define ENDIAN_LOOKUP(little_endian) !little_endian +#endif #elif defined(_MSC_VER) #include #define SWAP16(val) _byteswap_ushort(val) @@ -61,59 +61,76 @@ namespace blt::mem { + template + inline static R type_cast(T type) + { + static_assert(std::is_trivially_copyable_v, "Type must be trivially copyable to be type casted!"); + static_assert(sizeof(T) == sizeof(R)); + R r; + std::memcpy(&r, &type, sizeof(type)); + return r; + } + + template + inline void reverse(T& out) + { + static_assert(std::is_trivially_copyable_v, "Type must be trivially copyable to be reversible!"); + // if we need to swap find the best way to do so + if constexpr (std::is_same_v || std::is_same_v) + out = type_cast(SWAP16(type_cast(out))); + else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + out = type_cast(SWAP32(type_cast(out))); + else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + out = type_cast(SWAP64(type_cast(out))); + else + { + std::array data; + std::memcpy(data.data(), &out, sizeof(T)); + std::reverse(data.begin(), data.end()); + std::memcpy(&out, data.data(), sizeof(T)); + } + } + // Used to grab the byte-data of any T element. Defaults to Big Endian, however can be configured to use little endian - template - inline static int toBytes(const T& in, BYTE_TYPE* out) + template + inline int toBytes(const T& in, BYTE_TYPE* out) { if constexpr (!(std::is_same_v || std::is_same_v)) static_assert("Must provide a signed/unsigned int8 type"); - std::memcpy(out, (void*) &in, sizeof(T)); - + std::memcpy(out, &in, sizeof(T)); + if constexpr (ENDIAN_LOOKUP(little_endian)) { // TODO: this but better. for (size_t i = 0; i < sizeof(T) / 2; i++) std::swap(out[i], out[sizeof(T) - 1 - i]); } - + return 0; } - + // Used to cast the binary data of any T object, into a T object. Assumes data is in big ending (configurable) - template - inline static int fromBytes(const BYTE_TYPE* in, T& out) + template + inline int fromBytes(const BYTE_TYPE* in, T& out) { if constexpr (!(std::is_same_v || std::is_same_v)) static_assert("Must provide a signed/unsigned int8 type"); - - std::array data; - std::memcpy(data.data(), in, sizeof(T)); - + + std::memcpy(&out, in, sizeof(T)); if constexpr (ENDIAN_LOOKUP(little_endian)) { - // if we need to swap find the best way to do so - if constexpr (std::is_same_v || std::is_same_v) - out = SWAP16(*reinterpret_cast(data.data())); - else if constexpr (std::is_same_v || std::is_same_v) - out = SWAP32(*reinterpret_cast(data.data())); - else if constexpr (std::is_same_v || std::is_same_v) - out = SWAP64(*reinterpret_cast(data.data())); - else - { - std::reverse(data.begin(), data.end()); - out = *reinterpret_cast(data.data()); - } + reverse(out); } - + return 0; } - - template + + template inline static int fromBytes(const BYTE_TYPE* in, T* out) { return fromBytes(in, *out); } - + inline static size_t next_byte_allocation(size_t prev_size, size_t default_allocation_block = 8192, size_t default_size = 16) { if (prev_size < default_size) @@ -122,139 +139,130 @@ namespace blt::mem return prev_size * 2; return prev_size + default_allocation_block; } - - template - inline static R type_cast(T type) - { - static_assert(sizeof(T) == sizeof(R)); - R r; - std::memcpy(&r, &type, sizeof(type)); - return r; - } - } namespace blt { - template + template struct ptr_iterator { - public: - using iterator_category = std::random_access_iterator_tag; - using difference_type = blt::ptrdiff_t; - using value_type = V; - using pointer = value_type*; - using reference = value_type&; - using iter_reference = ptr_iterator&; - - explicit ptr_iterator(V* v): _v(v) - {} - - reference operator*() const - { - return *_v; - } - - pointer operator->() - { - return _v; - } - - ptr_iterator& operator++() - { - _v++; - return *this; - } - - ptr_iterator& operator--() - { - _v--; - return *this; - } - - ptr_iterator operator++(int) - { - auto tmp = *this; - ++(*this); - return tmp; - } - - ptr_iterator operator--(int) - { - auto tmp = *this; - --(*this); - return tmp; - } - - iter_reference operator+=(difference_type amount) - { - _v += amount; - return *this; - } - - iter_reference operator-=(difference_type amount) - { - _v -= amount; - return *this; - } - - reference operator[](difference_type index) - { - return *(_v + index); - } - - reference operator[](blt::size_t index) - { - return *(_v + index); - } - - friend bool operator<(const ptr_iterator& a, const ptr_iterator& b) - { - return b._v - a._v > 0; - } - - friend bool operator>(const ptr_iterator& a, const ptr_iterator& b) - { - return a._v - b._v > 0; - } - - friend bool operator<=(const ptr_iterator& a, const ptr_iterator& b) - { - return b._v - a._v >= 0; - } - - friend bool operator>=(const ptr_iterator& a, const ptr_iterator& b) - { - return a._v - b._v >= 0; - } - - friend difference_type operator-(const ptr_iterator& a, const ptr_iterator& b) - { - return a._v - b._v; - } - - friend ptr_iterator operator+(const ptr_iterator& a, difference_type n) - { - return ptr_iterator(a._v + n); - } - - friend ptr_iterator operator+(difference_type n, const ptr_iterator& a) - { - return ptr_iterator(a._v + n); - } - - friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) - { - return a._v == b._v; - } - - friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) - { - return a._v != b._v; - } - - private: - V* _v; + public: + using iterator_category = std::random_access_iterator_tag; + using difference_type = blt::ptrdiff_t; + using value_type = V; + using pointer = value_type*; + using reference = value_type&; + using iter_reference = ptr_iterator&; + + explicit ptr_iterator(V* v): _v(v) + { + } + + reference operator*() const + { + return *_v; + } + + pointer operator->() + { + return _v; + } + + ptr_iterator& operator++() + { + _v++; + return *this; + } + + ptr_iterator& operator--() + { + _v--; + return *this; + } + + ptr_iterator operator++(int) + { + auto tmp = *this; + ++(*this); + return tmp; + } + + ptr_iterator operator--(int) + { + auto tmp = *this; + --(*this); + return tmp; + } + + iter_reference operator+=(difference_type amount) + { + _v += amount; + return *this; + } + + iter_reference operator-=(difference_type amount) + { + _v -= amount; + return *this; + } + + reference operator[](difference_type index) + { + return *(_v + index); + } + + reference operator[](blt::size_t index) + { + return *(_v + index); + } + + friend bool operator<(const ptr_iterator& a, const ptr_iterator& b) + { + return b._v - a._v > 0; + } + + friend bool operator>(const ptr_iterator& a, const ptr_iterator& b) + { + return a._v - b._v > 0; + } + + friend bool operator<=(const ptr_iterator& a, const ptr_iterator& b) + { + return b._v - a._v >= 0; + } + + friend bool operator>=(const ptr_iterator& a, const ptr_iterator& b) + { + return a._v - b._v >= 0; + } + + friend difference_type operator-(const ptr_iterator& a, const ptr_iterator& b) + { + return a._v - b._v; + } + + friend ptr_iterator operator+(const ptr_iterator& a, difference_type n) + { + return ptr_iterator(a._v + n); + } + + friend ptr_iterator operator+(difference_type n, const ptr_iterator& a) + { + return ptr_iterator(a._v + n); + } + + friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) + { + return a._v == b._v; + } + + friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) + { + return a._v != b._v; + } + + private: + V* _v; }; } diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 2d0b499..0bad098 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 2d0b499273ea02f7211ae2af705418c9509691fb +Subproject commit 0bad0987f1989294e73cdb1ebf41c75f49cdb0c1