[PATCH] D59141: [Support/Endian] Add support for endian-specific enums

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 8 10:14:40 PST 2019


Seems to me the variable templates in Endian.h are not specific to enums
and may as well be called little_t and big_t. Thoughts?
On Fri, Mar 8, 2019 at 10:03 AM Pavel Labath via Phabricator <
reviews at reviews.llvm.org> wrote:

> labath created this revision.
> labath added reviewers: Bigcheese, zturner.
> Herald added a subscriber: kristina.
> Herald added a project: LLVM.
>
> Binary formats often include various enumerations or bitsets, but using
> endian-specific types for accessing them is tricky because they
> currently only support integral types. This is particularly true for
> scoped enums (enum class), as these are not implicitly convertible to
> integral types, and so one has to perform two casts just to read the
> enum value.
>
> This fixes that support by adding first-class support for enumeration
> types to endian-specific types. The support for them was already almost
> working -- all I needed to do was overload getSwappedBytes for
> enumeration types (which casts the enum to its underlying type and
> performs the
> conversion there). I also add some convenience template aliases to simplify
> declaring endian-specific enums.
>
>
> Repository:
>   rL LLVM
>
> https://reviews.llvm.org/D59141
>
> Files:
>   include/llvm/Support/Endian.h
>   include/llvm/Support/SwapByteOrder.h
>   unittests/Support/EndianTest.cpp
>
>
> Index: unittests/Support/EndianTest.cpp
> ===================================================================
> --- unittests/Support/EndianTest.cpp
> +++ unittests/Support/EndianTest.cpp
> @@ -200,4 +200,13 @@
>    EXPECT_EQ(*big_val, *little_val);
>  }
>
> +TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
> +  enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };
> +  unsigned char bytes[] = {0x01, 0x02};
> +  using LittleTest = little_enum_t<Test>;
> +  using BigTest = big_enum_t<Test>;
> +  EXPECT_EQ(Test::TWOONE, *reinterpret_cast<LittleTest *>(bytes));
> +  EXPECT_EQ(Test::ONETWO, *reinterpret_cast<BigTest *>(bytes));
> +}
> +
>  } // end anon namespace
> Index: include/llvm/Support/SwapByteOrder.h
> ===================================================================
> --- include/llvm/Support/SwapByteOrder.h
> +++ include/llvm/Support/SwapByteOrder.h
> @@ -115,6 +115,13 @@
>    return out.d;
>  }
>
> +template <typename T>
> +inline typename std::enable_if<std::is_enum<T>::value, T>::type
> +getSwappedBytes(T C) {
> +  return static_cast<T>(
> +      getSwappedBytes(static_cast<typename
> std::underlying_type<T>::type>(C)));
> +}
> +
>  template<typename T>
>  inline void swapByteOrder(T &Value) {
>    Value = getSwappedBytes(Value);
> Index: include/llvm/Support/Endian.h
> ===================================================================
> --- include/llvm/Support/Endian.h
> +++ include/llvm/Support/Endian.h
> @@ -338,6 +338,12 @@
>  using unaligned_int64_t =
>      detail::packed_endian_specific_integral<int64_t, native, unaligned>;
>
> +template <typename T>
> +using little_enum_t =
> +    detail::packed_endian_specific_integral<T, little, unaligned>;
> +template <typename T>
> +using big_enum_t = detail::packed_endian_specific_integral<T, big,
> unaligned>;
> +
>  namespace endian {
>
>  template <typename T> inline T read(const void *P, endianness E) {
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190308/3a89b6b6/attachment.html>


More information about the llvm-commits mailing list