25#ifndef JAU_BYTE_UTIL_HPP_
26#define JAU_BYTE_UTIL_HPP_
64 #if defined __has_builtin
65 #if __has_builtin(__builtin_bswap16)
66 #define __has_builtin_bswap16 1
68 #elif defined(__GNUC__) && __GNUC_PREREQ (4, 8)
69 #define __has_builtin_bswap16 1
71 #if defined __has_builtin
72 #if __has_builtin(__builtin_bswap32)
73 #define __has_builtin_bswap32 1
75 #elif defined(__GNUC__) && __GNUC_PREREQ (4, 8)
76 #define __has_builtin_bswap32 1
78 #if defined __has_builtin
79 #if __has_builtin(__builtin_bswap64)
80 #define __has_builtin_bswap64 1
82 #elif defined(__GNUC__) && __GNUC_PREREQ (4, 8)
83 #define __has_builtin_bswap64 1
88 constexpr uint16_t
bswap(uint16_t
const source)
noexcept {
89 #if defined __has_builtin_bswap16
90 return __builtin_bswap16(source);
92 return (uint16_t) ( ( ( (source) >> 8 ) & 0xff ) |
93 ( ( (source) & 0xff) << 8 ) );
97 constexpr uint32_t
bswap(uint32_t
const source)
noexcept {
98 #if defined __has_builtin_bswap32
99 return __builtin_bswap32(source);
101 return ( ( source & 0xff000000U ) >> 24 ) |
102 ( ( source & 0x00ff0000U ) >> 8 ) |
103 ( ( source & 0x0000ff00U ) << 8 ) |
104 ( ( source & 0x000000ffU ) << 24 );
108 constexpr uint64_t
bswap(uint64_t
const & source)
noexcept {
109 #if defined __has_builtin_bswap64
110 return __builtin_bswap64(source);
112 return ( ( source & 0xff00000000000000ULL ) >> 56 ) |
113 ( ( source & 0x00ff000000000000ULL ) >> 40 ) |
114 ( ( source & 0x0000ff0000000000ULL ) >> 24 ) |
115 ( ( source & 0x000000ff00000000ULL ) >> 8 ) |
116 ( ( source & 0x00000000ff000000ULL ) << 8 ) |
117 ( ( source & 0x0000000000ff0000ULL ) << 24 ) |
118 ( ( source & 0x000000000000ff00ULL ) << 40 ) |
119 ( ( source & 0x00000000000000ffULL ) << 56 );
123 constexpr void bswap(uint8_t * sink, uint8_t
const * source,
nsize_t len) {
125 for (; len > 0; len--) {
149 return reinterpret_cast<char*
>(b);
152 return reinterpret_cast<const char*
>(b);
156 return reinterpret_cast<const uint8_t*
>(s);
171 constexpr uint8_t b[4] { 0x44, 0x43, 0x42, 0x41 };
172 return jau::bit_cast<uint32_t, uint8_t[4]>( b );
336 template <
typename Dummy_type>
struct has_endian_little : std::integral_constant<bool, endian_t::little == endian_t::native> {};
356 template <
typename Dummy_type>
struct has_endian_big : std::integral_constant<bool, endian_t::big == endian_t::native> {};
378 constexpr uint16_t
be_to_cpu(uint16_t
const n)
noexcept {
387 constexpr uint16_t
cpu_to_be(uint16_t
const h)
noexcept {
396 constexpr uint16_t
le_to_cpu(uint16_t
const l)
noexcept {
405 constexpr uint16_t
cpu_to_le(uint16_t
const h)
noexcept {
415 constexpr uint32_t
be_to_cpu(uint32_t
const n)
noexcept {
424 constexpr uint32_t
cpu_to_be(uint32_t
const h)
noexcept {
433 constexpr uint32_t
le_to_cpu(uint32_t
const l)
noexcept {
442 constexpr uint32_t
cpu_to_le(uint32_t
const h)
noexcept {
452 constexpr uint64_t
be_to_cpu(uint64_t
const & n)
noexcept {
461 constexpr uint64_t
cpu_to_be(uint64_t
const & h)
noexcept {
470 constexpr uint64_t
le_to_cpu(uint64_t
const & l)
noexcept {
479 constexpr uint64_t
cpu_to_le(uint64_t
const & h)
noexcept {
607 constexpr void put_uint8(uint8_t * buffer,
const uint8_t v)
noexcept
609 *pointer_cast<uint8_t *>( buffer ) = v;
611 constexpr uint8_t
get_uint8(uint8_t
const * buffer)
noexcept
613 return *pointer_cast<uint8_t const *>( buffer );
615 constexpr int8_t
get_int8(uint8_t
const * buffer)
noexcept
617 return *pointer_cast<int8_t const *>( buffer );
638 constexpr void put_uint16(uint8_t * buffer,
const uint16_t v)
noexcept
640 pointer_cast<packed_t<uint16_t>*>( buffer )->store = v;
661 constexpr uint16_t
get_uint16(uint8_t
const * buffer)
noexcept
663 return pointer_cast<const packed_t<uint16_t>*>( buffer )->store;
683 constexpr void put_uint32(uint8_t * buffer,
const uint32_t v)
noexcept
685 pointer_cast<packed_t<uint32_t>*>( buffer )->store = v;
699 constexpr uint32_t
get_uint32(uint8_t
const * buffer)
noexcept
701 return pointer_cast<const packed_t<uint32_t>*>( buffer )->store;
716 constexpr void put_uint64(uint8_t * buffer,
const uint64_t & v)
noexcept
718 pointer_cast<packed_t<uint64_t>*>( buffer )->store = v;
732 constexpr uint64_t
get_uint64(uint8_t
const * buffer)
noexcept
734 return pointer_cast<const packed_t<uint64_t>*>( buffer )->store;
751 pointer_cast<packed_t<uint128dp_t>*>( buffer )->store = v;
767 return pointer_cast<const packed_t<uint128dp_t>*>( buffer )->store;
784 pointer_cast<packed_t<uint192dp_t>*>( buffer )->store = v;
800 return pointer_cast<const packed_t<uint192dp_t>*>( buffer )->store;
817 pointer_cast<packed_t<uint256dp_t>*>( buffer )->store = v;
833 return pointer_cast<const packed_t<uint256dp_t>*>( buffer )->store;
861 typename std::enable_if_t<
862 std::is_standard_layout_v<T>,
867 pointer_cast<packed_t<T>*>( buffer )->store = v;
885 typename std::enable_if_t<
886 std::is_standard_layout_v<T>,
904 typename std::enable_if_t<
905 std::is_standard_layout_v<T>,
909 return pointer_cast<const packed_t<T>*>( buffer )->store;
927 typename std::enable_if_t<
928 std::is_standard_layout_v<T>,
constexpr uint192dp_t get_uint192(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr bool has_endian_big_v
Value access of big-endian type trait for convenience .
constexpr uint128dp_t get_uint128(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr T get_packed_value(const packed_t< T > *source, const lb_endian_t byte_order) noexcept
Return packed_t::store after converting it to from either lb_endian::little or lb_endian::big dependi...
constexpr bool is_big_endian() noexcept
Evaluates true if platform is running in big endian mode, i.e.
constexpr std::enable_if_t< std::is_standard_layout_v< T >, T > get_value(uint8_t const *buffer) noexcept
Returns a T value from the given byte address using packed_t to resolve a potential memory alignment ...
constexpr void put_uint256(uint8_t *buffer, const uint256dp_t &v) noexcept
See put_uint16() for reference.
constexpr bool is_defined_endian(const endian_t &v) noexcept
Evaluates true if the given endian is defined, i.e.
constexpr uint16_t get_uint16(uint8_t const *buffer) noexcept
Returns a uint16_t value from the given byte address using packed_t to resolve a potential memory ali...
constexpr uint16_t bswap(uint16_t const source) noexcept
constexpr bool is_little_or_big_endian() noexcept
Evaluates true if platform is running in little or big endian mode, i.e.
constexpr uint16_t cpu_to_be(uint16_t const h) noexcept
constexpr endian_t to_endian(const lb_endian_t v) noexcept
constexpr uint32_t get_uint32(uint8_t const *buffer) noexcept
See get_uint16() for reference.
char * cast_uint8_ptr_to_char(uint8_t *b) noexcept
constexpr void put_uint32(uint8_t *buffer, const uint32_t v) noexcept
See put_uint16() for reference.
endian_t
Endian identifier, indicating endianess of all scalar types.
constexpr uint256dp_t get_uint256(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr void put_uint192(uint8_t *buffer, const uint192dp_t &v) noexcept
See put_uint16() for reference.
constexpr bool has_endian_little_v
Value access of little-endian type trait for convenience .
constexpr uint16_t le_to_cpu(uint16_t const l) noexcept
constexpr void put_uint8(uint8_t *buffer, const uint8_t v) noexcept
lb_endian_t
Simplified reduced endian type only covering little- and big-endian.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr void put_uint64(uint8_t *buffer, const uint64_t &v) noexcept
See put_uint16() for reference.
constexpr bool is_little_endian(const endian_t byte_order) noexcept
Returns true if given byte_order equals endian::little, otherwise false.
constexpr void put_uint16(uint8_t *buffer, const uint16_t v) noexcept
Put the given uint16_t value into the given byte address using packed_t to resolve a potential memory...
constexpr uint16_t be_to_cpu(uint16_t const n) noexcept
constexpr void put_uint128(uint8_t *buffer, const uint128dp_t &v) noexcept
See put_uint16() for reference.
constexpr std::enable_if_t< std::is_standard_layout_v< T >, void > put_value(uint8_t *buffer, const T &v) noexcept
Put the given T value into the given byte address using packed_t to resolve a potential memory alignm...
constexpr lb_endian_t to_lb_endian(const endian_t v) noexcept
constexpr uint16_t cpu_to_le(uint16_t const h) noexcept
constexpr uint64_t get_uint64(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr int8_t get_int8(uint8_t const *buffer) noexcept
constexpr uint8_t get_uint8(uint8_t const *buffer) noexcept
const uint8_t * cast_char_ptr_to_uint8(const char *s) noexcept
@ pdp
Identifier for DEC PDP-11, aka ENDIAN_LITTLE_WORD.
@ undefined
Undetermined endian.
@ native
Identifier for native platform type, one of the above.
@ little
Identifier for little endian.
@ honeywell
Identifier for Honeywell 316, aka ENDIAN_BIG_WORD.
@ big
Identifier for big endian.
@ little
Identifier for little endian, equivalent to endian::little.
@ big
Identifier for big endian, equivalent to endian::big.
#define PRAGMA_DISABLE_WARNING_PUSH
#define PRAGMA_DISABLE_WARNING_MULTICHAR
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_pointer_v< Source > &&std::is_pointer_v< Dest >, Dest > pointer_cast(const Source &src) noexcept
A constexpr pointer cast implementation for C++17, inspired by C++20 bit_cast<>(arg).
consteval_cxx20 bool is_builtin_bit_cast_available() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available, using jau::has_builtin_bit_cast.
#define PRAGMA_DISABLE_WARNING_POP
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
constexpr uint32_t get_host_order() noexcept
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
A big-endian type trait for convenience .
A little-endian type trait for convenience .
Support aligned memory transfer from and to potentially unaligned memory.
A 128-bit packed uint8_t data array.
A 196-bit packed uint8_t data array.
A 256-bit packed uint8_t data array.