Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Endian.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <bit>
5#include <cstdint>
6
8
10
11 /*
12 ********************************************************************************
13 ****************************** Common::GetEndianness ***************************
14 ********************************************************************************
15 */
16#if !qCompilerAndStdLib_constexpr_union_enter_one_use_other_Buggy
17 namespace Private_ {
18 union EndianTester_ {
19 uint32_t sdat;
20 uint8_t cdat[4];
21 };
22 static constexpr EndianTester_ kMix_{0x01020304};
23 }
24#endif
25 inline constexpr Endian GetEndianness ()
26 {
27 if constexpr (endian::native == endian::little) {
28 return Endian::eLittle;
29 }
30 if constexpr (endian::native == endian::big) {
31 return Endian::eBig;
32 }
33#if !qCompilerAndStdLib_constexpr_union_enter_one_use_other_Buggy
34 return (Private_::kMix_.cdat[0] == 4) ? Endian::eLittleByte : // aka little endian
35 (Private_::kMix_.cdat[0] == 1) ? Endian::eBigByte
36 : // aka big endian
37 (Private_::kMix_.cdat[0] == 2) ? Endian::eLittleWord
38 : // aka little PDP
39 Endian::eBigWord;
40#else
41#if (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
42 defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || \
43 defined(__MIBSEB) || defined(__MIBSEB__)
44 return Endian::eBigByte;
45#endif
46#if (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
47 defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \
48 defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64) || defined(_M_ARM)
49 return Endian::eLittle;
50#endif
51#endif
52 }
53
54 /*
55 ********************************************************************************
56 **************************** Common::EndianConverter ***************************
57 ********************************************************************************
58 */
59 template <integral T>
60 constexpr inline T EndianConverter (T value, Endian from, Endian to)
61 {
62 if (from == to) {
63 return value;
64 }
65 Require (from == Endian::eBig or from == Endian::eLittle); // just cuz that's all that's implemented
66 Require (to == Endian::eBig or to == Endian::eLittle); // ""
67 // @todo re-implement some cases using https://en.cppreference.com/w/cpp/numeric/byteswap
68 // Require ((from == Endian::eBig or from == Endian::eLittle) and (to == Endian::eBig or to == Endian::eLittle));
69 // return std::byteswap (value) ;; double check this is right for all integral sizes... and use my stdcompat code for this
70 if constexpr (sizeof (T) == 1) {
71 return value;
72 }
73 if constexpr (sizeof (T) == 2) {
74 // since we only support big endian and little endian and from != to - swap is easy
75 return ((value & 0xFF) << 8) | ((value >> 8) & 0xFF);
76 }
77 if constexpr (sizeof (T) == 4) {
78 // since we only support big endian and little endian and from != to - I THINK This is right...
79 return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value >> 8) & 0xFF00) | ((value >> 24) & 0xFF);
80 }
82 return value;
83 }
84
85}
#define AssertNotImplemented()
Definition Assertions.h:401
Endian
in principle complicated question of correspondence between bit and byte and word numbering,...
Definition Endian.h:30
constexpr Endian GetEndianness()
returns native (std::endian::native) Endianness flag. Can be complicated (mixed, etc)....
Definition Endian.inl:25
constexpr T EndianConverter(T value, Endian from, Endian to)
Definition Endian.inl:60