Skip to content

Instantly share code, notes, and snippets.

@jtsylve
Last active February 19, 2020 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jtsylve/b95ed06e559e584906853a76c000b490 to your computer and use it in GitHub Desktop.
Save jtsylve/b95ed06e559e584906853a76c000b490 to your computer and use it in GitHub Desktop.
More efficient version of endian_struct that supports C++17 but requires abseil
#include <absl/base/internal/endian.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#if __has_include("bit")
#include <bit>
#if defined(__cpp_lib_endian) && __cpp_lib_endian >= 201907
#define USE_STD_ENDIAN
#endif
#endif
template <typename T, typename = std::enable_if_t<std::is_scalar_v<T>>>
inline T bswap(T val) noexcept {
if constexpr (sizeof(T) == 1) {
return val;
}
if constexpr (sizeof(T) == sizeof(uint16_t)) {
return (T)absl::gbswap_16(reinterpret_cast<const uint16_t &>(val));
}
if constexpr (sizeof(T) == sizeof(uint32_t)) {
return (T)absl::gbswap_32(reinterpret_cast<const uint32_t &>(val));
}
if constexpr (sizeof(T) == sizeof(uint64_t)) {
return (T)absl::gbswap_64(reinterpret_cast<const uint64_t &>(val));
}
}
#ifdef USE_STD_ENDIAN
using std::endian;
#else
enum class endian {
little,
big,
#ifdef ABSL_IS_LITTLE_ENDIAN
native = little,
#else
native = big,
#endif
};
#endif
template <typename T, endian endianess,
typename = std::enable_if_t<std::is_scalar_v<T>>>
class base_endian {
public:
constexpr base_endian() noexcept = default;
base_endian(const T &val) noexcept : _val{swap(val)} {}
operator T() const noexcept { return swap(_val); }
private:
static T swap(T val) noexcept {
if constexpr (endianess == endian::native) {
return val;
}
return bswap(val);
}
T _val{};
};
template <typename T>
using big_endian = base_endian<T, endian::big>;
template <typename T>
using little_endian = base_endian<T, endian::little>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment