diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/swap.h | 130 |
1 files changed, 91 insertions, 39 deletions
diff --git a/src/common/swap.h b/src/common/swap.h index 466096f58..97aacb4dc 100644 --- a/src/common/swap.h +++ b/src/common/swap.h | |||
| @@ -645,64 +645,116 @@ protected: | |||
| 645 | } | 645 | } |
| 646 | }; | 646 | }; |
| 647 | 647 | ||
| 648 | #if COMMON_LITTLE_ENDIAN | 648 | struct SwapTag {}; // Use the different endianness from the system |
| 649 | using u16_le = u16; | 649 | struct KeepTag {}; // Use the same endianness as the system |
| 650 | using u32_le = u32; | 650 | |
| 651 | using u64_le = u64; | 651 | template <typename T, typename Tag> |
| 652 | struct AddEndian; | ||
| 652 | 653 | ||
| 653 | using s16_le = s16; | 654 | // KeepTag specializations |
| 654 | using s32_le = s32; | ||
| 655 | using s64_le = s64; | ||
| 656 | 655 | ||
| 657 | template <typename T> | 656 | template <typename T> |
| 658 | using enum_le = std::enable_if_t<std::is_enum_v<T>, T>; | 657 | struct AddEndian<T, KeepTag> { |
| 658 | using type = T; | ||
| 659 | }; | ||
| 660 | |||
| 661 | // SwapTag specializations | ||
| 659 | 662 | ||
| 660 | using float_le = float; | 663 | template <> |
| 661 | using double_le = double; | 664 | struct AddEndian<u8, SwapTag> { |
| 665 | using type = u8; | ||
| 666 | }; | ||
| 662 | 667 | ||
| 663 | using u64_be = swap_struct_t<u64, swap_64_t<u64>>; | 668 | template <> |
| 664 | using s64_be = swap_struct_t<s64, swap_64_t<s64>>; | 669 | struct AddEndian<u16, SwapTag> { |
| 670 | using type = swap_struct_t<u16, swap_16_t<u16>>; | ||
| 671 | }; | ||
| 665 | 672 | ||
| 666 | using u32_be = swap_struct_t<u32, swap_32_t<u32>>; | 673 | template <> |
| 667 | using s32_be = swap_struct_t<s32, swap_32_t<s32>>; | 674 | struct AddEndian<u32, SwapTag> { |
| 675 | using type = swap_struct_t<u32, swap_32_t<u32>>; | ||
| 676 | }; | ||
| 668 | 677 | ||
| 669 | using u16_be = swap_struct_t<u16, swap_16_t<u16>>; | 678 | template <> |
| 670 | using s16_be = swap_struct_t<s16, swap_16_t<s16>>; | 679 | struct AddEndian<u64, SwapTag> { |
| 680 | using type = swap_struct_t<u64, swap_64_t<u64>>; | ||
| 681 | }; | ||
| 682 | |||
| 683 | template <> | ||
| 684 | struct AddEndian<s8, SwapTag> { | ||
| 685 | using type = s8; | ||
| 686 | }; | ||
| 687 | |||
| 688 | template <> | ||
| 689 | struct AddEndian<s16, SwapTag> { | ||
| 690 | using type = swap_struct_t<s16, swap_16_t<s16>>; | ||
| 691 | }; | ||
| 692 | |||
| 693 | template <> | ||
| 694 | struct AddEndian<s32, SwapTag> { | ||
| 695 | using type = swap_struct_t<s32, swap_32_t<s32>>; | ||
| 696 | }; | ||
| 697 | |||
| 698 | template <> | ||
| 699 | struct AddEndian<s64, SwapTag> { | ||
| 700 | using type = swap_struct_t<s64, swap_64_t<s64>>; | ||
| 701 | }; | ||
| 702 | |||
| 703 | template <> | ||
| 704 | struct AddEndian<float, SwapTag> { | ||
| 705 | using type = swap_struct_t<float, swap_float_t<float>>; | ||
| 706 | }; | ||
| 707 | |||
| 708 | template <> | ||
| 709 | struct AddEndian<double, SwapTag> { | ||
| 710 | using type = swap_struct_t<double, swap_double_t<double>>; | ||
| 711 | }; | ||
| 671 | 712 | ||
| 672 | template <typename T> | 713 | template <typename T> |
| 673 | using enum_be = swap_enum_t<T>; | 714 | struct AddEndian<T, SwapTag> { |
| 715 | static_assert(std::is_enum_v<T>); | ||
| 716 | using type = swap_enum_t<T>; | ||
| 717 | }; | ||
| 718 | |||
| 719 | // Alias LETag/BETag as KeepTag/SwapTag depending on the system | ||
| 720 | #if COMMON_LITTLE_ENDIAN | ||
| 721 | |||
| 722 | using LETag = KeepTag; | ||
| 723 | using BETag = SwapTag; | ||
| 674 | 724 | ||
| 675 | using float_be = swap_struct_t<float, swap_float_t<float>>; | ||
| 676 | using double_be = swap_struct_t<double, swap_double_t<double>>; | ||
| 677 | #else | 725 | #else |
| 678 | 726 | ||
| 679 | using u64_le = swap_struct_t<u64, swap_64_t<u64>>; | 727 | using BETag = KeepTag; |
| 680 | using s64_le = swap_struct_t<s64, swap_64_t<s64>>; | 728 | using LETag = SwapTag; |
| 681 | 729 | ||
| 682 | using u32_le = swap_struct_t<u32, swap_32_t<u32>>; | 730 | #endif |
| 683 | using s32_le = swap_struct_t<s32, swap_32_t<s32>>; | ||
| 684 | 731 | ||
| 685 | using u16_le = swap_struct_t<u16, swap_16_t<u16>>; | 732 | // Aliases for LE types |
| 686 | using s16_le = swap_struct_t<s16, swap_16_t<s16>>; | 733 | using u16_le = AddEndian<u16, LETag>::type; |
| 734 | using u32_le = AddEndian<u32, LETag>::type; | ||
| 735 | using u64_le = AddEndian<u64, LETag>::type; | ||
| 736 | |||
| 737 | using s16_le = AddEndian<s16, LETag>::type; | ||
| 738 | using s32_le = AddEndian<s32, LETag>::type; | ||
| 739 | using s64_le = AddEndian<s64, LETag>::type; | ||
| 687 | 740 | ||
| 688 | template <typename T> | 741 | template <typename T> |
| 689 | using enum_le = swap_enum_t<T>; | 742 | using enum_le = std::enable_if_t<std::is_enum_v<T>, typename AddEndian<T, LETag>::type>; |
| 690 | 743 | ||
| 691 | using float_le = swap_struct_t<float, swap_float_t<float>>; | 744 | using float_le = AddEndian<float, LETag>::type; |
| 692 | using double_le = swap_struct_t<double, swap_double_t<double>>; | 745 | using double_le = AddEndian<double, LETag>::type; |
| 693 | 746 | ||
| 694 | using u16_be = u16; | 747 | // Aliases for BE types |
| 695 | using u32_be = u32; | 748 | using u16_be = AddEndian<u16, BETag>::type; |
| 696 | using u64_be = u64; | 749 | using u32_be = AddEndian<u32, BETag>::type; |
| 750 | using u64_be = AddEndian<u64, BETag>::type; | ||
| 697 | 751 | ||
| 698 | using s16_be = s16; | 752 | using s16_be = AddEndian<s16, BETag>::type; |
| 699 | using s32_be = s32; | 753 | using s32_be = AddEndian<s32, BETag>::type; |
| 700 | using s64_be = s64; | 754 | using s64_be = AddEndian<s64, BETag>::type; |
| 701 | 755 | ||
| 702 | template <typename T> | 756 | template <typename T> |
| 703 | using enum_be = std::enable_if_t<std::is_enum_v<T>, T>; | 757 | using enum_be = std::enable_if_t<std::is_enum_v<T>, typename AddEndian<T, BETag>::type>; |
| 704 | |||
| 705 | using float_be = float; | ||
| 706 | using double_be = double; | ||
| 707 | 758 | ||
| 708 | #endif | 759 | using float_be = AddEndian<float, BETag>::type; |
| 760 | using double_be = AddEndian<double, BETag>::type; | ||