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 5740e4a37e3ad7ea57ae495a7fad669a1f1293f5
parent 8a89faafaf9905c2a7d7201dde01dec81c233500
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue,  8 Nov 2022 11:15:58 +0000

Fixes for GCC: constexpr, common_type etc

Diffstat:
Minclude/kfr/base/expression.hpp | 6+++---
Minclude/kfr/base/generators.hpp | 6+++---
Minclude/kfr/base/impl/static_array.hpp | 2+-
Minclude/kfr/base/reduce.hpp | 4+---
Minclude/kfr/base/tensor.hpp | 2+-
Minclude/kfr/cometa/string.hpp | 1+
Minclude/kfr/dsp/sample_rate_conversion.hpp | 16+++++++---------
Minclude/kfr/except.hpp | 7++++++-
Minclude/kfr/simd/complex.hpp | 10++++++++++
Minclude/kfr/simd/vec.hpp | 8++++----
10 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/include/kfr/base/expression.hpp b/include/kfr/base/expression.hpp @@ -415,7 +415,7 @@ struct expression_function : expression_with_arguments<Args...>, expression_trai vec<typename expression_traits<Args>::value_type, 1>...>::value_type; constexpr static size_t dims = const_max(expression_traits<Args>::dims...); -#ifdef CMT_COMPILER_IS_MSVC +#if defined CMT_COMPILER_IS_MSVC || defined CMT_COMPILER_GCC struct lambda_get_shape { template <size_t... idx> @@ -428,8 +428,8 @@ struct expression_function : expression_with_arguments<Args...>, expression_trai struct lambda_get_shape_self { const expression_function& self; - template <typename... Args> - constexpr auto operator()(const Args&... args) const + template <typename... TArgs> + constexpr auto operator()(const TArgs&... args) const { return internal_generic::common_shape<true>(expression_traits<Args>::shapeof(args)...); } diff --git a/include/kfr/base/generators.hpp b/include/kfr/base/generators.hpp @@ -184,7 +184,7 @@ struct generator_exp2 : public generator<T, VecWidth, generator_exp2<T, VecWidth KFR_MEM_INTRINSIC void sync(T start) const CMT_NOEXCEPT { - this->value = exp2(start + enumerate(vec_shape<T, VecWidth>, step)); + this->value = exp2(start + enumerate(vec_shape<T, VecWidth>{}, step)); } KFR_MEM_INTRINSIC void next() const CMT_NOEXCEPT { this->value += this->value * vstep; } @@ -216,7 +216,7 @@ protected: T beta; CMT_NOINLINE static vec<T, VecWidth> init_cossin(T w, T phase) { - return cossin(dup(phase + enumerate(vec_shape<T, VecWidth / 2>, w))); + return cossin(dup(phase + enumerate(vec_shape<T, VecWidth / 2>{}, w))); } }; @@ -230,7 +230,7 @@ struct generator_sin : public generator<T, VecWidth, generator_sin<T, VecWidth>, } KFR_MEM_INTRINSIC void sync(T start) const CMT_NOEXCEPT { - const vec<T, 2 * VecWidth> cs = cossin(dup(start + enumerate(vec_shape<T, VecWidth>, step))); + const vec<T, 2 * VecWidth> cs = cossin(dup(start + enumerate(vec_shape<T, VecWidth>{}, step))); this->value = vec<vec<T, 2>, VecWidth>::from_flatten(cs); } diff --git a/include/kfr/base/impl/static_array.hpp b/include/kfr/base/impl/static_array.hpp @@ -54,7 +54,7 @@ struct static_array_base<T, csizes_t<indices...>> constexpr static size_t static_size = sizeof...(indices); - constexpr static_array_base() = default; + constexpr static_array_base() : array{ (static_cast<void>(indices), 0)... } {} constexpr static_array_base(const static_array_base&) = default; constexpr static_array_base(static_array_base&&) = default; diff --git a/include/kfr/base/reduce.hpp b/include/kfr/base/reduce.hpp @@ -74,8 +74,6 @@ struct expression_reduce : public expression_traits_defaults constexpr static size_t width = vector_width<Tin> * bitness_const(1, 2); - using value_type = Tin; - expression_reduce(ReduceFn&& reducefn, TransformFn&& transformfn, FinalFn&& finalfn) : counter(0), reducefn(std::move(reducefn)), transformfn(std::move(transformfn)), finalfn(std::move(finalfn)), value(resize<width>(make_vector(reducefn(initialvalue<Twork>{})))) @@ -156,7 +154,7 @@ KFR_INTRINSIC Tout reduce(const E1& e1, ReduceFn&& reducefn, result = reducefn(result, transformfn(in)); ++counter; } - return internal::reduce_call_final(finalfn, counter, result); + return reduce_call_final(finalfn, counter, result); } /** diff --git a/include/kfr/base/tensor.hpp b/include/kfr/base/tensor.hpp @@ -807,7 +807,7 @@ public: if (empty()) return {}; else - return as_string(wrap_fmt(access(shape_type{}), ctype<Fmt>)); + return as_string(wrap_fmt(access(shape_type{}), cometa::ctype<Fmt>)); } else { diff --git a/include/kfr/cometa/string.hpp b/include/kfr/cometa/string.hpp @@ -8,6 +8,7 @@ #include "ctti.hpp" #include "named_arg.hpp" #include <array> +#include <climits> #include <cstdio> #include <memory> #include <numeric> diff --git a/include/kfr/dsp/sample_rate_conversion.hpp b/include/kfr/dsp/sample_rate_conversion.hpp @@ -271,7 +271,7 @@ struct expression_upsample<2, E> : expression_with_arguments<E>, expression_trai KFR_INTRINSIC friend vec<T, N> get_elements(const expression_upsample& self, shape<1> index, axis_params<0, N>) { - const vec<T, N / 2> x = get_elements(self.first() index / 2, axis_params<0, N / 2>()); + const vec<T, N / 2> x = get_elements(self.first(), index / 2, axis_params<0, N / 2>()); return interleave(x, zerovector(x)); } KFR_INTRINSIC friend vec<T, 1> get_elements(const expression_upsample& self, shape<1> index, @@ -297,7 +297,7 @@ struct expression_upsample<4, E> : expression_with_arguments<E> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_upsample& self, shape<1> index, axis_params<0, N>) CMT_NOEXCEPT { - const vec<T, N / 4> x = self.argument_first(cinput, index / 4, axis_params<0, N / 4>()); + const vec<T, N / 4> x = get_elements(self.first(), index / 4, axis_params<0, N / 4>()); const vec<T, N / 2> xx = interleave(x, zerovector(x)); return interleave(xx, zerovector(xx)); } @@ -307,11 +307,9 @@ struct expression_upsample<4, E> : expression_with_arguments<E> switch (index & 3) { case 0: - return interleave(self.argument_first(cinput, index / 4, axis_params<0, 1>()), - zerovector<T, 1>()); + return interleave(get_elements(self.first(), index / 4, axis_params<0, 1>()), zerovector<T, 1>()); case 3: - return interleave(zerovector<T, 1>(), - self.argument_first(cinput, index / 4, axis_params<0, 1>())); + return interleave(zerovector<T, 1>(), get_elements(self.first(), index / 4, axis_params<0, 1>())); default: return 0; } @@ -322,7 +320,7 @@ struct expression_upsample<4, E> : expression_with_arguments<E> if (index & 3) return 0; else - return self.argument_first(cinput, index / 4, axis_params<0, 1>()); + return get_elements(self.first(), index / 4, axis_params<0, 1>()); } }; @@ -339,7 +337,7 @@ struct expression_downsample<2, offset, E> : expression_with_arguments<E> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_downsample& self, size_t index, axis_params<0, N>) CMT_NOEXCEPT { - const vec<T, N* 2> x = self.argument_first(cinput, index * 2, axis_params<0, N * 2>()); + const vec<T, N* 2> x = get_elements(self.first(), index * 2, axis_params<0, N * 2>()); return x.shuffle(csizeseq<N, offset, 2>); } }; @@ -357,7 +355,7 @@ struct expression_downsample<4, offset, E> : expression_with_arguments<E> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_downsample& self, shape<1> index, axis_params<0, N>) CMT_NOEXCEPT { - const vec<T, N* 4> x = self.argument_first(cinput, index * 4, axis_params<0, N * 4>()); + const vec<T, N* 4> x = get_elements(self.first(), index * 4, axis_params<0, N * 4>()); return x.shuffle(csizeseq<N, offset, 4>); } }; diff --git a/include/kfr/except.hpp b/include/kfr/except.hpp @@ -32,7 +32,12 @@ class exception : public std::exception { public: using std::exception::exception; - exception(const std::string& str) : exception(str.c_str()) {} + exception(std::string str) : m_what(std::move(str)) {} + + const char* what() const noexcept final { return m_what.c_str(); } + +private: + std::string m_what; }; class logic_error : public exception { diff --git a/include/kfr/simd/complex.hpp b/include/kfr/simd/complex.hpp @@ -453,6 +453,16 @@ template <typename T1, typename T2> struct common_type<T1, kfr::complex<T2>> : kfr::construct_common_type<std::common_type<T1, T2>, kfr::complex> { }; +template <typename T1, typename T2, size_t N> +struct common_type<kfr::complex<T1>, kfr::vec<T2, N>> + : kfr::construct_common_type<std::common_type<T1, T2>, kfr::vec_of_complex<N>::template type> +{ +}; +template <typename T1, typename T2, size_t N> +struct common_type<kfr::vec<T1, N>, kfr::complex<T2>> + : kfr::construct_common_type<std::common_type<T1, T2>, kfr::vec_of_complex<N>::template type> +{ +}; } // namespace std CMT_PRAGMA_MSVC(warning(pop)) diff --git a/include/kfr/simd/vec.hpp b/include/kfr/simd/vec.hpp @@ -1235,7 +1235,7 @@ void test_function1(cint_t<Cat> cat, Fn&& fn, RefFn&& reffn, IsApplicable&& isap [&](special_value value, auto type) { using T = typename decltype(type)::type; - if (isapplicable(ctype<T>, value)) + if (isapplicable(cometa::ctype<T>, value)) { const T x(value); #if !defined(_MSC_VER) || defined(__clang__) @@ -1274,11 +1274,11 @@ void test_function2(cint_t<Cat> cat, Fn&& fn, RefFn&& reffn, IsApplicable&& isap [&](special_value value1, special_value value2, auto type) { using T = typename decltype(type)::type; - if constexpr (IsDefined{}(ctype<T>)) + if constexpr (IsDefined{}(cometa::ctype<T>)) { const T x1(value1); const T x2(value2); - if (isapplicable(ctype<T>, value1, value2)) + if (isapplicable(cometa::ctype<T>, value1, value2)) { CHECK(std::is_same_v<decltype(fn(x1, x2)), typename compound_type_traits<T>::template rebind<decltype(reffn( @@ -1294,7 +1294,7 @@ void test_function2(cint_t<Cat> cat, Fn&& fn, RefFn&& reffn, IsApplicable&& isap using T = typename decltype(type)::type; const T x1 = test_enumerate(T::shape(), csizeseq<T::size()>, 0, 1); const T x2 = test_enumerate(T::shape(), csizeseq<T::size()>, 100, -1); - if constexpr (IsDefined{}(ctype<T>)) + if constexpr (IsDefined{}(cometa::ctype<T>)) { CHECK(fn(x1, x2) == apply(reffn, x1, x2)); }