yuzu/externals/vcpkg/packages/boost-core_x64-windows/include/boost/core/type_name.hpp

1138 lines
26 KiB
C++
Executable File

#ifndef BOOST_CORE_TYPE_NAME_HPP_INCLUDED
#define BOOST_CORE_TYPE_NAME_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// std::string boost::core::type_name<T>()
//
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/demangle.hpp>
#include <boost/core/is_same.hpp>
#include <boost/config.hpp>
#include <string>
#include <functional>
#include <memory>
#include <utility>
#include <cstdio>
#include <cstddef>
#include <cstring>
#include <iosfwd>
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
# include <string_view>
#endif
namespace boost
{
namespace core
{
namespace detail
{
// tn_identity
template<class T> struct tn_identity
{
typedef T type;
};
// tn_remove_prefix
inline bool tn_remove_prefix( std::string& str, char const* prefix )
{
std::size_t n = std::strlen( prefix );
if( str.substr( 0, n ) == prefix )
{
str = str.substr( n );
return true;
}
else
{
return false;
}
}
#if !defined(BOOST_NO_TYPEID)
// typeid_name
inline std::string fix_typeid_name( char const* n )
{
std::string r = boost::core::demangle( n );
#if defined(_MSC_VER)
tn_remove_prefix( r, "class " );
tn_remove_prefix( r, "struct " );
tn_remove_prefix( r, "enum " );
#endif
// libc++ inline namespace
if( tn_remove_prefix( r, "std::__1::" ) )
{
r = "std::" + r;
}
// libstdc++ inline namespace
if( tn_remove_prefix( r, "std::__cxx11::" ) )
{
r = "std::" + r;
}
#if defined(BOOST_MSVC) && BOOST_MSVC == 1600
// msvc-10.0 puts TR1 things in std::tr1
if( tn_remove_prefix( r, "std::tr1::" ) )
{
r = "std::" + r;
}
#endif
return r;
}
template<class T> std::string typeid_name()
{
return fix_typeid_name( typeid(T).name() );
}
// template names
template<class T> std::string class_template_name()
{
#if defined(BOOST_GCC)
std::string r = typeid_name<T()>();
#else
std::string r = typeid_name<T*>();
#endif
return r.substr( 0, r.find( '<' ) );
}
template<class T> std::string sequence_template_name()
{
return detail::class_template_name<T>();
}
template<class T> std::string set_template_name()
{
return detail::class_template_name<T>();
}
template<class T> std::string map_template_name()
{
return detail::class_template_name<T>();
}
template<class T> std::string array_template_name()
{
return detail::class_template_name<T>();
}
#else // #if !defined(BOOST_NO_TYPEID)
template<class T> std::string typeid_name()
{
return "_Tp";
}
template<class T> std::string class_template_name()
{
return "_Tm";
}
template<class T> std::string sequence_template_name()
{
return "_Sq";
}
template<class T> std::string set_template_name()
{
return "_St";
}
template<class T> std::string map_template_name()
{
return "_Mp";
}
template<class T> std::string array_template_name()
{
return "_Ar";
}
#endif
// tn_to_string
#if defined(BOOST_MSVC)
# pragma warning( push )
# pragma warning( disable: 4996 )
#endif
inline std::string tn_to_string( std::size_t n )
{
char buffer[ 32 ];
std::sprintf( buffer, "%lu", static_cast< unsigned long >( n ) );
return buffer;
}
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
// tn_holder
template<class T> struct tn_holder
{
static std::string type_name( std::string const& suffix )
{
return typeid_name<T>() + suffix;
}
};
// integrals
template<> struct tn_holder<bool>
{
static std::string type_name( std::string const& suffix )
{
return "bool" + suffix;
}
};
template<> struct tn_holder<char>
{
static std::string type_name( std::string const& suffix )
{
return "char" + suffix;
}
};
template<> struct tn_holder<signed char>
{
static std::string type_name( std::string const& suffix )
{
return "signed char" + suffix;
}
};
template<> struct tn_holder<unsigned char>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned char" + suffix;
}
};
template<> struct tn_holder<short>
{
static std::string type_name( std::string const& suffix )
{
return "short" + suffix;
}
};
template<> struct tn_holder<unsigned short>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned short" + suffix;
}
};
template<> struct tn_holder<int>
{
static std::string type_name( std::string const& suffix )
{
return "int" + suffix;
}
};
template<> struct tn_holder<unsigned>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned" + suffix;
}
};
template<> struct tn_holder<long>
{
static std::string type_name( std::string const& suffix )
{
return "long" + suffix;
}
};
template<> struct tn_holder<unsigned long>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned long" + suffix;
}
};
template<> struct tn_holder<boost::long_long_type>
{
static std::string type_name( std::string const& suffix )
{
return "long long" + suffix;
}
};
template<> struct tn_holder<boost::ulong_long_type>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned long long" + suffix;
}
};
template<> struct tn_holder<wchar_t>
{
static std::string type_name( std::string const& suffix )
{
return "wchar_t" + suffix;
}
};
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template<> struct tn_holder<char16_t>
{
static std::string type_name( std::string const& suffix )
{
return "char16_t" + suffix;
}
};
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template<> struct tn_holder<char32_t>
{
static std::string type_name( std::string const& suffix )
{
return "char32_t" + suffix;
}
};
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
template<> struct tn_holder<char8_t>
{
static std::string type_name( std::string const& suffix )
{
return "char8_t" + suffix;
}
};
#endif
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
template<> struct tn_holder<std::byte>
{
static std::string type_name( std::string const& suffix )
{
return "std::byte" + suffix;
}
};
#endif
// floating point
template<> struct tn_holder<float>
{
static std::string type_name( std::string const& suffix )
{
return "float" + suffix;
}
};
template<> struct tn_holder<double>
{
static std::string type_name( std::string const& suffix )
{
return "double" + suffix;
}
};
template<> struct tn_holder<long double>
{
static std::string type_name( std::string const& suffix )
{
return "long double" + suffix;
}
};
// void
template<> struct tn_holder<void>
{
static std::string type_name( std::string const& suffix )
{
return "void" + suffix;
}
};
// nullptr_t
#if !defined(BOOST_NO_CXX11_NULLPTR)
template<> struct tn_holder<std::nullptr_t>
{
static std::string type_name( std::string const& suffix )
{
return "std::nullptr_t" + suffix;
}
};
#endif
// cv
template<class T> struct tn_holder<T const>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( " const" + suffix );
}
};
template<class T> struct tn_holder<T volatile>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( " volatile" + suffix );
}
};
template<class T> struct tn_holder<T const volatile>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( " const volatile" + suffix );
}
};
// refs
template<class T> struct tn_holder<T&>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( "&" + suffix );
}
};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T> struct tn_holder<T&&>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( "&&" + suffix );
}
};
#endif
// function types
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// tn_add_each
template<class T> int tn_add_each_impl( std::string& st )
{
if( !st.empty() ) st += ", ";
st += tn_holder<T>::type_name( "" );
return 0;
}
template<class... T> std::string tn_add_each()
{
std::string st;
typedef int A[ sizeof...(T) + 1 ];
(void)A{ 0, tn_add_each_impl<T>( st )... };
return st;
}
template<class R, class... A> std::string function_type_name( tn_identity<R(A...)>, std::string const& trailer, std::string const& suffix )
{
std::string r = tn_holder<R>::type_name( "" );
if( !suffix.empty() )
{
r += '(';
if( suffix[ 0 ] == ' ' )
{
r += suffix.substr( 1 );
}
else
{
r += suffix;
}
r += ')';
}
r += '(' + tn_add_each<A...>() + ')';
r += trailer;
return r;
}
template<class R, class... A> struct tn_holder<R(A...)>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), "", suffix );
}
};
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
template<class R, class... A> struct tn_holder<R(A...) const>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile", suffix );
}
};
#endif
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
template<class R, class... A> struct tn_holder<R(A...) &>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " &", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const &>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const &", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile &>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile &", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile &>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile &", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) &&>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " &&", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const &&>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const &&", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile &&>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile &&", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile &&>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile &&", suffix );
}
};
#endif
#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
template<class R, class... A> struct tn_holder<R(A...) noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) & noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " & noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const & noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const & noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile & noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile & noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile & noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile & noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) && noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " && noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const && noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const && noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) volatile && noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile && noexcept", suffix );
}
};
template<class R, class... A> struct tn_holder<R(A...) const volatile && noexcept>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile && noexcept", suffix );
}
};
#endif
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// pointers
template<class T> struct tn_holder<T*>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<T>::type_name( "*" + suffix );
}
};
// arrays
template<class T> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T> )
{
return std::pair<std::string, std::string>( tn_holder<T>::type_name( "" ), "" );
}
template<class T, std::size_t N> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T[N]> )
{
std::pair<std::string, std::string> r = detail::array_prefix_suffix( tn_identity<T>() );
r.second = '[' + tn_to_string( N ) + ']' + r.second;
return r;
}
template<class T> std::string array_type_name( tn_identity<T[]>, std::string const& suffix )
{
std::pair<std::string, std::string> r = detail::array_prefix_suffix( tn_identity<T>() );
if( suffix.empty() )
{
return r.first + "[]" + r.second;
}
else
{
return r.first + '(' + suffix + ")[]" + r.second;
}
}
template<class T> struct tn_holder<T[]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T[]>(), suffix );
}
};
template<class T> struct tn_holder<T const[]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T const[]>(), suffix );
}
};
template<class T> struct tn_holder<T volatile[]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T volatile[]>(), suffix );
}
};
template<class T> struct tn_holder<T const volatile[]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T const volatile[]>(), suffix );
}
};
template<class T, std::size_t N> std::string array_type_name( tn_identity<T[N]>, std::string const& suffix )
{
std::pair<std::string, std::string> r = detail::array_prefix_suffix( tn_identity<T[N]>() );
if( suffix.empty() )
{
return r.first + r.second;
}
else
{
return r.first + '(' + suffix + ")" + r.second;
}
}
template<class T, std::size_t N> struct tn_holder<T[N]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T[N]>(), suffix );
}
};
template<class T, std::size_t N> struct tn_holder<T const[N]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T const[N]>(), suffix );
}
};
template<class T, std::size_t N> struct tn_holder<T volatile[N]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T volatile[N]>(), suffix );
}
};
template<class T, std::size_t N> struct tn_holder<T const volatile[N]>
{
static std::string type_name( std::string const& suffix )
{
return detail::array_type_name( tn_identity<T const volatile[N]>(), suffix );
}
};
// pointers to members
template<class R, class T> struct tn_holder<R T::*>
{
static std::string type_name( std::string const& suffix )
{
return tn_holder<R>::type_name( ' ' + tn_holder<T>::type_name( "" ) + "::*" + suffix );
}
};
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class R, class T, class... A> struct tn_holder<R(T::*)(A...)>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), "", ' ' + tn_holder<T>::type_name( "" ) + "::*" + suffix );
}
};
template<class R, class T, class... A> struct tn_holder<R(T::*)(A...) const>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const", ' ' + tn_holder<T>::type_name( "" ) + "::*" + suffix );
}
};
template<class R, class T, class... A> struct tn_holder<R(T::*)(A...) volatile>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " volatile", ' ' + tn_holder<T>::type_name( "" ) + "::*" + suffix );
}
};
template<class R, class T, class... A> struct tn_holder<R(T::*)(A...) const volatile>
{
static std::string type_name( std::string const& suffix )
{
return detail::function_type_name( tn_identity<R(A...)>(), " const volatile", ' ' + tn_holder<T>::type_name( "" ) + "::*" + suffix );
}
};
#endif
// strings
template<template<class Ch, class Tr, class A> class L, class Ch> struct tn_holder< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >();
return tn + '<' + tn_holder<Ch>::type_name( "" ) + '>' + suffix;
}
};
template<> struct tn_holder<std::string>
{
static std::string type_name( std::string const& suffix )
{
return "std::string" + suffix;
}
};
template<> struct tn_holder<std::wstring>
{
static std::string type_name( std::string const& suffix )
{
return "std::wstring" + suffix;
}
};
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template<> struct tn_holder<std::u16string>
{
static std::string type_name( std::string const& suffix )
{
return "std::u16string" + suffix;
}
};
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template<> struct tn_holder<std::u32string>
{
static std::string type_name( std::string const& suffix )
{
return "std::u32string" + suffix;
}
};
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
template<> struct tn_holder< std::basic_string<char8_t> >
{
static std::string type_name( std::string const& suffix )
{
return "std::u8string" + suffix;
}
};
#endif
// string views (et al)
template<template<class Ch, class Tr> class L, class Ch> struct tn_holder< L<Ch, std::char_traits<Ch> > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch> > >();
return tn + '<' + tn_holder<Ch>::type_name( "" ) + '>' + suffix;
}
};
// needed for libstdc++
template<> struct tn_holder<std::ostream>
{
static std::string type_name( std::string const& suffix )
{
return "std::ostream" + suffix;
}
};
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
template<> struct tn_holder<std::string_view>
{
static std::string type_name( std::string const& suffix )
{
return "std::string_view" + suffix;
}
};
template<> struct tn_holder<std::wstring_view>
{
static std::string type_name( std::string const& suffix )
{
return "std::wstring_view" + suffix;
}
};
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template<> struct tn_holder<std::u16string_view>
{
static std::string type_name( std::string const& suffix )
{
return "std::u16string_view" + suffix;
}
};
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template<> struct tn_holder<std::u32string_view>
{
static std::string type_name( std::string const& suffix )
{
return "std::u32string_view" + suffix;
}
};
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
template<> struct tn_holder< std::basic_string_view<char8_t> >
{
static std::string type_name( std::string const& suffix )
{
return "std::u8string_view" + suffix;
}
};
#endif
#endif
// class templates
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class...> class L, class... T> struct tn_holder< L<T...> >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::class_template_name< L<T...> >();
std::string st = tn_add_each<T...>();
return tn + '<' + st + '>' + suffix;
}
};
#else
template<template<class T1> class L, class T1> struct tn_holder< L<T1> >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::class_template_name< L<T1> >();
return tn + '<' + tn_holder<T1>::type_name( "" ) + '>' + suffix;
}
};
template<template<class T1, class T2> class L, class T1, class T2> struct tn_holder< L<T1, T2> >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::class_template_name< L<T1, T2> >();
return tn + '<' + tn_holder<T1>::type_name( "" ) + ", " + tn_holder<T2>::type_name( "" ) + '>' + suffix;
}
};
#endif
// sequence containers
template<template<class T, class A> class L, class T> struct tn_holder< L<T, std::allocator<T> > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::sequence_template_name< L<T, std::allocator<T> > >();
return tn + '<' + tn_holder<T>::type_name( "" ) + '>' + suffix;
}
};
// set
template<template<class T, class Pr, class A> class L, class T> struct tn_holder< L<T, std::less<T>, std::allocator<T> > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::set_template_name< L<T, std::less<T>, std::allocator<T> > >();
return tn + '<' + tn_holder<T>::type_name( "" ) + '>' + suffix;
}
};
// map
template<template<class T, class U, class Pr, class A> class L, class T, class U> struct tn_holder< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::map_template_name< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >();
return tn + '<' + tn_holder<T>::type_name( "" ) + ", " + tn_holder<U>::type_name( "" ) + '>' + suffix;
}
};
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
// unordered_set
template<template<class T, class H, class Eq, class A> class L, class T> struct tn_holder< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::set_template_name< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >();
return tn + '<' + tn_holder<T>::type_name( "" ) + '>' + suffix;
}
};
// unordered_map
template<template<class T, class U, class H, class Eq, class A> class L, class T, class U> struct tn_holder< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::map_template_name< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >();
return tn + '<' + tn_holder<T>::type_name( "" ) + ", " + tn_holder<U>::type_name( "" ) + '>' + suffix;
}
};
#endif
// array
template<template<class T, std::size_t N> class L, class T, std::size_t N> struct tn_holder< L<T, N> >
{
static std::string type_name( std::string const& suffix )
{
std::string tn = detail::array_template_name< L<T, N> >();
return tn + '<' + tn_holder<T>::type_name( "" ) + ", " + tn_to_string( N ) + '>' + suffix;
}
};
} // namespace detail
template<class T> std::string type_name()
{
return core::detail::tn_holder<T>::type_name( "" );
}
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_TYPE_NAME_HPP_INCLUDED