#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <boost/preprocessor.hpp>
#include <boost/tuple/tuple.hpp>
namespace hecomi {
// 定義されてない型については "undefined" を表示
template <typename T>
struct Type
{
static std::string Get() {
return "undefined";
}
};
// 組込み型やテンプレートクラス以外
#define HECOMI_GETTYPE_BASE_TYPE(type)\
template <>\
struct Type<type>\
{\
static std::string Get() {\
return #type;\
}\
};\
template <>\
struct Type<type*>\
{\
static std::string Get() {\
return #type"*";\
}\
};
// 型を登録
HECOMI_GETTYPE_BASE_TYPE(int)
HECOMI_GETTYPE_BASE_TYPE(float)
HECOMI_GETTYPE_BASE_TYPE(std::string)
// コンテナ版
#define HECOMI_GETTYPE_CONTAINER_INNER_TYPE(z, n, max)\
Type<BOOST_PP_CAT(T, n)>::Get()\
BOOST_PP_IF(BOOST_PP_EQUAL(n, BOOST_PP_SUB(max, 1)), + , + ", " +)
#define HECOMI_GETTYPE_CONTAINER_TYPE(type, n)\
template <BOOST_PP_ENUM_PARAMS(n, typename T)/* typename T##n, ... */>\
struct Type<type<BOOST_PP_ENUM_PARAMS(n, T)/* T##n, ... */> >\
{\
static std::string Get() {\
return #type"<" + BOOST_PP_REPEAT(n, HECOMI_GETTYPE_CONTAINER_INNER_TYPE, n) + ">";\
}\
};
// コンテナの場合はそのテンプレート引数の数も登録
HECOMI_GETTYPE_CONTAINER_TYPE(std::vector, 1)
HECOMI_GETTYPE_CONTAINER_TYPE(std::pair, 2)
HECOMI_GETTYPE_CONTAINER_TYPE(boost::tuple, 3)
// ヘルパ関数
template <typename T>
std::string GetTypeName(const T& x)
{
return Type<T>::Get();
}
}
int main()
{
int a;
float b;
std::vector<int> c;
std::vector<float*> d;
std::vector<std::vector<int> > e;
std::pair<int, std::string> f;
boost::tuple<int, float, std::vector<std::string> > g;
std::cout << hecomi::GetTypeName(a) << std::endl;
std::cout << hecomi::GetTypeName(b) << std::endl;
std::cout << hecomi::GetTypeName(c) << std::endl;
std::cout << hecomi::GetTypeName(d) << std::endl;
std::cout << hecomi::GetTypeName(e) << std::endl;
std::cout << hecomi::GetTypeName(f) << std::endl;
std::cout << hecomi::GetTypeName(g) << std::endl;
return 0;
}