commit bacf6f6498d6ef3d40e8d7e6af97a36ece729f6b
parent 56f4aea6c6fb2716543f806193e19e883e34e914
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Sat, 20 Aug 2016 00:01:58 +0300
Add expression_adjacent
Diffstat:
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -307,6 +307,24 @@ protected:
std::array<size_t, base::size + 2> segments;
};
+
+template <typename Fn, typename E>
+struct expression_adjacent : expression<E>
+{
+ using value_type = value_type_of<E>;
+ expression_adjacent(Fn&& fn, E&& e) : expression<E>(std::forward<E>(e)), fn(std::forward<Fn>(fn)) {}
+
+ template <typename T, size_t N>
+ vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
+ {
+ const vec<T, N> in = this->argument_first(index, vec_t<T, N>());
+ const vec<T, N> delayed = insertleft(data, in);
+ data = in[N - 1];
+ return this->fn(in, delayed);
+ }
+ Fn fn;
+ mutable value_type data = value_type(0);
+};
}
template <typename E1>
@@ -339,6 +357,15 @@ CMT_INLINE internal::expression_sequence<decay<E>...> gen_sequence(const size_t
}
KFR_FN(gen_sequence)
+/**
+ * @brief Returns template expression that returns the result of calling \f$ fn(x_i, x_{i-1}) \f$
+ */
+template <typename Fn, typename E1>
+CMT_INLINE internal::expression_adjacent<Fn, E1> adjacent(Fn&& fn, E1&& e1)
+{
+ return internal::expression_adjacent<Fn, E1>(std::forward<Fn>(fn), std::forward<E1>(e1));
+}
+
namespace internal
{
template <typename... E>
diff --git a/tests/vec_test.cpp b/tests/vec_test.cpp
@@ -291,4 +291,15 @@ TEST(test_delay)
CHECK(v3[19] == 116);
}
+TEST(test_adjacent)
+{
+ univector<int, 20> v1 = adjacent(fn_mul(), typed<int>(counter()));
+ CHECK(v1[0] == 0);
+ CHECK(v1[1] == 0);
+ CHECK(v1[2] == 2);
+ CHECK(v1[3] == 6);
+ CHECK(v1[4] == 12);
+ CHECK(v1[19] == 342);
+}
+
int main(int argc, char** argv) { return testo::run_all("", true); }