From 95956444b75c5a806dfbf1caaf5664a697ba31e3 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Thu, 4 Sep 2014 00:12:25 +0100 Subject: [PATCH 1/5] catch_tostring: Move toString overload declarations - Put all the declarations of the overloads early in the file, so they get seen by the templates later on --- include/internal/catch_tostring.h | 56 ++++++++++++++++--------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index dbb31423..62d33cfe 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -27,6 +27,35 @@ namespace Catch { template std::string toString( T const& value ); +// Built in overloads + +std::string toString( std::string const& value ); +std::string toString( std::wstring const& value ); +std::string toString( const char* const value ); +std::string toString( char* const value ); +std::string toString( const wchar_t* const value ); +std::string toString( wchar_t* const value ); +std::string toString( int value ); +std::string toString( unsigned long value ); +std::string toString( unsigned int value ); +std::string toString( const double value ); +std::string toString( const float value ); +std::string toString( bool value ); +std::string toString( char value ); +std::string toString( signed char value ); +std::string toString( unsigned char value ); + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ); +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); + std::string toString( NSObject* const& nsObject ); +#endif + + namespace Detail { // SFINAE is currently disabled by default for all compilers. @@ -178,33 +207,6 @@ std::string toString( T const& value ) { return StringMaker::convert( value ); } -// Built in overloads - -std::string toString( std::string const& value ); -std::string toString( std::wstring const& value ); -std::string toString( const char* const value ); -std::string toString( char* const value ); -std::string toString( const wchar_t* const value ); -std::string toString( wchar_t* const value ); -std::string toString( int value ); -std::string toString( unsigned long value ); -std::string toString( unsigned int value ); -std::string toString( const double value ); -std::string toString( const float value ); -std::string toString( bool value ); -std::string toString( char value ); -std::string toString( signed char value ); -std::string toString( unsigned char value ); - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ); -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ); - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); - std::string toString( NSObject* const& nsObject ); -#endif namespace Detail { template From 31969373437700ad989875be2dd63d5408663b56 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Thu, 4 Sep 2014 00:17:36 +0100 Subject: [PATCH 2/5] catch_tostring: Add includes for tuple, type_traits --- include/internal/catch_tostring.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index 62d33cfe..097219bb 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -21,6 +21,11 @@ #include "catch_objc_arc.hpp" #endif +#ifdef CATCH_CPP11_OR_GREATER +#include +#include +#endif + namespace Catch { // Why we're here. From 022a0b4fcb742afa3eeaea96ef01bedd22ea6e74 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Thu, 4 Sep 2014 00:31:11 +0100 Subject: [PATCH 3/5] catch_tostring: toString for std::tuple --- include/internal/catch_tostring.h | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index 097219bb..cf60547f 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -193,6 +193,50 @@ struct StringMaker > { } }; + +#ifdef CATCH_CPP11_OR_GREATER + /* + toString for tuples + */ +namespace TupleDetail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct ElementPrinter { + static void print( const Tuple& tuple, std::ostream& os ) + { + os << ( N ? ", " : " " ) + << Catch::toString(std::get(tuple)); + ElementPrinter::print(tuple,os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct ElementPrinter { + static void print( const Tuple&, std::ostream& ) {} + }; + +} + +template +struct StringMaker> { + + static std::string convert( const std::tuple& tuple ) + { + std::ostringstream os; + os << '{'; + TupleDetail::ElementPrinter>::print( tuple, os ); + os << " }"; + return os.str(); + } +}; +#endif + namespace Detail { template std::string makeString( T const& value ) { From 13cbdf7e7d84e281820500661fdf516a4f663025 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Thu, 4 Sep 2014 00:32:05 +0100 Subject: [PATCH 4/5] Add tests for toString(std::tuple<...>) --- projects/CMake/CMakeLists.txt | 6 ++++ projects/SelfTest/ToStringTuple.cpp | 48 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 projects/SelfTest/ToStringTuple.cpp diff --git a/projects/CMake/CMakeLists.txt b/projects/CMake/CMakeLists.txt index 952ba43e..240e1ebe 100644 --- a/projects/CMake/CMakeLists.txt +++ b/projects/CMake/CMakeLists.txt @@ -6,6 +6,11 @@ project(Catch) get_filename_component(CATCH_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CATCH_DIR "${CATCH_DIR}" PATH) set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest) +if(USE_CPP11) + ## We can't turn this on by default, since it breaks on travis + message(STATUS "Enabling C++11") + set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") +endif() # define the sources of the self test set(SOURCES @@ -25,6 +30,7 @@ set(SOURCES ${SELF_TEST_DIR}/ToStringPair.cpp ${SELF_TEST_DIR}/ToStringVector.cpp ${SELF_TEST_DIR}/ToStringWhich.cpp + ${SELF_TEST_DIR}/ToStringTuple.cpp ) # configure the executable diff --git a/projects/SelfTest/ToStringTuple.cpp b/projects/SelfTest/ToStringTuple.cpp new file mode 100644 index 00000000..46aa314b --- /dev/null +++ b/projects/SelfTest/ToStringTuple.cpp @@ -0,0 +1,48 @@ +#include "catch.hpp" + +#ifdef CATCH_CPP11_OR_GREATER + +TEST_CASE( "tuple<>", "[toString][tuple]" ) +{ + typedef std::tuple<> type; + CHECK( "{ }" == Catch::toString(type{}) ); + type value {}; + CHECK( "{ }" == Catch::toString(value) ); +} + +TEST_CASE( "tuple", "[toString][tuple]" ) +{ + typedef std::tuple type; + CHECK( "{ 0 }" == Catch::toString(type{0}) ); +} + + +TEST_CASE( "tuple", "[toString][tuple]" ) +{ + typedef std::tuple type; + CHECK( "1.2f" == Catch::toString(float(1.2)) ); + CHECK( "{ 1.2f, 0 }" == Catch::toString(type{1.2,0}) ); +} + +TEST_CASE( "tuple", "[toString][tuple]" ) +{ + typedef std::tuple type; + CHECK( "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"}) ); +} + +TEST_CASE( "tuple,tuple<>,float>", "[toString][tuple]" ) +{ + typedef std::tuple,std::tuple<>,float> type; + type value { {42}, {}, 1.2f }; + CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) ); +} + +TEST_CASE( "tuple", "[toString][tuple]" ) +{ + typedef std::tuple type; + type value { nullptr, 42, "Catch me" }; + CHECK( "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value) ); +} + +#endif /* #ifdef CATCH_CPP11_OR_GREATER */ + From f559a51926c6590db94029fd116e5cec6088d41f Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Thu, 4 Sep 2014 01:05:51 +0100 Subject: [PATCH 5/5] ToStringTuple - gcc doesn't like tuple init_list ctor --- projects/SelfTest/ToStringTuple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/SelfTest/ToStringTuple.cpp b/projects/SelfTest/ToStringTuple.cpp index 46aa314b..012ee665 100644 --- a/projects/SelfTest/ToStringTuple.cpp +++ b/projects/SelfTest/ToStringTuple.cpp @@ -33,7 +33,7 @@ TEST_CASE( "tuple", "[toString][tuple]" ) TEST_CASE( "tuple,tuple<>,float>", "[toString][tuple]" ) { typedef std::tuple,std::tuple<>,float> type; - type value { {42}, {}, 1.2f }; + type value { std::tuple{42}, {}, 1.2f }; CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) ); }