libzypp  17.32.5
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 
22 namespace 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>
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
typename function_traits< T >::return_type has_func_trait
Definition: redo.h:137
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
Definition: Arch.h:363
typename enable_if< B, T >::type enable_if_t
Definition: TypeTraits.h:42
static auto create(T &&t, P &&p)
Definition: redo.h:49
unsigned short a
auto redo_while(Task &&todo, Pred &&until)
Definition: redo.h:142
typename remove_smart_ptr< T >::type remove_smart_ptr_t
Definition: type_traits.h:128