kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit 29e69c6ce91f7c12581893063e7c5954f719b157
parent eb364e92a8c504757aaa41b1feb82c2ea1825542
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue,  8 Nov 2016 07:56:33 +0300

expression_pointer: size function and other improvements

Diffstat:
Minclude/kfr/base/pointer.hpp | 48++++++++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/include/kfr/base/pointer.hpp b/include/kfr/base/pointer.hpp @@ -32,9 +32,9 @@ namespace kfr { -constexpr size_t maximum_expression_width = bitness_const(16, 32); +constexpr size_t maximum_expression_width = platform<float>::vector_capacity / 4; -constexpr size_t expression_vtable_size = 2 + ilog2(maximum_expression_width) + 1; +constexpr size_t expression_vtable_size = 3 + ilog2(maximum_expression_width) + 1; template <typename T> using expression_vtable = std::array<void*, expression_vtable_size>; @@ -77,19 +77,24 @@ struct expression_pointer : input_expression : instance(instance), vtable(vtable), resource(std::move(resource)) { } - template <size_t N> + template <size_t N, KFR_ENABLE_IF(N <= maximum_expression_width)> CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const { using func_t = void (*)(void*, size_t, vec<T, N>&); static_assert(is_poweroftwo(N), "N must be a power of two"); constexpr size_t findex = ilog2(N); - static_assert(N <= maximum_expression_width, "N is greater than maxwidth"); - func_t func = reinterpret_cast<func_t>((*vtable)[2 + findex]); + func_t func = reinterpret_cast<func_t>((*vtable)[3 + findex]); vec<T, N> result; func(instance, index, result); return result; } + template <size_t N, KFR_ENABLE_IF(N > maximum_expression_width)> + CMT_INLINE vec<T, N> operator()(cinput_t cinput, size_t index, vec_t<T, N>) const + { + return concat(operator()(cinput, index, vec_t<T, N / 2>()), + operator()(cinput, index + N / 2, vec_t<T, N / 2>())); + } CMT_INLINE void begin_block(cinput_t, size_t size) const { using func_t = void (*)(void*, size_t); @@ -102,6 +107,12 @@ struct expression_pointer : input_expression func_t func = reinterpret_cast<func_t>((*vtable)[1]); func(instance, size); } + CMT_INLINE size_t size() const + { + using func_t = size_t (*)(void*); + func_t func = reinterpret_cast<func_t>((*vtable)[2]); + return func(instance); + } private: void* instance; @@ -119,19 +130,24 @@ struct expression_pointer<T, false> : input_expression : instance(instance), vtable(vtable) { } - template <size_t N> + template <size_t N, KFR_ENABLE_IF(N <= maximum_expression_width)> CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const { using func_t = void (*)(void*, size_t, vec<T, N>&); static_assert(is_poweroftwo(N), "N must be a power of two"); constexpr size_t findex = ilog2(N); - static_assert(N <= maximum_expression_width, "N is greater than maxwidth"); - func_t func = reinterpret_cast<func_t>((*vtable)[2 + findex]); + func_t func = reinterpret_cast<func_t>((*vtable)[3 + findex]); vec<T, N> result; func(instance, index, result); return result; } + template <size_t N, KFR_ENABLE_IF(N > maximum_expression_width)> + CMT_INLINE vec<T, N> operator()(cinput_t input, size_t index, vec_t<T, N>) const + { + return concat(operator()(cinput, index, vec_t<T, N / 2>()), + operator()(cinput, index + N / 2, vec_t<T, N / 2>())); + } CMT_INLINE void begin_block(cinput_t, size_t size) const { using func_t = void (*)(void*, size_t); @@ -144,6 +160,12 @@ struct expression_pointer<T, false> : input_expression func_t func = reinterpret_cast<func_t>((*vtable)[1]); func(instance, size); } + CMT_INLINE size_t size() const + { + using func_t = size_t (*)(void*); + func_t func = reinterpret_cast<func_t>((*vtable)[2]); + return func(instance); + } private: void* instance; @@ -171,6 +193,11 @@ CMT_INLINE NonMemFn make_expression_end_block() { return [](void* fn, size_t size) { reinterpret_cast<Fn*>(fn)->end_block(cinput, size); }; } +template <typename Fn, typename NonMemFn = size_t (*)(void*)> +CMT_INLINE NonMemFn make_expression_size() +{ + return [](void* fn) -> size_t { return reinterpret_cast<Fn*>(fn)->size(); }; +} template <typename T, typename E> expression_vtable<T> make_expression_vtable_impl() @@ -179,10 +206,11 @@ expression_vtable<T> make_expression_vtable_impl() result[0] = reinterpret_cast<void*>(internal::make_expression_begin_block<decay<E>>()); result[1] = reinterpret_cast<void*>(internal::make_expression_end_block<decay<E>>()); + result[2] = reinterpret_cast<void*>(internal::make_expression_size<decay<E>>()); - cforeach(csizeseq_t<expression_vtable_size - 2>(), [&](auto u) { + cforeach(csizeseq_t<expression_vtable_size - 3>(), [&](auto u) { constexpr size_t N = 1 << val_of(decltype(u)()); - result[2 + val_of(decltype(u)())] = + result[3 + val_of(decltype(u)())] = reinterpret_cast<void*>(internal::make_expression_func<T, N, decay<E>>()); }); return result;