Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 37 additions & 17 deletions be/src/core/column/column.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,33 +795,53 @@ struct IsMutableColumns<> {
};

// prefer assert_cast than check_and_get
template <typename Type>
const Type* check_and_get_column(const IColumn& column) {
return typeid_cast<const Type*>(&column);
template <typename Type, typename From>
const Type* check_and_get_column(const From& column) {
using FromType = std::remove_cv_t<From>;
static_assert(std::is_base_of_v<IColumn, FromType>,
"check_and_get_column requires an IColumn-derived source type");
static_assert(!std::is_same_v<std::remove_cv_t<Type>, FromType>,
"check_and_get_column is redundant for the same column type");
return typeid_cast<const Type*>(static_cast<const IColumn*>(&column));
}

template <typename Type>
Type* check_and_get_column(IColumn& column) {
return typeid_cast<Type*>(&column);
template <typename Type, typename From>
Type* check_and_get_column(From& column) {
using FromType = std::remove_cv_t<From>;
static_assert(std::is_base_of_v<IColumn, FromType>,
"check_and_get_column requires an IColumn-derived source type");
static_assert(!std::is_same_v<std::remove_cv_t<Type>, FromType>,
"check_and_get_column is redundant for the same column type");
return typeid_cast<Type*>(static_cast<IColumn*>(&column));
}

template <typename Type>
const Type* check_and_get_column(const IColumn* column) {
return typeid_cast<const Type*>(column);
template <typename Type, typename From>
const Type* check_and_get_column(const From* column) {
using FromType = std::remove_cv_t<From>;
static_assert(std::is_base_of_v<IColumn, FromType>,
"check_and_get_column requires an IColumn-derived source type");
static_assert(!std::is_same_v<std::remove_cv_t<Type>, FromType>,
"check_and_get_column is redundant for the same column type");
return typeid_cast<const Type*>(static_cast<const IColumn*>(column));
}

template <typename Type>
Type* check_and_get_column(IColumn* column) {
return typeid_cast<Type*>(column);
template <typename Type, typename From>
Type* check_and_get_column(From* column) {
using FromType = std::remove_cv_t<From>;
static_assert(std::is_base_of_v<IColumn, FromType>,
"check_and_get_column requires an IColumn-derived source type");
static_assert(!std::is_same_v<std::remove_cv_t<Type>, FromType>,
"check_and_get_column is redundant for the same column type");
return typeid_cast<Type*>(static_cast<IColumn*>(column));
}

template <typename Type>
bool is_column(const IColumn& column) {
return check_and_get_column<Type>(&column);
template <typename Type, typename From>
bool is_column(const From& column) {
return check_and_get_column<Type>(column);
}

template <typename Type>
bool is_column(const IColumn* column) {
template <typename Type, typename From>
bool is_column(const From* column) {
return check_and_get_column<Type>(column);
}

Expand Down
24 changes: 24 additions & 0 deletions be/src/core/typeid_cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,37 @@
#include "common/exception.h"
#include "common/status.h"

template <typename T>
struct TypeIdCastNormalizedType {
using no_ref_t = std::remove_reference_t<T>;
using no_cv_t = std::remove_cv_t<no_ref_t>;
using type =
std::conditional_t<std::is_pointer_v<no_cv_t>,
std::add_pointer_t<std::remove_cv_t<std::remove_pointer_t<no_cv_t>>>,
no_cv_t>;
};

template <typename T>
using TypeIdCastNormalizedType_t = typename TypeIdCastNormalizedType<T>::type;

template <typename T>
using TypeIdCastClassType_t = std::remove_pointer_t<TypeIdCastNormalizedType_t<T>>;

/** Checks type by comparing typeid.
* The exact match of the type is checked. That is, cast to the ancestor will be unsuccessful.
* In the rest, behaves like a dynamic_cast.
*/

template <typename To, typename From>
To typeid_cast(From* from) {
static_assert(!std::is_same_v<TypeIdCastNormalizedType_t<To>, TypeIdCastNormalizedType_t<From>>,
"typeid_cast is redundant for the same type after removing cv/ref qualifiers");
static_assert(std::is_class_v<TypeIdCastClassType_t<To>> &&
std::is_class_v<TypeIdCastClassType_t<From>>,
"typeid_cast requires casting between class pointer types");
static_assert(std::is_base_of_v<TypeIdCastClassType_t<From>, TypeIdCastClassType_t<To>>,
"typeid_cast only supports downcast from a base type to a derived type");

#ifndef NDEBUG
try {
if (typeid(*from) == typeid(std::remove_pointer_t<To>)) {
Expand Down
Loading