GrPPI  0.3.1
Generic and Reusable Parallel Pattern Interface
pipeline_pattern.h
Go to the documentation of this file.
1 
20 #ifndef GRPPI_COMMON_PIPELINE_PATTERN_H
21 #define GRPPI_COMMON_PIPELINE_PATTERN_H
22 
23 #include <type_traits>
24 
25 namespace grppi {
26 
33 template <typename ... Transformers>
34 class pipeline_t {
35 public:
36 
37  using transformers_type = std::tuple<Transformers...>;
38 
44  pipeline_t(Transformers && ... others) noexcept :
45  transformers_{others...}
46  {}
47 
48 
49 
50  template <std::size_t index, typename T, typename std::enable_if< index == (sizeof...(Transformers) -1) ,int>::type = 0 >
51  auto invoke_all(T item) const
52  {
53  return invoke<index>(item);
54  }
55 
56  template <std::size_t index, typename T, typename std::enable_if< index != (sizeof...(Transformers) -1) ,int>::type = 0 >
57  auto invoke_all(T item) const
58  {
59  return invoke_all<index+1>(invoke<index>(item));
60  }
61 
62  template <typename T>
63  auto operator()(T item) const{
64  return invoke_all<0>(item);
65  }
66 
71  template <std::size_t I, typename T>
72  auto invoke(T && item) const {
73  auto f = std::get<I>(transformers_);
74  return f(std::forward<T>(item));
75  }
76 
82  template <std::size_t I>
83  auto stage() const noexcept {
84  static_assert(I<sizeof...(Transformers),
85  "Pipeline has not so many transformers");
86  return std::get<I>(transformers_);
87  }
88 
89  auto transformers() const noexcept {
90  return transformers_;
91  }
92 
93 private:
94  std::tuple<Transformers...> transformers_;
95 };
96 
97 namespace internal {
98 
99 template<typename T>
100 struct is_pipeline : std::false_type {};
101 
102 template <typename ... T>
103 struct is_pipeline<pipeline_t<T...>> :std::true_type {};
104 
105 } // namespace internal
106 
107 template <typename T>
109 
110 template <typename T>
111 using requires_pipeline = typename std::enable_if_t<is_pipeline<T>, int>;
112 
113 namespace internal {
114 
115 template <typename I, typename T>
117  using type = std::decay_t<typename std::result_of<T(I)>::type>;
118 };
119 
120 template <typename I, typename T, typename ... U>
121 struct output_value_type<I,pipeline_t<T,U...>> {
122  using first_result = std::decay_t<typename std::result_of<T(I)>::type>;
123  using type = std::conditional_t<sizeof...(U)==0,
124  first_result,
126  >;
127 };
128 
129 }
130 
131 template <typename I, typename T>
133 
134 }
135 
136 #endif
Definition: callable_traits.h:26
auto invoke(T &&item) const
Invokes a trasnformer from the pipeline.
Definition: pipeline_pattern.h:72
std::conditional_t< sizeof...(U)==0, first_result, typename output_value_type< first_result, U... >::type > type
Definition: pipeline_pattern.h:126
std::tuple< Transformers... > transformers_type
Definition: pipeline_pattern.h:37
auto stage() const noexcept
Gets a transformer from the pipeline.
Definition: pipeline_pattern.h:83
Representation of pipeline pattern. Represents a pipeline with multiple chained transformers.
Definition: pipeline_pattern.h:34
typename internal::output_value_type< I, T >::type output_value_type
Definition: pipeline_pattern.h:132
pipeline_t(Transformers &&...others) noexcept
Constructs a pipeline with several transformers.
Definition: pipeline_pattern.h:44
auto invoke_all(T item) const
Definition: pipeline_pattern.h:51
Definition: pipeline_pattern.h:100
static constexpr bool is_pipeline
Definition: pipeline_pattern.h:108
typename std::enable_if_t< is_pipeline< T >, int > requires_pipeline
Definition: pipeline_pattern.h:111
std::decay_t< typename std::result_of< T(I)>::type > first_result
Definition: pipeline_pattern.h:122
std::decay_t< typename std::result_of< T(I)>::type > type
Definition: pipeline_pattern.h:117
auto transformers() const noexcept
Definition: pipeline_pattern.h:89
Definition: pipeline_pattern.h:116
auto operator()(T item) const
Definition: pipeline_pattern.h:63