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 int16_t 
bswap(int16_t 
const source) 
noexcept {
 
   98        #if defined __has_builtin_bswap64 
  101            return (int16_t) ( ( ( (source) >> 8 ) & 0xff ) |
 
  102                               ( ( (source) & 0xff) << 8 ) );
 
 
  106    constexpr uint32_t 
bswap(uint32_t 
const source) 
noexcept {
 
  107        #if defined __has_builtin_bswap32 
  108            return __builtin_bswap32(source);
 
  110            return ( ( source & 0xff000000U ) >> 24 ) |
 
  111                   ( ( source & 0x00ff0000U ) >>  8 ) |
 
  112                   ( ( source & 0x0000ff00U ) <<  8 ) |
 
  113                   ( ( source & 0x000000ffU ) << 24 );
 
 
  117    constexpr int32_t 
bswap(int32_t 
const source) 
noexcept {
 
  118        #if defined __has_builtin_bswap64 
  122                                           ( ( source & 0x00ff0000U ) >>  8 ) |
 
  123                                           ( ( source & 0x0000ff00U ) <<  8 ) |
 
  124                                           ( ( source & 0x000000ffU ) << 24 ) );
 
 
  128    constexpr uint64_t 
bswap(uint64_t 
const & source) 
noexcept {
 
  129        #if defined __has_builtin_bswap64 
  130            return __builtin_bswap64(source);
 
  132            return ( ( source & 0xff00000000000000ULL ) >> 56 ) |
 
  133                   ( ( source & 0x00ff000000000000ULL ) >> 40 ) |
 
  134                   ( ( source & 0x0000ff0000000000ULL ) >> 24 ) |
 
  135                   ( ( source & 0x000000ff00000000ULL ) >>  8 ) |
 
  136                   ( ( source & 0x00000000ff000000ULL ) <<  8 ) |
 
  137                   ( ( source & 0x0000000000ff0000ULL ) << 24 ) |
 
  138                   ( ( source & 0x000000000000ff00ULL ) << 40 ) |
 
  139                   ( ( source & 0x00000000000000ffULL ) << 56 );
 
 
  143    constexpr int64_t 
bswap(int64_t 
const & source) 
noexcept {
 
  144        #if defined __has_builtin_bswap64 
  148                                           ( ( source & 0x00ff000000000000ULL ) >> 40 ) |
 
  149                                           ( ( source & 0x0000ff0000000000ULL ) >> 24 ) |
 
  150                                           ( ( source & 0x000000ff00000000ULL ) >>  8 ) |
 
  151                                           ( ( source & 0x00000000ff000000ULL ) <<  8 ) |
 
  152                                           ( ( source & 0x0000000000ff0000ULL ) << 24 ) |
 
  153                                           ( ( source & 0x000000000000ff00ULL ) << 40 ) |
 
  154                                           ( ( source & 0x00000000000000ffULL ) << 56 ) );
 
 
  158    constexpr void bswap(uint8_t * sink, uint8_t 
const * source, 
nsize_t len) {
 
  160        for (; len > 0; len--) {
 
 
  184        return reinterpret_cast<char*
>(b);
 
 
  187        return reinterpret_cast<const char*
>(b);
 
 
  191       return reinterpret_cast<const uint8_t*
>(s);
 
 
  206                constexpr uint8_t b[4] { 0x44, 0x43, 0x42, 0x41 }; 
 
 
 
  371    template <
typename Dummy_type> 
struct has_endian_little : std::integral_constant<bool, endian_t::little == endian_t::native> {};
 
  391    template <
typename Dummy_type> 
struct has_endian_big : std::integral_constant<bool, endian_t::big == endian_t::native> {};
 
  413    constexpr uint16_t 
be_to_cpu(uint16_t 
const n) 
noexcept {
 
 
  422    constexpr uint16_t 
cpu_to_be(uint16_t 
const h) 
noexcept {
 
 
  431    constexpr uint16_t 
le_to_cpu(uint16_t 
const l) 
noexcept {
 
 
  440    constexpr uint16_t 
cpu_to_le(uint16_t 
const h) 
noexcept {
 
 
  487    constexpr uint32_t 
be_to_cpu(uint32_t 
const n) 
noexcept {
 
 
  496    constexpr uint32_t 
cpu_to_be(uint32_t 
const h) 
noexcept {
 
 
  505    constexpr uint32_t 
le_to_cpu(uint32_t 
const l) 
noexcept {
 
 
  514    constexpr uint32_t 
cpu_to_le(uint32_t 
const h) 
noexcept {
 
 
  561    constexpr uint64_t 
be_to_cpu(uint64_t 
const & n) 
noexcept {
 
 
  570    constexpr uint64_t 
cpu_to_be(uint64_t 
const & h) 
noexcept {
 
 
  579    constexpr uint64_t 
le_to_cpu(uint64_t 
const & l) 
noexcept {
 
 
  588    constexpr uint64_t 
cpu_to_le(uint64_t 
const & h) 
noexcept {
 
 
  598    constexpr int64_t 
be_to_cpu(int64_t 
const & n) 
noexcept {
 
 
  607    constexpr int64_t 
cpu_to_be(int64_t 
const & h) 
noexcept {
 
 
  616    constexpr int64_t 
le_to_cpu(int64_t 
const & l) 
noexcept {
 
 
  625    constexpr int64_t 
cpu_to_le(int64_t 
const & h) 
noexcept {
 
 
  756            []() 
constexpr -> std::array<uint8_t, 256> {
 
  758                std::array<uint8_t, 256> result{};
 
  759                for (
size_t i = 0; i < 256; ++i) {
 
  761                    result[i] = ( (i * 0x80200802_u64) & 0x0884422110_u64 ) * 0x0101010101_u64 >> 32;
 
 
  806    template<jau::req::
unsigned_
integral T>
 
  808        if ( n >= 
sizeof(T) * CHAR_BIT ) {
 
  809            return std::numeric_limits<T>::max();
 
  811            return (T(1) << n) - T(1);
 
 
  822    template<jau::req::
unsigned_
integral T>
 
  824        if ( n >= 
sizeof(T) * CHAR_BIT ) {
 
  827        v &= (T(1) << n) - T(1); 
 
  830        for (v >>= 1; v; v >>= 1) {
 
 
  844    constexpr void put_uint8(uint8_t * buffer, 
const uint8_t v) 
noexcept 
 
  848    constexpr uint8_t 
get_uint8(uint8_t 
const * buffer) 
noexcept 
 
  852    constexpr int8_t 
get_int8(uint8_t 
const * buffer) 
noexcept 
 
  875    constexpr void put_uint16(uint8_t * buffer, 
const uint16_t v) 
noexcept 
 
  898    constexpr uint16_t 
get_uint16(uint8_t 
const * buffer) 
noexcept 
 
  922    constexpr void put_int16(uint8_t * buffer, 
const int16_t v) 
noexcept 
 
  945    constexpr int16_t 
get_int16(uint8_t 
const * buffer) 
noexcept 
 
  967    constexpr void put_uint32(uint8_t * buffer, 
const uint32_t v) 
noexcept 
 
  983    constexpr uint32_t 
get_uint32(uint8_t 
const * buffer) 
noexcept 
 
 1000    constexpr void put_int32(uint8_t * buffer, 
const int32_t v) 
noexcept 
 
 1016    constexpr int32_t 
get_int32(uint8_t 
const * buffer) 
noexcept 
 
 1033    constexpr void put_uint64(uint8_t * buffer, 
const uint64_t & v) 
noexcept 
 
 1066    constexpr void put_int64(uint8_t * buffer, 
const int64_t & v) 
noexcept 
 
 1082    constexpr int64_t 
get_int64(uint8_t 
const * buffer) 
noexcept 
 
 1209    template<
typename T>
 
 1211    typename std::enable_if_t<
 
 1212        std::is_standard_layout_v<T>,
 
 1233    template<
typename T>
 
 1235    typename std::enable_if_t<
 
 1236        std::is_standard_layout_v<T>,
 
 1252    template<
typename T>
 
 1254    typename std::enable_if_t<
 
 1255        std::is_standard_layout_v<T>,
 
 1275    template<
typename T>
 
 1277    typename std::enable_if_t<
 
 1278        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 int64_t get_int64(uint8_t const *buffer) noexcept
See get_int16() 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_little_endian() noexcept
Evaluates true if platform is running in little endian mode, i.e.
 
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.
 
static constexpr T bit_mask(size_t n) noexcept
Returns the T bit mask of n-bits, 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.
 
constexpr int16_t get_int16(uint8_t const *buffer) noexcept
Returns a int16_t value from the given byte address using packed_t to resolve a potential memory alig...
 
endian_t
Endian identifier, indicating endianess of all scalar types.
 
constexpr int32_t get_int32(uint8_t const *buffer) noexcept
See get_int16() for reference.
 
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 void put_int16(uint8_t *buffer, const int16_t v) noexcept
Put the given int16_t value into the given byte address using packed_t to resolve a potential memory ...
 
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.
 
constexpr void put_uint64(uint8_t *buffer, const uint64_t &v) noexcept
See put_uint16() for reference.
 
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 void put_int64(uint8_t *buffer, const int64_t &v) noexcept
See put_int16() for reference.
 
constexpr uint16_t cpu_to_le(uint16_t const h) noexcept
 
constexpr void put_int32(uint8_t *buffer, const int32_t v) noexcept
See put_int16() for reference.
 
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 rev_bits(uint8_t v) noexcept
Reverse bits of one byte.
 
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.
 
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_trivially_copyable_v< Dest > &&std::is_trivially_copyable_v< Source >, Dest > bit_cast(const Source &src) noexcept
C++20 bit_cast<>(arg) implementation for C++17.
 
#define PRAGMA_DISABLE_WARNING_PUSH
 
consteval_cxx20 bool has_builtin_bit_cast() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available via __has_builtin(__builtin_bit_cast).
 
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).
 
#define PRAGMA_DISABLE_WARNING_MULTICHAR
 
#define PRAGMA_DISABLE_WARNING_POP
 
uint_bytes_t< sizeof(unsigned long int)> nsize_t
Natural 'size_t' alternative using uint<XX>_t with xx = sizeof(unsigned long int)*8 as its natural si...
 
constexpr uint32_t get_host_order() noexcept
 
static constexpr std::array< uint8_t, 256 > BitRevTable256
 
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
 
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.
 
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.