2018-11-26 16:20:40 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Common/typeid_cast.h>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2021-09-11 20:14:34 +00:00
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
template <typename Typelist, size_t ...I>
|
|
|
|
static bool castTypeToEither(const auto * type, auto && f, std::index_sequence<I...>)
|
|
|
|
{
|
|
|
|
return (
|
|
|
|
(typeid_cast<const typename Typelist::template At<I> *>(type)
|
|
|
|
? std::forward<decltype(f)>(f)(
|
|
|
|
*typeid_cast<const typename Typelist::template At<I> *>(type))
|
|
|
|
: false)
|
|
|
|
|| ...);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 15:42:40 +00:00
|
|
|
template <typename... Ts, typename T, typename F>
|
|
|
|
static bool castTypeToEither(const T * type, F && f)
|
2018-11-26 16:20:40 +00:00
|
|
|
{
|
|
|
|
/// XXX can't use && here because gcc-7 complains about parentheses around && within ||
|
|
|
|
return ((typeid_cast<const Ts *>(type) ? f(*typeid_cast<const Ts *>(type)) : false) || ...);
|
|
|
|
}
|
|
|
|
|
2021-09-11 20:14:34 +00:00
|
|
|
/// Use Common/TypeList as template argument
|
|
|
|
template <class Typelist>
|
|
|
|
static constexpr bool castTypeToEitherTL(const auto * type, auto && f)
|
|
|
|
{
|
|
|
|
return detail::castTypeToEither<Typelist>(
|
|
|
|
type, std::forward<decltype(f)>(f),
|
|
|
|
std::make_index_sequence<Typelist::size>());
|
|
|
|
}
|
2018-11-26 16:20:40 +00:00
|
|
|
}
|