1 #ifndef DUNE_COMMON_SIMD_STANDARD_HH
2 #define DUNE_COMMON_SIMD_STANDARD_HH
3 
4 /** @file
5  *  @ingroup SIMDStandard
6  *  @brief SIMD abstractions for the standard built-in types
7  *
8  * This file should not normally be included by users of the SIMD abstraction
9  * (i.e. other Dune headers).  Neither should it be included by the
10  * translation units passing built-in types to Dune headers that in turn
11  * support SIMD types through the SIMD abstraction.  Dune-functionality always
12  * supports built-in types.  Either because that functionality does not
13  * support SIMD types and so only supports built-in types, or if it does
14  * support SIMD types it must include `<dune/common/simd/simd.hh>`, which in
15  * turn includes this header.
16  */
17 
18 #include <cstddef>
19 #include <type_traits>
20 #include <utility>
21 
22 #include <dune/common/indices.hh>
23 #include <dune/common/simd/base.hh>
24 #include <dune/common/simd/defaults.hh>
25 
26 /** @defgroup SIMDStandard SIMD Abstraction Implementation for standard types
27  *  @ingroup SIMDApp
28  *
29  * This implements the vectorization interface for scalar types.  It applies
30  * to any type that does not have a specialized interface implementation.
31  *
32  * As an application developer, there is nothing special you need to do to get
33  * support for standard types in the vectorization abstraction.  If the dune
34  * classes you are using provide support for vectorization, they will include
35  * `<dune/common/simd/simd.hh>`, which will pull in the abstraction for
36  * standard types automatically.  You simply need to make sure that the types
37  * themselves are supported:
38  * - for built-in types there is nothing you need to do,
39  * - for `std::complex`, you need to `#include <complex>`
40  * - etc.
41  */
42 
43 namespace Dune {
44   namespace Simd {
45 
46     namespace Overloads {
47 
48       /** @name Specialized classes and overloaded functions
49        *  @ingroup SIMDStandard
50        *  @{
51        */
52 
53       //! should have a member type \c type
54       /**
55        * Implements Simd::Scalar
56        */
57       template<class V, class>
58       struct ScalarType { using type = V; };
59 
60       //! should have a member type \c type
61       /**
62        * Implements Simd::Rebind
63        */
64       template<class S, class, class>
65       struct RebindType { using type = S; };
66 
67       //! should be derived from an Dune::index_constant
68       /**
69        * Implements Simd::lanes()
70        */
71       template<class, class>
72       struct LaneCount : public index_constant<1> { };
73 
74       //! implements Simd::lane()
75       /**
76        * This binds to rvalues and const lvalues.  It would bind to non-const
77        * lvalues too, but those are caught by the overload with ADLTag<3>.
78        * Using a universal reference here would bind to any argument with a
79        * perfect match.  This would mean ambiguous overloads with other
80        * abstractions, if those only declare overloads for `const TheirType &`
81        * and `TheirType &`, because because universal references match
82        * perfectly.
83        */
84       template<class V>
lane(ADLTag<2>,std::size_t,V v)85       V lane(ADLTag<2>, std::size_t, V v)
86       {
87         return v;
88       }
89 
90       template<class V>
lane(ADLTag<3>,std::size_t,V & v)91       V &lane(ADLTag<3>, std::size_t, V &v)
92       {
93         return v;
94       }
95 
96       // No Simd::cond() implementation, the overload for bool masks in the
97       // interface is sufficient
98 
99       //! implements Simd::anyTrue()
anyTrue(ADLTag<2>,bool mask)100       inline bool anyTrue(ADLTag<2>, bool mask) { return mask; }
101 
102       //! implements Simd::allTrue()
allTrue(ADLTag<2>,bool mask)103       inline bool allTrue(ADLTag<2>, bool mask) { return mask; }
104 
105       //! implements Simd::anyFalse()
anyFalse(ADLTag<2>,bool mask)106       inline bool anyFalse(ADLTag<2>, bool mask) { return !mask; }
107 
108       //! implements Simd::allFalse()
allFalse(ADLTag<2>,bool mask)109       inline bool allFalse(ADLTag<2>, bool mask) { return !mask; }
110 
111       //! @} group SIMDStandard
112 
113     } // namespace Overloads
114   } // namespace Simd
115 } // namespace Dune
116 
117 #endif // DUNE_COMMON_SIMD_STANDARD_HH
118