Changed operator<< + mock::formatter into format + mock::protect

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@252 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-03-08 18:49:15 +00:00
parent 374cc95c0d
commit 8550353e63
2 changed files with 53 additions and 51 deletions

View file

@ -62,10 +62,10 @@ namespace detail
} }
template< typename T > template< typename T >
class formatter class protect
{ {
public: public:
explicit formatter( const T& t ) explicit protect( const T& t )
: t_( &t ) : t_( &t )
{} {}
const T& operator*() const const T& operator*() const
@ -79,74 +79,76 @@ namespace detail
private: private:
const T* t_; const T* t_;
}; };
template< typename T > template< typename T >
formatter< T > format( const T& t ) std::ostream& operator<<( std::ostream& s, protect< T > t )
{ {
return formatter< T >( t ); format( s, t );
}
template< typename T >
BOOST_DEDUCED_TYPENAME boost::disable_if<
detail::is_container< T >,
std::ostream&
>::type
operator<<( std::ostream& s, const formatter< T >& f )
{
detail::serialize( s, *f );
return s; return s;
} }
inline std::ostream& operator<<( std::ostream& s, const formatter< bool >& f ) template< typename T >
protect< T > format( const T& t )
{ {
return s << std::boolalpha << *f; return protect< T >( t );
} }
inline std::ostream& operator<<( std::ostream& s, const formatter< std::string >& f )
template< typename T >
void format( std::ostream& s, protect< T > t,
BOOST_DEDUCED_TYPENAME boost::disable_if<
detail::is_container< T >
>::type* = 0 )
{ {
return s << '"' << *f << '"'; detail::serialize( s, *t );
} }
inline std::ostream& operator<<( std::ostream& s, const formatter< const char* >& f )
inline void format( std::ostream& s, protect< bool > b )
{ {
return s << '"' << *f << '"'; s << std::boolalpha << *b;
}
inline void format( std::ostream& s, protect< std::string > str )
{
s << '"' << *str << '"';
}
inline void format( std::ostream& s, protect< const char* > str )
{
s << '"' << *str << '"';
} }
template< typename T1, typename T2 > template< typename T1, typename T2 >
std::ostream& operator<<( std::ostream& s, const formatter< std::pair< T1, T2 > >& f ) void format( std::ostream& s, protect< std::pair< T1, T2 > > p )
{ {
return s << '(' << mock::format( f->first ) s << '(' << mock::format( p->first )
<< ',' << mock::format( f->second ) << ')'; << ',' << mock::format( p->second ) << ')';
} }
template< typename T > template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if< void format( std::ostream& s, protect< T* >,
boost::function_types::is_callable_builtin< T* >, BOOST_DEDUCED_TYPENAME boost::enable_if<
std::ostream& boost::function_types::is_callable_builtin< T* >
>::type >::type* = 0 )
operator<<( std::ostream& s, const formatter< T* >& )
{ {
return s << '?'; s << '?';
} }
template< typename T > template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if< void format( std::ostream& s, protect< T > c,
detail::is_container< T >, BOOST_DEDUCED_TYPENAME boost::enable_if<
std::ostream& detail::is_container< T >
>::type >::type* = 0 )
operator<<( std::ostream& s, const formatter< T >& f )
{ {
s << '('; s << '(';
// if an error is generated by the line below it means T is // if an error is generated by the line below it means T is
// being mismatched for a container because it has a typedef // being mistaken for a container because it has a typedef
// const_iterator : the solution would be to add a serialization // const_iterator : the solution would be to add a format override
// operator for mock::formatter< T >. // for mock::protect< T >.
for( BOOST_DEDUCED_TYPENAME T::const_iterator it = f->begin(); for( BOOST_DEDUCED_TYPENAME T::const_iterator it = c->begin();
it != f->end(); ++it ) it != c->end(); ++it )
{ {
if( it != f->begin() ) if( it != c->begin() )
s << ','; s << ',';
s << mock::format( *it ); s << mock::format( *it );
} }
return s << ')'; s << ')';
} }
} }

View file

@ -82,30 +82,30 @@ namespace
namespace namespace
{ {
struct formatterable {}; struct protected_formattable {};
std::ostream& operator<<( std::ostream& s, const formatterable& ) std::ostream& operator<<( std::ostream& s, const protected_formattable& )
{ {
BOOST_FAIL( "should not be called" ); BOOST_FAIL( "should not be called" );
return s; return s;
} }
void format( std::ostream&, const formatterable& ) void format( std::ostream&, const protected_formattable& )
{ {
BOOST_FAIL( "should not be called" ); BOOST_FAIL( "should not be called" );
} }
} }
BOOST_AUTO_TEST_CASE( formatter_overrides_standard_stream_serialization_and_format_even_if_defined_after_being_used ) BOOST_AUTO_TEST_CASE( protected_format_overrides_standard_stream_serialization_and_format_even_if_defined_after_being_used )
{ {
BOOST_CHECK_EQUAL( "formatterable", to_string( formatterable() ) ); BOOST_CHECK_EQUAL( "protected_formattable", to_string( protected_formattable() ) );
} }
namespace namespace
{ {
std::ostream& operator<<( std::ostream& s, const mock::formatter< formatterable >& ) void format( std::ostream& s, mock::protect< protected_formattable > )
{ {
return s << "formatterable"; s << "protected_formattable";
} }
} }
@ -205,9 +205,9 @@ namespace
}; };
BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > )); BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > ));
std::ostream& operator<<( std::ostream& s, const mock::formatter< false_positive_container >& ) void format( std::ostream& s, mock::protect< false_positive_container > )
{ {
return s << "false_positive_container"; s << "false_positive_container";
} }
} }