template auto operator|(F&& f) (1) template auto operator|(detail::annotated_process&& ap) (2)

Attaches a new process to the channel.

1. Attaches the given process to the receiver and returns a new receiver. It can either be a function object with a single parameter or a process that has an await() and a yield() method.

2. Attaches the given annotated process to the receiver and returns a new receiver. It can either be a function object with a single parameter or a process that follows this signature. An annotated_process should not be explicitly instantiated but it gets implicitly created as soon as one combines a function object with an operator& and an executor or a buffer_size or both.

Creates a new receiver, attaches the given process as downstream to it and returns this new receiver. The new receiver inherits the executor from its upstream receiver if not an alternative executor is attached. In case that T of receiver<T> is a move only type, repeated calls of this operator overwrite the previous attached downstream channel.

### Parameters

 f The process to be executed. args Futures that shall be joined

### Return value

A receiver of type of the result of the passed function object

### Example 1

#include <atomic>
#include <stlab/concurrency/channel.hpp>
#include <stlab/concurrency/default_executor.hpp>
#include <stlab/concurrency/immediate_executor.hpp>

using namespace stlab;

int main() {
sender<int> send;

std::tie(send, receive) = channel<int>(default_executor);

std::atomic_int v{0};

// The code demonstrates how a process can be annotated
auto result = receive
| buffer_size{ 3 } & [](int x) { return x * 2; }
| [](int x) { return x * 2; } & buffer_size{ 2 }
| buffer_size{ 3 } & executor{ default_executor } & [](int x) { return x * 2; }

| executor{ default_executor } & [](int x) { return x + 1; }
| [](int x) { return x + 1; } & executor{ immediate_executor }
| executor{ default_executor } & buffer_size{ 3 } & [](int x) { return x * 2; }

| [](int x) { return x + 1; } & executor{ default_executor } & buffer_size{ 3 }
| [](int x) { return x * 2; } & buffer_size{ 3 } & executor{ immediate_executor }

| [&v](int x) { v = x; };

send(1);

while (v == 0) {
}
}