1 | /* |
2 | Copyright Rene Rivera 2013-2015 |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://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 | |
21 | Detection of endian memory ordering. There are four defined macros |
22 | in this header that define the various generally possible endian |
23 | memory 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 | |
30 | The detection is conservative in that it only identifies endianness |
31 | that it knows for certain. In particular bi-endianness is not |
32 | indicated as is it not practically possible to determine the |
33 | endianness from anything but an operating system provided |
34 | header. And the currently known headers do not define that |
35 | programatic bi-endianness is available. |
36 | |
37 | This implementation is a compilation of various publicly available |
38 | information 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 |
58 | # include <endian.h> |
59 | # else |
60 | # if BOOST_OS_MACOS |
61 | # include <machine/endian.h> |
62 | # else |
63 | # if BOOST_OS_BSD |
64 | # if BOOST_OS_BSD_OPEN |
65 | # include <machine/endian.h> |
66 | # else |
67 | # include <sys/endian.h> |
68 | # endif |
69 | # endif |
70 | # endif |
71 | # endif |
72 | # if defined(__BYTE_ORDER) |
73 | # if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) |
74 | # undef BOOST_ENDIAN_BIG_BYTE |
75 | # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
76 | # endif |
77 | # if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) |
78 | # undef BOOST_ENDIAN_LITTLE_BYTE |
79 | # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
80 | # endif |
81 | # if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN) |
82 | # undef BOOST_ENDIAN_LITTLE_WORD |
83 | # define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE |
84 | # endif |
85 | # endif |
86 | # if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER) |
87 | # if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) |
88 | # undef BOOST_ENDIAN_BIG_BYTE |
89 | # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
90 | # endif |
91 | # if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) |
92 | # undef BOOST_ENDIAN_LITTLE_BYTE |
93 | # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
94 | # endif |
95 | # if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN) |
96 | # undef BOOST_ENDIAN_LITTLE_WORD |
97 | # define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE |
98 | # endif |
99 | # endif |
100 | #endif |
101 | |
102 | /* Built-in byte-swpped big-endian macros. |
103 | */ |
104 | #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ |
105 | !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD |
106 | # if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ |
107 | (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \ |
108 | defined(__ARMEB__) || \ |
109 | defined(__THUMBEB__) || \ |
110 | defined(__AARCH64EB__) || \ |
111 | defined(_MIPSEB) || \ |
112 | defined(__MIPSEB) || \ |
113 | defined(__MIPSEB__) |
114 | # undef BOOST_ENDIAN_BIG_BYTE |
115 | # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
116 | # endif |
117 | #endif |
118 | |
119 | /* Built-in byte-swpped little-endian macros. |
120 | */ |
121 | #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ |
122 | !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD |
123 | # if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ |
124 | (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ |
125 | defined(__ARMEL__) || \ |
126 | defined(__THUMBEL__) || \ |
127 | defined(__AARCH64EL__) || \ |
128 | defined(_MIPSEL) || \ |
129 | defined(__MIPSEL) || \ |
130 | defined(__MIPSEL__) || \ |
131 | defined(__riscv) |
132 | # undef BOOST_ENDIAN_LITTLE_BYTE |
133 | # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
134 | # endif |
135 | #endif |
136 | |
137 | /* Some architectures are strictly one endianess (as opposed |
138 | * the current common bi-endianess). |
139 | */ |
140 | #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ |
141 | !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD |
142 | # include <boost/predef/architecture.h> |
143 | # if BOOST_ARCH_M68K || \ |
144 | BOOST_ARCH_PARISC || \ |
145 | BOOST_ARCH_SPARC || \ |
146 | BOOST_ARCH_SYS370 || \ |
147 | BOOST_ARCH_SYS390 || \ |
148 | BOOST_ARCH_Z |
149 | # undef BOOST_ENDIAN_BIG_BYTE |
150 | # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
151 | # endif |
152 | # if BOOST_ARCH_IA64 || \ |
153 | BOOST_ARCH_X86 || \ |
154 | BOOST_ARCH_BLACKFIN |
155 | # undef BOOST_ENDIAN_LITTLE_BYTE |
156 | # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
157 | # endif |
158 | #endif |
159 | |
160 | /* Windows on ARM, if not otherwise detected/specified, is always |
161 | * byte-swaped little-endian. |
162 | */ |
163 | #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ |
164 | !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD |
165 | # if BOOST_ARCH_ARM |
166 | # include <boost/predef/os/windows.h> |
167 | # if BOOST_OS_WINDOWS |
168 | # undef BOOST_ENDIAN_LITTLE_BYTE |
169 | # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE |
170 | # endif |
171 | # endif |
172 | #endif |
173 | |
174 | #if BOOST_ENDIAN_BIG_BYTE |
175 | # define BOOST_ENDIAN_BIG_BYTE_AVAILABLE |
176 | #endif |
177 | #if BOOST_ENDIAN_BIG_WORD |
178 | # define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE |
179 | #endif |
180 | #if BOOST_ENDIAN_LITTLE_BYTE |
181 | # define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE |
182 | #endif |
183 | #if BOOST_ENDIAN_LITTLE_WORD |
184 | # define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE |
185 | #endif |
186 | |
187 | #define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian" |
188 | #define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian" |
189 | #define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian" |
190 | #define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian" |
191 | |
192 | #endif |
193 | |
194 | #include <boost/predef/detail/test.h> |
195 | BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) |
196 | |
197 | #include <boost/predef/detail/test.h> |
198 | BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) |
199 | |
200 | #include <boost/predef/detail/test.h> |
201 | BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) |
202 | |
203 | #include <boost/predef/detail/test.h> |
204 | BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) |
205 | |