libzypp  17.34.1
algorithm.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_PIPELINES_ALGORITHM_H_INCLUDED
15 #define ZYPPNG_PIPELINES_ALGORITHM_H_INCLUDED
16 
17 #include <zypp-core/zyppng/async/AsyncOp>
18 #include <functional>
19 
20 namespace zyppng {
21 
22  namespace detail {
23 
25  template< class Arg >
26  bool operator()( const Arg &value ) {
27  // works if operator bool() const is implemented by type Arg
28  return !value;
29  }
30  };
31 
32  template <typename T>
33  struct showme;
34 
35  template < class Container, class AsyncResType, class Transformation, class Predicate, class DefaultType >
36  struct AsyncFirstOfImpl : public AsyncOp<AsyncResType> {
37 
38  AsyncFirstOfImpl( Container &&inData, Transformation &&transFunc, DefaultType &&defaultVal, Predicate &&predicate )
39  : _inData ( std::move(inData) )
40  , _transFunc ( std::move(transFunc) )
41  , _defaultVal( std::move(defaultVal) )
42  , _predicate ( std::move(predicate))
43  , _currIter ( _inData.begin() ) { execute(); }
44 
45  private:
46  void execute() {
47  // seems this is empty we are ready
48  if ( _currIter == _inData.end() ) {
49  return returnDefault();
50  }
51  invokeCurrent();
52  }
53 
54  void resultReady ( AsyncResType &&res ) {
55 
56  if ( !_predicate(res) ) {
57  _currIter = std::next( _currIter );
58  // seems we reached the end
59  if ( _currIter == _inData.end() ) {
60  return returnDefault();
61  }
62  invokeCurrent();
63  } else {
64  this->setReady ( std::move(res) );
65  return;
66  }
67 
68  }
69 
70  void invokeCurrent() {
72  _currentPipeline->onReady( [ this ]( AsyncResType &&res ) {
73  this->resultReady( std::move(res));
74  });
75  }
76  void returnDefault() {
77  this->setReady ( std::move(_defaultVal) );
78  return;
79  }
80 
81  private:
82  Container _inData;
83  Transformation _transFunc;
84  DefaultType _defaultVal;
85  Predicate _predicate;
86  typename Container::iterator _currIter;
88  };
89 
90  template < class Transformation, class Predicate, class DefaultType >
91  struct FirstOfHelper {
92 
93  FirstOfHelper( Transformation transFunc, DefaultType defaultVal, Predicate predicate )
94  : _transFunc ( std::move(transFunc) )
95  , _defaultVal( std::move(defaultVal) )
96  , _predicate ( std::move(predicate)) { }
97 
98  template < class Container
99  , typename ...CArgs>
100  auto operator()( Container &&container ) {
101 
102  using InputType = typename Container::value_type;
103  static_assert( std::is_invocable_v<Transformation, InputType>, "Transformation function must take the container value type as input " );
104  static_assert( std::is_rvalue_reference_v<decltype(std::forward<Container>(container))>, "Input container must be a rvalue reference" );
105 
106  using OutputType = std::invoke_result_t<Transformation, InputType>;
107 
108  if constexpr ( detail::is_async_op_v<OutputType> ) {
109 
110  using AsyncResultType = typename remove_smart_ptr_t<OutputType>::value_type;
111 
112  static_assert( std::is_same_v<AsyncResultType, DefaultType>, "Default type and transformation result type must match" );
113 
115  return static_cast<AsyncOpRef<AsyncResultType>>( std::make_shared<ImplType>( std::forward<Container>(container), std::move(_transFunc), std::move(_defaultVal), std::move(_predicate) ) );
116 
117  } else {
118 
119  static_assert( std::is_same_v<OutputType, DefaultType>, "Default type and transformation result type must match" );
120 
121  for ( auto &in : std::forward<Container>(container) ) {
122  OutputType res = std::invoke( _transFunc, std::move(in) );
123  if ( !_predicate(res) ) {
124  return res;
125  }
126  }
127  return _defaultVal;
128  }
129  }
130 
131  private:
132  Transformation _transFunc;
133  DefaultType _defaultVal;
134  Predicate _predicate;
135  };
136 
137  }
138 
143  public:
144  NotFoundException() : zypp::Exception("No Entry found"){}
145  };
146 
147  template < class Transformation, class DefaultType, class Predicate >
148  inline auto firstOf( Transformation &&transformFunc, DefaultType &&def, Predicate &&predicate = detail::ContinueUntilValidPredicate() ) {
149  return detail::FirstOfHelper<Transformation, Predicate, DefaultType> ( std::forward<Transformation>(transformFunc), std::forward<DefaultType>(def), std::forward<Predicate>(predicate) );
150  }
151 
152  namespace detail {
153 
154  template <typename Excpt, typename ...Rest>
155  bool containsOneOfExceptionImpl( const std::exception_ptr &exceptionPtr ) {
156  try {
157  if constexpr ( sizeof...(Rest) == 0 ) {
158  // on the lowest level we throw the exception
159  std::rethrow_exception ( exceptionPtr );
160  } else {
161  return containsOneOfExceptionImpl<Rest...>(exceptionPtr);
162  }
163  } catch ( const Excpt &e ) {
164  return true;
165  }
166  }
167 
168  }
169 
185  template <typename ...Excpt>
186  bool containsOneOfException( const std::exception_ptr &exceptionPtr ) {
187  try {
188  return detail::containsOneOfExceptionImpl<Excpt...>( exceptionPtr );
189  } catch ( ... ) {}
190  return false;
191  }
192 
206  template <typename Excpt>
207  bool containsException( const std::exception_ptr &exceptionPtr ) {
208  try {
209  std::rethrow_exception ( exceptionPtr );;
210  } catch ( const Excpt &e ) {
211  return true;
212  } catch ( ... ) {}
213  return false;
214  }
215 
216 
217 }
218 
219 
220 
221 
222 #endif
FirstOfHelper(Transformation transFunc, DefaultType defaultVal, Predicate predicate)
Definition: algorithm.h:93
bool containsException(const std::exception_ptr &exceptionPtr)
Definition: algorithm.h:207
Definition: Arch.h:363
void setReady(value_type &&val)
Definition: asyncop.h:183
std::enable_if< std::is_member_pointer< typename std::decay< Functor >::type >::value, typename std::result_of< Functor &&(Args &&...)>::type >::type invoke(Functor &&f, Args &&... args)
Definition: functional.h:32
bool containsOneOfExceptionImpl(const std::exception_ptr &exceptionPtr)
Definition: algorithm.h:155
void resultReady(AsyncResType &&res)
Definition: algorithm.h:54
auto firstOf(Transformation &&transformFunc, DefaultType &&def, Predicate &&predicate=detail::ContinueUntilValidPredicate())
Definition: algorithm.h:148
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition: asyncop.h:255
auto operator()(Container &&container)
Definition: algorithm.h:100
Base class for Exception.
Definition: Exception.h:146
Predicate predicate
Definition: PoolQuery.cc:314
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
Container::iterator _currIter
Definition: algorithm.h:86
bool containsOneOfException(const std::exception_ptr &exceptionPtr)
Definition: algorithm.h:186
typename remove_smart_ptr< T >::type remove_smart_ptr_t
Definition: type_traits.h:128
AsyncOpRef< AsyncResType > _currentPipeline
Definition: algorithm.h:87
AsyncFirstOfImpl(Container &&inData, Transformation &&transFunc, DefaultType &&defaultVal, Predicate &&predicate)
Definition: algorithm.h:38