Textractor/include/common.h

119 lines
2.9 KiB
C
Raw Permalink Normal View History

2018-08-22 12:24:55 -04:00
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string>
#include <vector>
#include <deque>
2019-02-09 00:30:38 -05:00
#include <array>
2018-08-22 12:24:55 -04:00
#include <unordered_map>
2018-11-04 21:19:00 -05:00
#include <unordered_set>
2018-08-22 12:24:55 -04:00
#include <functional>
#include <algorithm>
2018-11-04 21:19:00 -05:00
#include <regex>
#include <memory>
#include <optional>
2018-08-22 12:24:55 -04:00
#include <thread>
2018-08-23 11:53:23 -04:00
#include <mutex>
2019-01-23 13:59:34 -05:00
#include <shared_mutex>
2019-02-09 00:30:38 -05:00
#include <atomic>
2018-09-20 21:59:07 -04:00
#include <cstdint>
2018-12-26 23:56:42 -05:00
#include <cassert>
2019-02-18 23:12:12 -05:00
2019-05-31 14:48:07 -04:00
#ifdef _WIN64
constexpr bool x64 = true;
#else
constexpr bool x64 = false;
#endif
#define MESSAGE(text) MessageBoxW(NULL, text, L"Textractor", MB_OK)
2019-06-04 23:12:45 -04:00
#define CRITIAL_SECTION static std::mutex m; std::scoped_lock l(m)
2019-05-31 14:48:07 -04:00
2019-02-18 23:12:12 -05:00
template <typename T> using Array = T[];
2019-08-07 05:18:04 -04:00
template <auto F> using Functor = std::integral_constant<std::decay_t<decltype(F)>, F>;
template <typename V>
struct Identity { V operator()(V v) const { return v; } };
struct PermissivePointer
{
template <typename T>
operator T*() { return (T*)p; }
void* p;
};
template <typename HandleCloser = Functor<CloseHandle>>
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<void, HandleCleaner> h;
};
2019-06-10 01:49:11 -04:00
template<typename T, typename M = std::mutex>
2019-06-04 23:12:45 -04:00
class Synchronized
2019-02-18 23:12:12 -05:00
{
public:
template <typename... Args>
2019-06-04 23:12:45 -04:00
Synchronized(Args&&... args) : contents(std::forward<Args>(args)...) {}
struct Locker
2019-02-18 23:12:12 -05:00
{
2019-06-10 01:49:11 -04:00
T* operator->() { return &contents; }
2019-06-04 23:12:45 -04:00
std::unique_lock<M> lock;
2019-06-10 01:49:11 -04:00
T& contents;
2019-06-04 23:12:45 -04:00
};
2019-06-10 01:49:11 -04:00
Locker Acquire() { return { std::unique_lock(m), contents }; }
2019-06-04 23:12:45 -04:00
Locker operator->() { return Acquire(); }
2019-02-18 23:12:12 -05:00
private:
2019-06-10 01:49:11 -04:00
T contents;
M m;
2019-02-18 23:12:12 -05:00
};
2019-06-09 07:33:26 -04:00
static struct
2019-06-03 17:58:30 -04:00
{
BYTE DUMMY[100];
template <typename T>
operator T*() { static_assert(sizeof(T) < sizeof(DUMMY)); return (T*)DUMMY; }
} DUMMY;
2019-06-13 04:01:29 -04:00
template <typename T>
inline auto FormatArg(T arg) { return arg; }
template <typename C>
inline auto FormatArg(const std::basic_string<C>& arg) { return arg.c_str(); }
2019-06-01 13:59:37 -04:00
#pragma warning(push)
#pragma warning(disable: 4996)
template <typename... Args>
2019-06-29 15:43:26 +05:30
inline std::string FormatString(const char* format, const Args&... args)
2019-06-01 13:59:37 -04:00
{
2019-06-13 04:01:29 -04:00
std::string buffer(snprintf(nullptr, 0, format, FormatArg(args)...), '\0');
sprintf(buffer.data(), format, FormatArg(args)...);
2019-06-01 13:59:37 -04:00
return buffer;
}
template <typename... Args>
2019-06-29 15:43:26 +05:30
inline std::wstring FormatString(const wchar_t* format, const Args&... args)
2019-06-01 13:59:37 -04:00
{
2019-06-13 04:01:29 -04:00
std::wstring buffer(_snwprintf(nullptr, 0, format, FormatArg(args)...), L'\0');
_swprintf(buffer.data(), format, FormatArg(args)...);
2019-06-01 13:59:37 -04:00
return buffer;
}
#pragma warning(pop)
2019-02-18 23:12:12 -05:00
#ifdef _DEBUG
2019-06-13 04:01:29 -04:00
#define TEST(...) static auto _ = CreateThread(nullptr, 0, [](auto) { __VA_ARGS__; return 0UL; }, NULL, 0, nullptr);
2019-02-18 23:12:12 -05:00
#else
#define TEST(...)
#endif