@@ -323,46 +323,86 @@ TEST(ChannelTest, ReadWriteClose)
323323 EXPECT_EQ (nums, numbers);
324324}
325325
326- TEST (ChannelTest, MergeChannels)
326+ class MovableOnly {
327+ public:
328+ explicit MovableOnly (int v) : value(v) {}
329+
330+ MovableOnly () = default ;
331+
332+ MovableOnly (const MovableOnly&)
333+ {
334+ std::cout << " Copy constructor should not be called for MovableOnly" ;
335+ std::abort ();
336+ }
337+
338+ MovableOnly (MovableOnly&& other) noexcept : value{std::move (other.value )} { other.value = 0 ; }
339+
340+ MovableOnly& operator =(const MovableOnly&)
341+ {
342+ std::cout << " Copy assignment should not be called for MovableOnly" ;
343+ std::abort ();
344+ }
345+
346+ MovableOnly& operator =(MovableOnly&& other) noexcept
347+ {
348+ if (this != &other) {
349+ value = other.value ;
350+ other.value = 0 ;
351+ }
352+
353+ return *this ;
354+ }
355+
356+ int getValue () const { return value; }
357+
358+ private:
359+ int value{0 };
360+ };
361+
362+ TEST (ChannelTest, Transform)
327363{
328364 const int numbers = 100 ;
329365 const std::int64_t expected_sum = 5050 * 2 ;
330366 std::atomic<std::int64_t > sum{0 };
331367 std::atomic<std::int64_t > nums{0 };
332368
333- msd::channel<int > input_chan{30 };
369+ msd::channel<MovableOnly > input_chan{30 };
334370 msd::channel<int > output_chan{10 };
335371
336- // Send to channel
372+ // Send to channel input channel
337373 const auto writer = [&input_chan]() {
338374 for (int i = 1 ; i <= numbers; ++i) {
339- input_chan.write (i );
375+ input_chan.write (MovableOnly{i} );
340376 }
341377 input_chan.close ();
342378 };
343379
380+ // Transform input channel values from MovableOnly to int
381+ // by multiplying by 2 and write to output channel
382+ const auto double_transformer = [&input_chan, &output_chan]() {
383+ std::transform (input_chan.begin (), input_chan.end (), msd::back_inserter (output_chan),
384+ [](auto && value) { return value.getValue () * 2 ; });
385+ output_chan.close ();
386+ };
387+
388+ // Read from output channel
344389 const auto reader = [&output_chan, &sum, &nums]() {
345390 for (const auto out : output_chan) { // blocking until channel is drained (closed and empty)
346391 sum += out;
347392 ++nums;
348393 }
349394 };
350395
351- const auto double_transformer = [&input_chan, &output_chan]() {
352- std::transform (input_chan.begin (), input_chan.end (), msd::back_inserter (output_chan),
353- [](int value) { return value * 2 ; });
354- output_chan.close ();
355- };
356-
357- const auto reader_1 = std::async (std::launch::async, reader);
358- const auto reader_2 = std::async (std::launch::async, reader);
396+ // Create async tasks for reading, transforming, and writing
397+ const auto reader_task_1 = std::async (std::launch::async, reader);
398+ const auto reader_task_2 = std::async (std::launch::async, reader);
359399 const auto writer_task = std::async (std::launch::async, writer);
360400 const auto transformer_task = std::async (std::launch::async, double_transformer);
361401
362- reader_1.wait ();
363- reader_2.wait ();
364402 writer_task.wait ();
365403 transformer_task.wait ();
404+ reader_task_1.wait ();
405+ reader_task_2.wait ();
366406
367407 EXPECT_EQ (sum, expected_sum);
368408 EXPECT_EQ (nums, numbers);
0 commit comments