Fixed type name extraction involving template classes

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@585 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2013-01-20 16:50:37 +00:00
parent b21790be27
commit 4cd3d08e3e
3 changed files with 152 additions and 25 deletions

View file

@ -35,13 +35,16 @@ namespace detail
return s;
}
private:
typedef boost::unit_test::const_string const_string;
typedef const_string::size_type size_type;
void serialize( std::ostream& s,
const boost::detail::sp_typeinfo& info ) const
{
const char* name = info.name();
#ifdef __GNUC__
int status = 0;
char* result = abi::__cxa_demangle( name, NULL, 0, &status );
char* result = abi::__cxa_demangle( name, 0, 0, &status );
struct guard
{
explicit guard( char* p )
@ -49,7 +52,7 @@ namespace detail
{}
~guard()
{
free( p_ );
std::free( p_ );
}
private:
char* p_;
@ -60,22 +63,51 @@ namespace detail
#endif
serialize( s, name );
}
void serialize( std::ostream& s,
boost::unit_test::const_string name ) const
void serialize( std::ostream& s, const_string name ) const
{
boost::unit_test::const_string::size_type p = name.rfind( "::" );
if( p != boost::unit_test::const_string::npos )
const size_type tpl_end = name.rfind( ">" );
const size_type nm = name.rfind( "::" );
if( tpl_end == const_string::npos || tpl_end <= nm )
{
s << name.substr( p + 2 );
s << remove_prefix( remove_namespace( name ) );
return;
}
p = name.rfind( " " );
if( p != boost::unit_test::const_string::npos )
const size_type tpl_start = find_template_start( name );
s << remove_namespace( name.substr( 0, tpl_start ) ) << '<';
serialize( s, name.substr( tpl_start + 1, tpl_end ) );
s << '>';
}
const_string remove_prefix( const_string name ) const
{
name = remove_prefix( name, "class " );
name = remove_prefix( name, "struct " );
return name;
}
const_string remove_prefix( const_string name,
const_string prefix ) const
{
if( name.substr( 0, prefix.size() ) == prefix )
return name.substr( prefix.size() );
return name;
}
size_type find_template_start( const_string name ) const
{
size_type count = 0;
for( size_type i = name.size(); i > 0; --i )
{
s << name.substr( p + 1 );
return;
if( name[ i ] == '>' )
++count;
if( name[ i ] == '<' && --count == 0 )
return i;
}
s << name;
return static_cast< size_type >( const_string::npos );
}
const_string remove_namespace( const_string name ) const
{
size_type p = name.rfind( "::" );
if( p == const_string::npos )
return name;
return name.substr( p + 2 );
}
const boost::detail::sp_typeinfo* info_;