+#include "misc.h"
+
+#ifdef _WIN32
+ #if _WIN32_WINNT < 0x0601
+ #undef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0601 // Force to include needed API prototypes
+ #endif
+
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+
+ #include <windows.h>
+// The needed Windows API for processor groups could be missed from old Windows
+// versions, so instead of calling them directly (forcing the linker to resolve
+// the calls at compile time), try to load them at runtime. To do this we need
+// first to define the corresponding function pointers.
+extern "C" {
+using fun1_t = bool (*)(LOGICAL_PROCESSOR_RELATIONSHIP,
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX,
+ PDWORD);
+using fun2_t = bool (*)(USHORT, PGROUP_AFFINITY);
+using fun3_t = bool (*)(HANDLE, CONST GROUP_AFFINITY*, PGROUP_AFFINITY);
+using fun4_t = bool (*)(USHORT, PGROUP_AFFINITY, USHORT, PUSHORT);
+using fun5_t = WORD (*)();
+using fun6_t = bool (*)(HANDLE, DWORD, PHANDLE);
+using fun7_t = bool (*)(LPCSTR, LPCSTR, PLUID);
+using fun8_t = bool (*)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
+}
+#endif
+
+#include <atomic>
+#include <cmath>
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <mutex>
+#include <sstream>
+#include <string_view>
+
+#include "types.h"
+
+#if defined(__linux__) && !defined(__ANDROID__)
+ #include <sys/mman.h>
+#endif
+
+#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) \
+ || (defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) && !defined(_WIN32)) \
+ || defined(__e2k__)
+ #define POSIXALIGNEDALLOC
+ #include <stdlib.h>
+#endif
+
+namespace Stockfish {
+
+namespace {
+
+// Version number or dev.
+constexpr std::string_view version = "dev";
+
+// Our fancy logging facility. The trick here is to replace cin.rdbuf() and
+// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We
+// can toggle the logging of std::cout and std:cin at runtime whilst preserving
+// usual I/O functionality, all without changing a single line of code!
+// Idea from http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81
+
+struct Tie: public std::streambuf { // MSVC requires split streambuf for cin and cout
+
+ Tie(std::streambuf* b, std::streambuf* l) :
+ buf(b),
+ logBuf(l) {}
+
+ int sync() override { return logBuf->pubsync(), buf->pubsync(); }
+ int overflow(int c) override { return log(buf->sputc(char(c)), "<< "); }
+ int underflow() override { return buf->sgetc(); }
+ int uflow() override { return log(buf->sbumpc(), ">> "); }
+
+ std::streambuf *buf, *logBuf;
+
+ int log(int c, const char* prefix) {
+
+ static int last = '\n'; // Single log file
+
+ if (last == '\n')
+ logBuf->sputn(prefix, 3);
+
+ return last = logBuf->sputc(char(c));
+ }
+};
+
+class Logger {
+
+ Logger() :
+ in(std::cin.rdbuf(), file.rdbuf()),
+ out(std::cout.rdbuf(), file.rdbuf()) {}
+ ~Logger() { start(""); }
+
+ std::ofstream file;
+ Tie in, out;
+
+ public:
+ static void start(const std::string& fname) {
+
+ static Logger l;
+
+ if (l.file.is_open())
+ {
+ std::cout.rdbuf(l.out.buf);
+ std::cin.rdbuf(l.in.buf);
+ l.file.close();
+ }
+
+ if (!fname.empty())
+ {
+ l.file.open(fname, std::ifstream::out);
+
+ if (!l.file.is_open())
+ {
+ std::cerr << "Unable to open debug log file " << fname << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ std::cin.rdbuf(&l.in);
+ std::cout.rdbuf(&l.out);
+ }
+ }
+};