commit 49ee6ce02cc9a457293cfebd99ee3852b9adef86
parent 279015634881c47020a484c09b5221cdf1a61993
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Sun, 21 Oct 2018 19:31:06 +0300
safe_cast, small fixes
Diffstat:
4 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/include/kfr/base/types.hpp b/include/kfr/base/types.hpp
@@ -184,7 +184,7 @@ inline datatype operator|(datatype x, datatype y)
inline datatype operator&(datatype x, datatype y)
{
using type = underlying_type<datatype>;
- return static_cast<datatype>(static_cast<type>(x) | static_cast<type>(y));
+ return static_cast<datatype>(static_cast<type>(x) & static_cast<type>(y));
}
template <typename T>
diff --git a/include/kfr/dsp/weighting.hpp b/include/kfr/dsp/weighting.hpp
@@ -43,7 +43,7 @@ KFR_SINTRIN T weight_a_unnorm(T f)
}
template <typename T>
-constexpr static T weight_a_gain = reciprocal(weight_a_unnorm(T(1000.0)));
+const static T weight_a_gain = reciprocal(weight_a_unnorm(T(1000.0)));
template <typename T>
KFR_SINTRIN T aweighting(T f)
@@ -62,7 +62,7 @@ KFR_SINTRIN T weight_b_unnorm(T f)
}
template <typename T>
-constexpr static T weight_b_gain = reciprocal(weight_b_unnorm(T(1000.0)));
+const static T weight_b_gain = reciprocal(weight_b_unnorm(T(1000.0)));
template <typename T>
KFR_SINTRIN T bweighting(T f)
@@ -81,7 +81,7 @@ KFR_SINTRIN T weight_c_unnorm(T f)
}
template <typename T>
-constexpr static T weight_c_gain = reciprocal(weight_c_unnorm(T(1000.0)));
+const static T weight_c_gain = reciprocal(weight_c_unnorm(T(1000.0)));
template <typename T>
KFR_SINTRIN T cweighting(T f)
diff --git a/include/kfr/dsp/window.hpp b/include/kfr/dsp/window.hpp
@@ -127,7 +127,7 @@ struct expression_rectangular : input_expression
template <size_t N>
CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
- using TI = utype<T>;
+ using TI = utype<T>;
const vec<TI, N> i = enumerate(vec<TI, N>()) + cast<TI>(index);
return select(i < cast<TI>(m_size), T(1), T(0));
}
@@ -369,11 +369,11 @@ struct expression_flattop : input_expression
CMT_INLINE vec<T, N> operator()(cinput_t cinput, size_t index, vec_t<T, N> y) const
{
const vec<T, N> n = linspace(cinput, index, y) * c_pi<T, 2>;
- constexpr T a0 = 1;
- constexpr T a1 = 1.93;
- constexpr T a2 = 1.29;
- constexpr T a3 = 0.388;
- constexpr T a4 = 0.028;
+ constexpr T a0 = 1;
+ constexpr T a1 = 1.93;
+ constexpr T a2 = 1.29;
+ constexpr T a3 = 0.388;
+ constexpr T a4 = 0.028;
return a0 - a1 * cos(n) + a2 * cos(2 * n) - a3 * cos(3 * n) + a4 * cos(4 * n);
}
size_t size() const { return m_size; }
@@ -399,6 +399,7 @@ struct expression_gaussian : input_expression
}
size_t size() const { return m_size; }
+
private:
window_linspace_m1_1_trunc<T> linspace;
T alpha;
@@ -452,7 +453,7 @@ KFR_WINDOW_BY_TYPE(flattop)
KFR_WINDOW_BY_TYPE(gaussian)
KFR_WINDOW_BY_TYPE(lanczos)
#undef KFR_WINDOW_BY_TYPE
-}
+} // namespace internal
/**
* @brief Returns template expression that generates Rrectangular window of length @c size
@@ -609,11 +610,11 @@ CMT_NOINLINE expression_pointer<T> window(size_t size, window_type type, identit
window_type::bohman, window_type::blackman, window_type::blackman_harris, window_type::kaiser,
window_type::flattop, window_type::gaussian, window_type::lanczos>(),
type,
- [=](auto win) {
+ [size, win_param, symmetry](auto win) {
constexpr window_type window = val_of(decltype(win)());
- return to_pointer<T>(
+ return to_pointer(
typename internal::window_by_type<window>::template type<T>(size, win_param, symmetry));
},
fn::returns<expression_pointer<T>>());
}
-}
+} // namespace kfr
diff --git a/include/kfr/testo/assert.hpp b/include/kfr/testo/assert.hpp
@@ -21,8 +21,11 @@ inline void assertion_failed(const std::string& string, const char* file, int li
errorln("Assertion failed at ", file, ":", line);
errorln(string);
errorln();
+ std::fflush(stderr);
}
+bool check_assertion(...);
+
template <typename Op, typename L, typename R>
bool check_assertion(const comparison<Op, L, R>& comparison, const char* expr, const char* file, int line)
{
@@ -44,7 +47,7 @@ bool check_assertion(const half_comparison<L>& comparison, const char* expr, con
{
assertion_failed(as_string(padleft(22, expr), " | ", comparison.left), file, line);
}
- return false;
+ return result;
}
#if defined(TESTO_ASSERTION_ON) || !(defined(NDEBUG) || defined(TESTO_ASSERTION_OFF))
@@ -67,4 +70,35 @@ bool check_assertion(const half_comparison<L>& comparison, const char* expr, con
#ifndef TESTO_NO_SHORT_MACROS
#define ASSERT TESTO_ASSERT
#endif
+
+template <typename OutType, typename InType>
+inline OutType safe_cast(const InType& val)
+{
+ static_assert(std::is_integral<InType>::value && std::is_integral<OutType>::value,
+ "safe_cast is for numeric types only");
+ if (std::is_signed<InType>::value && std::is_signed<OutType>::value) // S->S
+ {
+ ASSERT(val >= std::numeric_limits<OutType>::min());
+ ASSERT(val <= std::numeric_limits<OutType>::max());
+ }
+ else if (!std::is_signed<InType>::value && !std::is_signed<OutType>::value) // U->U
+ {
+ ASSERT(val <= std::numeric_limits<OutType>::max());
+ }
+ else if (std::is_signed<InType>::value && !std::is_signed<OutType>::value) // S->U
+ {
+ ASSERT(val >= 0);
+ ASSERT(val <= std::numeric_limits<OutType>::max());
+ // val will be converted to an unsigned number for the above comparison.
+ // it's safe because we've already checked that it is positive
+ }
+ else // U->S
+ {
+ ASSERT(val <= std::numeric_limits<OutType>::max());
+ // std::numeric_limits<OutType>::max() will be converted to an unsigned number for the above
+ // comparison. it's also safe here
+ }
+ return static_cast<OutType>(val);
}
+
+} // namespace testo