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/os/android.h>
17
18/*`
19[heading `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 */
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_OS_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# undef BOOST_ENDIAN_LITTLE_BYTE
132# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
133# endif
134#endif
135
136/* Some architectures are strictly one endianess (as opposed
137 * the current common bi-endianess).
138 */
139#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
140 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
141# include <boost/predef/architecture.h>
142# if BOOST_ARCH_M68K || \
143 BOOST_ARCH_PARISC || \
144 BOOST_ARCH_SPARC || \
145 BOOST_ARCH_SYS370 || \
146 BOOST_ARCH_SYS390 || \
147 BOOST_ARCH_Z
148# undef BOOST_ENDIAN_BIG_BYTE
149# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
150# endif
151# if BOOST_ARCH_IA64 || \
152 BOOST_ARCH_X86 || \
153 BOOST_ARCH_BLACKFIN
154# undef BOOST_ENDIAN_LITTLE_BYTE
155# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
156# endif
157#endif
158
159/* Windows on ARM, if not otherwise detected/specified, is always
160 * byte-swaped little-endian.
161 */
162#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
163 !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
164# if BOOST_ARCH_ARM
165# include <boost/predef/os/windows.h>
166# if BOOST_OS_WINDOWS
167# undef BOOST_ENDIAN_LITTLE_BYTE
168# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
169# endif
170# endif
171#endif
172
173#if BOOST_ENDIAN_BIG_BYTE
174# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE
175#endif
176#if BOOST_ENDIAN_BIG_WORD
177# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
178#endif
179#if BOOST_ENDIAN_LITTLE_BYTE
180# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
181#endif
182#if BOOST_ENDIAN_LITTLE_WORD
183# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE
184#endif
185
186#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian"
187#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian"
188#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
189#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
190
191#endif
192
193#include <boost/predef/detail/test.h>
194BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME)
195
196#include <boost/predef/detail/test.h>
197BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME)
198
199#include <boost/predef/detail/test.h>
200BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME)
201
202#include <boost/predef/detail/test.h>
203BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME)
204