Chris@16: /* Chris@101: Copyright Rene Rivera 2013-2014 Chris@16: Distributed under the Boost Software License, Version 1.0. Chris@16: (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_PREDEF_ENDIAN_H Chris@16: #define BOOST_PREDEF_ENDIAN_H Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: /*` Chris@16: [heading `BOOST_ENDIAN_*`] Chris@16: Chris@16: Detection of endian memory ordering. There are four defined macros Chris@16: in this header that define the various generally possible endian Chris@16: memory orderings: Chris@16: Chris@16: * `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian. Chris@16: * `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian. Chris@16: * `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian. Chris@16: * `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian. Chris@16: Chris@16: The detection is conservative in that it only identifies endianness Chris@16: that it knows for certain. In particular bi-endianness is not Chris@16: indicated as is it not practically possible to determine the Chris@16: endianness from anything but an operating system provided Chris@16: header. And the currently known headers do not define that Chris@16: programatic bi-endianness is available. Chris@16: Chris@16: This implementation is a compilation of various publicly available Chris@16: information and acquired knowledge: Chris@16: Chris@16: # The indispensable documentation of "Pre-defined Compiler Macros" Chris@16: [@http://sourceforge.net/p/predef/wiki/Endianness Endianness]. Chris@16: # The various endian specifications available in the Chris@16: [@http://wikipedia.org/ Wikipedia] computer architecture pages. Chris@16: # Generally available searches for headers that define endianness. Chris@16: */ Chris@16: Chris@16: #define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE Chris@16: #define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE Chris@16: #define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE Chris@16: #define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE Chris@16: Chris@16: /* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER. Chris@16: * And some OSs provide some for of endian header also. Chris@16: */ Chris@16: #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ Chris@16: !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD Chris@101: # if BOOST_LIB_C_GNU || BOOST_OS_ANDROID Chris@16: # include Chris@16: # else Chris@16: # if BOOST_OS_MACOS Chris@16: # include Chris@16: # else Chris@16: # if BOOST_OS_BSD Chris@16: # if BOOST_OS_BSD_OPEN Chris@16: # include Chris@16: # else Chris@16: # include Chris@16: # endif Chris@16: # endif Chris@16: # endif Chris@16: # endif Chris@16: # if defined(__BYTE_ORDER) Chris@101: # if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) Chris@16: # undef BOOST_ENDIAN_BIG_BYTE Chris@16: # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@101: # if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) Chris@16: # undef BOOST_ENDIAN_LITTLE_BYTE Chris@16: # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@101: # if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN) Chris@16: # undef BOOST_ENDIAN_LITTLE_WORD Chris@16: # define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: # endif Chris@16: # if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER) Chris@101: # if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) Chris@16: # undef BOOST_ENDIAN_BIG_BYTE Chris@16: # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@101: # if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) Chris@16: # undef BOOST_ENDIAN_LITTLE_BYTE Chris@16: # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@101: # if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN) Chris@16: # undef BOOST_ENDIAN_LITTLE_WORD Chris@16: # define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: /* Built-in byte-swpped big-endian macros. Chris@16: */ Chris@16: #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ Chris@16: !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD Chris@101: # if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ Chris@101: (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \ Chris@101: defined(__ARMEB__) || \ Chris@101: defined(__THUMBEB__) || \ Chris@101: defined(__AARCH64EB__) || \ Chris@101: defined(_MIPSEB) || \ Chris@101: defined(__MIPSEB) || \ Chris@101: defined(__MIPSEB__) Chris@101: # undef BOOST_ENDIAN_BIG_BYTE Chris@101: # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: /* Built-in byte-swpped little-endian macros. Chris@16: */ Chris@16: #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ Chris@16: !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD Chris@101: # if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ Chris@101: (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ Chris@101: defined(__ARMEL__) || \ Chris@101: defined(__THUMBEL__) || \ Chris@101: defined(__AARCH64EL__) || \ Chris@101: defined(_MIPSEL) || \ Chris@101: defined(__MIPSEL) || \ Chris@101: defined(__MIPSEL__) Chris@101: # undef BOOST_ENDIAN_LITTLE_BYTE Chris@101: # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: /* Some architectures are strictly one endianess (as opposed Chris@16: * the current common bi-endianess). Chris@16: */ Chris@16: #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ Chris@16: !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD Chris@16: # include Chris@16: # if BOOST_ARCH_M68K || \ Chris@16: BOOST_ARCH_PARISK || \ Chris@101: BOOST_ARCH_SPARC || \ Chris@16: BOOST_ARCH_SYS370 || \ Chris@16: BOOST_ARCH_SYS390 || \ Chris@16: BOOST_ARCH_Z Chris@16: # undef BOOST_ENDIAN_BIG_BYTE Chris@16: # define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: # if BOOST_ARCH_AMD64 || \ Chris@16: BOOST_ARCH_IA64 || \ Chris@16: BOOST_ARCH_X86 || \ Chris@16: BOOST_ARCH_BLACKFIN Chris@16: # undef BOOST_ENDIAN_LITTLE_BYTE Chris@16: # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: /* Windows on ARM, if not otherwise detected/specified, is always Chris@16: * byte-swaped little-endian. Chris@16: */ Chris@16: #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ Chris@16: !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD Chris@16: # if BOOST_ARCH_ARM Chris@16: # include Chris@16: # if BOOST_OS_WINDOWS Chris@16: # undef BOOST_ENDIAN_LITTLE_BYTE Chris@16: # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE Chris@16: # endif Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: #if BOOST_ENDIAN_BIG_BYTE Chris@16: # define BOOST_ENDIAN_BIG_BYTE_AVAILABLE Chris@16: #endif Chris@16: #if BOOST_ENDIAN_BIG_WORD Chris@16: # define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE Chris@16: #endif Chris@16: #if BOOST_ENDIAN_LITTLE_BYTE Chris@16: # define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE Chris@16: #endif Chris@16: #if BOOST_ENDIAN_LITTLE_WORD Chris@16: # define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE Chris@16: #endif Chris@16: Chris@16: #define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian" Chris@16: #define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian" Chris@16: #define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian" Chris@16: #define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian" Chris@16: Chris@16: #include Chris@16: BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) Chris@16: Chris@16: #include Chris@16: BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) Chris@16: Chris@16: #include Chris@16: BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) Chris@16: Chris@16: #include Chris@16: BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) Chris@16: Chris@16: Chris@16: #endif