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/os/android.h> 17 18 /*` 19 [heading `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 */ 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> 194 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) 195 196 #include <boost/predef/detail/test.h> 197 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) 198 199 #include <boost/predef/detail/test.h> 200 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) 201 202 #include <boost/predef/detail/test.h> 203 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) 204