渡された型のtemplate parametersを得るメタ関数2
先日の件を経てcv修飾に対応しました。
もっと賢い実装がありそうですが、constとvolatileならせいぜい2 * 2通りしかないので凝ったことせずにそのままSFINAEで対応。
#include <iostream> #include <typeinfo> #include <cxxabi.h> #include <type_traits> #include <boost/mpl/vector.hpp> template<class... Types> struct Foo; template<class T> struct tp_type { private: template<class> struct type_holder {}; template<class T1, template<class...> class Type, class... Args> static boost::mpl::vector<const volatile Type<Args...>, Args...> tp_type_impl( type_holder<Type<Args...>>, typename std::enable_if<std::is_const<T1>::value>::type* = 0, typename std::enable_if<std::is_volatile<T1>::value>::type* = 0 ); template<class T1, template<class...> class Type, class... Args> static boost::mpl::vector<volatile Type<Args...>, Args...> tp_type_impl( type_holder<Type<Args...>>, typename std::enable_if<!std::is_const<T1>::value>::type* = 0, typename std::enable_if<std::is_volatile<T1>::value>::type* = 0 ); template<class T1, template<class...> class Type, class... Args> static boost::mpl::vector<const Type<Args...>, Args...> tp_type_impl( type_holder<Type<Args...>>, typename std::enable_if<std::is_const<T1>::value>::type* = 0, typename std::enable_if<!std::is_volatile<T1>::value>::type* = 0 ); template<class T1, template<class...> class Type, class... Args> static boost::mpl::vector<Type<Args...>, Args...> tp_type_impl( type_holder<Type<Args...>>, typename std::enable_if<!std::is_const<T1>::value>::type* = 0, typename std::enable_if<!std::is_volatile<T1>::value>::type* = 0 ); template<class T1, class Type> static boost::mpl::vector<const volatile Type> tp_type_impl( type_holder<Type>, typename std::enable_if<std::is_const<T1>::value>::type* = 0, typename std::enable_if<std::is_volatile<T1>::value>::type* = 0 ); template<class T1, class Type> static boost::mpl::vector<volatile Type> tp_type_impl( type_holder<Type>, typename std::enable_if<!std::is_const<T1>::value>::type* = 0, typename std::enable_if<std::is_volatile<T1>::value>::type* = 0 ); template<class T1, class Type> static boost::mpl::vector<const Type> tp_type_impl( type_holder<Type>, typename std::enable_if<std::is_const<T1>::value>::type* = 0, typename std::enable_if<!std::is_volatile<T1>::value>::type* = 0 ); template<class T1, class Type> static boost::mpl::vector<Type> tp_type_impl( type_holder<Type>, typename std::enable_if<!std::is_const<T1>::value>::type* = 0, typename std::enable_if<!std::is_volatile<T1>::value>::type* = 0 ); public: using type = decltype(tp_type_impl<T>(type_holder<typename std::remove_cv<T>::type>())); }; int main() { int status; using type = tp_type<const int>::type; using test = boost::mpl::vector<const int>; std::cout << abi::__cxa_demangle(typeid(type).name(), 0, 0, &status) << std::endl; std::cout << abi::__cxa_demangle(typeid(test).name(), 0, 0, &status) << std::endl; std::cout << std::boolalpha << std::is_same<type, test>::value << std::endl; using type2 = tp_type<const volatile Foo<Foo<int>, double, const char>>::type; using test2 = boost::mpl::vector<const volatile Foo<Foo<int>, double, const char>, Foo<int>, double, const char>; std::cout << abi::__cxa_demangle(typeid(type2).name(), 0, 0, &status) << std::endl; std::cout << abi::__cxa_demangle(typeid(test2).name(), 0, 0, &status) << std::endl; std::cout << std::boolalpha << std::is_same<type2, test2>::value << std::endl; }
出力
boost::mpl::vector<int const, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na>
boost::mpl::vector<int const, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na>
true
boost::mpl::vector<Foo<Foo<int>, double, char const> const volatile, Foo<int>, double, char const, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na>
boost::mpl::vector<Foo<Foo<int>, double, char const> const volatile, Foo<int>, double, char const, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na, mpl::na>
true