enumerate.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 
32 #include <atria/meta/utils.hpp>
33 
34 namespace atria {
35 namespace xform {
36 
37 #if ABL_CXX14
38 
39 auto enumerate_from = [](auto initial) mutable
40 {
41  return [=](auto step) mutable
42  {
43  return [=](auto&& s, auto&& ...is) mutable
44  {
45  auto count = state_data(ABL_FORWARD(s), constantly(initial));
46  return wrap_state(
47  step(state_unwrap(ABL_FORWARD(s)),
48  std::move(count),
49  ABL_FORWARD(is)...),
50  decltype(initial)(std::move(count) + 1));
51  };
52  };
53 };
54 
55 auto enumerate = enumerate_from(std::size_t{});
56 
57 #else // ABL_CXX14
58 
59 namespace detail {
60 
61 struct enumerate_rf_gen
62 {
63  template <typename ReducingFnT,
64  typename IntegralT>
65  struct apply
66  {
67  ReducingFnT step;
68  IntegralT initial;
69 
70  template <typename StateT, typename ...InputTs>
71  auto operator() (StateT&& s, InputTs&& ...is)
72  -> decltype(wrap_state(step(state_unwrap(s), initial, is...), initial))
73  {
74  auto next = state_data(std::forward<StateT>(s), constantly(initial));
75  auto count = next++;
76  return wrap_state(
77  step(state_unwrap(std::forward<StateT>(s)),
78  std::move(count),
79  std::forward<InputTs>(is)...),
80  std::move(next));
81  }
82  };
83 };
84 
85 } // namespace detail
86 
87 template <typename T>
88 using enumerate_t = transducer_impl<detail::enumerate_rf_gen, T>;
89 
101 template <typename IntegralT>
102 constexpr auto enumerate_from(IntegralT&& init)
104 {
106  std::forward<IntegralT>(init) };
107 }
108 
114 
115 #endif // ABL_CXX14
116 
117 } // namespace xform
118 } // namespace atria
constexpr auto count(InitT init=InitT{0}, StepT step=StepT{1}) -> count_t< InitT, StepT >
Generator transducer produces a sequence:
Definition: count.hpp:78
const enumerate_t< std::size_t > enumerate
Equivalent to enumerate_from(std::size_t{}).
auto state_unwrap(T &&s) -> decltype(state_traits_t< T >::unwrap(std::forward< T >(s)))
Convenience function for calling state_traits::unwrap
auto constantly(T &&value) -> constantly_t< estd::decay_t< T > >
Similar to clojure.core/constantly.
Definition: constantly.hpp:56
auto state_data(T &&s, D &&d) -> decltype(state_traits_t< T >::data(std::forward< T >(s), std::forward< D >(d)))
Convenience function for calling state_traits::data
Utility to write simple transducers easily.
constexpr auto enumerate_from(IntegralT &&init) -> enumerate_t< estd::decay_t< IntegralT > >
Transducer that given a sequence:
Definition: enumerate.hpp:102
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
auto wrap_state(StateT &&next, DataT &&data=DataT{}) -> state_wrapper< TagT, estd::decay_t< StateT >, estd::decay_t< DataT > >
Given a tag TagT and a state next and associated data, returns a state_wrapper instance.
Fork me on GitHub