#pragma once #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int BAD_CAST; } } /** Perform static_cast in release build. * Checks type by comparing typeid and throw an exception in debug build. * The exact match of the type is checked. That is, cast to the ancestor will be unsuccessful. */ template To assert_cast(From && from) { #ifndef NDEBUG try { if constexpr (std::is_pointer_v) { if (typeid(*from) == typeid(std::remove_pointer_t)) return static_cast(from); } else { if (typeid(from) == typeid(To)) return static_cast(from); } } catch (const std::exception & e) { throw DB::Exception(e.what(), DB::ErrorCodes::BAD_CAST); } throw DB::Exception("Bad cast from type " + demangle(typeid(from).name()) + " to " + demangle(typeid(To).name()), DB::ErrorCodes::BAD_CAST); #else return static_cast(from); #endif }