diff --git a/build/vc80/turtle.vcproj b/build/vc80/turtle.vcproj index 8d4b98c..a211f88 100644 --- a/build/vc80/turtle.vcproj +++ b/build/vc80/turtle.vcproj @@ -192,10 +192,6 @@ RelativePath="..\..\src\libraries\turtle\invocation.hpp" > - - diff --git a/build/vc80/turtle_test.vcproj b/build/vc80/turtle_test.vcproj index 2f1e986..f154c83 100644 --- a/build/vc80/turtle_test.vcproj +++ b/build/vc80/turtle_test.vcproj @@ -210,10 +210,6 @@ RelativePath="..\..\src\tests\turtle_test\invocation_test.cpp" > - - diff --git a/src/libraries/turtle/is_container.hpp b/src/libraries/turtle/is_container.hpp deleted file mode 100644 index 5b7673b..0000000 --- a/src/libraries/turtle/is_container.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Mathieu Champlon 2011 -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef MOCK_IS_CONTAINER_HPP_INCLUDED -#define MOCK_IS_CONTAINER_HPP_INCLUDED - -#include - -namespace mock -{ -namespace detail -{ - BOOST_MPL_HAS_XXX_TRAIT_DEF( const_iterator ) - - template< typename T > - struct is_container : has_const_iterator< T > - {}; -} -} - -#endif // #ifndef MOCK_IS_CONTAINER_HPP_INCLUDED diff --git a/src/libraries/turtle/log.hpp b/src/libraries/turtle/log.hpp index 83ad440..ca23745 100644 --- a/src/libraries/turtle/log.hpp +++ b/src/libraries/turtle/log.hpp @@ -9,13 +9,20 @@ #ifndef MOCK_LOG_HPP_INCLUDED #define MOCK_LOG_HPP_INCLUDED -#include "is_container.hpp" #include -#include +#include #include -#include +#include #include +namespace boost +{ +namespace assign_detail +{ + template< typename T > class generic_list; +} +} + namespace mock { struct stream @@ -26,87 +33,9 @@ namespace mock std::ostream* s_; }; -namespace detail3 -{ - template< typename T > - struct serializer - { - explicit serializer( const T& t ) - : t_( &t ) - {} - void serialize( stream& s ) const - { - // if it fails here because ambiguous stuff - // -> add operator<< to mock::stream for T - s << *t_; - } - const T* t_; - }; - template<> - struct serializer< bool > - { - explicit serializer( bool b ) - : b_( b ) - {} - void serialize( stream& s ) const - { - *s.s_ << std::boolalpha << b_; - } - bool b_; - }; - template<> - struct serializer< const char* > - { - explicit serializer( const char* s ) - : s_( s ) - {} - void serialize( stream& s ) const - { - *s.s_ << '"' << s_ << '"'; - } - const char* s_; - }; - template<> - struct serializer< std::string > - { - explicit serializer( const std::string& s ) - : s_( &s ) - {} - void serialize( stream& s ) const - { - *s.s_ << '"' << *s_ << '"'; - } - const std::string* s_; - }; - - template< typename T > - stream& operator<<( stream& s, const serializer< T >& ser ) - { - ser.serialize( s ); - return s; - } - - template< typename T > - std::ostream& operator<<( std::ostream& s, const serializer< T >& ser ) - { - stream ss( s ); - ser.serialize( ss ); - return s; - } -} - template< typename T > - detail3::serializer< T > format( const T& t ) - { - return detail3::serializer< T >( t ); - } - inline detail3::serializer< const char* > format( const char* s ) - { - return detail3::serializer< const char* >( s ); - } - #ifdef MOCK_LOG_CONVERSIONS -namespace detail5 +namespace detail3 { struct sink { @@ -156,7 +85,7 @@ namespace detail5 }; } - inline stream& operator<<( stream& s, const detail5::data& d ) + inline stream& operator<<( stream& s, const detail3::data& d ) { d.h_->serialize( *s.s_ ); return s; @@ -164,7 +93,7 @@ namespace detail5 #else // MOCK_LOG_CONVERSIONS -namespace detail4 +namespace detail3 { template< typename S, typename T > S& operator<<( S &s, const T& ) @@ -173,36 +102,77 @@ namespace detail4 } } - template< typename T > - void serialize( std::ostream& s, const T& t ) - { - using namespace detail4; - s << t; - } - -namespace detail2 -{ - template< typename S, typename T > - S& operator<<( S& s, const T& t ) - { - serialize( s, t ); - return s; - } -} - template< typename T > BOOST_DEDUCED_TYPENAME boost::disable_if< - detail::is_container< T >, stream& + boost::function_types::is_callable_builtin< T >, stream& >::type operator<<( stream& s, const T& t ) { - using namespace detail2; + using namespace detail3; *s.s_ << t; return s; } #endif // MOCK_LOG_CONVERSIONS +namespace detail2 +{ + template< typename T > + void serialize( stream& s, const T& t ) + { + // if it fails here because ambiguous stuff + // -> add operator<< to mock::stream for T + s << t; + } + inline void serialize( stream& s, bool b ) + { + s << (b ? "true" : "false"); + } + template< typename C, typename T, typename A > + void serialize( stream& s, const std::basic_string< C, T, A >& str ) + { + s << '"' << str << '"'; + } + inline void serialize( stream& s, const char* str ) + { + s << '"' << str << '"'; + } + + template< typename T > + struct formatter + { + explicit formatter( const T& t ) + : t_( &t ) + {} + void serialize( stream& s ) const + { + detail2::serialize( s, *t_ ); + } + const T* t_; + }; + + template< typename T > + stream& operator<<( stream& s, const formatter< T >& ser ) + { + ser.serialize( s ); + return s; + } + + template< typename T > + std::ostream& operator<<( std::ostream& s, const formatter< T >& ser ) + { + stream ss( s ); + ser.serialize( ss ); + return s; + } +} + + template< typename T > + detail2::formatter< T > format( const T& t ) + { + return detail2::formatter< T >( t ); + } + template< typename T1, typename T2 > stream& operator<<( stream& s, const std::pair< T1, T2 >& p ) { @@ -210,35 +180,76 @@ namespace detail2 << ',' << mock::format( p.second ) << ')'; } - template< typename Container > - BOOST_DEDUCED_TYPENAME boost::enable_if< - detail::is_container< Container >, stream& - >::type - operator<<( stream& s, const Container& c ) +namespace detail +{ + template< typename T > + void serialize( stream& s, const T& begin, const T& end ) { s << '('; - // if an error is generated by the line below it means Container is - // being mismatched for a container because it has a typedef - // const_iterator : the easiest solution would be to add a format - // function for Container as well. - for( BOOST_DEDUCED_TYPENAME Container::const_iterator it = c.begin(); - it != c.end(); ++it ) - { - if( it != c.begin() ) - s << ','; - s << mock::format( *it ); - } - return s << ')'; + for( T it = begin; it != end; ++it ) + s << (it == begin ? "" : ",") << mock::format( *it ); + s << ')'; + } +} + + template< typename T, typename A > + stream& operator<<( stream& s, const std::deque< T, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename T, typename A > + stream& operator<<( stream& s, const std::list< T, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename T, typename A > + stream& operator<<( stream& s, const std::vector< T, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename K, typename T, typename C, typename A > + stream& operator<<( stream& s, const std::map< K, T, C, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename K, typename T, typename C, typename A > + stream& operator<<( stream& s, const std::multimap< K, T, C, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename T, typename C, typename A > + stream& operator<<( stream& s, const std::set< T, C, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename T, typename C, typename A > + stream& operator<<( stream& s, const std::multiset< T, C, A >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; + } + template< typename T > + stream& operator<<( stream& s, + const boost::assign_detail::generic_list< T >& t ) + { + detail::serialize( s, t.begin(), t.end() ); + return s; } - //template< typename T > - //BOOST_DEDUCED_TYPENAME boost::enable_if< - // boost::function_types::is_callable_builtin< T >, stream& - //>::type - //operator<<( stream& s, const T& ) - //{ - // return s << '?'; - //} + template< typename T > + BOOST_DEDUCED_TYPENAME boost::enable_if< + boost::function_types::is_callable_builtin< T >, stream& + >::type + operator<<( stream& s, const T& ) + { + return s << '?'; + } } #endif // #ifndef MOCK_LOG_HPP_INCLUDED diff --git a/src/tests/turtle_test/is_container_test.cpp b/src/tests/turtle_test/is_container_test.cpp deleted file mode 100644 index 1c5bde2..0000000 --- a/src/tests/turtle_test/is_container_test.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright Mathieu Champlon 2009 -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include - -#include -#define BOOST_LIB_NAME boost_unit_test_framework -#include - -BOOST_MPL_ASSERT_NOT(( mock::detail::is_container< int > )); - -BOOST_MPL_ASSERT(( mock::detail::is_container< std::vector< int > > )); -BOOST_MPL_ASSERT(( mock::detail::is_container< std::deque< int > > )); -BOOST_MPL_ASSERT(( mock::detail::is_container< std::list< int > > )); -BOOST_MPL_ASSERT(( mock::detail::is_container< std::map< int, float > > )); -BOOST_MPL_ASSERT(( mock::detail::is_container< std::multimap< int, float > > )); -BOOST_MPL_ASSERT(( mock::detail::is_container< std::multiset< int > > )); diff --git a/src/tests/turtle_test/log_with_conversions_test.cpp b/src/tests/turtle_test/log_with_conversions_test.cpp index 75cbb16..1e61116 100644 --- a/src/tests/turtle_test/log_with_conversions_test.cpp +++ b/src/tests/turtle_test/log_with_conversions_test.cpp @@ -412,35 +412,16 @@ BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized_with_conversions ) namespace { - struct false_positive_container - { - typedef int const_iterator; - }; - BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > )); - - mock::stream& operator<<( mock::stream& s, false_positive_container ) - { - return s << "false_positive_container"; - } + void callable_builtin() + {} } -BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden_with_conversions ) +BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_with_conversions ) { - BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) ); + BOOST_CHECK_EQUAL( "?", to_string_2( callable_builtin ) ); + BOOST_CHECK_EQUAL( "?", to_string_2( &callable_builtin ) ); } -//namespace -//{ -// void callable_builtin() -// {} -//} -// -//BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_with_conversions ) -//{ -// BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) ); -// BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) ); -//} - namespace { struct serialized_using_format @@ -471,6 +452,21 @@ BOOST_AUTO_TEST_CASE( type_can_use_format_when_streamed_with_conversions ) BOOST_CHECK_EQUAL( "\"string\"", to_string( streamed_using_format() ) ); } +namespace +{ + struct std_string_streamed + {}; + mock::stream& operator<<( mock::stream& s, const std_string_streamed& ) + { + return s << std::string( "string" ); + } +} + +BOOST_AUTO_TEST_CASE( std_string_streamed_is_not_a_container_with_conversions ) +{ + BOOST_CHECK_EQUAL( "string", to_string( std_string_streamed() ) ); +} + namespace mock { namespace detail diff --git a/src/tests/turtle_test/log_without_conversions_test.cpp b/src/tests/turtle_test/log_without_conversions_test.cpp index 0638d82..84f75e8 100644 --- a/src/tests/turtle_test/log_without_conversions_test.cpp +++ b/src/tests/turtle_test/log_without_conversions_test.cpp @@ -408,35 +408,16 @@ BOOST_AUTO_TEST_CASE( boost_assign_map_list_of_are_serialized_without_conversion namespace { - struct false_positive_container - { - typedef int const_iterator; - }; - BOOST_MPL_ASSERT(( mock::detail::is_container< false_positive_container > )); - - mock::stream& operator<<( mock::stream& s, false_positive_container ) - { - return s << "false_positive_container"; - } + void callable_builtin() + {} } -BOOST_AUTO_TEST_CASE( false_positive_container_serialization_can_still_be_overriden_without_conversions ) +BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_without_conversions ) { - BOOST_CHECK_EQUAL( "false_positive_container", to_string( false_positive_container() ) ); + BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) ); + BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) ); } -//namespace -//{ -// void callable_builtin() -// {} -//} -// -//BOOST_AUTO_TEST_CASE( callable_builtin_yields_an_interrogation_mark_when_serialized_without_conversions ) -//{ -// BOOST_CHECK_EQUAL( "?", to_string( callable_builtin ) ); -// BOOST_CHECK_EQUAL( "?", to_string( &callable_builtin ) ); -//} - namespace { struct serialized_using_format @@ -467,6 +448,21 @@ BOOST_AUTO_TEST_CASE( type_can_use_format_when_streamed_without_conversions ) BOOST_CHECK_EQUAL( "\"string\"", to_string( streamed_using_format() ) ); } +namespace +{ + struct std_string_streamed + {}; + mock::stream& operator<<( mock::stream& s, const std_string_streamed& ) + { + return s << std::string( "string" ); + } +} + +BOOST_AUTO_TEST_CASE( std_string_streamed_is_not_a_container_without_conversions ) +{ + BOOST_CHECK_EQUAL( "string", to_string( std_string_streamed() ) ); +} + namespace mock { namespace detail