diff --git a/include/ureact/adaptor/join.hpp b/include/ureact/adaptor/join.hpp index bbf0985..539f4c4 100644 --- a/include/ureact/adaptor/join.hpp +++ b/include/ureact/adaptor/join.hpp @@ -36,59 +36,10 @@ struct JoinClosure : AdaptorClosure } }; -struct JoinWithAdaptor : Adaptor -{ - /*! - * @brief Emits the sequence obtained from flattening received event value, with the delimiter in between elements - * - * The delimiter can be a single element or an iterable container of elements. - */ - template - UREACT_WARN_UNUSED_RESULT constexpr auto operator()( - const events& source, Pattern&& pattern ) const - { - using E = container_value_t; - return process( source, // - [first = true, pattern = std::forward( pattern )] // - ( event_range range, event_emitter out ) mutable { - if( !first ) - { - if constexpr( std::is_convertible_v ) - { - out << pattern; - } - else if constexpr( std::is_convertible_v, - E> ) - { - for( const auto& i : pattern ) - out << i; - } - else - { - static_assert( always_false, "Unsupported separator type" ); - } - } - first = false; - - for( const auto& e : range ) - for( const auto& i : e ) - out << i; - } ); - } - - template - UREACT_WARN_UNUSED_RESULT constexpr auto operator()( Pattern&& pattern ) const - { - return make_partial( std::forward( pattern ) ); - } -}; - } // namespace detail inline constexpr detail::JoinClosure join; -inline constexpr detail::JoinWithAdaptor join_with; - UREACT_END_NAMESPACE #endif // UREACT_ADAPTOR_JOIN_HPP diff --git a/include/ureact/adaptor/join_with.hpp b/include/ureact/adaptor/join_with.hpp new file mode 100644 index 0000000..9859a4d --- /dev/null +++ b/include/ureact/adaptor/join_with.hpp @@ -0,0 +1,74 @@ +// +// Copyright (C) 2014-2017 Sebastian Jeckel. +// Copyright (C) 2020-2023 Krylov Yaroslav. +// +// 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 UREACT_ADAPTOR_JOIN_WITH_HPP +#define UREACT_ADAPTOR_JOIN_WITH_HPP + +#include +#include + +UREACT_BEGIN_NAMESPACE + +namespace detail +{ + +struct JoinWithAdaptor : Adaptor +{ + /*! + * @brief Emits the sequence obtained from flattening received event value, with the delimiter in between elements + * + * The delimiter can be a single element or an iterable container of elements. + */ + template + UREACT_WARN_UNUSED_RESULT constexpr auto operator()( + const events& source, Pattern&& pattern ) const + { + using E = container_value_t; + return process( source, // + [first = true, pattern = std::forward( pattern )] // + ( event_range range, event_emitter out ) mutable { + if( !first ) + { + if constexpr( std::is_convertible_v ) + { + out << pattern; + } + else if constexpr( std::is_convertible_v, + E> ) + { + for( const auto& i : pattern ) + out << i; + } + else + { + static_assert( always_false, "Unsupported separator type" ); + } + } + first = false; + + for( const auto& e : range ) + for( const auto& i : e ) + out << i; + } ); + } + + template + UREACT_WARN_UNUSED_RESULT constexpr auto operator()( Pattern&& pattern ) const + { + return make_partial( std::forward( pattern ) ); + } +}; + +} // namespace detail + +inline constexpr detail::JoinWithAdaptor join_with; + +UREACT_END_NAMESPACE + +#endif // UREACT_ADAPTOR_JOIN_WITH_HPP diff --git a/tests/src/CMakeLists.txt b/tests/src/CMakeLists.txt index bd24b59..dffcd97 100644 --- a/tests/src/CMakeLists.txt +++ b/tests/src/CMakeLists.txt @@ -24,6 +24,7 @@ target_sources( adaptor/happened.cpp adaptor/hold.cpp adaptor/join.cpp + adaptor/join_with.cpp adaptor/keys.cpp adaptor/lift.cpp adaptor/merge.cpp diff --git a/tests/src/adaptor/join.cpp b/tests/src/adaptor/join.cpp index 5f43a42..c3127cd 100644 --- a/tests/src/adaptor/join.cpp +++ b/tests/src/adaptor/join.cpp @@ -79,36 +79,3 @@ TEST_CASE( "ureact::join (bits)" ) CHECK( result.get() == std::vector{ /*0b*/ 1, 0, 1, 0, /*'*/ 1, 0, 1, 1 } ); } - -// Based on https://en.cppreference.com/w/cpp/ranges/join_with_view -TEST_CASE( "ureact::join_with" ) -{ - ureact::context ctx; - - auto src = ureact::make_source( ctx ); - ureact::events chars_1; - ureact::events chars_2; - - using namespace std::literals; - - SECTION( "Functional syntax" ) - { - chars_1 = ureact::join_with( src, ' ' ); - chars_2 = ureact::join_with( src, ".."sv ); - } - SECTION( "Piped syntax" ) - { - chars_1 = src | ureact::join_with( ' ' ); - chars_2 = src | ureact::join_with( ".."sv ); - } - - const auto result_1 = ureact::collect( chars_1 ); - const auto result_2 = ureact::collect( chars_2 ); - - using namespace std::literals; - for( auto s : { "This"sv, "is"sv, "a"sv, "test."sv } ) - src << s; - - CHECK( result_1.get() == "This is a test."s ); - CHECK( result_2.get() == "This..is..a..test."s ); -} diff --git a/tests/src/adaptor/join_with.cpp b/tests/src/adaptor/join_with.cpp new file mode 100644 index 0000000..d34e4e1 --- /dev/null +++ b/tests/src/adaptor/join_with.cpp @@ -0,0 +1,48 @@ +// +// Copyright (C) 2020-2023 Krylov Yaroslav. +// +// 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 "ureact/adaptor/join_with.hpp" + +#include +#include + +#include "catch2_extra.hpp" +#include "ureact/adaptor/collect.hpp" +#include "ureact/events.hpp" + +// Based on https://en.cppreference.com/w/cpp/ranges/join_with_view +TEST_CASE( "ureact::join_with" ) +{ + ureact::context ctx; + + auto src = ureact::make_source( ctx ); + ureact::events chars_1; + ureact::events chars_2; + + using namespace std::literals; + + SECTION( "Functional syntax" ) + { + chars_1 = ureact::join_with( src, ' ' ); + chars_2 = ureact::join_with( src, ".."sv ); + } + SECTION( "Piped syntax" ) + { + chars_1 = src | ureact::join_with( ' ' ); + chars_2 = src | ureact::join_with( ".."sv ); + } + + const auto result_1 = ureact::collect( chars_1 ); + const auto result_2 = ureact::collect( chars_2 ); + + using namespace std::literals; + for( auto s : { "This"sv, "is"sv, "a"sv, "test."sv } ) + src << s; + + CHECK( result_1.get() == "This is a test."s ); + CHECK( result_2.get() == "This..is..a..test."s ); +}