29 #ifndef Vc_CURRENT_CLASS_NAME
30 #error "incorrect use of common/gatherinterface.h: Vc_CURRENT_CLASS_NAME must be defined to the current class name for declaring constructors."
56 template <
typename MT,
typename IT>
57 inline void gatherImplementation(
const MT *mem, IT &&indexes);
63 template <
typename MT,
typename IT>
64 inline void gatherImplementation(
const MT *mem, IT &&indexes, MaskArgument mask);
74 template <typename IT, typename = enable_if<std::is_pointer<IT>::value ||
75 Traits::is_simd_vector<IT>::value>>
76 static Vc_INTRINSIC IT adjustIndexParameter(IT &&indexes)
78 return std::forward<IT>(indexes);
91 template <
typename IT,
93 !std::is_pointer<IT>::value && !Traits::is_simd_vector<IT>::value &&
94 std::is_lvalue_reference<decltype(std::declval<IT>()[0])>::value>>
95 static Vc_INTRINSIC decltype(std::addressof(std::declval<IT>()[0]))
96 adjustIndexParameter(IT &&i)
98 return std::addressof(i[0]);
108 template <
typename IT>
110 enable_if<!std::is_pointer<IT>::value && !Traits::is_simd_vector<IT>::value &&
111 !std::is_lvalue_reference<decltype(std::declval<IT>()[0])>::value,
113 adjustIndexParameter(IT &&i)
115 return std::forward<IT>(i);
119 #define Vc_ASSERT_GATHER_PARAMETER_TYPES__ \
120 static_assert(std::is_convertible<MT, EntryType>::value, \
121 "The memory pointer needs to point to a type that can be converted to the " \
122 "EntryType of this SIMD vector type."); \
124 Vc::Traits::has_subscript_operator<IT>::value, \
125 "The indexes argument must be a type that implements the subscript operator."); \
126 static_assert(!Traits::is_simd_vector<IT>::value || Traits::simd_vector_size<IT>::value >= Size, \
127 "If you use a SIMD vector for the indexes parameter, the index vector must " \
128 "have at least as many entries as this SIMD vector."); \
129 static_assert(!std::is_array<T>::value || \
130 (std::rank<T>::value == 1 && \
131 (std::extent<T>::value == 0 || std::extent<T>::value >= Size)), \
132 "If you use a simple array for the indexes parameter, the array must have " \
133 "at least as many entries as this SIMD vector.")
177 template <
typename MT,
typename IT,
178 typename = enable_if<Traits::has_subscript_operator<IT>::value>>
179 Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(
const MT *mem, IT &&indexes)
181 Vc_ASSERT_GATHER_PARAMETER_TYPES__;
182 gatherImplementation(mem, adjustIndexParameter(std::forward<IT>(indexes)));
186 template <
typename MT,
typename IT,
187 typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
188 Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(
const MT *mem, IT &&indexes, MaskArgument mask)
190 Vc_ASSERT_GATHER_PARAMETER_TYPES__;
191 gatherImplementation(mem, adjustIndexParameter(std::forward<IT>(indexes)), mask);
195 template <
typename MT,
197 typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
198 Vc_INTRINSIC
void gather(
const MT *mem, IT &&indexes)
200 Vc_ASSERT_GATHER_PARAMETER_TYPES__;
201 gatherImplementation(mem, adjustIndexParameter(std::forward<IT>(indexes)));
205 template <
typename MT,
207 typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
208 Vc_INTRINSIC
void gather(
const MT *mem, IT &&indexes, MaskArgument mask)
210 Vc_ASSERT_GATHER_PARAMETER_TYPES__;
211 gatherImplementation(mem, adjustIndexParameter(std::forward<IT>(indexes)), mask);
221 template <
typename MT,
typename IT>
223 Vc_INTRINSIC
void gather(
const Common::GatherArguments<MT, IT> &args)
225 gather(args.address, adjustIndexParameter(args.indexes));
228 template <
typename MT,
typename IT>
229 Vc_INTRINSIC
void gather(
const Common::GatherArguments<MT, IT> &args, MaskArgument mask)
231 gather(args.address, adjustIndexParameter(args.indexes), mask);
235 #undef Vc_ASSERT_GATHER_PARAMETER_TYPES__