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 36f6562cbff550d18d823a9499e4638ba7f36969
parent e96e4ecfbd02ad6bb84f648fe627b3138fa8faa0
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Thu,  8 Sep 2016 18:24:52 +0300

Expressions refactoring

Diffstat:
Minclude/kfr/base.hpp | 1-
Minclude/kfr/base/basic_expressions.hpp | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dinclude/kfr/base/conversion.hpp | 57---------------------------------------------------------
Minclude/kfr/base/function.hpp | 40----------------------------------------
Minclude/kfr/base/operators.hpp | 76+++-------------------------------------------------------------------------
Minclude/kfr/base/types.hpp | 23+++++++++++++++++++++++
Minclude/kfr/base/vec.hpp | 8+++++++-
Msources.cmake | 1-
8 files changed, 115 insertions(+), 173 deletions(-)

diff --git a/include/kfr/base.hpp b/include/kfr/base.hpp @@ -30,7 +30,6 @@ #include "base/compiletime.hpp" #include "base/complex.hpp" #include "base/constants.hpp" -#include "base/conversion.hpp" #include "base/cpuid.hpp" #include "base/cpuid_auto.hpp" #include "base/digitreverse.hpp" diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp @@ -34,6 +34,20 @@ namespace kfr namespace internal { + +template <typename To, typename E> +struct expression_convert : expression<E> +{ + using value_type = To; + CMT_INLINE expression_convert(E&& expr) noexcept : expression<E>(std::forward<E>(expr)) {} + + template <size_t N> + CMT_INLINE vec<To, N> operator()(cinput_t, size_t index, vec_t<To, N>) const + { + return this->argument_first(index, vec_t<To, N>()); + } +}; + template <typename T, typename E1> struct expression_iterator { @@ -63,6 +77,12 @@ struct expression_iterator }; } +template <typename To, typename E> +CMT_INLINE internal::expression_convert<To, E> convert(E&& expr) +{ + return internal::expression_convert<To, E>(std::forward<E>(expr)); +} + template <typename E1, typename T = value_type_of<E1>> CMT_INLINE internal::expression_iterator<T, E1> to_iterator(E1&& e1) { @@ -408,5 +428,67 @@ struct multioutput : output_expression private: }; + +template <typename... E> +struct expression_pack : expression<E...>, output_expression +{ + constexpr static size_t count = sizeof...(E); + + expression_pack(E&&... e) : expression<E...>(std::forward<E>(e)...) {} + using value_type = vec<common_type<value_type_of<E>...>, count>; + using T = value_type; + + using expression<E...>::size; + + template <size_t N> + CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const + { + return this->call(fn::packtranspose(), index, y); + } +}; + +template <typename... E> +struct expression_unpack : private expression<E...>, output_expression +{ + constexpr static size_t count = sizeof...(E); + + expression_unpack(E&&... e) : expression<E...>(std::forward<E>(e)...) {} + + using expression<E...>::size; + + template <typename U, size_t N> + CMT_INLINE void operator()(coutput_t, size_t index, const vec<vec<U, count>, N>& x) + { + output(index, x, csizeseq<count>); + } + + template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)> + CMT_INLINE expression_unpack& operator=(Input&& input) + { + using value_type = vec<common_type<value_type_of<E>...>, count>; + process<value_type>(*this, std::forward<Input>(input)); + return *this; + } + +private: + template <typename U, size_t N, size_t... indices> + void output(size_t index, const vec<vec<U, count>, N>& x, csizes_t<indices...>) + { + const vec<vec<U, N>, count> xx = compcast<vec<U, N>>(transpose<count>(flatten(x))); + swallow{ (std::get<indices>(this->args)(coutput, index, xx[indices]), void(), 0)... }; + } +}; +} + +template <typename... E, KFR_ENABLE_IF(is_output_expressions<E...>::value)> +internal::expression_unpack<internal::arg<E>...> unpack(E&&... e) +{ + return internal::expression_unpack<internal::arg<E>...>(std::forward<E>(e)...); +} + +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)> +internal::expression_pack<internal::arg<E>...> pack(E&&... e) +{ + return internal::expression_pack<internal::arg<E>...>(std::forward<E>(e)...); } } diff --git a/include/kfr/base/conversion.hpp b/include/kfr/base/conversion.hpp @@ -1,57 +0,0 @@ -/** @addtogroup expressions - * @{ - */ -/* - Copyright (C) 2016 D Levin (https://www.kfrlib.com) - This file is part of KFR - - KFR is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - KFR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with KFR. - - If GPL is not suitable for your project, you must purchase a commercial license to use KFR. - Buying a commercial license is mandatory as soon as you develop commercial activities without - disclosing the source code of your own applications. - See https://www.kfrlib.com for details. - */ - -#pragma once - -#include "basic_expressions.hpp" -#include "function.hpp" -#include "operators.hpp" -#include "vec.hpp" - -namespace kfr -{ -namespace internal -{ -template <typename To, typename E> -struct expression_convert : expression<E> -{ - using value_type = To; - CMT_INLINE expression_convert(E&& expr) noexcept : expression<E>(std::forward<E>(expr)) {} - - template <size_t N> - CMT_INLINE vec<To, N> operator()(cinput_t, size_t index, vec_t<To, N>) const - { - return this->argument_first(index, vec_t<To, N>()); - } -}; -} - -template <typename To, typename E> -CMT_INLINE internal::expression_convert<To, E> convert(E&& expr) -{ - return internal::expression_convert<To, E>(std::forward<E>(expr)); -} -} diff --git a/include/kfr/base/function.hpp b/include/kfr/base/function.hpp @@ -53,46 +53,6 @@ namespace kfr return to_scalar(::kfr::intrinsics::fn(vecout(a), vecout(b)...)); \ } -namespace internal -{ -template <typename T> -struct flt_type_impl -{ - using type = fbase; -}; - -template <typename T, size_t N> -struct flt_type_impl<vec<T, N>> -{ - using type = vec<fbase, N>; -}; - -template <> -struct flt_type_impl<float> -{ - using type = float; -}; -template <> -struct flt_type_impl<double> -{ - using type = double; -}; - -template <size_t N> -struct flt_type_impl<vec<float, N>> -{ - using type = vec<float, N>; -}; -template <size_t N> -struct flt_type_impl<vec<double, N>> -{ - using type = vec<double, N>; -}; -} - -template <typename T> -using flt_type = typename internal::flt_type_impl<T>::type; - namespace intrinsics { #ifdef CMT_ARCH_X86 diff --git a/include/kfr/base/operators.hpp b/include/kfr/base/operators.hpp @@ -132,15 +132,10 @@ KFR_FN(mul) /** * @brief Returns template expression that returns product of all the arguments passed to a function. */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> -CMT_INLINE internal::expression_function<fn::mul, E1, E2> mul(E1&& x, E2&& y) -{ - return { fn::mul(), std::forward<E1>(x), std::forward<E2>(y) }; -} -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> -CMT_INLINE internal::expression_function<fn::mul, E1> mul(E1&& x, E2&& y, E3&& z) +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)> +CMT_INLINE internal::expression_function<fn::mul, E...> mul(E&&... x) { - return { fn::mul(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) }; + return { fn::mul(), std::forward<E>(x)... }; } /** @@ -695,69 +690,4 @@ vec<vec<T, sizeof...(Ns) + 1>, N1> packtranspose(const vec<T, N1>& x, const vec< } KFR_FN(packtranspose) - -namespace internal -{ -template <typename... E> -struct expression_pack : expression<E...>, output_expression -{ - constexpr static size_t count = sizeof...(E); - - expression_pack(E&&... e) : expression<E...>(std::forward<E>(e)...) {} - using value_type = vec<common_type<value_type_of<E>...>, count>; - using T = value_type; - - using expression<E...>::size; - - template <size_t N> - CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const - { - return this->call(fn::packtranspose(), index, y); - } -}; - -template <typename... E> -struct expression_unpack : private expression<E...>, output_expression -{ - constexpr static size_t count = sizeof...(E); - - expression_unpack(E&&... e) : expression<E...>(std::forward<E>(e)...) {} - - using expression<E...>::size; - - template <typename U, size_t N> - CMT_INLINE void operator()(coutput_t, size_t index, const vec<vec<U, count>, N>& x) - { - output(index, x, csizeseq<count>); - } - - template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)> - CMT_INLINE expression_unpack& operator=(Input&& input) - { - using value_type = vec<common_type<value_type_of<E>...>, count>; - process<value_type>(*this, std::forward<Input>(input)); - return *this; - } - -private: - template <typename U, size_t N, size_t... indices> - void output(size_t index, const vec<vec<U, count>, N>& x, csizes_t<indices...>) - { - const vec<vec<U, N>, count> xx = compcast<vec<U, N>>(transpose<count>(flatten(x))); - swallow{ (std::get<indices>(this->args)(coutput, index, xx[indices]), void(), 0)... }; - } -}; -} - -template <typename... E, KFR_ENABLE_IF(is_output_expressions<E...>::value)> -internal::expression_unpack<internal::arg<E>...> unpack(E&&... e) -{ - return internal::expression_unpack<internal::arg<E>...>(std::forward<E>(e)...); -} - -template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)> -internal::expression_pack<internal::arg<E>...> pack(E&&... e) -{ - return internal::expression_pack<internal::arg<E>...>(std::forward<E>(e)...); -} } diff --git a/include/kfr/base/types.hpp b/include/kfr/base/types.hpp @@ -261,6 +261,29 @@ using enable_if_not_f = enable_if<typeclass<T> != datatype::f, R>; namespace internal { +template <typename T> +struct flt_type_impl +{ + using type = fbase; +}; + +template <> +struct flt_type_impl<float> +{ + using type = float; +}; +template <> +struct flt_type_impl<double> +{ + using type = double; +}; +} + +template <typename T> +using flt_type = typename internal::flt_type_impl<T>::type; + +namespace internal +{ #ifdef CMT_COMPILER_CLANG #define builtin_addressof(x) __builtin_addressof(x) #else diff --git a/include/kfr/base/vec.hpp b/include/kfr/base/vec.hpp @@ -59,6 +59,13 @@ struct mask; namespace internal { + +template <typename T, size_t N> +struct flt_type_impl<vec<T, N>> +{ + using type = vec<typename flt_type_impl<T>::type, N>; +}; + template <typename T> struct is_vec_impl : std::false_type { @@ -1332,7 +1339,6 @@ CMT_INLINE vec_t<T, Nout> high(vec_t<T, N>) } KFR_FN(low) KFR_FN(high) - } #pragma clang diagnostic pop diff --git a/sources.cmake b/sources.cmake @@ -21,7 +21,6 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/base/compiletime.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/complex.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/constants.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/base/conversion.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/cpuid.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/cpuid_auto.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/digitreverse.hpp