From 985cd878e6dd87cf5bd5fe408a6f4364bf1a5362 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 25 Jan 2019 12:09:12 -0500 Subject: [PATCH] common/swap: use template and tag for LE/BE specification The tag can be useful for other type-generic templates like BitFields to forward the endianness specification --- src/common/swap.h | 160 ++++++++++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 54 deletions(-) diff --git a/src/common/swap.h b/src/common/swap.h index 466096f583..97aacb4dc9 100644 --- a/src/common/swap.h +++ b/src/common/swap.h @@ -645,64 +645,116 @@ protected: } }; +struct SwapTag {}; // Use the different endianness from the system +struct KeepTag {}; // Use the same endianness as the system + +template +struct AddEndian; + +// KeepTag specializations + +template +struct AddEndian { + using type = T; +}; + +// SwapTag specializations + +template <> +struct AddEndian { + using type = u8; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = s8; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template +struct AddEndian { + static_assert(std::is_enum_v); + using type = swap_enum_t; +}; + +// Alias LETag/BETag as KeepTag/SwapTag depending on the system #if COMMON_LITTLE_ENDIAN -using u16_le = u16; -using u32_le = u32; -using u64_le = u64; -using s16_le = s16; -using s32_le = s32; -using s64_le = s64; +using LETag = KeepTag; +using BETag = SwapTag; -template -using enum_le = std::enable_if_t, T>; - -using float_le = float; -using double_le = double; - -using u64_be = swap_struct_t>; -using s64_be = swap_struct_t>; - -using u32_be = swap_struct_t>; -using s32_be = swap_struct_t>; - -using u16_be = swap_struct_t>; -using s16_be = swap_struct_t>; - -template -using enum_be = swap_enum_t; - -using float_be = swap_struct_t>; -using double_be = swap_struct_t>; #else -using u64_le = swap_struct_t>; -using s64_le = swap_struct_t>; - -using u32_le = swap_struct_t>; -using s32_le = swap_struct_t>; - -using u16_le = swap_struct_t>; -using s16_le = swap_struct_t>; - -template -using enum_le = swap_enum_t; - -using float_le = swap_struct_t>; -using double_le = swap_struct_t>; - -using u16_be = u16; -using u32_be = u32; -using u64_be = u64; - -using s16_be = s16; -using s32_be = s32; -using s64_be = s64; - -template -using enum_be = std::enable_if_t, T>; - -using float_be = float; -using double_be = double; +using BETag = KeepTag; +using LETag = SwapTag; #endif + +// Aliases for LE types +using u16_le = AddEndian::type; +using u32_le = AddEndian::type; +using u64_le = AddEndian::type; + +using s16_le = AddEndian::type; +using s32_le = AddEndian::type; +using s64_le = AddEndian::type; + +template +using enum_le = std::enable_if_t, typename AddEndian::type>; + +using float_le = AddEndian::type; +using double_le = AddEndian::type; + +// Aliases for BE types +using u16_be = AddEndian::type; +using u32_be = AddEndian::type; +using u64_be = AddEndian::type; + +using s16_be = AddEndian::type; +using s32_be = AddEndian::type; +using s64_be = AddEndian::type; + +template +using enum_be = std::enable_if_t, typename AddEndian::type>; + +using float_be = AddEndian::type; +using double_be = AddEndian::type;