diff --git a/include/cppcore/conversion/string.h b/include/cppcore/conversion/string.h index 5c051f3..2f5f16a 100644 --- a/include/cppcore/conversion/string.h +++ b/include/cppcore/conversion/string.h @@ -210,22 +210,13 @@ namespace std { /** - * @brief Operator overload to write value to stream that supports the to_string method, with stream parameter. + * @brief Operator overload to write value to stream. */ template inline auto operator<<(basic_ostream& os, X&& x) - -> decltype( - std::forward(x).to_string(std::declval&>()), - std::declval&>()); - - /** - * @brief Operator overload to write value to stream that supports the to_string method, with stream parameter. - */ - template - inline auto operator<<(basic_ostream& os, X&& x) - -> decltype( - std::forward(x).to_string(), - std::declval&>()); + -> std::enable_if_t< + cppcore::__impl::op_to_stream>::enable_streaming, + basic_ostream&>; } diff --git a/include/cppcore/conversion/string.inl b/include/cppcore/conversion/string.inl index 52858b3..24a2302 100644 --- a/include/cppcore/conversion/string.inl +++ b/include/cppcore/conversion/string.inl @@ -224,6 +224,8 @@ namespace cppcore template struct op_to_stream>> { + static constexpr decltype(auto) enable_streaming = true; + inline void operator()(std::ostream& os, const T& v) const { os << enum_conversion::to_string(v); } }; @@ -231,6 +233,8 @@ namespace cppcore template struct op_to_stream().to_string(std::declval()), void())> { + static constexpr decltype(auto) enable_streaming = true; + inline void operator()(std::ostream& os, const T& v) const { v.to_string(os); } }; @@ -238,6 +242,8 @@ namespace cppcore template struct op_to_stream().to_string(), void())> { + static constexpr decltype(auto) enable_streaming = true; + inline void operator()(std::ostream& os, const T& v) const { os << v.to_string(); } }; @@ -246,6 +252,8 @@ namespace cppcore template struct op_to_stream, void> { + static constexpr decltype(auto) enable_streaming = true; + inline void operator()(std::ostream& os, const std::vector& v) const { bool first = true; @@ -263,6 +271,8 @@ namespace cppcore template struct op_to_stream, void> { + static constexpr decltype(auto) enable_streaming = true; + inline void operator()(std::ostream& os, const std::list& v) const { bool first = true; @@ -420,21 +430,12 @@ namespace std template inline auto operator<<(basic_ostream& os, X&& x) - -> decltype( - std::forward(x).to_string(std::declval&>()), - std::declval&>()) - { - std::forward(x).to_string(os); - return os; - } - - template - inline auto operator<<(basic_ostream& os, X&& x) - -> decltype( - std::forward(x).to_string(), - std::declval&>()) + -> std::enable_if_t< + cppcore::__impl::op_to_stream>::enable_streaming, + basic_ostream&> { - os << std::forward(x).to_string(); + using op_type = cppcore::__impl::op_to_stream>; + op_type()(os, std::forward(x)); return os; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8eebbcf..387286f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -45,7 +45,7 @@ ForEach ( FILE IN LISTS CPPCORE_TEST_SOURCE_FILES ) # test If ( HAS_CMAKE_TESTS ) - Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} ) + Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cppcore ) Else ( ) Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) EndIf ( ) diff --git a/test/cppcore/conversion/string_tests.cpp b/test/cppcore/conversion/string_tests.cpp index fb65b8e..bdc2cd3 100644 --- a/test/cppcore/conversion/string_tests.cpp +++ b/test/cppcore/conversion/string_tests.cpp @@ -73,6 +73,13 @@ TEST(string_tests, vector_to_string) ::cppcore::to_string(std::vector { 1, 2, 3, 4, 5 })); } +TEST(string_tests, vector_to_stream) +{ + std::ostringstream ss; + ss << std::vector { 1, 2, 3, 4, 5 }; + EXPECT_EQ("1,2,3,4,5", ss.str()); +} + TEST(string_tests, list_to_string) { EXPECT_EQ( @@ -80,6 +87,13 @@ TEST(string_tests, list_to_string) ::cppcore::to_string(std::list { 1, 2, 3, 4, 5 })); } +TEST(string_tests, list_to_stream) +{ + std::ostringstream ss; + ss << std::list { 1, 2, 3, 4, 5 }; + EXPECT_EQ("1,2,3,4,5", ss.str()); +} + TEST(string_tests, string_to_vector) { EXPECT_EQ(