#pragma once #include #include #include #include namespace geode::cast { /** * Alias for static_cast */ template static constexpr T as(F const v) { return static_cast(v); } /** * Cast from anything to anything else, * provided they are the same size */ template static constexpr T union_cast(F const v) { static_assert(sizeof(F) == sizeof(T), "union_cast: R and T don't match in size!"); union { T t; F f; } x; x.f = v; return x.t; } /** * Reference casting. Does a pointer-to-pointer * cast but uses reference syntactic sugar to * look cleaner. */ template static constexpr T reference_cast(F v) { return reinterpret_cast(v); } /** * Cast based on RTTI. Casts an adjusted this pointer * to it's non offset form. */ template static constexpr T base_cast(F const obj) { return static_cast(dynamic_cast(obj)); } /** * Cast based on RTTI. This is used to check * if an object is exactly the class needed. Returns * nullptr on failure. */ template static T exact_cast(F const obj) { if (std::strcmp(typeid(*obj).name(), typeid(std::remove_pointer_t).name()) == 0) { return base_cast(obj); } return nullptr; } }