1010
1111#include < thread>
1212#include < type_traits>
13+ #include < utility>
1314#include < vector>
1415
1516#include " ReactiveBase.h"
@@ -123,6 +124,39 @@ class EventSource : public Events<D,E>
123124 }
124125};
125126
127+ // /////////////////////////////////////////////////////////////////////////////////////////////////
128+ // / TempEvents
129+ // /////////////////////////////////////////////////////////////////////////////////////////////////
130+ template
131+ <
132+ typename D,
133+ typename E,
134+ typename TOp
135+ >
136+ class TempEvents : public Events <D,E>
137+ {
138+ protected:
139+ using NodeT = REACT_IMPL::EventOpNode<D,E,TOp>;
140+
141+ public:
142+ TempEvents () :
143+ Events ()
144+ {}
145+
146+ explicit TempEvents (const std::shared_ptr<NodeT>& ptr) :
147+ Events(ptr)
148+ {}
149+
150+ explicit TempEvents (std::shared_ptr<NodeT>&& ptr) :
151+ Events(std::move(ptr))
152+ {}
153+
154+ TOp StealOp ()
155+ {
156+ return std::move (std::static_pointer_cast<NodeT>(ptr_)->StealOp ());
157+ }
158+ };
159+
126160// /////////////////////////////////////////////////////////////////////////////////////////////////
127161// / MakeEventSource
128162// /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -149,32 +183,107 @@ template
149183<
150184 typename D,
151185 typename TArg1,
152- typename ... TArgs
186+ typename ... TArgs,
187+ typename E = TArg1,
188+ typename TOp = REACT_IMPL::EventMergeOp<E,
189+ REACT_IMPL::EventStreamNodePtr<D,TArg1>,
190+ REACT_IMPL::EventStreamNodePtr<D,TArgs> ...>
153191>
154- inline auto Merge (const Events<D,TArg1>& arg1,
155- const Events<D,TArgs>& ... args)
156- -> Events<D,TArg1>
192+ auto Merge (const Events<D,TArg1>& arg1, const Events<D,TArgs>& ... args)
193+ -> TempEvents<D,E,TOp>
157194{
158195 static_assert (sizeof ...(TArgs) > 0 ,
159196 " react::Merge requires at least 2 arguments." );
160197
161- typedef TArg1 E;
162- return Events<D,E>(
163- std::make_shared<REACT_IMPL::EventMergeNode<D, E, TArg1, TArgs ...>>(
198+ return TempEvents<D,E,TOp>(
199+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
164200 arg1.GetPtr (), args.GetPtr () ...));
165201}
166202
203+ template
204+ <
205+ typename TLeftEvents,
206+ typename TRightEvents,
207+ typename D = TLeftEvents::DomainT,
208+ typename TLeftVal = TLeftEvents::ValueT,
209+ typename TRightVal = TRightEvents::ValueT,
210+ typename E = TLeftVal,
211+ typename TOp = REACT_IMPL::EventMergeOp<E,
212+ REACT_IMPL::EventStreamNodePtr<D,TLeftVal>,
213+ REACT_IMPL::EventStreamNodePtr<D,TRightVal>>,
214+ class = std::enable_if<
215+ IsEvent<TLeftEvents>::value>::type,
216+ class = std::enable_if<
217+ IsEvent<TRightEvents>::value>::type
218+ >
219+ auto operator |(const TLeftEvents& lhs, const TRightEvents& rhs)
220+ -> TempEvents<D,E,TOp>
221+ {
222+ return TempEvents<D,E,TOp>(
223+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
224+ lhs.GetPtr (), rhs.GetPtr ()));
225+ }
226+
167227template
168228<
169229 typename D,
170- typename TLeftArg,
171- typename TRightArg
230+ typename TLeftVal,
231+ typename TLeftOp,
232+ typename TRightVal,
233+ typename TRightOp,
234+ typename E = TLeftVal,
235+ typename TOp = REACT_IMPL::EventMergeOp<E,TLeftOp,TRightOp>
172236>
173- inline auto operator |(const Events<D,TLeftArg>& lhs,
174- const Events<D,TRightArg>& rhs)
175- -> Events<D, TLeftArg>
237+ auto operator |(TempEvents<D,TLeftVal,TLeftOp>&& lhs, TempEvents<D,TRightVal,TRightOp>&& rhs)
238+ -> TempEvents<D,E,TOp>
176239{
177- return Merge (lhs,rhs);
240+ return TempEvents<D,E,TOp>(
241+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
242+ lhs.StealOp (), rhs.StealOp ()));
243+ }
244+
245+ template
246+ <
247+ typename D,
248+ typename TLeftVal,
249+ typename TLeftOp,
250+ typename TRightEvents,
251+ typename TRightVal = TRightEvents::ValueT,
252+ typename E = TLeftVal,
253+ typename TOp = REACT_IMPL::EventMergeOp<E,
254+ TLeftOp,
255+ REACT_IMPL::EventStreamNodePtr<D,TRightVal>>,
256+ class = std::enable_if<
257+ IsEvent<TRightEvents>::value>::type
258+ >
259+ auto operator |(TempEvents<D,TLeftVal,TLeftOp>&& lhs, const TRightEvents& rhs)
260+ -> TempEvents<D,E,TOp>
261+ {
262+ return TempEvents<D,E,TOp>(
263+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
264+ lhs.StealOp (), rhs.GetPtr ()));
265+ }
266+
267+ template
268+ <
269+ typename TLeftEvents,
270+ typename D,
271+ typename TRightVal,
272+ typename TRightOp,
273+ typename TLeftVal = TLeftEvents::ValueT,
274+ typename E = TLeftVal,
275+ typename TOp = REACT_IMPL::EventMergeOp<E,
276+ REACT_IMPL::EventStreamNodePtr<D,TRightVal>,
277+ TRightOp>,
278+ class = std::enable_if<
279+ IsEvent<TLeftEvents>::value>::type
280+ >
281+ auto operator |(const TLeftEvents& lhs, TempEvents<D,TRightVal,TRightOp>&& rhs)
282+ -> TempEvents<D,E,TOp>
283+ {
284+ return TempEvents<D,E,TOp>(
285+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
286+ lhs.GetPtr (), rhs.StealOp ()));
178287}
179288
180289// /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -184,14 +293,47 @@ template
184293<
185294 typename D,
186295 typename E,
187- typename F
296+ typename FIn,
297+ typename F = std::decay<FIn>::type,
298+ typename TOp = REACT_IMPL::EventFilterOp<E,F,
299+ REACT_IMPL::EventStreamNodePtr<D,E>>
188300>
189- inline auto Filter (const Events<D,E>& src, F && filter)
190- -> Events <D,E>
301+ auto Filter (const Events<D,E>& src, FIn && filter)
302+ -> TempEvents <D,E,TOp >
191303{
192- return Events<D,E>(
193- std::make_shared<REACT_IMPL::EventFilterNode<D,E,F>>(
194- src.GetPtr (), std::forward<F>(filter)));
304+ return TempEvents<D,E,TOp>(
305+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
306+ std::forward<FIn>(filter), src.GetPtr ()));
307+ }
308+
309+ template
310+ <
311+ typename D,
312+ typename E,
313+ typename TOpIn,
314+ typename FIn,
315+ typename F = std::decay<FIn>::type,
316+ typename TOpOut = REACT_IMPL::EventFilterOp<E,F,TOpIn>
317+ >
318+ auto Filter (TempEvents<D,E,TOpIn>&& src, FIn&& filter)
319+ -> TempEvents<D,E,TOpOut>
320+ {
321+ return TempEvents<D,E,TOpOut>(
322+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOpOut>>(
323+ std::forward<FIn>(filter), src.StealOp ()));
324+ }
325+
326+ template
327+ <
328+ typename TEvents,
329+ typename F,
330+ class = std::enable_if<
331+ IsEvent<TEvents>::value>::type
332+ >
333+ auto operator &(TEvents&& src, F&& filter)
334+ -> decltype (Filter(std::forward<TEvents>(src), std::forward<F>(filter)))
335+ {
336+ return Filter (std::forward<TEvents>(src), std::forward<F>(filter));
195337}
196338
197339// /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -200,17 +342,48 @@ inline auto Filter(const Events<D,E>& src, F&& filter)
200342template
201343<
202344 typename D,
203- typename TIn,
204- typename F
345+ typename E,
346+ typename FIn,
347+ typename F = std::decay<FIn>::type,
348+ typename TOp = REACT_IMPL::EventTransformOp<E,F,
349+ REACT_IMPL::EventStreamNodePtr<D,E>>
350+ >
351+ auto Transform (const Events<D,E>& src, FIn&& func)
352+ -> TempEvents<D,E,TOp>
353+ {
354+ return TempEvents<D,E,TOp>(
355+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
356+ std::forward<FIn>(func), src.GetPtr ()));
357+ }
358+
359+ template
360+ <
361+ typename D,
362+ typename E,
363+ typename TOpIn,
364+ typename FIn,
365+ typename F = std::decay<FIn>::type,
366+ typename TOpOut = REACT_IMPL::EventTransformOp<E,F,TOpIn>
205367>
206- inline auto Transform (const Events <D,TIn>& src, F && func)
207- -> Events <D, typename std::result_of<F(TIn)>::type >
368+ auto Transform (TempEvents <D,E,TOpIn>&& src, FIn && func)
369+ -> TempEvents <D,E,TOpOut >
208370{
209- using TOut = typename std::result_of<F (TIn)>::type;
371+ return TempEvents<D,E,TOpOut>(
372+ std::make_shared<REACT_IMPL::EventOpNode<D,E,TOpOut>>(
373+ std::forward<FIn>(func), src.StealOp ()));
374+ }
210375
211- return Events<D,TOut>(
212- std::make_shared<REACT_IMPL::EventTransformNode<D,TIn,TOut,F>>(
213- src.GetPtr (), std::forward<F>(func)));
376+ template
377+ <
378+ typename TEvents,
379+ typename F,
380+ class = std::enable_if<
381+ IsEvent<TEvents>::value>::type
382+ >
383+ auto operator ->*(TEvents&& src, F&& func)
384+ -> decltype (Transform(std::forward<TEvents>(src), std::forward<F>(func)))
385+ {
386+ return Transform (std::forward<TEvents>(src), std::forward<F>(func));
214387}
215388
216389/* *****************************************/ REACT_END /* *****************************************/
0 commit comments