Skip to content

Commit 96b7c5a

Browse files
committed
Add operations implementations
1 parent ae1d3a8 commit 96b7c5a

File tree

5 files changed

+290
-4
lines changed

5 files changed

+290
-4
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ add_executable(unittesting include/stream.h
6262
include/detail/stream_impl.h
6363
include/detail/continuation_impl.h
6464
tests/stream_deduction_guides.cpp
65-
#[[tests/filters_int_finite_stream.cpp
66-
tests/filters_int_infinite_stream.cpp
65+
tests/filters_int_finite_stream.cpp
66+
#[[tests/filters_int_infinite_stream.cpp
6767
tests/filters_generic_int_stream.cpp
6868
tests/filters_move_only_finite_stream.cpp
6969
tests/filters_move_only_infinite_stream.cpp

include/detail/traits_impl.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,39 @@ namespace stream
202202
// ============================================================================================================
203203

204204
// ============================================================================================================
205+
template<typename C, typename S, typename = void>
206+
struct ContinuationInvokeResult
207+
{};
208+
209+
template<typename C, typename S>
210+
struct ContinuationInvokeResult<Continuation<C, false>, S,
211+
VoidT<InvokeResultT<Continuation<C, false>,
212+
typename StreamTraits<S>::RealType&&,
213+
const S&>>>
214+
{
215+
using Type = InvokeResultT<Continuation<C, false>,
216+
typename StreamTraits<S>::RealType&&,
217+
const S&>;
218+
};
219+
220+
template<typename C, typename S>
221+
struct ContinuationInvokeResult<Continuation<C, true>, S,
222+
VoidT<InvokeResultT<Continuation<C, true>,
223+
typename StreamTraits<S>::RealType&&,
224+
const S&,
225+
bool&>>>
226+
{
227+
using Type = InvokeResultT<Continuation<C, true>,
228+
typename StreamTraits<S>::RealType&&,
229+
const S&,
230+
bool&>;
231+
};
232+
233+
template<typename C, typename S>
234+
using ContinuationInvokeResultT = typename ContinuationInvokeResult<C, S>::Type;
235+
236+
237+
205238
template<typename C, typename S, typename = void>
206239
struct ContinuationForTraitsImpl
207240
{
@@ -220,6 +253,11 @@ namespace stream
220253
const S&>;
221254
};
222255

256+
template<typename C, typename S>
257+
struct ContinuationForTraitsImpl<Continuation<C, false>, S,
258+
VoidT<::std::enable_if_t<::std::is_same<>::value>>
259+
>
260+
223261
template<typename C, typename S>
224262
struct ContinuationForTraitsImpl<Continuation<C, true>, S,
225263
VoidT<InvokeResultT<Continuation<C, true>,

include/operations.h

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,256 @@
33

44
#include "stream.h"
55
#include "traits.h"
6+
#include "continuation.h"
7+
#include <cstddef>
8+
#include <type_traits>
9+
610

711
namespace stream
812
{
913
namespace ops
1014
{
15+
template<typename OStream>
16+
auto print_to(OStream &oStream, const char *delim = " ")
17+
{
18+
return [&oStream, delim](auto &&stream) -> OStream& {
19+
while (!stream.isEnd())
20+
{
21+
auto val = stream.getNext();
22+
if (val)
23+
{
24+
oStream << val.value().get();
25+
break;
26+
}
27+
}
28+
29+
while (!stream.isEnd())
30+
{
31+
auto val = stream.getNext();
32+
if (val)
33+
{
34+
oStream << delim << val.value().get();
35+
}
36+
}
37+
38+
return oStream;
39+
};
40+
}
41+
42+
43+
inline auto skip(::std::size_t amount)
44+
{
45+
return makeContinuation<false>([amount](auto &&value, auto &&stream) mutable {
46+
using Type = typename stream::StreamTraits<decltype(stream)>::RealType;
47+
48+
if (amount > 0) {
49+
--amount;
50+
return ::std::optional<Type>{::std::nullopt};
51+
}
52+
53+
return ::std::optional<Type>{::std::forward<decltype(value)>(value)};
54+
});
55+
}
56+
57+
58+
template<typename Transform>
59+
auto map(Transform &&transform)
60+
{
61+
return makeContinuation<false>([transform = ::std::forward<Transform>(transform)](auto &&value, auto &&stream) mutable {
62+
using ReturnType = detail::InvokeResultT<::std::decay_t<Transform>, decltype(::std::move(value.get()))>;
63+
using Type = ValueHolder<ReturnType>;
64+
65+
return ::std::optional<Type>{transform(::std::move(value.get()))};
66+
});
67+
}
68+
69+
70+
inline auto get(::std::size_t n)
71+
{
72+
return makeContinuation<true>([n](auto &&value, auto &&stream, bool &end) mutable {
73+
using Type = typename stream::StreamTraits<decltype(stream)>::RealType;
74+
if (n > 0)
75+
{
76+
--n;
77+
end = (n == 0);
78+
return ::std::optional<Type>{::std::forward<decltype(value)>(value)};
79+
}
80+
81+
end = true;
82+
return ::std::optional<Type>{::std::nullopt};
83+
});
84+
}
85+
86+
87+
template<typename Identity, typename Accumulator>
88+
auto reduce(Identity &&identity, Accumulator &&accumulator)
89+
{
90+
return [f1 = ::std::forward<Identity>(identity), fn = ::std::forward<Accumulator>(accumulator)](
91+
auto &&stream) mutable {
92+
using Type = detail::InvokeResultT<decltype(f1), decltype(::std::move(stream.getNext()->get()))>;
93+
94+
if (stream.isEnd())
95+
{
96+
return Type{};
97+
}
98+
99+
Type result;
100+
while (!stream.isEnd())
101+
{
102+
auto initializer = stream.getNext();
103+
if (initializer)
104+
{
105+
result = f1(::std::move(initializer->get()));
106+
break;
107+
}
108+
}
109+
110+
while (!stream.isEnd())
111+
{
112+
auto forReduce = stream.getNext();
113+
if (forReduce)
114+
{
115+
result = fn(::std::move(result), ::std::move(forReduce->get()));
116+
}
117+
}
118+
119+
return result;
120+
};
121+
}
122+
123+
124+
template<typename Accumulator>
125+
auto reduce(Accumulator &&accumulator)
126+
{
127+
return reduce([](auto &&elem){ return ::std::forward<decltype(elem)>(elem); },
128+
::std::forward<Accumulator>(accumulator));
129+
}
130+
131+
132+
inline auto sum()
133+
{
134+
return reduce([](auto &&v1, auto &&v2) { return v1 + v2; });
135+
}
136+
137+
138+
inline auto nth(::std::size_t index)
139+
{
140+
return [index](auto &&stream) mutable {
141+
while (index > 0)
142+
{
143+
if constexpr (StreamTraits<decltype(stream)>::IsFinite)
144+
{
145+
if (stream.isEnd())
146+
{
147+
throw ::std::out_of_range("Out of Stream range");
148+
}
149+
}
150+
151+
if (stream.getNext())
152+
{
153+
--index;
154+
}
155+
}
156+
157+
auto result = stream.getNext();
158+
while (!result)
159+
{
160+
if constexpr (StreamTraits<decltype(stream)>::IsFinite)
161+
{
162+
if (stream.isEnd())
163+
{
164+
throw ::std::out_of_range("Out of Stream range");
165+
}
166+
}
167+
168+
result = stream.getNext();
169+
}
170+
171+
return ::std::move(result->get());
172+
};
173+
}
174+
175+
176+
inline auto to_vector()
177+
{
178+
return [](auto &&stream) {
179+
using Type = typename StreamTraits<decltype(stream)>::ValueType;
180+
181+
::std::vector<Type> result;
182+
while (!stream.isEnd())
183+
{
184+
auto value = stream.getNext();
185+
if (value)
186+
{
187+
result.emplace_back(::std::move(value->get()));
188+
}
189+
}
190+
191+
return result;
192+
};
193+
}
194+
195+
196+
template<typename Predicate>
197+
auto filter(Predicate &&predicate)
198+
{
199+
return makeContinuation<false>([predicate = ::std::forward<Predicate>(predicate)](auto &&value, auto &&stream) {
200+
using Type = typename StreamTraits<decltype(stream)>::RealType;
201+
if (predicate(static_cast<const Type&>(value).get()))
202+
{
203+
return ::std::optional<Type>{::std::forward<decltype(value)>(value)};
204+
}
205+
206+
return ::std::optional<Type>{::std::nullopt};
207+
});
208+
}
209+
210+
211+
class group
212+
{
213+
public:
214+
group(::std::size_t n) : n(n) {}
215+
216+
217+
template<typename Stream, ::std::enable_if_t<StreamTraits<Stream>::IsFinite>* = nullptr>
218+
auto createContinuation()
219+
{
220+
using Type = typename StreamTraits<Stream>::ValueType;
221+
222+
::std::size_t n = this->n;
223+
return makeContinuation<false>([n, vec = ::std::vector<Type>{}](auto &&value, auto &&stream) mutable {
224+
vec.emplace_back(::std::move(value.get()));
225+
226+
if ((vec.size() == n) || stream.isEnd())
227+
{
228+
return ::std::optional<::std::vector<Type>>(::std::move(vec));
229+
}
230+
231+
return ::std::optional<::std::vector<Type>>(::std::nullopt);
232+
});
233+
}
234+
235+
template<typename Stream, ::std::enable_if_t<!StreamTraits<Stream>::IsFinite>* = nullptr>
236+
auto createContinuation()
237+
{
238+
using Type = typename StreamTraits<Stream>::ValueType;
239+
240+
::std::size_t n = this->n;
241+
return makeContinuation<false>([n, vec = ::std::vector<Type>{}](auto &&value, auto &&stream) mutable {
242+
vec.emplace_back(::std::move(value.get()));
243+
244+
if (vec.size() == n)
245+
{
246+
return ::std::optional<::std::vector<Type>>(::std::move(vec));
247+
}
248+
249+
return ::std::optional<::std::vector<Type>>(::std::nullopt);
250+
});
251+
}
11252

253+
private:
254+
::std::size_t n;
255+
};
12256
}
13257
}
14258

include/traits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace stream
1616

1717
using detail::ContainerTraits;
1818
using detail::IsContainerV;
19+
20+
using detail::StreamTraits;
1921
}
2022

2123
#endif //CPP_STREAM_TRAITS_H

tests/filters_int_finite_stream.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <stream.h>
2-
#include <filters_lib.h>
2+
#include <operations.h>
33
#include <vector>
44
#include <sstream>
55
#include <type_traits>
@@ -8,7 +8,7 @@
88

99

1010
using namespace stream;
11-
using namespace stream::filters;
11+
using namespace stream::ops;
1212

1313

1414
TEST(FILTERS_INT_FINITE_STREAM, PRINT_TO_RETURNVALUE)
@@ -50,6 +50,7 @@ TEST(FILTERS_INT_FINITE_STREAM, PRINT_TO_GENERIC)
5050
stream::Stream(1, 2, 3, 4, 5, 6, 7, 8, 9) | print_to(stream);
5151
ASSERT_EQ(stream.str(), "1 2 3 4 5 6 7 8 9");
5252
}
53+
/*
5354
5455
5556
TEST(FILTERS_INT_FINITE_STREAM, SKIP_0)
@@ -351,3 +352,4 @@ TEST(FILTERS_INT_FINITE_STREAM, GROUP_GENERIC_TO_ONE_MORE2)
351352
ASSERT_EQ(result.size(), 1U);
352353
ASSERT_THAT(result[0], testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 9));
353354
}
355+
*/

0 commit comments

Comments
 (0)