#ifndef VC_SCALAR_MATH_H
#define VC_SCALAR_MATH_H
-#include "../common/const.h"
#include "macros.h"
+namespace AliRoot {
namespace Vc
{
namespace Scalar
{
#define VC_MINMAX(V) \
-static inline V min(const V &x, const V &y) { return V(std::min(x.data(), y.data())); } \
-static inline V max(const V &x, const V &y) { return V(std::max(x.data(), y.data())); }
+static Vc_ALWAYS_INLINE V min(const V &x, const V &y) { return V(std::min(x.data(), y.data())); } \
+static Vc_ALWAYS_INLINE V max(const V &x, const V &y) { return V(std::max(x.data(), y.data())); }
VC_ALL_VECTOR_TYPES(VC_MINMAX)
#undef VC_MINMAX
-template<typename T> static inline Vector<T> sqrt (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> sqrt (const Vector<T> &x)
{
return Vector<T>(std::sqrt(x.data()));
}
-template<typename T> static inline Vector<T> rsqrt(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> rsqrt(const Vector<T> &x)
{
const typename Vector<T>::EntryType one = 1; return Vector<T>(one / std::sqrt(x.data()));
}
-template<typename T> static inline Vector<T> abs (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> abs (const Vector<T> &x)
{
return Vector<T>(std::abs(x.data()));
}
-template<typename T> static inline void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
+template<> Vc_ALWAYS_INLINE int_v abs(const int_v &x) { return x < 0 ? -x : x; }
+template<> Vc_ALWAYS_INLINE uint_v abs(const uint_v &x) { return x; }
+template<> Vc_ALWAYS_INLINE short_v abs(const short_v &x) { return x < 0 ? -x : x; }
+template<> Vc_ALWAYS_INLINE ushort_v abs(const ushort_v &x) { return x; }
+
+template<typename T> static Vc_ALWAYS_INLINE void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
{
-#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincosf)) || (!defined(VC_CLANG) && defined(__GNUC__))
+#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincosf)) || (!defined(VC_CLANG) && defined(__GNUC__) && !defined(_WIN32))
__builtin_sincosf(x.data(), &sin->data(), &cos->data());
-#elif VC_MSVC
+#elif defined(_GNU_SOURCE)
+ sincosf(x.data(), &sin->data(), &cos->data());
+#else
sin->data() = std::sin(x.data());
cos->data() = std::cos(x.data());
-#else
- sincosf(x.data(), &sin->data(), &cos->data());
#endif
}
-template<> inline void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
+template<> Vc_ALWAYS_INLINE void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
{
-#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincos)) || (!defined(VC_CLANG) && defined(__GNUC__))
+#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincos)) || (!defined(VC_CLANG) && defined(__GNUC__) && !defined(_WIN32))
__builtin_sincos(x.data(), &sin->data(), &cos->data());
-#elif VC_MSVC
+#elif defined(_GNU_SOURCE)
+ ::sincos(x.data(), &sin->data(), &cos->data());
+#else
sin->data() = std::sin(x.data());
cos->data() = std::cos(x.data());
-#else
- ::sincos(x.data(), &sin->data(), &cos->data());
#endif
}
-template<typename T> static inline Vector<T> sin (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> sin (const Vector<T> &x)
{
return Vector<T>(std::sin(x.data()));
}
-template<typename T> static inline Vector<T> asin (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> asin (const Vector<T> &x)
{
return Vector<T>(std::asin(x.data()));
}
-template<typename T> static inline Vector<T> cos (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> cos (const Vector<T> &x)
{
return Vector<T>(std::cos(x.data()));
}
-template<typename T> static inline Vector<T> log (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> log (const Vector<T> &x)
{
return Vector<T>(std::log(x.data()));
}
-template<typename T> static inline Vector<T> log10(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> log10(const Vector<T> &x)
{
return Vector<T>(std::log10(x.data()));
}
-#if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
-static inline double_v log2(double_v::AsArg x) { return double_v(::log2 (x.data())); }
-static inline sfloat_v log2(sfloat_v::AsArg x) { return sfloat_v(::log2f(x.data())); }
-static inline float_v log2( float_v::AsArg x) { return float_v(::log2f(x.data())); }
+#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) || defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
+static Vc_ALWAYS_INLINE double_v log2(double_v::AsArg x) { return double_v(::log2 (x.data())); }
+static Vc_ALWAYS_INLINE sfloat_v log2(sfloat_v::AsArg x) { return sfloat_v(::log2f(x.data())); }
+static Vc_ALWAYS_INLINE float_v log2( float_v::AsArg x) { return float_v(::log2f(x.data())); }
#else
+namespace {
+template<typename T> static _VC_CONSTEXPR T c_ln2() { return Vc_buildFloat(1, 0x317218, -1); } // .693147182464599609375
+template<> _VC_CONSTEXPR double c_ln2() { return Vc_buildDouble(1, 0x62E42FEFA39EFull, -1); } // .69314718055994528622676398299518041312694549560546875
+}
#define VC_LOG2(V) \
-static inline V log2(const V &x) \
+static Vc_ALWAYS_INLINE V log2(const V &x) \
{ \
- return V(std::log(x.data()) / Math<V::EntryType>::ln2()); \
+ return V(std::log(x.data()) / c_ln2<V::EntryType>()); \
}
VC_ALL_FLOAT_VECTOR_TYPES(VC_LOG2)
#undef VC_LOG2
#endif
-template<typename T> static inline Vector<T> exp (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> exp (const Vector<T> &x)
{
return Vector<T>(std::exp(x.data()));
}
-template<typename T> static inline Vector<T> atan (const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan (const Vector<T> &x)
{
return Vector<T>(std::atan( x.data() ));
}
-template<typename T> static inline Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
{
return Vector<T>(std::atan2( x.data(), y.data() ));
}
-template<typename T> static inline Vector<T> floor(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> trunc(const Vector<T> &x)
+{
+#if __cplusplus >= 201103 /*C++11*/
+ return std::trunc(x.data());
+#else
+ return x.data() > 0 ? std::floor(x.data()) : std::ceil(x.data());
+#endif
+}
+
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> floor(const Vector<T> &x)
{
return Vector<T>(std::floor(x.data()));
}
-template<typename T> static inline Vector<T> ceil(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> ceil(const Vector<T> &x)
{
return Vector<T>(std::ceil(x.data()));
}
-template<typename T> static inline Vector<T> round(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> round(const Vector<T> &x)
{
return x;
}
return (x - f) == half;
}
} // namespace
-template<> inline Vector<float> round(const Vector<float> &x)
+template<> Vc_ALWAYS_INLINE Vector<float> round(const Vector<float> &x)
{
return float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
}
-template<> inline Vector<sfloat> round(const Vector<sfloat> &x)
+template<> Vc_ALWAYS_INLINE Vector<sfloat> round(const Vector<sfloat> &x)
{
return sfloat_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
}
-template<> inline Vector<double> round(const Vector<double> &x)
+template<> Vc_ALWAYS_INLINE Vector<double> round(const Vector<double> &x)
{
return double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1. : 0. ));
}
-template<typename T> static inline Vector<T> reciprocal(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE Vector<T> reciprocal(const Vector<T> &x)
{
const typename Vector<T>::EntryType one = 1; return Vector<T>(one / x.data());
}
#ifdef isnan
#undef isnan
#endif
-template<typename T> static inline typename Vector<T>::Mask isfinite(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isfinite(const Vector<T> &x)
{
return typename Vector<T>::Mask(
#ifdef _MSC_VER
);
}
-template<typename T> static inline typename Vector<T>::Mask isnan(const Vector<T> &x)
+template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isnan(const Vector<T> &x)
{
return typename Vector<T>::Mask(
#ifdef _MSC_VER
);
}
-inline Vector<float> frexp(Vector<float> x, Vector<int> *e) {
+Vc_ALWAYS_INLINE Vector<float> frexp(Vector<float> x, Vector<int> *e) {
return float_v(::frexpf(x.data(), &e->data()));
}
-inline Vector<double> frexp(Vector<double> x, Vector<int> *e) {
+Vc_ALWAYS_INLINE Vector<double> frexp(Vector<double> x, Vector<int> *e) {
return double_v(::frexp(x.data(), &e->data()));
}
-inline sfloat_v frexp(sfloat_v x, short_v *e) {
+Vc_ALWAYS_INLINE sfloat_v frexp(sfloat_v x, short_v *e) {
int ee;
const float r = ::frexpf(x.data(), &ee);
e->data() = ee;
return sfloat_v(r);
}
-inline Vector<float> ldexp(Vector<float> x, Vector<int> e) {
+Vc_ALWAYS_INLINE Vector<float> ldexp(Vector<float> x, Vector<int> e) {
return float_v(::ldexpf(x.data(), e.data()));
}
-inline Vector<double> ldexp(Vector<double> x, Vector<int> e) {
+Vc_ALWAYS_INLINE Vector<double> ldexp(Vector<double> x, Vector<int> e) {
return double_v(::ldexp(x.data(), e.data()));
}
-inline sfloat_v ldexp(sfloat_v x, short_v e) {
+Vc_ALWAYS_INLINE sfloat_v ldexp(sfloat_v x, short_v e) {
return sfloat_v(::ldexpf(x.data(), e.data()));
}
} // namespace Scalar
} // namespace Vc
+} // namespace AliRoot
#include "undomacros.h"