Skip to content

Commit 9df46e7

Browse files
Merge pull request #28 from andreiavrammsd/stream-order
Stream order
2 parents a12ef2c + f8daa14 commit 9df46e7

16 files changed

+103
-73
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.12)
22
project(cpp_channel)
3-
set(PROJECT_VERSION 0.7.3)
3+
set(PROJECT_VERSION 0.8.0)
44

55
set(CMAKE_CXX_STANDARD 11)
66
set(CMAKE_CXX_STANDARD_REQUIRED YES)

README.md

+15-18
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
### Thread-safe container for sharing data between threads. Header-only.
66

77
* Thread-safe push and fetch.
8-
* Use stream operators to push (>>) and fetch (<<) items.
8+
* Use stream operators to push (<<) and fetch (>>) items.
99
* Blocking (forever waiting to fetch).
1010
* Range-based for loop supported.
1111
* Close to prevent pushing and stop waiting to fetch.
1212
* Integrates well with STL algorithms. Eg: std::move(ch.begin(), ch.end(), ...).
13-
* Tested with GCC and Clang.
13+
* Tested with GCC, Clang, and MSVC.
1414

1515
## Requirements
1616

@@ -36,10 +36,10 @@ int main() {
3636
int out = 0;
3737

3838
// Send to channel
39-
in >> chan;
39+
chan << in;
4040

4141
// Read from channel
42-
out << chan;
42+
chan >> out;
4343

4444
assert(out == 1);
4545
}
@@ -51,12 +51,10 @@ int main() {
5151
int main() {
5252
msd::channel<int> chan{2}; // buffered
5353

54-
int in = 1;
55-
5654
// Send to channel
57-
in >> chan;
58-
in >> chan;
59-
in >> chan; // blocking because capacity is 2 (and no one reads from channel)
55+
chan << 1;
56+
chan << 2;
57+
chan << 3; // blocking because capacity is 2 (and no one reads from channel)
6058
}
6159
```
6260

@@ -70,13 +68,13 @@ int main() {
7068
int out = 0;
7169

7270
// Send to channel
73-
in >> chan;
74-
in >> chan;
71+
chan << in;
72+
chan << in;
7573

7674
// Read from channel
77-
out << chan;
78-
out << chan;
79-
out << chan; // blocking because channel is empty (and no one writes on it)
75+
chan >> out;
76+
chan >> out;
77+
chan >> out; // blocking because channel is empty (and no one writes on it)
8078
}
8179
```
8280

@@ -89,12 +87,11 @@ int main() {
8987
msd::channel<int> chan;
9088

9189
int in1 = 1;
92-
in1 >> chan;
93-
9490
int in2 = 2;
95-
in2 >> chan;
9691

97-
for (const auto out : chan) { // blocking: forever waiting for channel items
92+
chan << in1 << in2;
93+
94+
for (const auto out : chan) { // blocking: forever waiting for channel items
9895
std::cout << out << '\n';
9996
}
10097
}

examples/basic.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ int main()
99
int in{};
1010

1111
in = 1;
12-
in >> ch;
12+
ch << in;
1313

1414
in = 2;
15-
in >> ch;
15+
ch << in;
1616

1717
in = 3;
18-
in >> ch;
18+
ch << in;
1919

2020
for (auto out : ch) {
2121
std::cout << out << '\n';

examples/close.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ int main()
1717
break;
1818
}
1919

20-
++i >> ch;
20+
ch << ++i;
2121
std::cout << "in: " << i << "\n";
2222

2323
std::this_thread::sleep_for(std::chrono::milliseconds{ms});

examples/cmake-project/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ target_link_libraries(cmake_project)
1414

1515
include(FetchContent)
1616
if (NOT channel_POPULATED)
17-
FetchContent_Declare(channel URL https://github.com/andreiavrammsd/cpp-channel/archive/v0.7.3.zip)
17+
FetchContent_Declare(channel URL https://github.com/andreiavrammsd/cpp-channel/archive/v0.8.0.zip)
1818
FetchContent_Populate(channel)
1919
include_directories(${channel_SOURCE_DIR}/include)
2020
# OR

examples/cmake-project/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ CMAKE=cmake
44

55
build:
66
$(CMAKE) -B $(BUILD_PATH) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE)
7-
$(CMAKE) --build $(BUILD_PATH) --target cmake-project -- -j
7+
$(CMAKE) --build $(BUILD_PATH) --target cmake_project -- -j
88

99
run:
10-
$(BUILD_PATH)/cmake-project
10+
$(BUILD_PATH)/cmake_project
1111

1212
release:
1313
make BUILD_TYPE=release

examples/cmake-project/src/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ using chan = msd::channel<int>;
1111
{
1212
while (true) {
1313
static int i = 0;
14-
++i >> incoming;
14+
incoming << ++i;
1515
}
1616
}
1717

@@ -27,7 +27,7 @@ void Transform(chan& incoming, chan& outgoing)
2727
{
2828
for (auto in : incoming) {
2929
auto result = Add(in, 2);
30-
result >> outgoing;
30+
outgoing << result;
3131
}
3232
}
3333

examples/move.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ int main()
4141
msd::channel<Data> ch{10};
4242

4343
auto in1 = Data{1};
44-
in1 >> ch;
44+
ch << in1;
4545

46-
Data{2} >> ch;
46+
ch << Data{2};
4747

4848
auto in3 = Data{3};
49-
std::move(in3) >> ch;
49+
ch << std::move(in3);
5050

5151
for (auto out : ch) {
5252
std::cout << out.getI() << '\n';

examples/multithreading.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int main()
2929
const auto in = [](msd::channel<std::int64_t>& ch) {
3030
while (true) {
3131
static std::int64_t i = 0;
32-
++i >> ch;
32+
ch << ++i;
3333
}
3434
};
3535

examples/streaming.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ int main()
2323
}
2424

2525
++i;
26-
std::string{std::to_string(i) + " from: " + std::to_string(thread)} >> ch;
26+
ch << std::string{std::to_string(i) + " from: " + std::to_string(thread)};
2727

2828
std::this_thread::sleep_for(pause);
2929
}

include/msd/blocking_iterator.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class blocking_iterator {
3333
*/
3434
value_type operator*() const
3535
{
36-
value_type value;
37-
value << ch_;
36+
value_type value{};
37+
ch_ >> value;
3838

3939
return value;
4040
}

include/msd/channel.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ class channel {
6262
* @throws closed_channel if channel is closed.
6363
*/
6464
template <typename Type>
65-
friend void operator>>(Type&&, channel<typename std::decay<Type>::type>&);
65+
friend channel<typename std::decay<Type>::type>& operator<<(channel<typename std::decay<Type>::type>&, Type&&);
6666

6767
/**
6868
* Pops an element from the channel.
6969
*
7070
* @tparam Type The type of the elements
7171
*/
7272
template <typename Type>
73-
friend void operator<<(Type&, channel<Type>&);
73+
friend channel<Type>& operator>>(channel<Type>&, Type&);
7474

7575
/**
7676
* Returns the number of elements in the channel.
@@ -120,8 +120,8 @@ class channel {
120120
friend class blocking_iterator<channel>;
121121
};
122122

123-
#include "channel_impl.hpp"
124-
125123
} // namespace msd
126124

125+
#include "channel.inl"
126+
127127
#endif // MSD_CHANNEL_HPP_

include/msd/channel_impl.hpp include/msd/channel.inl

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// Copyright (C) 2023 Andrei Avram
22

3+
namespace msd {
4+
35
template <typename T>
46
constexpr channel<T>::channel(const size_type capacity) : cap_{capacity}
57
{
68
}
79

810
template <typename T>
9-
void operator>>(T&& in, channel<typename std::decay<T>::type>& ch)
11+
channel<typename std::decay<T>::type>& operator<<(channel<typename std::decay<T>::type>& ch, T&& in)
1012
{
1113
if (ch.closed()) {
1214
throw closed_channel{"cannot write on closed channel"};
@@ -21,13 +23,15 @@ void operator>>(T&& in, channel<typename std::decay<T>::type>& ch)
2123
}
2224

2325
ch.cnd_.notify_one();
26+
27+
return ch;
2428
}
2529

2630
template <typename T>
27-
void operator<<(T& out, channel<T>& ch)
31+
channel<T>& operator>>(channel<T>& ch, T& out)
2832
{
2933
if (ch.closed() && ch.empty()) {
30-
return;
34+
return ch;
3135
}
3236

3337
{
@@ -42,6 +46,8 @@ void operator<<(T& out, channel<T>& ch)
4246
}
4347

4448
ch.cnd_.notify_one();
49+
50+
return ch;
4551
}
4652

4753
template <typename T>
@@ -94,3 +100,5 @@ void channel<T>::waitBeforeWrite(std::unique_lock<std::mutex>& lock)
94100
cnd_.wait(lock, [this]() { return size_ < cap_; });
95101
}
96102
}
103+
104+
} // namespace msd

tests/blocking_iterator_test.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ TEST(ChannelIteratorTest, Dereference)
2121
msd::blocking_iterator<msd::channel<int>> it{channel};
2222

2323
int in = 1;
24-
in >> channel;
24+
channel << in;
2525
in = 2;
26-
in >> channel;
26+
channel << in;
2727

2828
EXPECT_EQ(1, *it);
2929
EXPECT_EQ(2, *it);
@@ -44,7 +44,7 @@ TEST(ChannelIteratorTest, NotEqualContinue)
4444
msd::channel<int> channel;
4545
msd::blocking_iterator<msd::channel<int>> it{channel};
4646

47-
1 >> channel;
47+
channel << 1;
4848

4949
EXPECT_TRUE(it != it);
5050
}

tests/channel_benchmark.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ static void BM_ChannelWithInt(benchmark::State& state)
3333
int in = 1;
3434
int out = 0;
3535
for (auto _ : state) {
36-
in >> channel;
37-
out << channel;
36+
channel << in;
37+
channel >> out;
3838
}
3939
}
4040

@@ -46,8 +46,8 @@ static void BM_ChannelWithString(benchmark::State& state)
4646
std::string in = "input";
4747
std::string out;
4848
for (auto _ : state) {
49-
in >> channel;
50-
out << channel;
49+
channel << in;
50+
channel >> out;
5151
}
5252
}
5353

@@ -59,8 +59,8 @@ static void BM_ChannelWithStruct(benchmark::State& state)
5959
Entry in{};
6060
Entry out{};
6161
for (auto _ : state) {
62-
in >> channel;
63-
out << channel;
62+
channel << in;
63+
channel >> out;
6464
}
6565
}
6666

0 commit comments

Comments
 (0)