mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Fixed type name extraction involving template classes
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@593 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
dccc50d3e9
commit
c2dd320bf4
2 changed files with 33 additions and 46 deletions
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include <turtle/detail/type_name.hpp>
|
#include <turtle/detail/type_name.hpp>
|
||||||
#include <boost/test/auto_unit_test.hpp>
|
#include <boost/test/auto_unit_test.hpp>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -16,12 +15,7 @@ namespace
|
||||||
template< typename T >
|
template< typename T >
|
||||||
std::string to_string( const T& )
|
std::string to_string( const T& )
|
||||||
{
|
{
|
||||||
std::string result = boost::lexical_cast< std::string >( mock::detail::type_name( BOOST_SP_TYPEID( T ) ) );
|
return boost::lexical_cast< std::string >( mock::detail::type_name( BOOST_SP_TYPEID( T ) ) );
|
||||||
boost::algorithm::replace_all( result, "& ", "&" );
|
|
||||||
boost::algorithm::replace_all( result, " &", "&" );
|
|
||||||
boost::algorithm::replace_all( result, "* ", "*" );
|
|
||||||
boost::algorithm::replace_all( result, " *", "*" );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@
|
||||||
#define MOCK_TYPE_NAME_HPP_INCLUDED
|
#define MOCK_TYPE_NAME_HPP_INCLUDED
|
||||||
|
|
||||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <boost/algorithm/string/erase.hpp>
|
||||||
#include <boost/detail/sp_typeinfo.hpp>
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
@ -35,77 +38,67 @@ namespace detail
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
typedef boost::unit_test::const_string const_string;
|
|
||||||
typedef const_string::size_type size_type;
|
|
||||||
|
|
||||||
void serialize( std::ostream& s,
|
void serialize( std::ostream& s,
|
||||||
const boost::detail::sp_typeinfo& info ) const
|
const boost::detail::sp_typeinfo& info ) const
|
||||||
{
|
{
|
||||||
const char* name = info.name();
|
const char* name = info.name();
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char* result = abi::__cxa_demangle( name, 0, 0, &status );
|
boost::shared_ptr< char > demangled(
|
||||||
struct guard
|
abi::__cxa_demangle( name, 0, 0, &status ),
|
||||||
{
|
&std::free );
|
||||||
explicit guard( char* p )
|
if( ! status && demangled )
|
||||||
: p_( p )
|
serialize( s, demangled.get() );
|
||||||
{}
|
|
||||||
~guard()
|
|
||||||
{
|
|
||||||
std::free( p_ );
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
char* p_;
|
|
||||||
} g( result );
|
|
||||||
if( ! status && result )
|
|
||||||
serialize( s, result );
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
serialize( s, name );
|
serialize( s, name );
|
||||||
}
|
}
|
||||||
void serialize( std::ostream& s, const_string name ) const
|
|
||||||
|
typedef std::string::size_type size_type;
|
||||||
|
|
||||||
|
void serialize( std::ostream& s, const std::string& name ) const
|
||||||
{
|
{
|
||||||
const size_type tpl_end = name.rfind( ">" );
|
const size_type tpl_end = name.rfind( ">" );
|
||||||
const size_type nm = name.rfind( "::" );
|
const size_type nm = name.rfind( "::" );
|
||||||
if( tpl_end == const_string::npos || tpl_end <= nm )
|
if( tpl_end == std::string::npos || tpl_end < nm )
|
||||||
{
|
{
|
||||||
s << remove_prefix( remove_namespace( name ) );
|
s << clean( name );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const size_type tpl_start = find_template_start( name );
|
const size_type tpl_start = find_template_start( name );
|
||||||
s << remove_namespace( name.substr( 0, tpl_start ) ) << '<';
|
s << strip_namespace( name.substr( 0, tpl_start ) ) << '<';
|
||||||
serialize( s, name.substr( tpl_start + 1, tpl_end ) );
|
serialize( s,
|
||||||
|
name.substr( tpl_start + 1, tpl_end - tpl_start - 1 ) );
|
||||||
s << '>';
|
s << '>';
|
||||||
}
|
}
|
||||||
const_string remove_prefix( const_string name ) const
|
std::string clean( std::string name ) const
|
||||||
{
|
{
|
||||||
name = remove_prefix( name, "class " );
|
name = strip_namespace( name );
|
||||||
name = remove_prefix( name, "struct " );
|
boost::algorithm::erase_all( name, "class " );
|
||||||
|
boost::algorithm::erase_all( name, "struct " );
|
||||||
|
boost::algorithm::erase_all( name, "__ptr64" );
|
||||||
|
boost::algorithm::replace_all( name, " &", "&" );
|
||||||
|
boost::algorithm::replace_all( name, "& ", "&" );
|
||||||
|
boost::algorithm::replace_all( name, " *", "*" );
|
||||||
|
boost::algorithm::replace_all( name, "* ", "*" );
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
const_string remove_prefix( const_string name,
|
size_type find_template_start( const std::string& name ) const
|
||||||
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;
|
size_type count = 0;
|
||||||
for( size_type i = name.size(); 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 )
|
if( name[ i ] == '<' && --count == 0 )
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return static_cast< size_type >( const_string::npos );
|
return std::string::npos;
|
||||||
}
|
}
|
||||||
const_string remove_namespace( const_string name ) const
|
std::string strip_namespace( const std::string& name ) const
|
||||||
{
|
{
|
||||||
size_type p = name.rfind( "::" );
|
const size_type p = name.rfind( "::" );
|
||||||
if( p == const_string::npos )
|
if( p == std::string::npos )
|
||||||
return name;
|
return name;
|
||||||
return name.substr( p + 2 );
|
return name.substr( p + 2 );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue