#ifndef UTIL_H #define UTIL_H #include #include #include #include #include #define CONCAT_IMPL(a, b) a##b #define CONCAT(a, b) CONCAT_IMPL(a, b) #define _ CONCAT(unused_, __LINE__) inline size_t Min(size_t a, size_t b) { return a < b? a: b; } inline int Cmp(const int a, const int b) { if (a == b) return 0; if (a > b) return 1; return -1; } /* Generic RAII type. */ template struct Managed { T obj; Managed(T obj) : obj(obj) { if (obj == reinterpret_cast(E)) throw U(); } ~Managed() { F(obj); } operator T() { return obj; } auto& operator *() { return *obj; } auto& operator ->() { return obj; } auto& operator [](size_t i) { return obj[i]; } }; /* Buf is a span-like structure of a buffer and its size. */ template struct Buf { T* data; size_t size; Buf(T* data, size_t size) : data(data), size(size) {} Buf(std::basic_string& s) : data(s.data()), size(s.capacity()) {} template Buf(T (&data)[N]) : data(data), size(N) {} operator T*() { return data; } T& operator *() { return *data; } T& operator [](size_t i) { return data[i]; } }; /* Format wide string. */ template inline int Swprintf(Buf buf, const wchar_t* const fmt, T... xs) { return _snwprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...); } /* Format static narrow string. */ template inline int Sprintf(Buf buf, const char* const fmt, T... xs) { return _snprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...); } /* Copy to static wide string buffer. */ inline wchar_t* Wcscpy(Buf dst, const wchar_t* const src) { const size_t len = Min(dst.size, wcslen(src)+1); memcpy(dst, src, len*sizeof(wchar_t)); dst[len-1] = 0; return dst; } /* Copy to static narrow string buffer. */ inline char* Strcpy(Buf dst, const char* const src) { const size_t len = Min(dst.size, strlen(src)+1); memcpy(dst, src, len); dst[len-1] = 0; return dst; } #endif