Skip to content

Commit

Permalink
C++ - extend endianess detection
Browse files Browse the repository at this point in the history
  • Loading branch information
K0lb3 committed Mar 7, 2025
1 parent 89dd1ac commit b2b8317
Showing 1 changed file with 64 additions and 28 deletions.
92 changes: 64 additions & 28 deletions src/Texture2DDecoder/endianness.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,76 @@

/* Detect platform endianness at compile time */

// If boost were available on all platforms, could use this instead to detect endianness
// #include <boost/predef/endian.h>

// When available, these headers can improve platform endianness detection
#ifdef __has_include // C++17, supported as extension to C++11 in clang, GCC 5+, vs2015
#if __has_include(<endian.h>)
#include <endian.h> // gnu libc normally provides, linux
#elif __has_include(<machine/endian.h>)
#include <machine/endian.h> //open bsd, macos
#elif __has_include(<sys/param.h>)
#include <sys/param.h> // mingw, some bsd (not open/macos)
#elif __has_include(<sys/isadefs.h>)
#include <sys/isadefs.h> // solaris
#endif
// Cross-platform header discovery using __has_include
#ifdef __has_include
# if __has_include(<endian.h>)
# include <endian.h> // GLIBC (Linux), BSDs
# elif __has_include(<sys/endian.h>)
# include <sys/endian.h> // OpenBSD, newer macOS
# elif __has_include(<machine/endian.h>)
# include <machine/endian.h> // Older macOS, BSD variants
# elif __has_include(<sys/param.h>)
# include <sys/param.h> // MinGW, some BSDs
# elif __has_include(<sys/isadefs.h>)
# include <sys/isadefs.h> // Solaris
# endif
#endif

// Comprehensive endianness detection
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
(defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || (defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN) || \
(defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || (defined(__sun) && defined(__SVR4) && defined(_BIG_ENDIAN)) || \
defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || \
defined(__MIBSEB__) || defined(_M_PPC)

/* Big Endian Detection */
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ // GCC/Clang
(defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || \ // GLIBC
(defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN) || \ // BSD
(defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || \ // MinGW/others
(defined(__sun) && defined(__SVR4) && defined(_BIG_ENDIAN)) || \ // Solaris
defined(__ARMEB__) || defined(__THUMBEB__) || \ // ARM big-endian
defined(__AARCH64EB__) || \ // ARM64 big-endian
defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \ // MIPS big-endian
defined(__PPC__) || defined(__PPC64__) || \ // PowerPC
defined(__sparc__) || defined(__sparc) || \ // SPARC
defined(__s390__) || defined(__s390x__) || \ // IBM zSeries
defined(__hppa__) || defined(__HPPA__) || \ // HP PA-RISC
defined(_M_PPC) || defined(_ARCH_PPC) || \ // PowerPC (MSVC)
defined(__BIG_ENDIAN__) || \ // Some compilers
defined(__TCS__) || \ // Tandem
defined(_AIX) || defined(__TOS_AIX__) || \ // AIX
defined(__m68k__) || defined(__MC68K__) || \ // Motorola 68k
defined(__ICL) // Intel Compiler (BE mode)
#define __BIG_ENDIAN__
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || /* gcc */ \
(defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) /* linux header */ || \
(defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN) || \
(defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) /* mingw header */ || \
(defined(__sun) && defined(__SVR4) && defined(_LITTLE_ENDIAN)) || /* solaris */ \
defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || \
defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64) || /* msvc for intel processors */ \
defined(_M_ARM) /* msvc code on arm executes in little endian mode */

/* Little Endian Detection */
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ // GCC/Clang
(defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ // GLIBC
(defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN) || \ // BSD
(defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || \ // MinGW/others
(defined(__sun) && defined(__SVR4) && defined(_LITTLE_ENDIAN)) || \ // Solaris
defined(__ARMEL__) || defined(__THUMBEL__) || \ // ARM LE
defined(__AARCH64EL__) || \ // ARM64 LE
defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || \ // MIPS LE
defined(__i386__) || defined(__x86_64__) || \ // x86
defined(__ia64__) || defined(__IA64__) || \ // Itanium
defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64) || \ // MSVC x86
defined(_M_ARM) || defined(_M_ARM64) || \ // MSVC ARM
defined(__alpha__) || \ // DEC Alpha
defined(__riscv) || \ // RISC-V
defined(__LITTLE_ENDIAN__) || \ // Some compilers
defined(__amd64__) || defined(__amd64) || \ // AMD64
defined(__e2k__) || \ // Elbrus
defined(__MICROBLAZE__) || \ // MicroBlaze
defined(__ARCEL__) || \ // ARC LE
defined(_WIN32) || defined(_WIN64) // Windows
#define __LITTLE_ENDIAN__

/* Universal Fallback */
#else
# warning "Cannot detect endianness! Assuming little-endian."
# define __LITTLE_ENDIAN__ // Most modern systems are little-endian
#endif
#endif

#endif // !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#endif // _ENDIANNESS_H

#ifdef bswap16
#undef bswap16
Expand Down

0 comments on commit b2b8317

Please sign in to comment.