Refactoring to work around g++ 4.3.2

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@246 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-02-20 00:45:58 +00:00
parent 171accfe27
commit 1c689400a0
6 changed files with 104 additions and 85 deletions

View file

@ -13,12 +13,54 @@
#include "is_formattable.hpp" #include "is_formattable.hpp"
#include <boost/function_types/is_callable_builtin.hpp> #include <boost/function_types/is_callable_builtin.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <utility> #include <utility>
#include <ostream> #include <ostream>
#include <string> #include <string>
namespace mock namespace mock
{ {
namespace detail
{
template< typename T >
void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >
>::type* = 0 )
{
format( s, t );
}
template< typename T >
void serialize( std::ostream& s, const T& t,
BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::mpl::and_<
boost::mpl::not_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >
>,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
>
>::type* = 0 )
{
s << t;
}
template< typename T >
void serialize( std::ostream& s, const T&,
BOOST_DEDUCED_TYPENAME boost::disable_if<
boost::mpl::or_<
BOOST_DEDUCED_TYPENAME detail::is_formattable< std::ostream, T >,
BOOST_DEDUCED_TYPENAME detail::is_serializable< std::ostream, T >
>
>::type* = 0 )
{
s << '?';
}
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(is_container, const_iterator, false)
}
template< typename T > template< typename T >
class formatter class formatter
{ {
@ -38,42 +80,20 @@ namespace mock
const T* t_; const T* t_;
}; };
namespace detail
{
template< typename T > template< typename T >
void serialize( std::ostream& s, const T& t, formatter< T > format( const T& t )
BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME protect::is_serializable< std::ostream, T > >::type* = 0 )
{ {
s << t; return formatter< T >( t );
}
template< typename T >
void serialize( std::ostream& s, const T&,
BOOST_DEDUCED_TYPENAME boost::disable_if<
BOOST_DEDUCED_TYPENAME protect::is_serializable< std::ostream, T > >::type* = 0 )
{
s << "?";
}
} }
template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME mock::detail::is_formattable< std::ostream, T >,
std::ostream&
>::type
operator<<( std::ostream& s, const formatter< T >& f )
{
format( s, *f );
return s;
}
template< typename T > template< typename T >
BOOST_DEDUCED_TYPENAME boost::disable_if< BOOST_DEDUCED_TYPENAME boost::disable_if<
BOOST_DEDUCED_TYPENAME mock::detail::is_formattable< std::ostream, T >, detail::is_container< T >,
std::ostream& std::ostream&
>::type >::type
operator<<( std::ostream& s, const formatter< T >& f ) operator<<( std::ostream& s, const formatter< T >& f )
{ {
mock::detail::serialize( s, *f ); detail::serialize( s, *f );
return s; return s;
} }
@ -90,45 +110,43 @@ namespace detail
return s << '"' << *f << '"'; return s << '"' << *f << '"';
} }
template< typename T > template< typename T1, typename T2 >
formatter< T > format( const T& t ) std::ostream& operator<<( std::ostream& s, const formatter< std::pair< T1, T2 > >& f )
{ {
return formatter< T >( t ); return s << '(' << mock::format( f->first )
<< ',' << mock::format( f->second ) << ')';
} }
template< typename Container > template< typename T >
void format( std::ostream& s, const Container& c, BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME Container::const_iterator* = 0 ) boost::function_types::is_callable_builtin< T* >,
std::ostream&
>::type
operator<<( std::ostream& s, const formatter< T* >& )
{
return s << '?';
}
template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if<
detail::is_container< T >,
std::ostream&
>::type
operator<<( std::ostream& s, const formatter< T >& f )
{ {
s << '('; s << '(';
// if an error is generated by the line below it means Container 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 mismatched for a container because it has a typedef
// const_iterator : the easiest solution would be to add a format // const_iterator : the easiest solution would be to add a format
// function for Container as well. // function for Container as well.
for( BOOST_DEDUCED_TYPENAME Container::const_iterator it = c.begin(); for( BOOST_DEDUCED_TYPENAME T::const_iterator it = f->begin();
it != c.end(); ++it ) it != f->end(); ++it )
{ {
if( it != c.begin() ) if( it != f->begin() )
s << ','; s << ',';
s << mock::format( *it ); s << mock::format( *it );
} }
s << ')'; return s << ')';
}
template< typename T1, typename T2 >
void format( std::ostream& s, const std::pair< T1, T2 >& p )
{
s << '(' << mock::format( p.first )
<< ',' << mock::format( p.second ) << ')';
}
template< typename T >
void format( std::ostream& s, T,
BOOST_DEDUCED_TYPENAME boost::enable_if<
BOOST_DEDUCED_TYPENAME
boost::function_types::is_callable_builtin< T > >::type* = 0 )
{
s << '?';
} }
} }

View file

@ -11,6 +11,7 @@
#include "yes_no_type.hpp" #include "yes_no_type.hpp"
#include "sink.hpp" #include "sink.hpp"
#include <boost/mpl/bool.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning( push ) #pragma warning( push )
@ -18,14 +19,16 @@
#endif #endif
namespace mock namespace mock
{
namespace detail
{
namespace formattable
{ {
template< typename S > template< typename S >
detail::yes_type format( S&, detail::sink ); detail::yes_type format( S&, detail::sink );
namespace detail
{
template< typename S, typename T > template< typename S, typename T >
struct is_formattable struct impl
{ {
static S* s; static S* s;
static T* t; static T* t;
@ -34,6 +37,11 @@ namespace detail
// solution would be to add a format function for T as well. // solution would be to add a format function for T as well.
enum { value = sizeof( yes_type(), format( *s, *t ), yes_type() ) == sizeof( yes_type ) }; enum { value = sizeof( yes_type(), format( *s, *t ), yes_type() ) == sizeof( yes_type ) };
}; };
}
template< typename S, typename T >
struct is_formattable
: boost::mpl::bool_< formattable::impl< S, T >::value >
{};
} }
} }

View file

@ -13,6 +13,7 @@
#include <boost/function_types/is_callable_builtin.hpp> #include <boost/function_types/is_callable_builtin.hpp>
#include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp> #include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp> #include <boost/mpl/or.hpp>
namespace mock namespace mock

View file

@ -11,6 +11,7 @@
#include "yes_no_type.hpp" #include "yes_no_type.hpp"
#include "sink.hpp" #include "sink.hpp"
#include <boost/mpl/bool.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning( push ) #pragma warning( push )
@ -21,13 +22,13 @@ namespace mock
{ {
namespace detail namespace detail
{ {
namespace protect namespace serializable
{ {
template< typename S > template< typename S >
yes_type operator<<( S&, sink ); yes_type operator<<( S&, sink );
template< typename S, typename T > template< typename S, typename T >
struct is_serializable struct impl
{ {
static S* s; static S* s;
static T* t; static T* t;
@ -37,6 +38,9 @@ namespace protect
enum { value = sizeof( yes_type(), (*s << *t), yes_type() ) == sizeof( yes_type ) }; enum { value = sizeof( yes_type(), (*s << *t), yes_type() ) == sizeof( yes_type ) };
}; };
} }
template< typename S, typename T >
struct is_serializable : boost::mpl::bool_< serializable::impl< S, T >::value >
{};
} }
} }

View file

@ -12,14 +12,14 @@
#define BOOST_LIB_NAME boost_unit_test_framework #define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp> #include <boost/config/auto_link.hpp>
BOOST_STATIC_ASSERT(( ! mock::detail::is_formattable< std::ostream, int >::value )); BOOST_MPL_ASSERT_NOT(( mock::detail::is_formattable< std::ostream, int > ));
namespace namespace
{ {
struct non_formattable {}; struct non_formattable {};
} }
BOOST_STATIC_ASSERT(( ! mock::detail::is_formattable< std::ostream, non_formattable >::value )); BOOST_MPL_ASSERT_NOT(( mock::detail::is_formattable< std::ostream, non_formattable > ));
namespace namespace
{ {
@ -28,19 +28,7 @@ namespace
void format( std::ostream&, const formattable& ); void format( std::ostream&, const formattable& );
} }
BOOST_STATIC_ASSERT(( mock::detail::is_formattable< std::ostream, formattable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, formattable > ));
namespace nm
{
struct formattable {};
}
namespace mock
{
void format( std::ostream&, nm::formattable );
}
BOOST_STATIC_ASSERT(( mock::detail::is_formattable< std::ostream, nm::formattable >::value ));
namespace namespace
{ {
@ -48,7 +36,7 @@ namespace
{}; {};
} }
BOOST_STATIC_ASSERT(( mock::detail::is_formattable< std::ostream, derived_from_formattable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, derived_from_formattable > ));
namespace namespace
{ {
@ -58,4 +46,4 @@ namespace
}; };
} }
BOOST_STATIC_ASSERT(( mock::detail::is_formattable< std::ostream, convertible_to_formattable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_formattable< std::ostream, convertible_to_formattable > ));

View file

@ -13,15 +13,15 @@
#define BOOST_LIB_NAME boost_unit_test_framework #define BOOST_LIB_NAME boost_unit_test_framework
#include <boost/config/auto_link.hpp> #include <boost/config/auto_link.hpp>
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, int >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, int > ));
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, std::string >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, std::string > ));
namespace namespace
{ {
struct declared_but_not_defined; struct declared_but_not_defined;
} }
BOOST_STATIC_ASSERT(( ! mock::detail::protect::is_serializable< std::ostream, declared_but_not_defined >::value )); BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, declared_but_not_defined > ));
namespace namespace
{ {
@ -29,7 +29,7 @@ namespace
{}; {};
} }
BOOST_STATIC_ASSERT(( ! mock::detail::protect::is_serializable< std::ostream, non_serializable >::value )); BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, non_serializable > ));
namespace namespace
{ {
@ -39,7 +39,7 @@ namespace
std::ostream& operator<<( std::ostream& s, const serializable& ); std::ostream& operator<<( std::ostream& s, const serializable& );
} }
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, serializable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, serializable > ));
namespace namespace
{ {
@ -50,7 +50,7 @@ namespace
std::ostream& operator<<( std::ostream& s, const template_serializable< T >& ); std::ostream& operator<<( std::ostream& s, const template_serializable< T >& );
} }
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, template_serializable< int > >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, template_serializable< int > > ));
namespace namespace
{ {
@ -60,7 +60,7 @@ namespace
}; };
} }
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, convertible_to_base >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, convertible_to_base > ));
namespace namespace
{ {
@ -70,7 +70,7 @@ namespace
}; };
} }
BOOST_STATIC_ASSERT(( ! mock::detail::protect::is_serializable< std::ostream, convertible_to_string >::value )); BOOST_MPL_ASSERT_NOT(( mock::detail::is_serializable< std::ostream, convertible_to_string > ));
namespace namespace
{ {
@ -80,7 +80,7 @@ namespace
}; };
} }
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, convertible_to_serializable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, convertible_to_serializable > ));
namespace namespace
{ {
@ -88,4 +88,4 @@ namespace
{}; {};
} }
BOOST_STATIC_ASSERT(( mock::detail::protect::is_serializable< std::ostream, derived_from_serializable >::value )); BOOST_MPL_ASSERT(( mock::detail::is_serializable< std::ostream, derived_from_serializable > ));