/// //////////////////////////////////////////////////////////////////////// ///
/// //////////////////////////////////////////////////////////////////////// ///
/// //////////////////////////////////////////////////////////////////////// ///
#include <cxxabi.h>
#include <string>
#include <typeinfo>
#include <cassert>
#include <cstdlib>
#include <iostream>
const std::string demangle(const char* const mangledTypeName) {
int resultStatus = -4;
const char* const result = abi::__cxa_demangle( mangledTypeName, 0, 0, &resultStatus );
std::string demangledTypeName;
const bool noError = (0 == resultStatus);
const bool demangledSuccess = (noError && result != 0);
assert(demangledSuccess);
demangledTypeName = (demangledSuccess ? result : "Unknown type.");
free(const_cast<char*>(result));
return demangledTypeName;
}
const std::string demangle(const std::string& mangledTypeName) {
return demangle(mangledTypeName.c_str());
}
const std::string demangledNameOfType(const std::type_info& type_id) {
return demangle(type_id.name());
}
#define DEMANGLED_NAME_OF_TYPE(TypeOrValue) (demangledNameOfType(typeid(TypeOrValue)))
#define PRINT_NAME_OF_TYPE(TypeOrValue) {std::cout<<DEMANGLED_NAME_OF_TYPE(TypeOrValue)<<std::endl;}
/// //////////////////////////////////////////////////////////////////////// ///
/// //////////////////////////////////////////////////////////////////////// ///
/// //////////////////////////////////////////////////////////////////////// ///
#include <string>
#include <vector>
#include <iostream>
// Store parameter pack
template<typename... T>
struct pack
{
static const unsigned int size = sizeof...(T);
};
// Get i-th element of parameter pack
template<int n, typename F, typename... T>
struct element_at : public element_at<n-1, T...>
{
};
template<typename F, typename... T>
struct element_at<0, F, T...>
{
typedef F type;
};
// Get i-th element of pack
template<int n, typename P>
struct element
{
};
template<int n, typename... T>
struct element<n, pack<T...>>
{
typedef typename element_at<n, T...>::type type;
};
// Concat at left
template<typename a, typename b>
struct tuple_concat_left
{
};
template<typename a, typename... b>
struct tuple_concat_left<a, pack<b...>>
{
typedef pack<a, b...> type;
};
// Concat 2 tuples
template<typename a, typename b, int n = 0, bool ok = (n < a::size)>
struct tuple_concat : public tuple_concat<a, b, n+1>
{
typedef typename tuple_concat_left<
typename element<n, a>::type,
typename tuple_concat<a, b, n+1>::type
>::type type;
};
template<typename a, typename b, int n>
struct tuple_concat<a, b, n, false>
{
typedef b type;
};
// Test
typedef pack<bool, int, char, float, std::string> MyPack;
typedef pack<double, std::vector<std::string>> PackToAppend;
int main()
{
typedef tuple_concat_left<void, MyPack>::type concat1;
typedef element<2, concat1>::type elem_at_2;
typedef tuple_concat<MyPack, PackToAppend>::type concat2;
typedef tuple_concat<PackToAppend, MyPack>::type concat3;
std::cout << "MyPack: "; PRINT_NAME_OF_TYPE(MyPack);
std::cout << "concat1: "; PRINT_NAME_OF_TYPE(concat1);
std::cout << "elem_at_2: "; PRINT_NAME_OF_TYPE(elem_at_2);
std::cout << "concat2: "; PRINT_NAME_OF_TYPE(concat2);
std::cout << "concat3: "; PRINT_NAME_OF_TYPE(concat3);
}