Skip to content

Latest commit

 

History

History
203 lines (155 loc) · 5 KB

262.md

File metadata and controls

203 lines (155 loc) · 5 KB
Info

Example

#include <typeinfo>
#include <type_traits>

static_assert(std::is_same_v<int, int>);
static_assert(typeid(int) == typeid(int));

static_assert(typeid(int) == typeid(const int));
static_assert(not std::is_same_v<int, const int>);

static_assert(typeid(int) == typeid(const int&));
static_assert(not std::is_same_v<int, const int&>);

https://godbolt.org/z/jddq7s1o4

Puzzle

  • Can you implement compare_types function which compare given types by leveraging typeid comparison?
#include <typeinfo>

template<class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool; // TODO

static_assert(compare_types());
static_assert(compare_types<int>());
static_assert(compare_types<void>());
static_assert(compare_types<int, int>());
static_assert(compare_types<const int, int, int const>());
static_assert(compare_types<const int&, int>());
static_assert(compare_types<int&, int&&>());
static_assert(compare_types<int, int&&, int&, const int&, int const&&>());
static_assert(compare_types<int&, const int&>());
static_assert(compare_types<void, void, void>());

static_assert(not compare_types<int, float>());
static_assert(not compare_types<void*, const void*, void* const>());
static_assert(not compare_types<int, int*>());
static_assert(not compare_types<int*, int**>());

https://godbolt.org/z/8P73zn9qP

Solutions

template <class T, class U>
using types_equal_t = std::bool_constant<typeid(T) == typeid(U)>;

template<class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool {
  using pairwise_equality_t = boost::mp11::mp_pairwise_fold<boost::mp11::mp_list<Ts...>, types_equal_t>;
  return boost::mp11::mp_apply<boost::mp11::mp_all, pairwise_equality_t>::value;
}

https://godbolt.org/z/nqjrbGrzf

consteval auto compare_types() -> bool{ return true; }

template<class T>
[[nodiscard]] consteval auto compare_types() -> bool{ return true; }

template<class R, class T, class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool{
    return typeid(R) == typeid(T) && compare_types<T,Ts...>();
}

https://godbolt.org/z/o3jPvPor5

template<class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool
{
    if constexpr (sizeof...(Ts) == 0) {
        return true;
    }
    else {
        auto helper = []<typename H, typename... Hs>() {
            return ((typeid(H) == typeid(Hs)) && ...);
        };

        return helper.template operator()<Ts...>();
    }
}

https://godbolt.org/z/cGne6Y5xa

[nodiscard]] consteval auto compare_types() -> bool {
    return true;
}

template <class T, class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool {
    if constexpr (sizeof...(Ts) == 0) {
        return true;
    } else {
        return (... and (typeid(T) == typeid(Ts)));
    }

https://godbolt.org/z/469d6oPc5

template<class... Ts>
[[nodiscard]] consteval bool compare_types();

template<class A, class B, class... Ts>
[[nodiscard]] consteval auto compare_2types_and_a_seq_of_types() -> bool {
  return (typeid(A) == typeid(B)) && (compare_types<A, Ts...>());
}

template<class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool{
  if constexpr(sizeof...(Ts) > 1){ return compare_2types_and_a_seq_of_types<Ts...>(); }
  else                           { return true; }
}

https://godbolt.org/z/5ePox7vEh

template <class... Ts>
[[nodiscard]] constexpr auto compare_types() -> bool {
  const std::type_info* type_ptrs[]{&typeid(std::remove_cvref_t<Ts>)...};

  for (auto type_ptr : type_ptrs) {
    if (*type_ptr != **type_ptrs) return false;
  }

  return true;
}

https://godbolt.org/z/4c6qK3aoE

[[nodiscard]] consteval bool compare_types() {
    return true;
}

template<class T1>
[[nodiscard]] consteval bool compare_types() {
    return true;
}

template<class T1, class T2, class...Ts>
[[nodiscard]] consteval bool compare_types() {
        return typeid(T1) == typeid(T2) and compare_types<T2, Ts...>();
}

https://godbolt.org/z/ee8a7sKxh

template<typename ... Ts>
struct types{};

template<class... Ts>
consteval bool compare_types(){
  constexpr auto n = sizeof...(Ts);
  if constexpr (n == 0 || n == 1){ return true;
  } else {
    return []<typename U1, typename U2, typename ... Us>(types<U1, U2, Us ...>){
      return typeid(U1) == typeid(U2) && compare_types<U2, Us ...>();
    }(types<Ts...>{});
  }
}

https://godbolt.org/z/K9n1erMxa

template<class... Ts>
[[nodiscard]] consteval auto compare_types() -> bool {
    if constexpr( sizeof...(Ts) < 1)
        return true;
    else {
        auto all_equal = []<typename T1, typename...Tr>() {
            return ((typeid(T1) == typeid(Tr)) && ...);
        };
        return all_equal.template operator()<Ts...>();
    }
}

https://godbolt.org/z/TMTEsEzxc