DocWire SDK
DocWire SDK: Award-winning modern data processing in C++20. SourceForge Community Choice & Microsoft support. AI-driven processing. Supports nearly 100 data formats, including email boxes and OCR. Boost efficiency in text extraction, web data extraction, data mining, document analysis. Offline processing possible for security and confidentiality
chaining.h
1 /*********************************************************************************************************************************************/
2 /* DocWire SDK: Award-winning modern data processing in C++20. SourceForge Community Choice & Microsoft support. AI-driven processing. */
3 /* Supports nearly 100 data formats, including email boxes and OCR. Boost efficiency in text extraction, web data extraction, data mining, */
4 /* document analysis. Offline processing possible for security and confidentiality */
5 /* */
6 /* Copyright (c) SILVERCODERS Ltd, http://silvercoders.com */
7 /* Project homepage: https://github.com/docwire/docwire */
8 /* */
9 /* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-DocWire-Commercial */
10 /*********************************************************************************************************************************************/
11 
12 #ifndef DOCWIRE_CHAINING_H
13 #define DOCWIRE_CHAINING_H
14 
15 #include "invocation_concepts.h"
16 #include "invocation_traits.h"
17 #include "ref_or_owned.h"
18 #include "tuple_utils.h"
19 
27 {
28 
41 template<invocation_concepts::not_invocable V, invocation_concepts::invocable F>
43 {
48 
52  ref_or_owned<F> function;
53 
61  template <typename... Args>
62  auto operator()(Args&&... args)
63  {
64  return function.get()(value.get(), std::forward<Args>(args)...);
65  }
66 
71 };
72 
90 template <invocation_concepts::not_invocable V, invocation_concepts::invocable F>
91 auto operator|(V&& value, F&& function)
92 {
93  value_to_function_binding<std::decay_t<V>, std::decay_t<F>> binding
94  { std::forward<V>(value), std::forward<F>(function) };
95  if constexpr (invocation_traits::arity_v<decltype(binding)> == 0)
96  return binding();
97  else
98  return binding;
99 }
100 
115 template<invocation_concepts::invocable F1, invocation_concepts::invocable F2>
117 {
118  static_assert(invocation_traits::arity_v<F1> > 0);
119 
124 
129 
137  template <typename... Args>
138  auto operator()(Args&&... args) const
139  {
140  constexpr auto f1_arg_count = invocation_traits::arity_v<F1> - 1; // exclude callback
141  constexpr auto f2_arg_count = invocation_traits::arity_v<F2> - 1; // exclude callback argument;
142  static_assert(f1_arg_count + f2_arg_count == sizeof...(args));
143 
144  auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
145 
146  auto f2_args = tuple_utils::subrange<f1_arg_count, f2_arg_count>(args_tuple);
147  auto callback = [this, f2_args](auto&& arg) {
148  auto merged_args = std::tuple_cat(std::make_tuple(std::forward<decltype(arg)>(arg)), f2_args);
149  return std::apply(
150  function2.get(), merged_args);
151  };
152 
153  auto f1_args = tuple_utils::subrange<0, f1_arg_count>(args_tuple);
154  return std::apply(function1.get(), std::tuple_cat(f1_args, std::make_tuple(callback)));
155  }
156 
161  decltype(std::tuple_cat(
164  ));
165 };
166 
183 template <invocation_concepts::invocable F1, invocation_concepts::invocable F2>
184 auto operator|(F1&& function1, F2&& function2)
185 {
186  function_to_function_binding<std::decay_t<F1>, std::decay_t<F2>> binding
187  { std::forward<F1>(function1), std::forward<F2>(function2) };
188  if constexpr (invocation_traits::arity_v<decltype(binding)> == 0)
189  return binding();
190  else
191  return binding;
192 }
193 
206 template<invocation_concepts::invocable F, invocation_concepts::pushable C>
208 {
212  ref_or_owned<F> function;
213 
218 
226  template <typename... Args>
227  auto operator()(Args&&... args)
228  {
229  using F_args_t = invocation_traits::args_t<F>;
230  static_assert(std::tuple_size_v<F_args_t> > 0);
231  using F_last_arg_t = tuple_utils::last_element_t<F_args_t>;
232  using callback_ret_type = invocation_traits::result_t<F_last_arg_t>;
233  return function.get()(std::forward<Args>(args)..., [this](auto&& arg)->callback_ret_type
234  {
235  container.get().push_back(arg);
236  if constexpr (!std::is_void_v<callback_ret_type>)
237  return callback_ret_type{};
238  });
239  }
240 
245 };
246 
264 template <invocation_concepts::invocable F, invocation_concepts::pushable C>
265 auto operator|(F&& function, C&& container)
266 {
267  function_to_pushable_binding<std::decay_t<F>, std::decay_t<C>> binding
268  { std::forward<F>(function), std::forward<C>(container) };
269  if constexpr (invocation_traits::arity_v<decltype(binding)> == 0)
270  return binding();
271  else
272  return binding;
273 }
274 
275 } // namespace docwire::chaining
276 
277 #endif //DOCWIRE_CHAINING_H
const T & get() const
Returns a const reference to the stored object, regardless of whether it is stored as a reference or ...
Definition: ref_or_owned.h:81
Provides functionality for chaining function calls and value transformations.
Definition: chaining.h:27
auto operator|(V &&value, F &&function)
Binds a value to a function, enabling the creation of a function call chain.
Definition: chaining.h:91
typename result< T >::type result_t
Type alias for the type member of the result struct.
typename args< T >::type args_t
Type alias for the type member of the args struct.
decltype(last_element(std::declval< T >())) last_element_t
Type alias for the type of the last element of a tuple.
Definition: tuple_utils.h:142
decltype(remove_first(std::declval< T >())) remove_first_t
Type alias for the type of the result of removing the first element from a tuple.
Definition: tuple_utils.h:76
decltype(remove_last(std::declval< T >())) remove_last_t
Type alias for the type of the result of removing the last element from a tuple.
Definition: tuple_utils.h:100
concept container
Concept to detect if a type is a container (iterable and not self-recursive).
Binds a function to a function, enabling the creation of a function call chain.
Definition: chaining.h:117
ref_or_owned< F1 > function1
First bound function.
Definition: chaining.h:118
auto operator()(Args &&... args) const
Calls the first function with second function as a callback. Divides and forwards arguments according...
Definition: chaining.h:138
decltype(std::tuple_cat(std::declval< tuple_utils::remove_last_t< invocation_traits::args_t< F1 > >>(), std::declval< tuple_utils::remove_first_t< invocation_traits::args_t< F2 > >>())) invocation_args_t
The type of the arguments of this functor.
Definition: chaining.h:164
ref_or_owned< F2 > function2
Second bound function.
Definition: chaining.h:128
Binds a function to a pushable, enabling the creation of a function call chain.
Definition: chaining.h:208
ref_or_owned< C > container
The bound pushable.
Definition: chaining.h:217
auto operator()(Args &&... args)
Calls the bound function with specified arguments and the pushable push_back method as a callback.
Definition: chaining.h:227
tuple_utils::remove_last_t< invocation_traits::args_t< F > > invocation_args_t
The type of the arguments of this functor.
Definition: chaining.h:244
Binds a value to a function, enabling the creation of a function call chain.
Definition: chaining.h:43
tuple_utils::remove_first_t< invocation_traits::args_t< F > > invocation_args_t
The type of the arguments of this functor.
Definition: chaining.h:70
auto operator()(Args &&... args)
Calls the bound function with the bound value and additional arguments.
Definition: chaining.h:62
ref_or_owned< V > value
The bound value.
Definition: chaining.h:47