|
1 | 1 | #ifndef CPP_STREAM_DETAIL_STREAM_BASE_H |
2 | 2 | #define CPP_STREAM_DETAIL_STREAM_BASE_H |
3 | 3 |
|
4 | | -#include "traits_impl.h" // InvokeResultT |
5 | | -#include "stream_traits_impl.h" // IsStreamFilterFor |
6 | | -#include "is_filters_factory_for_impl.h" // IsFiltersFactoryFor |
7 | | -#include <type_traits> // ::std::enable_if_t, ::std::decay_t, ::std::is_reference |
8 | | -#include <utility> // ::std::move, ::std::forward |
| 4 | +#include "traits_impl.h" |
| 5 | +#include <type_traits> // ::std::enable_if_t |
| 6 | +#include <optional> // ::std::optional |
| 7 | +#include "../value_holder.h" |
9 | 8 |
|
10 | 9 | namespace stream |
11 | 10 | { |
12 | 11 | template<typename, typename> |
13 | 12 | struct Stream; |
14 | 13 |
|
| 14 | + |
15 | 15 | namespace detail |
16 | 16 | { |
17 | | - template<typename, typename, typename> |
18 | | - class StreamFilter; |
| 17 | + template<typename OldStream, typename Contin> |
| 18 | + struct CombinedStreamTag; |
19 | 19 |
|
20 | 20 |
|
21 | | - template<typename T, bool Finiteness, typename StreamImpl> |
22 | | - class StreamBase |
| 21 | + template<typename T, bool Finiteness, typename Derived> |
| 22 | + struct StreamBase |
23 | 23 | { |
24 | | - public: |
25 | | - using Type = ::std::conditional_t<::std::is_reference<T>::value, |
26 | | - ::std::reference_wrapper<::std::remove_reference_t<T>>, |
27 | | - T>; |
| 24 | + using ValueType = RemoveCVRefT<T>; |
28 | 25 | static constexpr bool IsFinite = Finiteness; |
29 | 26 |
|
30 | 27 |
|
31 | | - template<typename Filter, typename ::std::enable_if_t<IsStreamFilterFor<Filter, StreamImpl>::value>* = nullptr> |
32 | | - auto operator|(Filter &&filter) |
| 28 | + bool isEnd() const |
33 | 29 | { |
34 | | - using V = typename InvokeResultT<::std::decay_t<Filter>, Type&&, const StreamImpl&, bool&>::value_type; |
35 | | - return stream::Stream<V, StreamFilter<StreamImpl, Filter, void>>(::std::move(static_cast<StreamImpl&>(*this)), |
36 | | - ::std::forward<Filter>(filter)); |
| 30 | + static_assert(IsFinite, "This Stream is infinite"); |
| 31 | + return static_cast<const Derived*>(this)->isEndImpl(); |
37 | 32 | } |
38 | 33 |
|
39 | 34 |
|
40 | | - template<typename Factory, typename ::std::enable_if_t<!IsStreamFilterFor<Factory, StreamImpl>::value |
41 | | - && IsFiltersFactoryFor<Factory, StreamImpl>::value>* = nullptr> |
42 | | - auto operator|(Factory &&factory) |
| 35 | + template<typename Contin, ::std::enable_if_t<IsContinuationForV<Contin, Derived>>* = nullptr> |
| 36 | + auto operator|(Contin &&contin) |
43 | 37 | { |
44 | | - return operator|(::std::forward<Factory>(factory).template createFilter<StreamImpl>()); |
45 | | - }; |
| 38 | + using V = UnwrapValueHolderT<typename ContinuationForTraits<Contin, Derived>::ValueType>; |
| 39 | + using RetStreamT = stream::Stream<V, CombinedStreamTag<Derived, ::std::remove_reference_t<Contin>>>; |
46 | 40 |
|
| 41 | + return RetStreamT(::std::move(static_cast<Derived&>(*this)), ::std::forward<Contin>(contin)); |
| 42 | + } |
47 | 43 |
|
48 | | - template<typename Term, typename ::std::enable_if_t<!IsStreamFilterFor<Term, StreamImpl>::value |
49 | | - && !IsFiltersFactoryFor<Term, StreamImpl>::value>* = nullptr> |
50 | | - decltype(auto) operator|(Term &&nonFilter) |
| 44 | + |
| 45 | + template<typename Factory, ::std::enable_if_t<!IsContinuationForV<Factory, Derived> |
| 46 | + && IsContinuationsFactoryForV<Factory, Derived>>* = nullptr> |
| 47 | + auto operator|(Factory &&factory) |
51 | 48 | { |
52 | | - return ::std::forward<Term>(nonFilter)(::std::move(static_cast<StreamImpl&>(*this))); |
| 49 | + return operator|(::std::forward<Factory>(factory).template createContinuation<Derived>()); |
53 | 50 | } |
54 | 51 |
|
55 | 52 |
|
56 | | - bool isEnd() const |
| 53 | + template<typename Consumer, ::std::enable_if_t< !IsContinuationForV<Consumer, Derived> |
| 54 | + && !IsContinuationsFactoryForV<Consumer, Derived> |
| 55 | + && IsConsumerForV<Consumer, Derived> >* = nullptr> |
| 56 | + decltype(auto) operator|(Consumer &&consumer) |
57 | 57 | { |
58 | | - static_assert(IsFinite, "This stream is infinite"); |
59 | | - return static_cast<const StreamImpl *>(this)->isEndImpl(); |
| 58 | + return ::std::forward<Consumer>(consumer)(::std::move(static_cast<Derived&>(*this))); |
60 | 59 | } |
61 | 60 | }; |
62 | 61 | } |
|
0 commit comments