11 #ifndef smtk_common_TypeName_h
12 #define smtk_common_TypeName_h
16 #include "smtk/common/CompilerInformation.h"
18 #include <boost/type_index.hpp>
22 #include <forward_list>
32 #include <unordered_map>
33 #include <unordered_set>
59 static std::true_type testNamed(decltype(X::type_name)*);
61 static std::false_type testNamed(...);
64 using type = decltype(testNamed<T>(
nullptr));
67 template<
typename Type>
72 static typename std::enable_if<is_named<T>::type::value, std::string>::type value_()
79 static typename std::enable_if<!is_named<T>::type::value, std::string>::type
value_()
86 std::string pretty_name = boost::typeindex::type_id<Type>().pretty_name();
88 while ((badness = pretty_name.find(
"class ")) != std::string::npos)
90 pretty_name.erase(badness, 6);
92 while ((badness = pretty_name.find(
"struct ")) != std::string::npos)
94 pretty_name.erase(badness, 7);
98 while ((badness = pretty_name.find(
"`anonymous namespace'")) != std::string::npos)
100 pretty_name[badness] =
'(';
101 pretty_name[badness + 20] =
')';
105 return boost::typeindex::type_id<Type>().pretty_name();
109 static std::string value() {
return value_<Type>(); }
116 static std::string value() {
return "string"; }
120 template<
typename... Types>
121 struct name<std::tuple<Types...>>
123 static std::string value()
125 std::string subtypes = subType<0, std::tuple<Types...>>();
126 return std::string(
"tuple<" + subtypes +
">");
129 template<std::
size_t I,
typename Tuple>
130 inline static typename std::enable_if<I != std::tuple_size<Tuple>::value, std::string>::type
133 typedef typename std::tuple_element<I, Tuple>::type Type;
136 return (I != 0 ? std::string(
", ") : std::string()) + subtype + subType<I + 1, Tuple>();
139 template<std::
size_t I,
typename Tuple>
140 inline static typename std::enable_if<I == std::tuple_size<Tuple>::value, std::string>::type
143 return std::string();
148 template<
typename Type,
size_t N>
149 struct name<std::array<Type, N>>
151 static std::string value()
154 return std::string(
"array<" + subtype +
"," + std::to_string(N) +
">");
159 template<
typename Type>
160 struct name<std::priority_queue<Type, std::vector<Type>, std::less<Type>>>
162 static std::string value()
166 return std::string(
"priority_queue<" + subtype +
">");
171 #define name_single_argument_stl_pointer(POINTER) \
172 template<typename Type> \
173 struct name<std::POINTER<Type>> \
175 static std::string value() \
177 std::string subtype = name<Type>::value(); \
178 return std::string(#POINTER) + "<" + subtype + ">"; \
182 name_single_argument_stl_pointer(shared_ptr);
183 name_single_argument_stl_pointer(weak_ptr);
184 name_single_argument_stl_pointer(unique_ptr);
187 #undef name_single_argument_stl_container
189 #define name_single_argument_stl_container(CONTAINER) \
190 template<typename Type> \
191 struct name<std::CONTAINER<Type, std::allocator<Type>>> \
193 static std::string value() \
195 std::string subtype = name<Type>::value(); \
196 return std::string(#CONTAINER) + "<" + subtype + ">"; \
200 name_single_argument_stl_container(vector);
201 name_single_argument_stl_container(deque);
202 name_single_argument_stl_container(forward_list);
203 name_single_argument_stl_container(list);
205 #undef name_single_argument_stl_container
208 #define name_single_argument_sorted_stl_container(CONTAINER) \
209 template<typename Type> \
210 struct name<std::CONTAINER<Type, std::less<Type>, std::allocator<Type>>> \
212 static std::string value() \
214 std::string subtype = name<Type>::value(); \
215 return std::string(#CONTAINER) + "<" + subtype + ">"; \
219 name_single_argument_sorted_stl_container(set);
220 name_single_argument_sorted_stl_container(multiset);
221 name_single_argument_sorted_stl_container(unordered_set);
222 name_single_argument_sorted_stl_container(unordered_multiset);
224 #undef name_single_argument_sorted_stl_container
227 #define name_double_argument_stl_container(CONTAINER) \
228 template<typename Type> \
229 struct name<std::CONTAINER<Type, std::deque<Type>>> \
231 static std::string value() \
233 std::string type = name<Type>::value(); \
234 return std::string(#CONTAINER) + "<" + type + ">"; \
238 name_double_argument_stl_container(queue);
239 name_double_argument_stl_container(stack);
241 #undef name_double_argument_stl_container
244 #define name_double_argument_sorted_stl_container(CONTAINER) \
245 template<typename KeyType, typename ValueType> \
246 struct name<std::CONTAINER< \
249 std::less<KeyType>, \
250 std::allocator<std::pair<const KeyType, ValueType>>>> \
252 static std::string value() \
254 std::string keytype = name<KeyType>::value(); \
255 std::string valuetype = name<ValueType>::value(); \
256 return std::string(#CONTAINER) + "<" + keytype + ", " + valuetype + ">"; \
260 name_double_argument_sorted_stl_container(map);
261 name_double_argument_sorted_stl_container(multimap);
264 #define name_double_argument_hashed_stl_container(CONTAINER) \
265 template<typename KeyType, typename ValueType> \
266 struct name<std::CONTAINER< \
269 std::hash<KeyType>, \
270 std::equal_to<KeyType>, \
271 std::allocator<std::pair<const KeyType, ValueType>>>> \
273 static std::string value() \
275 std::string keytype = name<KeyType>::value(); \
276 std::string valuetype = name<ValueType>::value(); \
277 return std::string(#CONTAINER) + "<" + keytype + ", " + valuetype + ">"; \
281 name_double_argument_hashed_stl_container(unordered_map);
282 name_double_argument_hashed_stl_container(unordered_multimap);
284 #undef name_double_argument_hashed_stl_container
288 template<
typename Type>
296 #endif // smtk_common_TypeName_h