libzypp 17.37.17
redo.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------/
9*
10* This file contains private API, this might break at any time between releases.
11* You have been warned!
12*
13*/
14#ifndef ZYPPNG_MONADIC_REDO_H_INCLUDED
15#define ZYPPNG_MONADIC_REDO_H_INCLUDED
16
17#include <zypp-core/zyppng/pipelines/AsyncResult>
18#include <zypp-core/zyppng/meta/FunctionTraits>
19#include <zypp-core/zyppng/meta/TypeTraits>
20#include <zypp-core/zyppng/meta/Functional>
21
22namespace zyppng {
23
24 namespace detail {
25
26
27 template< typename Task, typename Pred, typename = void >
29 {
30
31 static_assert ( !is_async_op< zyppng::remove_smart_ptr<Pred> >::value, "" );
32
33 template <typename T, typename P>
34 RedoWhileImpl( T &&t, P &&p ) :
35 _task( std::forward<T>(t) )
36 , _pred( std::forward<P>(p) ) {}
37
38 template <typename Arg>
39 std::enable_if_t< is_async_op< remove_smart_ptr_t<std::result_of_t<Task(Arg)>> >::value == false, Arg > operator()( Arg &&arg ) {
40 Arg store = std::forward<Arg>(arg);
41 do {
42 auto res = _task ( Arg(store) );
43 if ( !_pred( res ) )
44 return std::move(res);
45 } while( true );
46 }
47
48 template <typename T, typename P>
49 static auto create ( T &&t, P &&p ) {
50 return RedoWhileImpl( std::forward<T>(t), std::forward<P>(p));
51 }
52
53 private:
54 Task _task;
55 Pred _pred;
56 };
57
58 template< typename MyAsyncOp, typename Pred >
59 struct RedoWhileImpl< std::shared_ptr<MyAsyncOp>,Pred, std::enable_if_t< is_async_op< MyAsyncOp >::value > > : public AsyncOp<typename MyAsyncOp::value_type> {
60
61 using Task = std::shared_ptr<MyAsyncOp>;
62 using OutType = typename MyAsyncOp::value_type;
63
64 template <typename T, typename P>
65 RedoWhileImpl( T &&t, P &&p ) :
66 _task( std::forward<T>(t) )
67 , _pred( std::forward<P>(p) ) {}
68
69 static_assert ( !is_async_op< remove_smart_ptr<Pred> >::value, "" );
70
71 template<typename InType>
72 void operator()( InType &&arg ) {
73 _task->onReady(
74 [this, inArg = arg]( OutType &&a) mutable {
75 if ( _pred(a) )
76 this->operator()(std::move(inArg));
77 else
78 this->setReady( std::move(a) );
79 }
80 );
81 _task->operator()( InType(arg) );
82 }
83
84 template <typename T, typename P>
85 static auto create ( T &&t, P &&p ) {
86 return std::make_shared<RedoWhileImpl>( std::forward<T>(t), std::forward<P>(p));
87 }
88
89 private:
90
92 Pred _pred;
93 std::shared_ptr<AsyncOp<OutType>> _pipeline;
94 };
95
96 //implementation for a function returning a asynchronous result
97 template< typename Task, typename Pred >
98 struct RedoWhileImpl< Task,Pred, std::enable_if_t< is_async_op< remove_smart_ptr_t<typename function_traits<Task>::return_type> >::value > > : public AsyncOp< typename remove_smart_ptr_t<typename function_traits<Task>::return_type>::value_type> {
99
101
102 //the task function needs to return the same type it takes
103 using OutType = typename FunRet::value_type;
104
105 template <typename T, typename P>
106 RedoWhileImpl( T &&t, P &&p ) :
107 _task( std::forward<T>(t) )
108 , _pred( std::forward<P>(p) ) {}
109
110 template<typename InType>
111 void operator() ( InType &&arg ) {
112 _asyncRes.reset();
113 _asyncRes = _task( InType( arg ) );
114 _asyncRes->onReady(
115 [this, inArg = arg ]( OutType &&arg ) mutable {
116 if ( _pred(arg) )
117 this->operator()( std::move(inArg) );
118 else
119 this->setReady( std::move(arg) );
120 });
121 }
122
123 template <typename T, typename P>
124 static auto create ( T &&t, P &&p ) {
125 return std::make_shared<RedoWhileImpl>( std::forward<T>(t), std::forward<P>(p));
126 }
127
128 private:
129 std::shared_ptr<AsyncOp<OutType>> _asyncRes;
130
131 Task _task;
132 Pred _pred;
133 };
134
135 //check if it is possible to query the given type for function_traits
136 template <typename T>
138
139 }
140
141 template <typename Task, typename Pred>
142 auto redo_while ( Task &&todo, Pred &&until )
143 {
144 static_assert ( std::is_detected_v< detail::has_func_trait, Task >, "Not possible to deduce the function_traits for Task, maybe a generic lambda?" );
145 return detail::RedoWhileImpl<Task,Pred>::create( std::forward<Task>(todo), std::forward<Pred>(until) );
146 }
147
148}
149
150#endif
unsigned short a
Definition Arch.h:364
typename enable_if< B, T >::type enable_if_t
Definition TypeTraits.h:45
typename result_of< T >::type result_of_t
Definition TypeTraits.h:51
constexpr bool is_detected_v
Definition type_traits.h:57
std::conjunction< has_value_type< remove_smart_ptr_t< T > >, is_asyncop_type< remove_smart_ptr_t< T > > > is_async_op
Definition asyncop.h:55
typename function_traits< T >::return_type has_func_trait
Definition redo.h:137
typename remove_smart_ptr< T >::type remove_smart_ptr_t
auto redo_while(Task &&todo, Pred &&until)
Definition redo.h:142
void setReady(value_type &&val)
Definition asyncop.h:183
std::enable_if_t< is_async_op< remove_smart_ptr_t< std::result_of_t< Task(Arg)> > >::value==false, Arg > operator()(Arg &&arg)
Definition redo.h:39
RedoWhileImpl(T &&t, P &&p)
Definition redo.h:34
static auto create(T &&t, P &&p)
Definition redo.h:49