reductor.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
29 #include <atria/xform/skip.hpp>
32 
33 namespace atria {
34 namespace xform {
35 
43 template <typename ReducingFnT,
44  typename StateT,
45  typename... InputTs>
47 {
48  using reducing_fn_type = ReducingFnT;
49  using state_type = StateT;
50  using complete_type = estd::decay_t<
51  decltype(state_complete(std::declval<state_type>()))>;
52 
53  reductor_fn_base() = delete;
54 
58  explicit operator bool() const
59  { return !state_is_reduced(state_); }
60 
65  complete_type complete() const&
66  { return state_complete(state_); }
67 
68  complete_type complete() &&
69  { return state_complete(std::move(state_)); }
70 
75  complete_type current() const&
76  { return state_unwrap_all(state_); }
77 
78  complete_type current() &&
79  { return state_unwrap_all(std::move(state_)); }
80 
81  template <typename T>
82  void current(T&& x)
83  { state_ = state_rewrap(std::move(state_), std::forward<T>(x)); }
84 
94  template <typename... InputTs2>
95  reductor_fn_base& operator() (InputTs2&& ...ins) &
96  {
97  auto next = step_(std::move(state_), std::forward<InputTs2>(ins)...);
98  state_ = std::move(next);
99  return *this;
100  }
101 
102  template <typename... InputTs2>
103  reductor_fn_base operator() (InputTs2&& ...ins) const&
104  {
105  auto copied = *this;
106  copied(std::forward<InputTs2>(ins)...);
107  return copied;
108  }
109 
110  template <typename... InputTs2>
111  reductor_fn_base&& operator() (InputTs2&& ...ins) &&
112  {
113  return std::move((*this)(std::forward<InputTs2>(ins)...));
114  }
115 
116 protected:
117  template <typename ReducingFnT2,
118  typename StateT2>
119  reductor_fn_base(ReducingFnT2&& step,
120  StateT2&& state)
121  : step_(std::forward<ReducingFnT2>(step))
122  , state_(std::forward<StateT2>(state))
123  {}
124 
125 private:
126  reducing_fn_type step_;
127  state_type state_;
128 };
129 
146 template <typename ReducingFnT,
147  typename InitialStateT,
148  typename... InputTs>
150  ReducingFnT,
151  estd::result_of_t<ReducingFnT(InitialStateT, InputTs...)>,
152  InputTs...>
153 {
154  using base_t = reductor_fn_base<
155  ReducingFnT,
156  estd::result_of_t<ReducingFnT(InitialStateT, InputTs...)>,
157  InputTs...>;
158 
159  template <typename ReducingFnT2,
160  typename InitialStateT2,
161  typename... InputTs2>
162  reductor_fn(ReducingFnT2&& step,
163  InitialStateT2&& state,
164  InputTs2&& ...ins)
165  : base_t(std::forward<ReducingFnT2>(step),
166  step(std::forward<InitialStateT2>(state),
167  std::forward<InputTs2>(ins)...))
168  {}
169 };
170 
174 template <typename ReducingFnT, typename InitialStateT, typename... InputTs>
175 auto reductor(ReducingFnT&& step, InitialStateT&& state, InputTs&& ...ins)
179 {
180  return {
181  std::forward<ReducingFnT>(step),
182  std::forward<InitialStateT>(state),
183  std::forward<InputTs>(ins)...
184  };
185 }
186 
187 namespace detail {
188 
189 template <typename ReducingFnT>
190 struct caller
191 {
192  ReducingFnT step;
193 
194  template <typename... Args>
195  auto operator() (Args&& ...args)
197  call(step, std::forward<Args>(args)...))
198 };
199 
200 } // namespace detail
201 
210 template <typename ReducingFnT,
211  typename InitialStateT,
212  typename... InputTs>
214  detail::caller<estd::decay_t<ReducingFnT>>,
215  estd::decay_t<skip_result_t<ReducingFnT, InitialStateT, InputTs...> >,
216  InputTs...>
217 {
218  using base_t = reductor_fn_base<
219  detail::caller<estd::decay_t<ReducingFnT> >,
220  estd::decay_t<skip_result_t<ReducingFnT, InitialStateT, InputTs...> >,
221  InputTs...>;
222 
223  template <typename ReducingFnT2,
224  typename InitialStateT2,
225  typename... InputTs2>
226  empty_reductor_fn(ReducingFnT2&& step,
227  InitialStateT2&& state)
228  : base_t(detail::caller<estd::decay_t<ReducingFnT>> {
229  std::forward<ReducingFnT2>(step) },
230  typename base_t::state_type {
231  std::forward<InitialStateT2>(state) })
232  {}
233 };
234 
235 template <typename ReducingFnT,
236  typename InitialStateT,
237  typename... InputTs>
238 struct empty_reductor_fn<ReducingFnT, InitialStateT, meta::pack<InputTs...> >
239  : empty_reductor_fn<ReducingFnT, InitialStateT, InputTs...>
240 {
241  using empty_reductor_fn<ReducingFnT, InitialStateT, InputTs...>::empty_reductor_fn;
242 };
243 
249 template <typename... InputTs, typename ReducingFnT, typename InitialStateT>
250 auto empty_reductor(ReducingFnT&& step, InitialStateT&& state)
252  estd::decay_t<InitialStateT>,
254 {
255  return {
256  std::forward<ReducingFnT>(step),
257  std::forward<InitialStateT>(state)
258  };
259 }
260 
261 } // namespace xform
262 } // namespace atria
auto empty_reductor(ReducingFnT &&step, InitialStateT &&state) -> empty_reductor_fn< estd::decay_t< ReducingFnT >, estd::decay_t< InitialStateT >, estd::decay_t< InputTs >... >
Constructs an empty_reductor_fn object with deduced argument types.
Definition: reductor.hpp:250
Common reductor interface.
Definition: reductor.hpp:46
auto call(ReducingFnT &&step, StateT &&state, InputTs &&...ins) -> estd::enable_if_t< is_skip_state< estd::decay_t< StateT > >
Call the next reducing function in a transducer that could otherwise skip calling the next reducing f...
Definition: skip.hpp:276
#define ABL_DECLTYPE_RETURN(body_expr)
Utility for defining generic functions with a deduced return type, that are composed of a single expr...
Definition: utils.hpp:109
complete_type current() const &
Peeks at the current visible state of the reduction.
Definition: reductor.hpp:75
Reductor_Fn object that does not require inputs to be fed at construction time.
Definition: reductor.hpp:213
STL namespace.
typename std::decay< T >::type decay_t
Similar to C++14 std::decay_t.
Definition: type_traits.hpp:54
complete_type complete() const &
Completes and returns the state of the reduction.
Definition: reductor.hpp:65
auto state_rewrap(T &&s, U &&x) -> decltype(state_traits_t< T >::rewrap(std::forward< T >(s), std::forward< U >(x)))
Convenience function for calling state_traits::unwrap_all
auto state_complete(T &&s) -> decltype(state_traits_t< T >::complete(std::forward< T >(s)))
Convenience function for calling state_traits::complete
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
auto state_is_reduced(T &&s) -> bool
Convenience function for calling state_traits::is_reduced
auto state_unwrap_all(T &&s) -> decltype(state_traits_t< T >::unwrap_all(std::forward< T >(s)))
Convenience function for calling state_traits::unwrap_all
reductor_fn_base & operator()(InputTs2 &&...ins)&
Evaluates the next step of the reduction, passing the inputs ins to the reducing function.
Definition: reductor.hpp:95
auto reductor(ReducingFnT &&step, InitialStateT &&state, InputTs &&...ins) -> reductor_fn< estd::decay_t< ReducingFnT >, estd::decay_t< InitialStateT >, estd::decay_t< InputTs >... >
Constructs a reductor_fn object with deduced argument types.
Definition: reductor.hpp:175
Function object that performs a reduction using a reducing function of type ReducingFnT, an initial state of type of type InitialStateT and inputs of types InputTs....
Definition: reductor.hpp:149
typename std::result_of< T >::type result_of_t
Similar to C++14 std::result_of_t.
Definition: type_traits.hpp:60
Fork me on GitHub