llvm.org GIT mirror llvm / fbbf45e
[Support/Endian] Add support for endian-specific enums Summary: 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. Reviewers: Bigcheese, zturner Subscribers: kristina, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59141 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355812 91177308-0d34-0410-b5e6-96231b3b80d8 Pavel Labath 1 year, 2 months ago
3 changed file(s) with 27 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
337337 using unaligned_int64_t =
338338 detail::packed_endian_specific_integral;
339339
340 template
341 using little_t = detail::packed_endian_specific_integral;
342 template
343 using big_t = detail::packed_endian_specific_integral;
344
345 template
346 using aligned_little_t =
347 detail::packed_endian_specific_integral;
348 template
349 using aligned_big_t = detail::packed_endian_specific_integral;
350
340351 namespace endian {
341352
342353 template inline T read(const void *P, endianness E) {
114114 return out.d;
115115 }
116116
117 template
118 inline typename std::enable_if::value, T>::type
119 getSwappedBytes(T C) {
120 return static_cast(
121 getSwappedBytes(static_cast::type>(C)));
122 }
123
117124 template
118125 inline void swapByteOrder(T &Value) {
119126 Value = getSwappedBytes(Value);
199199 EXPECT_EQ(*big_val, *little_val);
200200 }
201201
202 TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
203 enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };
204 unsigned char bytes[] = {0x01, 0x02};
205 using LittleTest = little_t;
206 using BigTest = big_t;
207 EXPECT_EQ(Test::TWOONE, *reinterpret_cast(bytes));
208 EXPECT_EQ(Test::ONETWO, *reinterpret_cast(bytes));
209 }
210
202211 } // end anon namespace