commit 0623d0d73c72b57ed50a0499a9646af05b5f1489
parent 17451d4038fda5ad6a720003554db67ee56a9b2e
Author: [email protected] <[email protected]>
Date: Wed, 7 Sep 2016 15:20:53 +0300
New function: reverse(Expr)
Diffstat:
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -190,6 +190,21 @@ struct expression_slice : expression<E1>
size_t new_size;
};
+template <typename E1>
+struct expression_reverse : expression<E1>
+{
+ using value_type = value_type_of<E1>;
+ using T = value_type;
+ expression_reverse(E1&& e1) : expression<E1>(std::forward<E1>(e1)), expr_size(e1.size()) {}
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
+ {
+ return reverse(this->argument_first(expr_size - index - N, y));
+ }
+ size_t size() const { return expr_size; }
+ size_t expr_size;
+};
+
template <typename T, bool precise = false>
struct expression_linspace;
@@ -334,6 +349,13 @@ CMT_INLINE internal::expression_slice<E1> truncate(E1&& e1, size_t size)
return internal::expression_slice<E1>(std::forward<E1>(e1), 0, size);
}
+template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)>
+CMT_INLINE internal::expression_reverse<E1> reverse(E1&& e1)
+{
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
+ return internal::expression_reverse<E1>(std::forward<E1>(e1));
+}
+
template <typename T1, typename T2, bool precise = false, typename TF = ftype<common_type<T1, T2>>>
CMT_INLINE internal::expression_linspace<TF, precise> linspace(T1 start, T2 stop, size_t size,
bool endpoint = false)
diff --git a/tests/expression_test.cpp b/tests/expression_test.cpp
@@ -91,6 +91,14 @@ TEST(size_calc)
CHECK(d.size() == 900);
}
+TEST(reverse)
+{
+ univector<int, 21> a = reverse(truncate(counter(), 21));
+ CHECK(a[0] == 20);
+ CHECK(a[1] == 19);
+ CHECK(a[20] == 0);
+}
+
int main(int argc, char** argv)
{
println(library_version());