#pragma once #include #include #include #include #include #include #include namespace Utils { enum IoMode { Read, WriteTruncate, WriteAppend, }; FILE* OpenCstdioFile(const std::filesystem::path& path, IoMode mode, bool binary = false); FILE* OpenCstdioFile(const char* path, IoMode mode, bool binary = false); std::string ReadFileAsString(const std::filesystem::path& path); constexpr float Abs(float v) noexcept { return v < 0.0f ? -v : v; } bool InRangeInclusive(int n, int lower, int upper); bool LineContains(glm::ivec2 p1, glm::ivec2 p2, glm::ivec2 candidate); bool IsColinear(glm::ivec2 p1, glm::ivec2 p2); template void HashCombine(std::size_t& seed, const T& v) { seed ^= std::hash{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } std::string MakeRandomNumberedName(const char* tag); } // namespace Utils struct StringHash { using is_transparent = void; std::size_t operator()(const std::string& key) const { return robin_hood::hash_bytes(key.c_str(), key.size()); } std::size_t operator()(std::string_view key) const { return robin_hood::hash_bytes(key.data(), key.size()); } std::size_t operator()(const char* key) const { return robin_hood::hash_bytes(key, std::strlen(key)); } }; struct StringEqual { using is_transparent = int; bool operator()(std::string_view lhs, const std::string& rhs) const { const std::string_view view = rhs; return lhs == view; } bool operator()(const char* lhs, const std::string& rhs) const { return std::strcmp(lhs, rhs.c_str()) == 0; } bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; } };