1212#include < cmath>
1313#include < complex>
1414
15- #ifndef RA_OPT
16- #define RA_OPT opt
17- #endif
18-
19- #if defined(RA_FMA)
20- #elif defined(FP_FAST_FMA)
21- #define RA_FMA FP_FAST_FMA
22- #else
23- #define RA_FMA 0
24- #endif
25-
2615// ADL with explicit template args. See http://stackoverflow.com/questions/9838862.
2716template <int A> constexpr void iter (ra::noarg<>);
2817template <class T > constexpr void cast (ra::noarg<>);
@@ -126,6 +115,10 @@ template <class T> constexpr bool is_scalar_def<std::complex<T>> = true;
126115// Optimization pass over expression templates.
127116// --------------------------------
128117
118+ #ifndef RA_OPT
119+ #define RA_OPT opt
120+ #endif
121+
129122constexpr decltype (auto ) opt(auto && e) { return RA_FW (e); }
130123
131124// FIXME only reduces exprs as operated on in ra.hh (operators), not a tree like wlen() does.
@@ -239,16 +232,10 @@ RA_FE(RA_USING, fma)
239232#undef RA_NAME
240233
241234template <class T > constexpr auto
242- cast (auto && a)
243- {
244- return map ([](auto && b) -> decltype (auto ) { return T (b); }, RA_FW (a));
245- }
235+ cast (auto && a) { return map ([](auto && b) -> decltype (auto ) { return T (b); }, RA_FW (a)); }
246236
247237template <class T > constexpr auto
248- pack (auto && ... a)
249- {
250- return map ([](auto && ... a){ return T { RA_FW (a) ... }; }, RA_FW (a) ...);
251- }
238+ pack (auto && ... a) { return map ([](auto && ... a){ return T { RA_FW (a) ... }; }, RA_FW (a) ...); }
252239
253240template <class A > constexpr decltype (auto )
254241at(A && a, auto const & i) requires (Slice<std::decay_t <A>> || Iterator<std::decay_t <A>>)
@@ -275,25 +262,25 @@ at_view(A && a, auto && i)
275262 }
276263}
277264
278- template <class T , class F > requires (toreduce<T, F>)
279- constexpr decltype( auto ) where(bool const w, T && t, F && f) { return w ? VAL (t) : VAL (f); }
265+ template <class T , class F > requires (toreduce<T, F>) constexpr decltype( auto )
266+ where(bool const w, T && t, F && f) { return w ? VAL (t) : VAL (f); }
280267
281- template <class W , class T , class F > requires (tomap<W, T, F>)
282- constexpr auto where(W && w, T && t, F && f) { return pick (cast<bool >(RA_FW (w)), RA_FW (f), RA_FW (t)); }
268+ template <class W , class T , class F > requires (tomap<W, T, F>) constexpr auto
269+ where(W && w, T && t, F && f) { return pick (cast<bool >(RA_FW (w)), RA_FW (f), RA_FW (t)); }
283270
284271// catch all for non-ra types.
285- template <class T , class F > requires (!(tomap<T, F>) && !(toreduce<T, F>))
286- constexpr decltype( auto ) where(bool const w, T && t, F && f) { return w ? t : f; }
272+ template <class T , class F > requires (!(tomap<T, F>) && !(toreduce<T, F>)) constexpr decltype( auto )
273+ where(bool const w, T && t, F && f) { return w ? t : f; }
287274
288- template <class A , class B > requires (tomap<A, B>)
289- constexpr auto operator &&(A && a, B && b) { return where (RA_FW (a), cast<bool >(RA_FW (b)), false ); }
275+ template <class A , class B > requires (tomap<A, B>) constexpr auto
276+ operator &&(A && a, B && b) { return where (RA_FW (a), cast<bool >(RA_FW (b)), false ); }
290277
291- template <class A , class B > requires (tomap<A, B>)
292- constexpr auto operator ||(A && a, B && b) { return where (RA_FW (a), true , cast<bool >(RA_FW (b))); }
278+ template <class A , class B > requires (tomap<A, B>) constexpr auto
279+ operator ||(A && a, B && b) { return where (RA_FW (a), true , cast<bool >(RA_FW (b))); }
293280
294281#define RA_BINOP_SHORT (OP ) \
295- template <class A , class B > requires (toreduce<A, B>) \
296- constexpr auto operator OP(A && a, B && b) { return VAL (a) OP VAL (b); }
282+ template <class A , class B > requires (toreduce<A, B>) constexpr auto \
283+ operator OP(A && a, B && b) { return VAL (a) OP VAL (b); }
297284RA_FE (RA_BINOP_SHORT, &&, ||)
298285#undef RA_BINOP_SHORT
299286
@@ -389,6 +376,13 @@ prod(auto && a)
389376 return c;
390377}
391378
379+ #if defined(RA_FMA)
380+ #elif defined(FP_FAST_FMA)
381+ #define RA_FMA FP_FAST_FMA
382+ #else
383+ #define RA_FMA 0
384+ #endif
385+
392386constexpr void maybe_fma (auto && a, auto && b, auto & c) { if constexpr (RA_FMA) c=fma (a, b, c); else c+=a*b; }
393387constexpr void maybe_fma_conj (auto && a, auto && b, auto & c) { if constexpr (RA_FMA) c=fma_conj (a, b, c); else c+=conj (a)*b; }
394388constexpr void maybe_fma_sqrm (auto && a, auto & c) { if constexpr (RA_FMA) c=fma_sqrm (a, c); else c+=sqrm (a); }
0 commit comments