Fixed type name extraction involving template classes

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@594 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2013-02-05 21:20:37 +00:00
parent c2dd320bf4
commit f33f31fb29
2 changed files with 35 additions and 21 deletions

View file

@ -209,3 +209,17 @@ BOOST_AUTO_TEST_CASE( name_of_template_inner_type_from_template_type_in_named_na
BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< int >::inner< int const*& >() ) ); BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< int >::inner< int const*& >() ) );
BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< std::exception >::inner< int const*& >() ) ); BOOST_CHECK_EQUAL( "inner<int const*&>", to_string( nm2::my_template_type< std::exception >::inner< int const*& >() ) );
} }
namespace
{
template< typename T1, typename T2, typename T3 >
struct my_tpl
{};
}
BOOST_AUTO_TEST_CASE( name_of_nested_template_with_multiple_arguments_is_extracted )
{
BOOST_CHECK_EQUAL( "vector<int, allocator<int>>", to_string( std::vector< int >() ) );
BOOST_CHECK_EQUAL( "vector<vector<int, allocator<int>>, allocator<vector<int, allocator<int>>>>", to_string( std::vector< std::vector< int > >() ) );
BOOST_CHECK_EQUAL( "my_tpl<my_tpl<int, int, int>, my_tpl<int, int, int>, my_tpl<int, int, int>>", to_string( my_tpl< my_tpl< int, int, int >, my_tpl< int, int, int >, my_tpl< int, int, int > >() ) );
}

View file

@ -56,24 +56,29 @@ namespace detail
typedef std::string::size_type size_type; typedef std::string::size_type size_type;
void serialize( std::ostream& s, const std::string& name ) const void serialize( std::ostream& s, std::string name ) const
{ {
const size_type tpl_end = name.rfind( ">" ); const size_type nm = rfind( name, ':' ) + 1;
const size_type nm = name.rfind( "::" ); const size_type tpl = name.find( '<', nm );
if( tpl_end == std::string::npos || tpl_end < nm ) s << clean( name.substr( nm, tpl - nm ) );
{ if( tpl == std::string::npos )
s << clean( name );
return; return;
} s << '<';
const size_type tpl_start = find_template_start( name ); list( s, name.substr( tpl + 1, name.rfind( '>' ) - tpl - 1 ) );
s << strip_namespace( name.substr( 0, tpl_start ) ) << '<';
serialize( s,
name.substr( tpl_start + 1, tpl_end - tpl_start - 1 ) );
s << '>'; s << '>';
} }
void list( std::ostream& s, const std::string& name ) const
{
const size_type comma = rfind( name, ',' );
if( comma != std::string::npos )
{
list( s, name.substr( 0, comma ) );
s << ", ";
}
serialize( s, name.substr( comma + 1 ) );
}
std::string clean( std::string name ) const std::string clean( std::string name ) const
{ {
name = strip_namespace( name );
boost::algorithm::erase_all( name, "class " ); boost::algorithm::erase_all( name, "class " );
boost::algorithm::erase_all( name, "struct " ); boost::algorithm::erase_all( name, "struct " );
boost::algorithm::erase_all( name, "__ptr64" ); boost::algorithm::erase_all( name, "__ptr64" );
@ -83,25 +88,20 @@ namespace detail
boost::algorithm::replace_all( name, "* ", "*" ); boost::algorithm::replace_all( name, "* ", "*" );
return name; return name;
} }
size_type find_template_start( const std::string& name ) const size_type rfind( const std::string& name, char c ) const
{ {
size_type count = 0; size_type count = 0;
for( size_type i = name.size() - 1; i > 0; --i ) for( size_type i = name.size() - 1; i > 0; --i )
{ {
if( name[ i ] == '>' ) if( name[ i ] == '>' )
++count; ++count;
if( name[ i ] == '<' && --count == 0 ) else if( name[ i ] == '<' )
--count;
if( name[ i ] == c && count == 0 )
return i; return i;
} }
return std::string::npos; return std::string::npos;
} }
std::string strip_namespace( const std::string& name ) const
{
const size_type p = name.rfind( "::" );
if( p == std::string::npos )
return name;
return name.substr( p + 2 );
}
const boost::detail::sp_typeinfo* info_; const boost::detail::sp_typeinfo* info_;
}; };