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 7503a880e8a4e05c602de6878129c7129547fbde
parent 56cce26cda746e7b64ec23f12eca209627cd3695
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Wed,  9 Nov 2016 11:01:02 +0300

Refactor operators.hpp

Diffstat:
Minclude/kfr/base.hpp | 1+
Ainclude/kfr/base/comparison.hpp | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kfr/base/operators.hpp | 176++++++++++++++++++++++++++++---------------------------------------------------
Msources.cmake | 1+
4 files changed, 214 insertions(+), 113 deletions(-)

diff --git a/include/kfr/base.hpp b/include/kfr/base.hpp @@ -27,6 +27,7 @@ #include "base/atan.hpp" #include "base/basic_expressions.hpp" #include "base/clamp.hpp" +#include "base/comparison.hpp" #include "base/compiletime.hpp" #include "base/complex.hpp" #include "base/constants.hpp" diff --git a/include/kfr/base/comparison.hpp b/include/kfr/base/comparison.hpp @@ -0,0 +1,149 @@ +/** @addtogroup math + * @{ + */ +/* + 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 "constants.hpp" +#include "expression.hpp" +#include "vec.hpp" + +namespace kfr +{ + +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> equal(const T1& x, const T2& y) +{ + return x == y; +} +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> notequal(const T1& x, const T2& y) +{ + return x != y; +} +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> less(const T1& x, const T2& y) +{ + return x < y; +} +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> greater(const T1& x, const T2& y) +{ + return x > y; +} +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> lessorequal(const T1& x, const T2& y) +{ + return x <= y; +} +template <typename T1, typename T2> +inline maskfor<common_type<T1, T2>> greaterorequal(const T1& x, const T2& y) +{ + return x >= y; +} +KFR_FN(equal) +KFR_FN(notequal) +KFR_FN(less) +KFR_FN(greater) +KFR_FN(lessorequal) +KFR_FN(greaterorequal) + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::equal, E1, E2> operator==(E1&& e1, E2&& e2) +{ + return { fn::equal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::notequal, E1, E2> operator!=(E1&& e1, E2&& e2) +{ + return { fn::notequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::less, E1, E2> operator<(E1&& e1, E2&& e2) +{ + return { fn::less(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::greater, E1, E2> operator>(E1&& e1, E2&& e2) +{ + return { fn::greater(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::lessorequal, E1, E2> operator<=(E1&& e1, E2&& e2) +{ + return { fn::lessorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::greaterorequal, E1, E2> operator>=(E1&& e1, E2&& e2) +{ + return { fn::greaterorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> isnan(const vec<T, N>& x) +{ + return x != x; +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> isinf(const vec<T, N>& x) +{ + return x == constants<T>::infinity || x == -constants<T>::infinity; +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> isfinite(const vec<T, N>& x) +{ + return !isnan(x) && !isinf(x); +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> isnegative(const vec<T, N>& x) +{ + return (x & constants<T>::highbitmask()) != 0; +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> ispositive(const vec<T, N>& x) +{ + return !isnegative(x); +} + +template <typename T, size_t N> +CMT_INLINE mask<T, N> iszero(const vec<T, N>& x) +{ + return x == T(); +} + +template <typename T1, typename T2, typename T3> +KFR_SINTRIN maskfor<common_type<T1, T2, T3>> inrange(const T1& x, const T2& min, const T3& max) +{ + return x >= min && x <= max; +} +} diff --git a/include/kfr/base/operators.hpp b/include/kfr/base/operators.hpp @@ -268,43 +268,6 @@ inline T1 neg(const T1& x) } KFR_FN(neg) -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> equal(const T1& x, const T2& y) -{ - return x == y; -} -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> notequal(const T1& x, const T2& y) -{ - return x != y; -} -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> less(const T1& x, const T2& y) -{ - return x < y; -} -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> greater(const T1& x, const T2& y) -{ - return x > y; -} -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> lessorequal(const T1& x, const T2& y) -{ - return x <= y; -} -template <typename T1, typename T2> -inline maskfor<common_type<T1, T2>> greaterorequal(const T1& x, const T2& y) -{ - return x >= y; -} -KFR_FN(equal) -KFR_FN(notequal) -KFR_FN(less) -KFR_FN(greater) -KFR_FN(lessorequal) -KFR_FN(greaterorequal) - /// @brief Fused Multiply-Add template <typename T1, typename T2, typename T3> KFR_INTRIN constexpr common_type<T1, T2, T3> fmadd(const T1& x, const T2& y, const T3& z) @@ -465,48 +428,6 @@ constexpr CMT_INLINE vec<T, N> copysign(const vec<T, N>& x, const vec<T, N>& y) return (x & constants<T>::highbitmask()) | (y & constants<T>::highbitmask()); } -template <typename T, size_t N> -CMT_INLINE mask<T, N> isnan(const vec<T, N>& x) -{ - return x != x; -} - -template <typename T, size_t N> -CMT_INLINE mask<T, N> isinf(const vec<T, N>& x) -{ - return x == constants<T>::infinity || x == -constants<T>::infinity; -} - -template <typename T, size_t N> -CMT_INLINE mask<T, N> isfinite(const vec<T, N>& x) -{ - return !isnan(x) && !isinf(x); -} - -template <typename T, size_t N> -CMT_INLINE mask<T, N> isnegative(const vec<T, N>& x) -{ - return (x & constants<T>::highbitmask()) != 0; -} - -template <typename T, size_t N> -CMT_INLINE mask<T, N> ispositive(const vec<T, N>& x) -{ - return !isnegative(x); -} - -template <typename T, size_t N> -CMT_INLINE mask<T, N> iszero(const vec<T, N>& x) -{ - return x == T(); -} - -template <typename T1, typename T2, typename T3> -KFR_SINTRIN maskfor<common_type<T1, T2, T3>> inrange(const T1& x, const T2& min, const T3& max) -{ - return x >= min && x <= max; -} - /// @brief Swap byte order template <typename T, size_t N, KFR_ENABLE_IF(sizeof(vec<T, N>) > 8)> CMT_INLINE vec<T, N> swapbyteorder(const vec<T, N>& x) @@ -554,42 +475,71 @@ CMT_INLINE vec<T, N> negodd(const vec<T, N>& x) return x ^ broadcast<N>(T(), -T()); } -#define KFR_EXPR_UNARY(fn, op) \ - template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> \ - CMT_INLINE internal::expression_function<fn, E1> operator op(E1&& e1) \ - { \ - return { fn(), std::forward<E1>(e1) }; \ - } +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> +CMT_INLINE internal::expression_function<fn::neg, E1> operator-(E1&& e1) +{ + return { fn::neg(), std::forward<E1>(e1) }; +} -#define KFR_EXPR_BINARY(fn, op) \ - template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> \ - CMT_INLINE internal::expression_function<fn, E1, E2> operator op(E1&& e1, E2&& e2) \ - \ - { \ - return { fn(), std::forward<E1>(e1), std::forward<E2>(e2) }; \ - } +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> +CMT_INLINE internal::expression_function<fn::bitwisenot, E1> operator~(E1&& e1) +{ + return { fn::bitwisenot(), std::forward<E1>(e1) }; +} -KFR_EXPR_UNARY(fn::neg, -) -KFR_EXPR_UNARY(fn::bitwisenot, ~) - -KFR_EXPR_BINARY(fn::add, +) -KFR_EXPR_BINARY(fn::sub, -) -KFR_EXPR_BINARY(fn::mul, *) -KFR_EXPR_BINARY(fn::div, /) -KFR_EXPR_BINARY(fn::bitwiseand, &) -KFR_EXPR_BINARY(fn::bitwiseor, |) -KFR_EXPR_BINARY(fn::bitwisexor, ^) -KFR_EXPR_BINARY(fn::shl, <<) -KFR_EXPR_BINARY(fn::shr, >>) - -KFR_EXPR_BINARY(fn::equal, ==) -KFR_EXPR_BINARY(fn::notequal, !=) -KFR_EXPR_BINARY(fn::less, <) -KFR_EXPR_BINARY(fn::greater, >) -KFR_EXPR_BINARY(fn::lessorequal, <=) -KFR_EXPR_BINARY(fn::greaterorequal, >=) -#undef KFR_EXPR_UNARY -#undef KFR_EXPR_BINARY +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::add, E1, E2> operator+(E1&& e1, E2&& e2) +{ + return { fn::add(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::sub, E1, E2> operator-(E1&& e1, E2&& e2) +{ + return { fn::sub(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::mul, E1, E2> operator*(E1&& e1, E2&& e2) +{ + return { fn::mul(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::div, E1, E2> operator/(E1&& e1, E2&& e2) +{ + return { fn::div(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::bitwiseand, E1, E2> operator&(E1&& e1, E2&& e2) +{ + return { fn::bitwiseand(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::bitwiseor, E1, E2> operator|(E1&& e1, E2&& e2) +{ + return { fn::bitwiseor(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::bitwisexor, E1, E2> operator^(E1&& e1, E2&& e2) +{ + return { fn::bitwisexor(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::shl, E1, E2> operator<<(E1&& e1, E2&& e2) +{ + return { fn::shl(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)> +CMT_INLINE internal::expression_function<fn::shr, E1, E2> operator>>(E1&& e1, E2&& e2) +{ + return { fn::shr(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} template <typename T, size_t N1, size_t... Ns> vec<vec<T, sizeof...(Ns) + 1>, N1> packtranspose(const vec<T, N1>& x, const vec<T, Ns>&... rest) diff --git a/sources.cmake b/sources.cmake @@ -20,6 +20,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/base/basic_expressions.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/bitwise.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/clamp.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/comparison.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/compiletime.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/complex.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/constants.hpp