#pragma once // ReSharper disable once CppUnusedIncludeDirective #include "global_macros.hpp" #include #include #include #include #include // ReSharper disable once CppUnusedIncludeDirective #include namespace cru { template struct type_tag {}; //typedefs using String = std::wstring; using MultiByteString = std::string; using StringView = std::wstring_view; using MultiByteStringView = std::string_view; using FloatSecond = std::chrono::duration; enum class FlowControl { Continue, Break }; class Object { public: Object() = default; Object(const Object&) = default; Object& operator = (const Object&) = default; Object(Object&&) = default; Object& operator = (Object&&) = default; virtual ~Object() = default; }; struct Interface { virtual ~Interface() = default; }; [[noreturn]] inline void UnreachableCode() { throw std::logic_error("Unreachable code."); } MultiByteString ToUtf8String(const StringView& string); inline void Require(const bool condition, const MultiByteStringView& error_message) { if (!condition) throw std::invalid_argument(error_message.data()); } template >> float Coerce(const T n, const std::optional min, const std::optional max) { if (min.has_value() && n < min.value()) return min.value(); if (max.has_value() && n > max.value()) return max.value(); return n; } template >> float Coerce(const T n, const std::nullopt_t, const std::optional max) { if (max.has_value() && n > max.value()) return max.value(); return n; } template >> float Coerce(const T n, const std::optional min, const std::nullopt_t) { if (min.has_value() && n < min.value()) return min.value(); return n; } }