@@ -406,28 +406,86 @@ namespace xsimd
406406 }
407407#endif
408408
409+ namespace detail
410+ {
411+ #define XSIMD_HASSINCOS_TRAIT (func ) \
412+ template <class S > \
413+ struct has ##func \
414+ { \
415+ template <class T > static auto get (T* ptr) -> decltype(func(std::declval<T>(), std::declval<T*>(), std::declval<T*>()), std::true_type{});\
416+ static std::false_type get (...); \
417+ static constexpr bool value = decltype (get((S*)nullptr ))::value; \
418+ }
419+
420+ #define XSIMD_HASSINCOS (func, T ) has##func<T>::value
421+
422+ XSIMD_HASSINCOS_TRAIT (sincos);
423+ XSIMD_HASSINCOS_TRAIT (sincosf);
424+ XSIMD_HASSINCOS_TRAIT (__sincos);
425+ XSIMD_HASSINCOS_TRAIT (__sincosf);
426+
427+ struct generic_sincosf
428+ {
429+ template <class T >
430+ typename std::enable_if<XSIMD_HASSINCOS(sincosf, T), void >::type
431+ operator ()(float val, T &s, T &c)
432+ {
433+ sincosf (val, &s, &c);
434+ }
435+
436+ template <class T >
437+ typename std::enable_if<!XSIMD_HASSINCOS(sincosf, T) && XSIMD_HASSINCOS(__sincosf, T), void >::type
438+ operator ()(float val, T &s, T &c)
439+ {
440+ __sincosf (val, &s, &c);
441+ }
442+
443+ template <class T >
444+ typename std::enable_if<!XSIMD_HASSINCOS(sincosf, T) && !XSIMD_HASSINCOS(__sincosf, T), void >::type
445+ operator ()(float val, T &s, T &c)
446+ {
447+ s = std::sin (val);
448+ c = std::cos (val);
449+ }
450+ };
451+
452+ struct generic_sincos
453+ {
454+ template <class T >
455+ typename std::enable_if<XSIMD_HASSINCOS(sincos, T), void >::type
456+ operator ()(double val, T &s, T &c)
457+ {
458+ sincos (val, &s, &c);
459+ }
460+
461+ template <class T >
462+ typename std::enable_if<!XSIMD_HASSINCOS(sincos, T) && XSIMD_HASSINCOS(__sincos, T), void >::type
463+ operator ()(double val, T &s, T &c)
464+ {
465+ __sincos (val, &s, &c);
466+ }
467+
468+ template <class T >
469+ typename std::enable_if<!XSIMD_HASSINCOS(sincos, T) && !XSIMD_HASSINCOS(__sincos, T), void >::type
470+ operator ()(double val, T &s, T &c)
471+ {
472+ s = std::sin (val);
473+ c = std::cos (val);
474+ }
475+ };
476+
477+ #undef XSIMD_HASSINCOS_TRAIT
478+ #undef XSIMD_HASSINCOS
479+ }
480+
409481 inline void sincos (float val, float &s, float & c)
410482 {
411- #if defined(__APPLE__)
412- __sincosf (val, &s, &c);
413- #elif defined(_GNU_SOURCE)
414- ::sincosf (val, &s, &c);
415- #else
416- s = std::sin (val);
417- c = std::cos (val);
418- #endif
483+ detail::generic_sincosf{}(val, s, c);
419484 }
420485
421486 inline void sincos (double val, double &s, double & c)
422487 {
423- #if defined(__APPLE__)
424- __sincos (val, &s, &c);
425- #elif defined(_GNU_SOURCE)
426- ::sincos (val, &s, &c);
427- #else
428- s = std::sin (val);
429- c = std::cos (val);
430- #endif
488+ detail::generic_sincos{}(val, s, c);
431489 }
432490
433491 template <class T >
0 commit comments