+/// compiler_info() returns a string trying to describe the compiler we use
+
+std::string compiler_info() {
+
+ #define stringify2(x) #x
+ #define stringify(x) stringify2(x)
+ #define make_version_string(major, minor, patch) stringify(major) "." stringify(minor) "." stringify(patch)
+
+/// Predefined macros hell:
+///
+/// __GNUC__ Compiler is gcc, Clang or Intel on Linux
+/// __INTEL_COMPILER Compiler is Intel
+/// _MSC_VER Compiler is MSVC or Intel on Windows
+/// _WIN32 Building on Windows (any)
+/// _WIN64 Building on Windows 64 bit
+
+ std::string compiler = "\nCompiled by ";
+
+ #ifdef __clang__
+ compiler += "clang++ ";
+ compiler += make_version_string(__clang_major__, __clang_minor__, __clang_patchlevel__);
+ #elif __INTEL_COMPILER
+ compiler += "Intel compiler ";
+ compiler += "(version ";
+ compiler += stringify(__INTEL_COMPILER) " update " stringify(__INTEL_COMPILER_UPDATE);
+ compiler += ")";
+ #elif _MSC_VER
+ compiler += "MSVC ";
+ compiler += "(version ";
+ compiler += stringify(_MSC_FULL_VER) "." stringify(_MSC_BUILD);
+ compiler += ")";
+ #elif defined(__e2k__) && defined(__LCC__)
+ #define dot_ver2(n) \
+ compiler += (char)'.'; \
+ compiler += (char)('0' + (n) / 10); \
+ compiler += (char)('0' + (n) % 10);
+
+ compiler += "MCST LCC ";
+ compiler += "(version ";
+ compiler += std::to_string(__LCC__ / 100);
+ dot_ver2(__LCC__ % 100)
+ dot_ver2(__LCC_MINOR__)
+ compiler += ")";
+ #elif __GNUC__
+ compiler += "g++ (GNUC) ";
+ compiler += make_version_string(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+ #else
+ compiler += "Unknown compiler ";
+ compiler += "(unknown version)";
+ #endif
+
+ #if defined(__APPLE__)
+ compiler += " on Apple";
+ #elif defined(__CYGWIN__)
+ compiler += " on Cygwin";
+ #elif defined(__MINGW64__)
+ compiler += " on MinGW64";
+ #elif defined(__MINGW32__)
+ compiler += " on MinGW32";
+ #elif defined(__ANDROID__)
+ compiler += " on Android";
+ #elif defined(__linux__)
+ compiler += " on Linux";
+ #elif defined(_WIN64)
+ compiler += " on Microsoft Windows 64-bit";
+ #elif defined(_WIN32)
+ compiler += " on Microsoft Windows 32-bit";
+ #else
+ compiler += " on unknown system";
+ #endif
+
+ compiler += "\nCompilation settings include: ";
+ compiler += (Is64Bit ? " 64bit" : " 32bit");
+ #if defined(USE_VNNI)
+ compiler += " VNNI";
+ #endif
+ #if defined(USE_AVX512)
+ compiler += " AVX512";
+ #endif
+ compiler += (HasPext ? " BMI2" : "");
+ #if defined(USE_AVX2)
+ compiler += " AVX2";
+ #endif
+ #if defined(USE_SSE41)
+ compiler += " SSE41";
+ #endif
+ #if defined(USE_SSSE3)
+ compiler += " SSSE3";
+ #endif
+ #if defined(USE_SSE2)
+ compiler += " SSE2";
+ #endif
+ compiler += (HasPopCnt ? " POPCNT" : "");
+ #if defined(USE_MMX)
+ compiler += " MMX";
+ #endif
+ #if defined(USE_NEON)
+ compiler += " NEON";
+ #endif
+
+ #if !defined(NDEBUG)
+ compiler += " DEBUG";
+ #endif
+
+ compiler += "\n__VERSION__ macro expands to: ";
+ #ifdef __VERSION__
+ compiler += __VERSION__;
+ #else
+ compiler += "(undefined macro)";
+ #endif
+ compiler += "\n";
+
+ return compiler;
+}
+
+