#pragma once #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN64 constexpr bool x64 = true; #else constexpr bool x64 = false; #endif template struct ArrayImpl { using type = std::tuple[]; }; template struct ArrayImpl { using type = T[]; }; template using Array = typename ArrayImpl::type; template using Functor = std::integral_constant, F>; template struct Identity { V operator()(V v) const { return v; } }; struct PermissivePointer { template operator T*() { return (T*)p; } void* p; }; template > class AutoHandle { public: AutoHandle(HANDLE h) : h(h) {} operator HANDLE() { return h.get(); } PHANDLE operator&() { static_assert(sizeof(*this) == sizeof(HANDLE)); assert(!h); return (PHANDLE)this; } operator bool() { return h.get() != NULL && h.get() != INVALID_HANDLE_VALUE; } private: struct HandleCleaner { void operator()(void* h) { if (h != INVALID_HANDLE_VALUE) HandleCloser()(PermissivePointer{ h }); } }; std::unique_ptr h; }; template class Synchronized { public: template Synchronized(Args&&... args) : contents(std::forward(args)...) {} struct Locker { T* operator->() { return &contents; } std::unique_lock lock; T& contents; }; Locker Acquire() { return { std::unique_lock(m), contents }; } Locker operator->() { return Acquire(); } private: T contents; M m; }; static struct { BYTE DUMMY[100]; template operator T*() { static_assert(sizeof(T) < sizeof(DUMMY)); return (T*)DUMMY; } } DUMMY; template inline auto FormatArg(T arg) { return arg; } template inline auto FormatArg(const std::basic_string& arg) { return arg.c_str(); } #pragma warning(push) #pragma warning(disable: 4996) template inline std::string FormatString(const char* format, const Args&... args) { std::string buffer(snprintf(nullptr, 0, format, FormatArg(args)...), '\0'); sprintf(buffer.data(), format, FormatArg(args)...); return buffer; } template inline std::wstring FormatString(const wchar_t* format, const Args&... args) { std::wstring buffer(_snwprintf(nullptr, 0, format, FormatArg(args)...), L'\0'); _swprintf(buffer.data(), format, FormatArg(args)...); return buffer; } #pragma warning(pop) template inline void TEXTRACTOR_MESSAGE(const wchar_t* format, const Args&... args) { MessageBoxW(NULL, FormatString(format, args...).c_str(), L"Textractor", MB_OK); } #ifdef _DEBUG #define TEST(...) static auto _ = CreateThread(nullptr, 0, [](auto) { __VA_ARGS__; return 0UL; }, NULL, 0, nullptr); #else #define TEST(...) #endif