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 8a89faafaf9905c2a7d7201dde01dec81c233500
parent 3345865911299eb4bd77b769210327dc4cb91035
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Fri,  4 Nov 2022 18:49:13 +0000

Fixes for MSVC

Diffstat:
MCMakeLists.txt | 3+++
Minclude/kfr/base/expression.hpp | 36++++++++++++++++++++++++++++++++----
Minclude/kfr/base/impl/static_array.hpp | 16+++++-----------
Minclude/kfr/base/tensor.hpp | 16++++++++--------
Minclude/kfr/cident.h | 2+-
Minclude/kfr/simd/vec.hpp | 5++---
6 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -182,6 +182,9 @@ endif () if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(kfr INTERFACE -Wno-c++1z-extensions -Wno-psabi) endif () +if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + target_compile_options(kfr INTERFACE /wd4141) +endif () if (NOT KFR_ENABLE_DFT) target_compile_definitions(kfr INTERFACE -DKFR_NO_DFT) diff --git a/include/kfr/base/expression.hpp b/include/kfr/base/expression.hpp @@ -286,10 +286,9 @@ struct expression_with_arguments } else { - constexpr shape<Traits::dims> sh = Traits::shapeof(); - if constexpr (sh.cproduct() > 0) + if constexpr (Traits::shapeof().cproduct() > 0) { - return sh.tomask(); + return Traits::shapeof().tomask(); } else { @@ -391,8 +390,11 @@ template <typename... Args> expression_with_arguments(Args&&... args) -> expression_with_arguments<Args...>; template <typename Arg> -struct expression_with_traits : expression_with_arguments<Arg>, expression_traits_defaults +struct expression_with_traits : expression_with_arguments<Arg> { + constexpr static inline bool explicit_operand = true; + constexpr static inline bool random_access = true; + using first_arg_traits = expression_traits<Arg>; using value_type = typename first_arg_traits::value_type; constexpr static size_t dims = first_arg_traits::dims; @@ -413,6 +415,31 @@ 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 + struct lambda_get_shape + { + template <size_t... idx> + constexpr auto operator()(csize_t<idx>...) const + { + return internal_generic::common_shape( + expression_traits<typename expression_function::template nth<idx>>::shapeof()...); + } + }; + struct lambda_get_shape_self + { + const expression_function& self; + template <typename... Args> + constexpr auto operator()(const Args&... args) const + { + return internal_generic::common_shape<true>(expression_traits<Args>::shapeof(args)...); + } + }; + constexpr static shape<dims> shapeof(const expression_function& self) + { + return self.fold(lambda_get_shape_self{ self }); + } + constexpr static shape<dims> shapeof() { return expression_function::fold_idx(lambda_get_shape{}); } +#else constexpr static shape<dims> shapeof(const expression_function& self) { return self.fold([&](auto&&... args) CMT_INLINE_LAMBDA constexpr->auto { @@ -427,6 +454,7 @@ struct expression_function : expression_with_arguments<Args...>, expression_trai typename expression_function::template nth<val_of(decltype(args)())>>::shapeof()...); }); } +#endif constexpr static inline bool random_access = (expression_traits<Args>::random_access && ...); diff --git a/include/kfr/base/impl/static_array.hpp b/include/kfr/base/impl/static_array.hpp @@ -58,10 +58,7 @@ struct static_array_base<T, csizes_t<indices...>> constexpr static_array_base(const static_array_base&) = default; constexpr static_array_base(static_array_base&&) = default; - KFR_MEM_INTRINSIC constexpr static_array_base(type_for<value_type, indices>... args) - { - (static_cast<void>(array[indices] = args), ...); - } + KFR_MEM_INTRINSIC constexpr static_array_base(type_for<value_type, indices>... args) : array{ args... } {} template <typename U, typename otherindices_t> friend struct static_array_base; @@ -69,13 +66,10 @@ struct static_array_base<T, csizes_t<indices...>> template <size_t... idx1, size_t... idx2> KFR_MEM_INTRINSIC constexpr static_array_base(const static_array_base<T, csizes_t<idx1...>>& first, const static_array_base<T, csizes_t<idx2...>>& second) + : array{ (indices >= sizeof...(idx1) ? second.array[indices - sizeof...(idx1)] + : first.array[indices])... } { - constexpr size_t size1 = sizeof...(idx1); - constexpr size_t size2 = sizeof...(idx2); - static_assert(size1 + size2 == static_size); - (static_cast<void>(array[indices] = - indices >= size1 ? second.array[indices - size1] : first.array[indices]), - ...); + static_assert(sizeof...(idx1) + sizeof...(idx2) == static_size); } template <size_t... idx> @@ -95,8 +89,8 @@ struct static_array_base<T, csizes_t<indices...>> template <int dummy = 0, CMT_ENABLE_IF(dummy == 0 && static_size > 1)> KFR_MEM_INTRINSIC constexpr explicit static_array_base(value_type value) + : array{ (static_cast<void>(indices), value)... } { - (static_cast<void>(array[indices] = value), ...); } KFR_MEM_INTRINSIC vec<T, static_size> operator*() const { return read<static_size>(data()); } diff --git a/include/kfr/base/tensor.hpp b/include/kfr/base/tensor.hpp @@ -83,7 +83,7 @@ public: constexpr static inline index_t dims = NDims; - using shape_type = shape<dims>; + using shape_type = kfr::shape<dims>; struct tensor_iterator { @@ -101,9 +101,9 @@ public: KFR_MEM_INTRINSIC bool is_end() const { return indices.front() == internal_generic::null_index; } template <size_t num> - KFR_MEM_INTRINSIC shape<num> advance() + KFR_MEM_INTRINSIC kfr::shape<num> advance() { - shape<num> result; + kfr::shape<num> result; for (size_t i = 0; i < num; ++i) { result[i] = src->calc_index(indices); @@ -450,7 +450,7 @@ public: using tensor_subscript<T, tensor<T, NDims>, std::make_index_sequence<NDims>>::operator(); template <index_t dims> - KFR_MEM_INTRINSIC tensor<T, dims> reshape_may_copy(const shape<dims>& new_shape, + KFR_MEM_INTRINSIC tensor<T, dims> reshape_may_copy(const kfr::shape<dims>& new_shape, bool allow_copy = false) const { if (size_of_shape(new_shape) != m_size) @@ -485,12 +485,12 @@ public: } template <index_t dims> - KFR_MEM_INTRINSIC tensor<T, dims> reshape(const shape<dims>& new_shape) const + KFR_MEM_INTRINSIC tensor<T, dims> reshape(const kfr::shape<dims>& new_shape) const { return reshape_may_copy(new_shape, false); } - KFR_MEM_INTRINSIC tensor<T, 1> flatten() const { return reshape(shape<1>{ m_size }, false); } + KFR_MEM_INTRINSIC tensor<T, 1> flatten() const { return reshape(kfr::shape<1>{ m_size }, false); } KFR_MEM_INTRINSIC tensor<T, 1> flatten_may_copy(bool allow_copy = false) const { @@ -754,7 +754,7 @@ public: // } template <size_t N, bool only_last = false> - KFR_MEM_INTRINSIC shape<N> offsets(shape<dims> indices) const + KFR_MEM_INTRINSIC kfr::shape<N> offsets(kfr::shape<dims> indices) const { kfr::shape<N> result; if constexpr (only_last) @@ -774,7 +774,7 @@ public: } template <size_t N, bool only_last = false> - KFR_MEM_INTRINSIC shape<N> offsets(size_t flat_index) const + KFR_MEM_INTRINSIC kfr::shape<N> offsets(size_t flat_index) const { kfr::shape<dims> indices; for (index_t i = 0; i < dims; ++i) diff --git a/include/kfr/cident.h b/include/kfr/cident.h @@ -393,7 +393,7 @@ extern char* gets(char* __s); #endif #define CMT_NODEBUG -#define CMT_INLINE /*inline*/ CMT_ALWAYS_INLINE +#define CMT_INLINE inline CMT_ALWAYS_INLINE #define CMT_INLINE_MEMBER CMT_ALWAYS_INLINE #if _MSC_VER >= 1927 #define CMT_INLINE_LAMBDA CMT_ALWAYS_INLINE diff --git a/include/kfr/simd/vec.hpp b/include/kfr/simd/vec.hpp @@ -1267,7 +1267,6 @@ template <int Cat, typename Fn, typename RefFn, typename IsApplicable = fn_retur void test_function2(cint_t<Cat> cat, Fn&& fn, RefFn&& reffn, IsApplicable&& isapplicable = IsApplicable{}, IsDefined&& = IsDefined{}) { - constexpr IsDefined isdefined{}; testo::matrix( named("value1") = special_values(), // @@ -1275,7 +1274,7 @@ 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{}(ctype<T>)) { const T x1(value1); const T x2(value2); @@ -1295,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{}(ctype<T>)) { CHECK(fn(x1, x2) == apply(reffn, x1, x2)); }