@@ -22,19 +22,66 @@ documentation.
2222#define PROTOZERO_BIG_ENDIAN 4321
2323
2424// Find out which byte order the machine has.
25- #if defined(__BYTE_ORDER)
26- # if (__BYTE_ORDER == __LITTLE_ENDIAN)
25+
26+ // __BYTE_ORDER__ is set by GCC and Clang.
27+ #if !defined(PROTOZERO_BYTE_ORDER) && defined(__BYTE_ORDER__)
28+ # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2729# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN
28- # endif
29- # if (__BYTE_ORDER == __BIG_ENDIAN)
30+ # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
3031# define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN
3132# endif
32- #else
33- // This probably isn't a very good default, but might do until we figure
34- // out something better.
33+ #endif // defined(__BYTE_ORDER__)
34+
35+ // On Linux, we can use endian.h.
36+ #if !defined(PROTOZERO_BYTE_ORDER) && defined(__linux__)
37+ # include < endian.h>
38+ # if defined(__BYTE_ORDER)
39+ # if (__BYTE_ORDER == __LITTLE_ENDIAN)
40+ # define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN
41+ # elif (__BYTE_ORDER == __BIG_ENDIAN)
42+ # define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN
43+ # endif
44+ # endif
45+ #endif // !defined(PROTOZERO_BYTE_ORDER) && defined(__linux__)
46+
47+ // On BSD, we can use <sys/endian.h>
48+ #if !defined(PROTOZERO_BYTE_ORDER) && \
49+ (defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__))
50+ # include < sys/endian.h>
51+ # if defined(BYTE_ORDER)
52+ # if (BYTE_ORDER == LITTLE_ENDIAN)
53+ # define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN
54+ # elif (BYTE_ORDER == BIG_ENDIAN)
55+ # define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN
56+ # endif
57+ # endif
58+ #endif
59+
60+ // On Windows, we assume little endian.
61+ #if !defined(PROTOZERO_BYTE_ORDER) && defined(_MSC_VER)
3562# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN
63+ #endif // !defined(PROTOZERO_BYTE_ORDER) && defined(_MSC_VER)
64+
65+ #if !defined(PROTOZERO_BYTE_ORDER)
66+ # error "Could not determine byte order; define PROTOZERO_BYTE_ORDER"
3667#endif
3768
69+ namespace protozero {
70+ namespace detail {
71+
72+ constexpr bool is_little_endian () noexcept {
73+ return static_cast <unsigned char const &>(
74+ static_cast <unsigned int const &>(1u )) == 1u ;
75+ }
76+
77+ } // namespace detail
78+ } // namespace protozero
79+
80+ static_assert (
81+ protozero::detail::is_little_endian () ==
82+ (PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN ),
83+ "Could not determine byte order correctly; define PROTOZERO_BYTE_ORDER " );
84+
3885// Check whether __builtin_bswap is available
3986#if defined(__GNUC__) || defined(__clang__)
4087# define PROTOZERO_USE_BUILTIN_BSWAP
0 commit comments