#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_STORAGE_HELPERS_ENDIANFLIP_H #define NUCLEX_STORAGE_HELPERS_ENDIANFLIP_H #include "Nuclex/Storage/Config.h" #include // for std::uint8_t, std::uint16_t, std::uint32_t and std::uint64_t // Microsoft compilers need a special header to know their intrinsics #if defined(_MSC_VER) #include #endif namespace Nuclex { namespace Storage { namespace Helpers { // ------------------------------------------------------------------------------------------- // /// Does nothing /// Integer that will be returned unmodified /// The input value, unmodified NUCLEX_STORAGE_ALWAYS_INLINE uint8_t EndianFlip(uint8_t integer) { return integer; } // ------------------------------------------------------------------------------------------- // /// Reverses the bytes of a 16 bit integer /// Integer whose bytes will be reversed /// The endian-flipped 16 bit integer NUCLEX_STORAGE_ALWAYS_INLINE uint16_t EndianFlip(uint16_t integer) { #if defined(_MSC_VER) return _byteswap_ushort(integer); #elif defined(__clang__) || (defined(__GNUC__) || defined(__GNUG__)) return __builtin_bswap16(integer); #else return (integer << 8) | (integer >> 8); #endif } // ------------------------------------------------------------------------------------------- // /// Reverses the bytes of a 32 bit integer /// Integer whose bytes will be reversed /// The endian-flipped 32 bit integer NUCLEX_STORAGE_ALWAYS_INLINE uint32_t EndianFlip(std::uint32_t integer) { #if defined(_MSC_VER) return _byteswap_ulong(integer); #elif defined(__clang__) || (defined(__GNUC__) || defined(__GNUG__)) return __builtin_bswap32(integer); #else return ( (integer << 24) | ((integer & 0x0000FF00) << 8) | ((integer & 0x00FF0000) >> 8) | (integer >> 24) ); #endif } // ------------------------------------------------------------------------------------------- // /// Reverses the bytes of a 64 bit integer /// Integer whose bytes will be reversed /// The endian-flipped 64 bit integer NUCLEX_STORAGE_ALWAYS_INLINE uint64_t EndianFlip(std::uint64_t integer) { #if defined(_MSC_VER) return _byteswap_uint64(integer); #elif defined(__clang__) || (defined(__GNUC__) || defined(__GNUG__)) return __builtin_bswap64(integer); #else return ( (integer << 56) | ((integer & 0x000000000000FF00ULL) << 40) | ((integer & 0x0000000000FF0000ULL) << 24) | ((integer & 0x00000000FF000000ULL) << 8) | ((integer & 0x000000FF00000000ULL) >> 8) | ((integer & 0x0000FF0000000000ULL) >> 24) | ((integer & 0x00FF000000000000ULL) >> 40) | (integer >> 56) ); #endif } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Storage::Helpers #endif // NUCLEX_STORAGE_HELPERS_ENDIANFLIP_H