Skip to content

Commit

Permalink
join_with adaptor is extracted from ureact/adaptor/join.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
YarikTH committed Jul 16, 2023
1 parent 4aca266 commit 1e55ef2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 82 deletions.
49 changes: 0 additions & 49 deletions include/ureact/adaptor/join.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename InE, typename Pattern>
UREACT_WARN_UNUSED_RESULT constexpr auto operator()(
const events<InE>& source, Pattern&& pattern ) const
{
using E = container_value_t<InE>;
return process<E>( source, //
[first = true, pattern = std::forward<Pattern>( pattern )] //
( event_range<InE> range, event_emitter<E> out ) mutable {
if( !first )
{
if constexpr( std::is_convertible_v<decltype( pattern ), E> )
{
out << pattern;
}
else if constexpr( std::is_convertible_v<container_value_t<decltype( pattern )>,
E> )
{
for( const auto& i : pattern )
out << i;
}
else
{
static_assert( always_false<Pattern>, "Unsupported separator type" );
}
}
first = false;

for( const auto& e : range )
for( const auto& i : e )
out << i;
} );
}

template <typename Pattern>
UREACT_WARN_UNUSED_RESULT constexpr auto operator()( Pattern&& pattern ) const
{
return make_partial<JoinWithAdaptor>( std::forward<Pattern>( pattern ) );
}
};

} // namespace detail

inline constexpr detail::JoinClosure join;

inline constexpr detail::JoinWithAdaptor join_with;

UREACT_END_NAMESPACE

#endif // UREACT_ADAPTOR_JOIN_HPP
74 changes: 74 additions & 0 deletions include/ureact/adaptor/join_with.hpp
Original file line number Diff line number Diff line change
@@ -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 <ureact/adaptor/process.hpp>
#include <ureact/detail/container_type_traits.hpp>

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 <typename InE, typename Pattern>
UREACT_WARN_UNUSED_RESULT constexpr auto operator()(
const events<InE>& source, Pattern&& pattern ) const
{
using E = container_value_t<InE>;
return process<E>( source, //
[first = true, pattern = std::forward<Pattern>( pattern )] //
( event_range<InE> range, event_emitter<E> out ) mutable {
if( !first )
{
if constexpr( std::is_convertible_v<decltype( pattern ), E> )
{
out << pattern;
}
else if constexpr( std::is_convertible_v<container_value_t<decltype( pattern )>,
E> )
{
for( const auto& i : pattern )
out << i;
}
else
{
static_assert( always_false<Pattern>, "Unsupported separator type" );
}
}
first = false;

for( const auto& e : range )
for( const auto& i : e )
out << i;
} );
}

template <typename Pattern>
UREACT_WARN_UNUSED_RESULT constexpr auto operator()( Pattern&& pattern ) const
{
return make_partial<JoinWithAdaptor>( std::forward<Pattern>( pattern ) );
}
};

} // namespace detail

inline constexpr detail::JoinWithAdaptor join_with;

UREACT_END_NAMESPACE

#endif // UREACT_ADAPTOR_JOIN_WITH_HPP
1 change: 1 addition & 0 deletions tests/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 0 additions & 33 deletions tests/src/adaptor/join.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,36 +79,3 @@ TEST_CASE( "ureact::join (bits)" )

CHECK( result.get() == std::vector<bool>{ /*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<std::string_view>( ctx );
ureact::events<char> chars_1;
ureact::events<char> 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<std::basic_string>( chars_1 );
const auto result_2 = ureact::collect<std::basic_string>( 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 );
}
48 changes: 48 additions & 0 deletions tests/src/adaptor/join_with.cpp
Original file line number Diff line number Diff line change
@@ -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 <string>
#include <string_view>

#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<std::string_view>( ctx );
ureact::events<char> chars_1;
ureact::events<char> 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<std::basic_string>( chars_1 );
const auto result_2 = ureact::collect<std::basic_string>( 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 );
}

0 comments on commit 1e55ef2

Please sign in to comment.