1/*
2Copyright Rene Rivera 2013-2015
3Distributed under the Boost Software License, Version 1.0.
4(See accompanying file LICENSE_1_0.txt or copy at
5http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8#ifndef BOOST_PREDEF_ENDIAN_H
9#define BOOST_PREDEF_ENDIAN_H
10
11#include <boost/predef/version_number.h>
12#include <boost/predef/make.h>
13#include <boost/predef/library/c/gnu.h>
14#include <boost/predef/os/macos.h>
15#include <boost/predef/os/bsd.h>
16#include <boost/predef/platform/android.h>
17
18/* tag::reference[]
19= `BOOST_ENDIAN_*`
20
21Detection of endian memory ordering. There are four defined macros
22in this header that define the various generally possible endian
23memory orderings:
24
25* `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian.
26* `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian.
27* `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian.
28* `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian.
29
30The detection is conservative in that it only identifies endianness
31that it knows for certain. In particular bi-endianness is not
32indicated as is it not practically possible to determine the
33endianness from anything but an operating system provided
34header. And the currently known headers do not define that
35programatic bi-endianness is available.
36
37This implementation is a compilation of various publicly available
38information and acquired knowledge:
39
40. The indispensable documentation of "Pre-defined Compiler Macros"
41 http://sourceforge.net/p/predef/wiki/Endianness[Endianness].
42. The various endian specifications available in the
43 http://wikipedia.org/[Wikipedia] computer architecture pages.
44. Generally available searches for headers that define endianness.
45*/ // end::reference[]
46
47#define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
48#define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
49#define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
50#define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
51
52/* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER.
53 * And some OSs provide some for of endian header also.
54 */
55#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
56 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
57# if BOOST_LIB_C_GNU || BOOST_PLAT_ANDROID || BOOST_OS_BSD_OPEN
58# include <endian.h>
59# else
60# if BOOST_OS_MACOS
61# include <machine/endian.h>
62# else
63# if BOOST_OS_BSD
64# include <sys/endian.h>
65# endif
66# endif
67# endif
68# if defined(__BYTE_ORDER)
69# if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
70# undef BOOST_ENDIAN_BIG_BYTE
71# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
72# endif
73# if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
74# undef BOOST_ENDIAN_LITTLE_BYTE
75# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
76# endif
77# if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN)
78# undef BOOST_ENDIAN_LITTLE_WORD
79# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
80# endif
81# endif
82# if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER)
83# if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
84# undef BOOST_ENDIAN_BIG_BYTE
85# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
86# endif
87# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
88# undef BOOST_ENDIAN_LITTLE_BYTE
89# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
90# endif
91# if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN)
92# undef BOOST_ENDIAN_LITTLE_WORD
93# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
94# endif
95# endif
96#endif
97
98/* Built-in byte-swapped big-endian macros.
99 */
100#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
101 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
102# if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
103 (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \
104 defined(__ARMEB__) || \
105 defined(__THUMBEB__) || \
106 defined(__AARCH64EB__) || \
107 defined(_MIPSEB) || \
108 defined(__MIPSEB) || \
109 defined(__MIPSEB__)
110# undef BOOST_ENDIAN_BIG_BYTE
111# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
112# endif
113#endif
114
115/* Built-in byte-swapped little-endian macros.
116 */
117#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
118 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
119# if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
120 (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
121 defined(__ARMEL__) || \
122 defined(__THUMBEL__) || \
123 defined(__AARCH64EL__) || \
124 defined(__loongarch__) || \
125 defined(_MIPSEL) || \
126 defined(__MIPSEL) || \
127 defined(__MIPSEL__) || \
128 defined(__riscv) || \
129 defined(__e2k__)
130# undef BOOST_ENDIAN_LITTLE_BYTE
131# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
132# endif
133#endif
134
135/* Some architectures are strictly one endianess (as opposed
136 * the current common bi-endianess).
137 */
138#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
139 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
140# include <boost/predef/architecture.h>
141# if BOOST_ARCH_M68K || \
142 BOOST_ARCH_PARISC || \
143 BOOST_ARCH_SPARC || \
144 BOOST_ARCH_SYS370 || \
145 BOOST_ARCH_SYS390 || \
146 BOOST_ARCH_Z
147# undef BOOST_ENDIAN_BIG_BYTE
148# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
149# endif
150# if BOOST_ARCH_IA64 || \
151 BOOST_ARCH_X86 || \
152 BOOST_ARCH_BLACKFIN
153# undef BOOST_ENDIAN_LITTLE_BYTE
154# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
155# endif
156#endif
157
158/* Windows on ARM, if not otherwise detected/specified, is always
159 * byte-swapped little-endian.
160 */
161#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
162 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
163# if BOOST_ARCH_ARM
164# include <boost/predef/os/windows.h>
165# if BOOST_OS_WINDOWS
166# undef BOOST_ENDIAN_LITTLE_BYTE
167# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
168# endif
169# endif
170#endif
171
172#if BOOST_ENDIAN_BIG_BYTE
173# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE
174#endif
175#if BOOST_ENDIAN_BIG_WORD
176# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
177#endif
178#if BOOST_ENDIAN_LITTLE_BYTE
179# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
180#endif
181#if BOOST_ENDIAN_LITTLE_WORD
182# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE
183#endif
184
185#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian"
186#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian"
187#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
188#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
189
190#endif
191
192#include <boost/predef/detail/test.h>
193BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME)
194
195#include <boost/predef/detail/test.h>
196BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME)
197
198#include <boost/predef/detail/test.h>
199BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME)
200
201#include <boost/predef/detail/test.h>
202BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME)
203