Mercurial > minori
view include/core/endian.h @ 351:c844f8bb87ce
gui/theme: add xsettings backend
this also adds newly-necessary endianness methods in core/endian.h
which just so happen to be constexpr as well
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 14 Jul 2024 23:23:56 -0400 |
parents | |
children | 9aaf1e788896 |
line wrap: on
line source
#ifndef MINORI_CORE_ENDIAN_H_ #define MINORI_CORE_ENDIAN_H_ /* definition of endian-related stuff. primarily used for*/ #include <cstdint> #include <type_traits> class Endian { private: static constexpr uint32_t uint32_ = 0x01020304; static constexpr uint8_t magic_ = static_cast<const uint8_t&>(uint32_); /* check for compiler builtins for byteswapping */ #ifdef __has_builtin # if __has_builtin(__builtin_bswap16) # define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) # endif # if __has_builtin(__builtin_bswap32) # define COMPILER_BUILTIN_BSWAP32(x) __builtin_bswap32(x) # endif # if __has_builtin(__builtin_bswap64) # define COMPILER_BUILTIN_BSWAP64(x) __builtin_bswap64(x) # endif #endif static constexpr uint16_t byteswap_16(uint16_t x) { #ifdef COMPILER_BUILTIN_BSWAP16 return COMPILER_BUILTIN_BSWAP16(x); #else return ( ((x & UINT16_C(0x00FF)) << 8) | ((x & UINT16_C(0xFF00)) >> 8) ); #endif } static constexpr uint32_t byteswap_32(uint32_t x) { #ifdef COMPILER_BUILTIN_BSWAP32 return COMPILER_BUILTIN_BSWAP32(x); #else return ( ((x & UINT32_C(0x000000FF)) << 24) | ((x & UINT32_C(0x0000FF00)) << 8) | ((x & UINT32_C(0x00FF0000)) >> 8) | ((x & UINT32_C(0xFF000000)) >> 24) ); #endif } static constexpr uint64_t byteswap_64(uint64_t x) { #ifdef COMPILER_BUILTIN_BSWAP64 return COMPILER_BUILTIN_BSWAP64(x); #else return ( ((x & UINT64_C(0x00000000000000FF)) << 56) | ((x & UINT64_C(0x000000000000FF00)) << 40) | ((x & UINT64_C(0x0000000000FF0000)) << 24) | ((x & UINT64_C(0x00000000FF000000)) << 8) | ((x & UINT64_C(0x000000FF00000000)) >> 8) | ((x & UINT64_C(0x0000FF0000000000)) >> 24) | ((x & UINT64_C(0x00FF000000000000)) >> 40) | ((x & UINT64_C(0xFF00000000000000)) >> 56) ); #endif } #ifdef COMPILER_BUILTIN_BSWAP16 # undef COMPILER_BUILTIN_BSWAP16 #endif #ifdef COMPILER_BUILTIN_BSWAP32 # undef COMPILER_BUILTIN_BSWAP32 #endif #ifdef COMPILER_BUILTIN_BSWAP64 # undef COMPILER_BUILTIN_BSWAP64 #endif public: static constexpr bool little = magic_ == 0x04; static constexpr bool big = magic_ == 0x01; static_assert(little || big, "unsupported endianness"); template<typename T> static constexpr T byteswap(T x) { static_assert(std::is_integral<T>::value); static_assert(std::is_unsigned<T>::value); if constexpr (std::is_same<T, uint8_t>::value) { return x; } else if constexpr (std::is_same<T, uint16_t>::value) { return byteswap_16(x); } else if constexpr (std::is_same<T, uint32_t>::value) { return byteswap_32(x); } else if constexpr (std::is_same<T, uint64_t>::value) { return byteswap_64(x); } else { static_assert(false, "byteswapping with unknown integer type"); } } template<typename T> static constexpr T byteswap_little_to_host(T x) { if constexpr (little) { return x; } else if constexpr (big) { return byteswap(x); } } template<typename T> static constexpr T byteswap_big_to_host(T x) { if constexpr (big) { return x; } else if constexpr (little) { return byteswap(x); } } private: Endian() = delete; }; #endif /* MINORI_CORE_ENDIAN_H_ */