#pragma once #include "Result.hpp" #include "../DefaultInclude.hpp" #include #include #include #include #include #include #include // for some reason std::filesystem::path doesn't have std::hash defined in C++17 // and ghc seems to have inherited this limitation template<> struct std::hash { std::size_t operator()(ghc::filesystem::path const& path) const noexcept { return ghc::filesystem::hash_value(path); } }; namespace geode { using ByteVector = std::vector; template ByteVector toByteArray(T const& a) { ByteVector out; out.resize(sizeof(T)); std::memcpy(out.data(), &a, sizeof(T)); return out; } template struct TypeIdentity { using type = T; }; template using TypeIdentityType = typename TypeIdentity::type; namespace utils { // helper for std::visit template struct makeVisitor : Ts... { using Ts::operator()...; }; template makeVisitor(Ts...) -> makeVisitor; template constexpr T getOr(std::variant const& variant, T const& defValue) { return std::holds_alternative(variant) ? std::get(variant) : defValue; } constexpr unsigned int hash(char const* str, int h = 0) { return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h]; } constexpr unsigned int hash(wchar_t const* str, int h = 0) { return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h]; } constexpr size_t operator"" _h(char const* txt, size_t) { return geode::utils::hash(txt); } constexpr size_t operator"" _h(wchar_t const* txt, size_t) { return geode::utils::hash(txt); } template constexpr const T& clamp(const T& value, const T& minValue, const T& maxValue) { return value < minValue ? minValue : maxValue < value ? maxValue : value; } // from https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf template std::string strfmt(std::string const& format, Args... args) { int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' if (size_s <= 0) { throw std::runtime_error("Error during formatting."); } auto size = static_cast(size_s); auto buf = std::make_unique(size); std::snprintf(buf.get(), size, format.c_str(), args...); return std::string(buf.get(), buf.get() + size - 1); } /** * Format a string * @returns Pointer to char array. MAKE SURE TO CALL DELETE[]! */ template char const* cstrfmt(char const* fmt, Args... args) { auto str = strfmt(fmt, args...); char* ptr = new char[str.size() + 1]; strcpy_s(ptr, str.c_str()); return ptr; } template std::string intToHex(T i) { std::stringstream stream; stream << std::showbase << std::setbase(16) << (uint64_t)i; return stream.str(); } /** * Turn a number into a string, with support for specifying precision * (unlike std::to_string). * @param num Number to convert to string * @param precision Precision of the converted number * @returns Number as string */ template std::string numToString(Num num, size_t precision = 0) { std::stringstream ss; if (precision) { ss << std::fixed << std::setprecision(precision); } ss << num; return ss.str(); } GEODE_DLL std::string timePointAsString(std::chrono::system_clock::time_point const& tp); } } template<> struct matjson::Serialize { static matjson::Value to_json(geode::ByteVector const& bytes) { return matjson::Array(bytes.begin(), bytes.end()); } }; namespace geode::utils::clipboard { GEODE_DLL bool write(std::string const& data); GEODE_DLL std::string read(); } namespace geode::utils::game { GEODE_DLL void exit(); GEODE_DLL void restart(); GEODE_DLL void launchLoaderUninstaller(bool deleteSaveData); } namespace geode::utils::thread { GEODE_DLL std::string getName(); GEODE_DLL std::string getDefaultName(); GEODE_DLL void setName(std::string const& name); }