Skip to content

Instantly share code, notes, and snippets.

@mtao
Created October 16, 2023 00:06
Show Gist options
  • Save mtao/12796c10a03f9973b793bc3887bc16cf to your computer and use it in GitHub Desktop.
Save mtao/12796c10a03f9973b793bc3887bc16cf to your computer and use it in GitHub Desktop.
Getting unique types + removing void from a sequence of types
#include <tuple>
#include <type_traits>
template <typename T, typename U>
struct concatenate_tuple {};
template <typename... Ts, typename... Us>
struct concatenate_tuple<std::tuple<Ts...>, std::tuple<Us...>> {
using type = std::tuple<Ts..., Us...>;
};
template <typename T, typename U>
using concatenate_tuple_t = typename concatenate_tuple<T, U>::type;
template <typename...>
struct make_unique {
using type = std::tuple<>;
};
template <typename T>
struct make_unique<T> {
using type = std::tuple<T>;
};
template <typename... Ts>
using make_unique_t = typename make_unique<Ts...>::type;
template <typename T, typename RemainingTuple>
struct make_unique_tuple {};
template <typename T, typename... Ts>
struct make_unique_tuple<T, std::tuple<Ts...>> {
constexpr static bool t_is_unique = (!std::is_same_v<T, Ts> && ...);
using adding_t_type =
std::conditional_t<t_is_unique, std::tuple<T>, std::tuple<>>;
using type = concatenate_tuple_t<adding_t_type, make_unique_t<Ts...>>;
};
template <typename T, typename... Ts>
struct make_unique<T, Ts...> {
using type = typename make_unique_tuple<T, std::tuple<Ts...>>::type;
};
template <typename...>
struct remove_void {
using type = std::tuple<>;
};
template <>
struct remove_void<void> {
using type = std::tuple<>;
};
template <typename T>
struct remove_void<T> {
using type = std::tuple<T>;
};
template <typename... Ts>
using remove_void_t = typename remove_void<Ts...>::type;
template <typename T, typename RemainingTuple>
struct remove_void_tuple {};
template <typename T, typename... Ts>
struct remove_void_tuple<T, std::tuple<Ts...>> {
constexpr static bool t_not_void = !std::is_same_v<T, void>;
using adding_t_type =
std::conditional_t<t_not_void, std::tuple<T>, std::tuple<>>;
using type = concatenate_tuple_t<adding_t_type, remove_void_t<Ts...>>;
};
template <typename T, typename... Ts>
struct remove_void<T, Ts...> {
using type = typename remove_void_tuple<T, std::tuple<Ts...>>::type;
};
//
template <typename... Ts>
using make_unique_remove_void_t = // make_unique_t<Ts...>;
typename remove_void_tuple<void, make_unique_t<Ts...>>::type;
// from https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c
#include <iostream>
#include <type_traits>
#include <typeinfo>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include <cstdlib>
#include <memory>
#include <string>
template <class T>
std::string type_name() {
typedef typename std::remove_reference<T>::type TR;
std::unique_ptr<char, void (*)(void*)> own(
#ifndef _MSC_VER
abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr),
#else
nullptr,
#endif
std::free);
std::string r = own != nullptr ? own.get() : typeid(TR).name();
if (std::is_const<TR>::value) r += " const";
if (std::is_volatile<TR>::value) r += " volatile";
if (std::is_lvalue_reference<T>::value)
r += "&";
else if (std::is_rvalue_reference<T>::value)
r += "&&";
return r;
}
int main(int argc, char* argv[]) {
std::cout << type_name< //
make_unique_t<int, std::string, int, float, int, float,
float> //
>()
<< std::endl;
std::cout << type_name< //
make_unique_t<int> //
>()
<< std::endl;
std::cout << type_name< //
make_unique_t<> //
>()
<< std::endl;
std::cout << type_name< //
remove_void_t<int, std::string, void, int, float, int,
float, float, void> //
>()
<< std::endl;
std::cout << type_name< //
remove_void_t<int> //
>()
<< std::endl;
std::cout << type_name< //
remove_void_t<void, int> //
>()
<< std::endl;
std::cout << type_name< //
remove_void_t<int, void> //
>()
<< std::endl;
std::cout << type_name< //
remove_void_t<> //
>()
<< std::endl;
std::cout
<< type_name< //
make_unique_remove_void_t<int, std::string, void, int, float,
int, float, float, void> //
>()
<< std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment