Tensor Comprehensions
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
functional.h
Go to the documentation of this file.
1 
16 #pragma once
17 
19 
20 #include <functional>
21 #include <vector>
22 
23 namespace tc {
24 namespace polyhedral {
25 namespace functional {
26 
27 template <typename I>
28 void App(std::function<void(I)> fun, const std::vector<I>& vec) {
29  for (auto& i : vec) {
30  fun(i);
31  }
32 }
33 
34 template <typename I>
35 void App(std::function<void(I)> fun, const std::vector<I>&& vec) {
36  App(fun, vec);
37 }
38 
39 template <typename I>
40 void App(std::function<void(I, size_t)> fun, const std::vector<I>& vec) {
41  size_t pos = 0;
42  for (auto& i : vec) {
43  fun(i, pos++);
44  }
45 }
46 
47 template <typename I>
48 void App(std::function<void(I, size_t)> fun, const std::vector<I>&& vec) {
49  App(fun, vec);
50 }
51 
52 template <typename R, typename I>
53 std::vector<R> Map(std::function<R(I)> fun, const std::vector<I>& vec) {
54  std::vector<R> res;
55  res.reserve(vec.size());
56  for (auto& i : vec) {
57  res.push_back(fun(i));
58  }
59  return res;
60 }
61 
62 template <typename R, typename I>
63 std::vector<R> Map(std::function<R(I)> fun, std::vector<I>&& vec) {
64  return Map<R, I>(fun, vec);
65 }
66 
67 template <typename I>
68 I Reduce(
69  std::function<I(const I&, const I&)> red,
70  I initVal,
71  const std::vector<I>& vec) {
72  I res = initVal;
73  for (int i = 0; i < vec.size(); ++i) {
74  res = red(res, vec.at(i));
75  }
76  return res;
77 }
78 
79 template <typename I>
80 I Reduce(std::function<I(const I&, const I&)> red, const std::vector<I>& vec) {
81  const std::vector<I> v(vec.begin() + 1, vec.end());
82  return Reduce(red, vec.at(0), v);
83 }
84 
85 template <typename I>
86 I Reduce(std::function<I(I&&, I&&)> red, I&& initVal, std::vector<I>&& vec) {
87  I res = std::move(initVal);
88  for (int i = 0; i < vec.size(); ++i) {
89  res = red(std::move(res), std::move(vec.at(i)));
90  }
91  return res;
92 }
93 
94 template <typename I>
95 I Reduce(std::function<I(I&&, I&&)> red, std::vector<I>&& vec) {
96  I res = std::move(vec.at(0));
97  for (int i = 1; i < vec.size(); ++i) {
98  res = red(std::move(res), std::move(vec.at(i)));
99  }
100  return res;
101 }
102 
103 /*
104  * Return a copy of the vector that contains only those elements for which
105  * function "f" returns true.
106  *
107  * The first argument must be a function-like entity (function pointer,
108  * functor) with signature <bool(T)>.
109  *
110  * Template argument deduction takes care of vector<const T> cases
111  * automatically. Note that the signature of "f" must use the same type, that
112  * is "const T".
113  */
114 template <typename Func, typename T>
115 std::vector<T> Filter(Func f, const std::vector<T>& input) {
116  static_assert(
117  std::is_same<typename function_traits<Func>::result_type, bool>::value,
118  "Filtering function must return bool");
119  static_assert(
120  function_traits<Func>::n_args == 1,
121  "Filtering function must take one argument");
122  static_assert(
123  std::is_same<typename function_traits<Func>::template arg<0>::type, T>::
124  value,
125  "The argument of the filtering function must have the same type "
126  "as the element type of the collection being filtered");
127 
128  std::vector<T> res;
129  res.reserve(input.size());
130  for (const auto& i : input) {
131  if (f(i)) {
132  res.push_back(i);
133  }
134  }
135  res.shrink_to_fit();
136  return res;
137 }
138 
139 template <typename R, typename I>
140 R MapReduce(std::function<R(R, I, bool)> fun, const std::vector<I>& vec) {
141  R res = fun(R(), vec.at(0), true);
142  for (int i = 1; i < vec.size(); ++i) {
143  res = fun(res, vec.at(i), false);
144  }
145  return res;
146 }
147 
148 } // namespace functional
149 } // namespace polyhedral
150 } // namespace tc