28 #ifndef VC_COMMON_SIMDIZE_H_    29 #define VC_COMMON_SIMDIZE_H_    34 #include "../Allocator"    35 #include "interleavedmemory.h"   122 namespace Vc_VERSIONED_NAMESPACE
   130 namespace SimdizeDetail  
   137 using std::is_base_of;
   138 using std::false_type;
   139 using std::true_type;
   140 using std::iterator_traits;
   141 using std::conditional;
   143 template <
bool B, 
typename T, 
typename F>
   144 using conditional_t = 
typename conditional<B, T, F>::type;
   150 template <
typename... Ts> 
struct Typelist;
   155 enum class Category {
   159     ArithmeticVectorizable,
   167     BidirectionalIterator,
   169     RandomAccessIterator,
   178 template <
typename T, 
typename ItCat = 
typename T::iterator_category>
   179 constexpr Category iteratorCategories(
int, ItCat * = 
nullptr)
   181     return is_base_of<std::random_access_iterator_tag, ItCat>::value
   182                ? Category::RandomAccessIterator
   183                : is_base_of<std::bidirectional_iterator_tag, ItCat>::value
   184                      ? Category::BidirectionalIterator
   185                      : is_base_of<std::forward_iterator_tag, ItCat>::value
   186                            ? Category::ForwardIterator
   187                            : is_base_of<std::output_iterator_tag, ItCat>::value
   188                                  ? Category::OutputIterator
   189                                  : is_base_of<std::input_iterator_tag, ItCat>::value
   190                                        ? Category::InputIterator
   196 template <
typename T>
   197 constexpr enable_if<std::is_pointer<T>::value, Category> iteratorCategories(
float)
   199     return Category::RandomAccessIterator;
   204 template <
typename T> constexpr Category iteratorCategories(...)
   206     return Category::None;
   212 template <
typename T> 
struct is_class_template : 
public false_type
   215 template <
template <
typename...> 
class C, 
typename... Ts>
   216 struct is_class_template<C<Ts...>> : 
public true_type
   223 template <
typename T> constexpr Category typeCategory()
   225     return (is_same<T, bool>::value || is_same<T, short>::value ||
   226             is_same<T, unsigned short>::value || is_same<T, int>::value ||
   227             is_same<T, unsigned int>::value || is_same<T, float>::value ||
   228             is_same<T, double>::value)
   229                ? Category::ArithmeticVectorizable
   230                : iteratorCategories<T>(int()) != Category::None
   231                      ? iteratorCategories<T>(
int())
   232                      : is_class_template<T>::value ? Category::ClassTemplate
   241 template <typename T, size_t TupleSize = std::tuple_size<T>::value>
   242 constexpr 
size_t determine_tuple_size()
   246 template <
typename T, 
size_t TupleSize = T::tuple_size>
   247 constexpr 
size_t determine_tuple_size(
size_t = T::tuple_size)
   254 template <
typename T> 
struct determine_tuple_size_
   255 : 
public std::integral_constant<size_t, determine_tuple_size<T>()>
   260 template <
typename T> 
struct The_simdization_for_the_requested_type_is_not_implemented;
   275 template <
typename T, 
size_t N, 
typename MT, Category = typeCategory<T>()>
   276 struct ReplaceTypes : 
public The_simdization_for_the_requested_type_is_not_implemented<T>
   284 template <
typename T, 
size_t N, 
typename MT> 
struct ReplaceTypes<T, N, MT, Category::None>
   293 template <
typename T, 
size_t N = 0, 
typename MT = 
void>
   294 using simdize = 
typename SimdizeDetail::ReplaceTypes<T, N, MT>::type;
   297 template <
class T, 
size_t N,
   298           class Best = 
typename Common::select_best_vector_type<T, N>::type>
   299 using deduce_vector_t =
   300     typename std::conditional<Best::size() == N, Best, SimdArray<T, N>>::type;
   306 template <
typename T, 
size_t N, 
typename MT>
   307 struct ReplaceTypes<T, N, MT, Category::ArithmeticVectorizable>
   308     : 
public conditional<N == 0, Vector<T>, deduce_vector_t<T, N>> {
   315 template <
size_t N, 
typename MT>
   316 struct ReplaceTypes<bool, N, MT, Category::ArithmeticVectorizable>
   317     : 
public std::enable_if<true, typename ReplaceTypes<MT, N, MT>::type::mask_type> {
   323 struct ReplaceTypes<bool, N, void, Category::ArithmeticVectorizable>
   324     : 
public ReplaceTypes<bool, N, float, Category::ArithmeticVectorizable>
   334 template <
size_t N, 
typename MT, 
typename Replaced, 
typename... Remaining>
   335 struct SubstituteOneByOne;
   341 template <
size_t N, 
typename MT, 
typename... Replaced, 
typename T,
   342           typename... Remaining>
   343 struct SubstituteOneByOne<N, MT, Typelist<Replaced...>, T, Remaining...>
   350     template <
typename U, 
size_t M = U::Size>
   351     static std::integral_constant<size_t, M> size_or_0(
int);
   352     template <
typename U> 
static std::integral_constant<size_t, 0> size_or_0(...);
   355     using V = simdize<T, N, MT>;
   361     static constexpr 
auto NewN = N != 0 ? N : decltype(size_or_0<V>(
int()))::value;
   368     typedef conditional_t<(N != NewN && is_same<MT, void>::value),
   369                           conditional_t<is_same<T, bool>::value, 
float, T>, MT> NewMT;
   375     using type = 
typename SubstituteOneByOne<NewN, NewMT, Typelist<Replaced..., V>,
   381 template <
size_t Size, 
typename... Replaced> 
struct SubstitutedBase;
   383 template <
typename Replaced> 
struct SubstitutedBase<1, Replaced> {
   384     template <
typename ValueT, 
template <
typename, ValueT...> 
class C, ValueT... Values>
   385     using SubstitutedWithValues = C<Replaced, Values...>;
   388 template <
typename R0, 
typename R1> 
struct SubstitutedBase<2, R0, R1>
   390     template <
typename ValueT, 
template <
typename, 
typename, ValueT...> 
class C,
   392     using SubstitutedWithValues = C<R0, R1, Values...>;
   395 template <
typename R0, 
typename R1, 
typename R2> 
struct SubstitutedBase<3, R0, R1, R2>
   397     template <
typename ValueT, 
template <
typename, 
typename, 
typename, ValueT...> 
class C,
   399     using SubstitutedWithValues = C<R0, R1, R2, Values...>;
   401 #if defined Vc_ICC || defined Vc_MSVC   402 #define Vc_VALUE_PACK_EXPANSION_IS_BROKEN 1   404 template <
typename... Replaced> 
struct SubstitutedBase<4, Replaced...> {
   406 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   407     template <
typename ValueT,
   408               template <
typename, 
typename, 
typename, 
typename, ValueT...> 
class C,
   410     using SubstitutedWithValues = C<Replaced..., Values...>;
   411 #endif // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   414 template <
typename... Replaced> 
struct SubstitutedBase<5, Replaced...> {
   415 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   416     template <
typename ValueT, 
template <
typename, 
typename, 
typename, 
typename, 
typename,
   419     using SubstitutedWithValues = C<Replaced..., Values...>;
   420 #endif // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   423 template <
typename... Replaced> 
struct SubstitutedBase<6, Replaced...> {
   424 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   425     template <
typename ValueT, 
template <
typename, 
typename, 
typename, 
typename, 
typename,
   426                                          typename, ValueT...> 
class C,
   428     using SubstitutedWithValues = C<Replaced..., Values...>;
   429 #endif // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   432 template <
typename... Replaced> 
struct SubstitutedBase<7, Replaced...> {
   433 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   434     template <
typename ValueT, 
template <
typename, 
typename, 
typename, 
typename, 
typename,
   435                                          typename, 
typename, ValueT...> 
class C,
   437     using SubstitutedWithValues = C<Replaced..., Values...>;
   438 #endif // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   441 template <
typename... Replaced> 
struct SubstitutedBase<8, Replaced...> {
   442 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   443     template <
typename ValueT, 
template <
typename, 
typename, 
typename, 
typename, 
typename,
   444                                          typename, 
typename, 
typename, ValueT...> 
class C,
   446     using SubstitutedWithValues = C<Replaced..., Values...>;
   447 #endif // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   455 template <
size_t N_, 
typename MT, 
typename Replaced0, 
typename... Replaced>
   456 struct SubstituteOneByOne<N_, MT, Typelist<Replaced0, Replaced...>>
   462         : 
public SubstitutedBase<sizeof...(Replaced) + 1, Replaced0, Replaced...> {
   463         static constexpr 
auto N = N_;
   468         template <
template <
typename...> 
class C>
   469         using Substituted = C<Replaced0, Replaced...>;
   489 template <
typename Scalar, 
typename Base, 
size_t N> 
class Adapter;
   495 template <
template <
typename...> 
class C, 
typename... Ts, 
size_t N, 
typename MT>
   496 struct ReplaceTypes<C<Ts...>, N, MT, Category::ClassTemplate>
   499     using SubstitutionResult =
   500         typename SubstituteOneByOne<N, MT, Typelist<>, Ts...>::type;
   506     using Vectorized = 
typename SubstitutionResult::template Substituted<C>;
   512     using type = conditional_t<is_same<C<Ts...>, Vectorized>::value, C<Ts...>,
   513                                Adapter<C<Ts...>, Vectorized, SubstitutionResult::N>>;
   521 #ifdef Vc_VALUE_PACK_EXPANSION_IS_BROKEN   523 #define Vc_DEFINE_NONTYPE_REPLACETYPES_(ValueType_)                                      \   524     template <template <typename, ValueType_...> class C, typename T, ValueType_ Value0, \   525               ValueType_... Values>                                                      \   526     struct is_class_template<C<T, Value0, Values...>> : public true_type {               \   528     template <template <typename, typename, ValueType_...> class C, typename T0,         \   529               typename T1, ValueType_ Value0, ValueType_... Values>                      \   530     struct is_class_template<C<T0, T1, Value0, Values...>> : public true_type {          \   532     template <template <typename, typename, typename, ValueType_...> class C,            \   533               typename T0, typename T1, typename T2, ValueType_ Value0,                  \   534               ValueType_... Values>                                                      \   535     struct is_class_template<C<T0, T1, T2, Value0, Values...>> : public true_type {      \   537     template <template <typename, typename, typename, typename, ValueType_...> class C,  \   538               typename T0, typename T1, typename T2, typename T3, ValueType_ Value0,     \   539               ValueType_... Values>                                                      \   540     struct is_class_template<C<T0, T1, T2, T3, Value0, Values...>> : public true_type {  \   542     template <template <typename, typename, typename, typename, typename, ValueType_...> \   544               typename T0, typename T1, typename T2, typename T3, typename T4,           \   545               ValueType_ Value0, ValueType_... Values>                                   \   546     struct is_class_template<C<T0, T1, T2, T3, T4, Value0, Values...>>                   \   547         : public true_type {                                                             \   549     template <template <typename, typename, typename, typename, typename, typename,      \   550                         ValueType_...> class C,                                          \   551               typename T0, typename T1, typename T2, typename T3, typename T4,           \   552               typename T5, ValueType_ Value0, ValueType_... Values>                      \   553     struct is_class_template<C<T0, T1, T2, T3, T4, T5, Value0, Values...>>               \   554         : public true_type {                                                             \   556     template <template <typename, typename, typename, typename, typename, typename,      \   557                         typename, ValueType_...> class C,                                \   558               typename T0, typename T1, typename T2, typename T3, typename T4,           \   559               typename T5, typename T6, ValueType_ Value0, ValueType_... Values>         \   560     struct is_class_template<C<T0, T1, T2, T3, T4, T5, T6, Value0, Values...>>           \   561         : public true_type {                                                             \   563     template <template <typename, ValueType_> class C, typename T0, ValueType_ Value0,   \   564               size_t N, typename MT>                                                     \   565     struct ReplaceTypes<C<T0, Value0>, N, MT, Category::ClassTemplate> {                 \   566         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0>::type tmp;            \   567         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \   569         static constexpr auto NN = tmp::N;                                               \   570         typedef conditional_t<is_same<C<T0, Value0>, Substituted>::value, C<T0, Value0>, \   571                               Adapter<C<T0, Value0>, Substituted, NN>> type;             \   573     template <template <typename, typename, ValueType_> class C, typename T0,            \   574               typename T1, ValueType_ Value0, size_t N, typename MT>                     \   575     struct ReplaceTypes<C<T0, T1, Value0>, N, MT, Category::ClassTemplate> {             \   576         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1>::type tmp;        \   577         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \   579         static constexpr auto NN = tmp::N;                                               \   580         typedef conditional_t<is_same<C<T0, T1, Value0>, Substituted>::value,            \   582                               Adapter<C<T0, T1, Value0>, Substituted, NN>> type;         \   584     template <template <typename, typename, typename, ValueType_> class C, typename T0,  \   585               typename T1, typename T2, ValueType_ Value0, size_t N, typename MT>        \   586     struct ReplaceTypes<C<T0, T1, T2, Value0>, N, MT, Category::ClassTemplate> {         \   587         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1, T2>::type tmp;    \   588         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \   590         static constexpr auto NN = tmp::N;                                               \   591         typedef conditional_t<is_same<C<T0, T1, T2, Value0>, Substituted>::value,        \   592                               C<T0, T1, T2, Value0>,                                     \   593                               Adapter<C<T0, T1, T2, Value0>, Substituted, NN>> type;     \   596 #define Vc_DEFINE_NONTYPE_REPLACETYPES_(ValueType_)                                      \   597     template <template <typename, ValueType_...> class C, typename T, ValueType_ Value0, \   598               ValueType_... Values>                                                      \   599     struct is_class_template<C<T, Value0, Values...>> : public true_type {               \   601     template <template <typename, typename, ValueType_...> class C, typename T0,         \   602               typename T1, ValueType_ Value0, ValueType_... Values>                      \   603     struct is_class_template<C<T0, T1, Value0, Values...>> : public true_type {          \   605     template <template <typename, typename, typename, ValueType_...> class C,            \   606               typename T0, typename T1, typename T2, ValueType_ Value0,                  \   607               ValueType_... Values>                                                      \   608     struct is_class_template<C<T0, T1, T2, Value0, Values...>> : public true_type {      \   610     template <template <typename, typename, typename, typename, ValueType_...> class C,  \   611               typename T0, typename T1, typename T2, typename T3, ValueType_ Value0,     \   612               ValueType_... Values>                                                      \   613     struct is_class_template<C<T0, T1, T2, T3, Value0, Values...>> : public true_type {  \   615     template <template <typename, typename, typename, typename, typename, ValueType_...> \   617               typename T0, typename T1, typename T2, typename T3, typename T4,           \   618               ValueType_ Value0, ValueType_... Values>                                   \   619     struct is_class_template<C<T0, T1, T2, T3, T4, Value0, Values...>>                   \   620         : public true_type {                                                             \   622     template <template <typename, typename, typename, typename, typename, typename,      \   623                         ValueType_...> class C,                                          \   624               typename T0, typename T1, typename T2, typename T3, typename T4,           \   625               typename T5, ValueType_ Value0, ValueType_... Values>                      \   626     struct is_class_template<C<T0, T1, T2, T3, T4, T5, Value0, Values...>>               \   627         : public true_type {                                                             \   629     template <template <typename, typename, typename, typename, typename, typename,      \   630                         typename, ValueType_...> class C,                                \   631               typename T0, typename T1, typename T2, typename T3, typename T4,           \   632               typename T5, typename T6, ValueType_ Value0, ValueType_... Values>         \   633     struct is_class_template<C<T0, T1, T2, T3, T4, T5, T6, Value0, Values...>>           \   634         : public true_type {                                                             \   636     template <template <typename, ValueType_...> class C, typename T0,                   \   637               ValueType_ Value0, ValueType_... Values, size_t N, typename MT>            \   638     struct ReplaceTypes<C<T0, Value0, Values...>, N, MT, Category::ClassTemplate> {      \   639         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0>::type tmp;            \   640         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \   641                                                              Values...> Substituted;     \   642         static constexpr auto NN = tmp::N;                                               \   643         typedef conditional_t<is_same<C<T0, Value0, Values...>, Substituted>::value,     \   644                               C<T0, Value0, Values...>,                                  \   645                               Adapter<C<T0, Value0, Values...>, Substituted, NN>> type;  \   647     template <template <typename, typename, ValueType_...> class C, typename T0,         \   648               typename T1, ValueType_ Value0, ValueType_... Values, size_t N,            \   650     struct ReplaceTypes<C<T0, T1, Value0, Values...>, N, MT, Category::ClassTemplate> {  \   651         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1>::type tmp;        \   652         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \   653                                                              Values...> Substituted;     \   654         static constexpr auto NN = tmp::N;                                               \   655         typedef conditional_t<is_same<C<T0, T1, Value0, Values...>, Substituted>::value, \   656                               C<T0, T1, Value0, Values...>,                              \   657                               Adapter<C<T0, T1, Value0, Values...>, Substituted, NN>>    \   660     template <template <typename, typename, typename, ValueType_...> class C,            \   661               typename T0, typename T1, typename T2, ValueType_ Value0,                  \   662               ValueType_... Values, size_t N, typename MT>                               \   663     struct ReplaceTypes<C<T0, T1, T2, Value0, Values...>, N, MT,                         \   664                         Category::ClassTemplate> {                                       \   665         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1, T2>::type tmp;    \   666         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \   667                                                              Values...> Substituted;     \   668         static constexpr auto NN = tmp::N;                                               \   669         typedef conditional_t<                                                           \   670             is_same<C<T0, T1, T2, Value0, Values...>, Substituted>::value,               \   671             C<T0, T1, T2, Value0, Values...>,                                            \   672             Adapter<C<T0, T1, T2, Value0, Values...>, Substituted, NN>> type;            \   674 #endif  // Vc_VALUE_PACK_EXPANSION_IS_BROKEN   675 Vc_DEFINE_NONTYPE_REPLACETYPES_(
bool);
   676 Vc_DEFINE_NONTYPE_REPLACETYPES_(
wchar_t);
   677 Vc_DEFINE_NONTYPE_REPLACETYPES_(
char);
   678 Vc_DEFINE_NONTYPE_REPLACETYPES_(  
signed char);
   679 Vc_DEFINE_NONTYPE_REPLACETYPES_(
unsigned char);
   680 Vc_DEFINE_NONTYPE_REPLACETYPES_(  
signed short);
   681 Vc_DEFINE_NONTYPE_REPLACETYPES_(
unsigned short);
   682 Vc_DEFINE_NONTYPE_REPLACETYPES_(  
signed int);
   683 Vc_DEFINE_NONTYPE_REPLACETYPES_(
unsigned int);
   684 Vc_DEFINE_NONTYPE_REPLACETYPES_(  
signed long);
   685 Vc_DEFINE_NONTYPE_REPLACETYPES_(
unsigned long);
   686 Vc_DEFINE_NONTYPE_REPLACETYPES_(  
signed long long);
   687 Vc_DEFINE_NONTYPE_REPLACETYPES_(
unsigned long long);
   688 #undef Vc_DEFINE_NONTYPE_REPLACETYPES_   691 namespace preferred_construction_impl
   693 template <
typename T> T create();
   695 template <
class Type, 
class... Init, 
class = decltype(Type(create<Init>()...))>
   696 constexpr std::integral_constant<int, 0> test(
int);
   698 template <
class Type, 
class... Init, 
class = decltype(Type{create<Init>()...})>
   699 constexpr std::integral_constant<int, 1> test(
float);
   701 template <
class Type, 
class... Init, 
class T, 
class = decltype(Type{{create<Init>()...}})>
   702 constexpr std::integral_constant<int, 2> test(T);
   704 template <
class Type, 
class... Init> constexpr std::integral_constant<int, 3> test(...);
   707 template <
class Type, 
class... Init>
   708 constexpr 
inline decltype(preferred_construction_impl::test<Type, Init...>(0))
   709 preferred_construction()
   720 template <
size_t I, 
typename T,
   721           typename R = decltype(std::declval<T &>().
template vc_get_<I>())>
   722 R get_dispatcher(T &x, 
void * = 
nullptr)
   724     return x.template vc_get_<I>();
   726 template <
size_t I, 
typename T,
   727           typename R = decltype(std::declval<const T &>().
template vc_get_<I>())>
   728 R get_dispatcher(
const T &x, 
void * = 
nullptr)
   730     return x.template vc_get_<I>();
   732 template <
size_t I, 
typename T, 
typename R = decltype(std::get<I>(std::declval<T &>()))>
   733 R get_dispatcher(T &x, 
int = 0)
   735     return std::get<I>(x);
   737 template <
size_t I, 
typename T,
   738           typename R = decltype(std::get<I>(std::declval<const T &>()))>
   739 R get_dispatcher(
const T &x, 
int = 0)
   741     return std::get<I>(x);
   751 template <
class... Ts> 
struct homogeneous_sizeof;
   752 template <
class T, 
class = 
void> 
struct homogeneous_sizeof_one;
   754 template <
class T, 
size_t... Is>
   755 std::integral_constant<size_t,
   756                        homogeneous_sizeof<
typename std::remove_reference<decltype(
   757                            get_dispatcher<Is>(std::declval<T>()))>::type...>::value>
   758 homogeneous_sizeof_helper(index_sequence<Is...>);
   761 struct homogeneous_sizeof_one<T,
   762                               typename 
std::enable_if<std::is_arithmetic<T>::value>::type>
   763     : std::integral_constant<size_t, sizeof(T)> {
   767 struct homogeneous_sizeof_one<T, typename std::enable_if<std::is_class<T>::value>::type>
   768     : decltype(homogeneous_sizeof_helper<T>(
   769           make_index_sequence<determine_tuple_size_<T>::value>())) {
   772 template <
class T0> 
struct homogeneous_sizeof<T0> : homogeneous_sizeof_one<T0> {
   775 template <
class T0, 
class... Ts>
   776 struct homogeneous_sizeof<T0, Ts...>
   777     : std::integral_constant<size_t, homogeneous_sizeof<T0>::value ==
   778                                              homogeneous_sizeof<Ts...>::value
   779                                          ? homogeneous_sizeof<T0>::value
   784 template <
typename Scalar, 
typename Base, 
size_t N> 
class Adapter : 
public Base
   788     template <std::size_t... Indexes, 
int X>
   789     Adapter(Vc::index_sequence<Indexes...>, 
const Scalar,
   790             std::integral_constant<int, X>)
   793             X < 3, 
"Failed to construct an object of type Base. Neither via "   794                    "parenthesis-init, brace-init, nor double-brace init appear to work.");
   798     template <std::size_t... Indexes>
   799     Adapter(Vc::index_sequence<Indexes...>, 
const Scalar &x_,
   800             std::integral_constant<int, 2>)
   801         : Base{{get_dispatcher<Indexes>(x_)...}}
   806     template <std::size_t... Indexes>
   807     Adapter(Vc::index_sequence<Indexes...>, 
const Scalar &x_,
   808             std::integral_constant<int, 1>)
   809         : Base{get_dispatcher<Indexes>(x_)...}
   814     template <std::size_t... Indexes>
   815     Adapter(Vc::index_sequence<Indexes...>, 
const Scalar &x_,
   816             std::integral_constant<int, 0>)
   817         : Base(get_dispatcher<Indexes>(x_)...)
   821     template <std::size_t... Indexes>
   822     Adapter(Vc::index_sequence<Indexes...> seq_, 
const Scalar &x_)
   824                   preferred_construction<Base, decltype(get_dispatcher<Indexes>(
   825                                                    std::declval<const Scalar &>()))...>())
   831     static constexpr 
size_t size() { 
return N; }
   832     static constexpr 
size_t Size = N;
   835     using base_type = Base;
   838     using scalar_type = Scalar;
   845 #if defined Vc_CLANG && Vc_CLANG < 0x30700   846     Vc_INTRINSIC Adapter(
const Adapter &x) : Base(x) {}
   848     Adapter(
const Adapter &) = 
default;
   850     Adapter(Adapter &&) = 
default;
   853     Adapter &operator=(
const Adapter &) = 
default;
   855     Adapter &operator=(Adapter &&) = 
default;
   858     template <typename U, size_t TupleSize = determine_tuple_size_<Scalar>::value,
   859               typename Seq = Vc::make_index_sequence<TupleSize>,
   860               typename = enable_if<std::is_convertible<U, Scalar>::value>>
   862         : Adapter(Seq(), static_cast<const Scalar &>(x_))
   868               class = decltype(static_cast<Scalar>(std::declval<F>()(
   872         for (
size_t i = 0; i < N; ++i) {
   879     template <
typename A0, 
typename... Args,
   880               typename = 
typename std::enable_if<
   881                   !Traits::is_index_sequence<A0>::value &&
   882                   (
sizeof...(Args) > 0 || !std::is_convertible<A0, Scalar>::value)>::type>
   883     Adapter(A0 &&arg0_, Args &&... arguments_)
   884         : Base(std::forward<A0>(arg0_), std::forward<Args>(arguments_)...)
   889     template <
typename T,
   890               typename = decltype(Base(std::declval<
const std::initializer_list<T> &>()))>
   891     Adapter(
const std::initializer_list<T> &l_)
   898     void *
operator new(
size_t size)
   900         return Vc::Common::aligned_malloc<alignof(Adapter)>(size);
   902     void *
operator new(size_t, 
void *p_) { 
return p_; }
   903     void *
operator new[](
size_t size)
   905         return Vc::Common::aligned_malloc<alignof(Adapter)>(size);
   907     void *
operator new[](size_t , 
void *p_) { 
return p_; }
   909     void operator delete(
void *, 
void *) {}
   911     void operator delete[](
void *, 
void *) {}
   918 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   919 inline void operator==(
   920     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   921     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   922 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   923 inline void operator!=(
   924     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   925     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   926 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   927 inline void operator<=(
   928     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   929     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   930 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   931 inline void operator>=(
   932     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   933     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   934 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   935 inline void operator<(
   936     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   937     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   938 template <
class... TTypes, 
class... TTypesV, 
class... UTypes, 
class... UTypesV, 
size_t N>
   939 inline void operator>(
   940     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
   941     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = 
delete;
   952 template <
typename Scalar, 
typename Base, 
size_t N>
   953 class tuple_size<
Vc::SimdizeDetail::Adapter<Scalar, Base, N>> : 
public tuple_size<Base>
   959 template <
size_t I, 
typename Scalar, 
typename Base, 
size_t N>
   960 class tuple_element<I, Vc::SimdizeDetail::Adapter<Scalar, Base, N>>
   961     : 
public tuple_element<I, Base>
   971 template <
typename S, 
typename T, 
size_t N>
   972 class allocator<Vc::SimdizeDetail::Adapter<S, T, N>>
   976     template <
typename U> 
struct rebind
   978         typedef std::allocator<U> other;
   983 namespace Vc_VERSIONED_NAMESPACE
   985 namespace SimdizeDetail
   995 template <
typename T> 
static inline T decay_workaround(
const T &x) { 
return x; }
  1001 template <
typename S, 
typename T, 
size_t N, 
size_t... Indexes>
  1002 inline void assign_impl(Adapter<S, T, N> &a, 
size_t i, 
const S &x,
  1003                         Vc::index_sequence<Indexes...>)
  1005     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(x)))...> tmp(
  1006         decay_workaround(get_dispatcher<Indexes>(x))...);
  1007     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(tmp), 0)...};
  1008     if (&unused == &unused) {}
  1011 template <
class S, 
class... Args>
  1012 S construct(std::integral_constant<int, 0>, Args &&... args)
  1014     return S(std::forward<Args>(args)...);
  1016 template <
class S, 
class... Args>
  1017 S construct(std::integral_constant<int, 1>, Args &&... args)
  1019     return S{std::forward<Args>(args)...};
  1021 template <
class S, 
class... Args>
  1022 S construct(std::integral_constant<int, 2>, Args &&... args)
  1024     return S{{std::forward<Args>(args)...}};
  1031 template <
typename S, 
typename T, 
size_t N, 
size_t... Indexes>
  1032 inline S extract_impl(
const Adapter<S, T, N> &a, 
size_t i, Vc::index_sequence<Indexes...>)
  1034     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a)[i]))...> tmp(
  1035         decay_workaround(get_dispatcher<Indexes>(a)[i])...);
  1036     return construct<S>(
  1037         preferred_construction<S, decltype(decay_workaround(
  1038                                       get_dispatcher<Indexes>(a)[i]))...>(),
  1039         decay_workaround(get_dispatcher<Indexes>(a)[i])...);
  1044 template <
typename S, 
typename T, std::size_t N, std::size_t... Indexes>
  1045 inline Adapter<S, T, N> shifted_impl(
const Adapter<S, T, N> &a, 
int shift,
  1046                                      Vc::index_sequence<Indexes...>)
  1049     auto &&unused = {(get_dispatcher<Indexes>(r) = get_dispatcher<Indexes>(a).shifted(shift), 0)...};
  1050     if (&unused == &unused) {}
  1063 template <
typename S, 
typename T, 
size_t N>
  1064 inline Adapter<S, T, N> 
shifted(
const Adapter<S, T, N> &a, 
int shift)
  1066     return shifted_impl(a, shift, Vc::make_index_sequence<determine_tuple_size<T>()>());
  1073 template <
typename S, 
typename T, std::size_t N, std::size_t... Indexes>
  1074 inline void swap_impl(Adapter<S, T, N> &a, std::size_t i, S &x,
  1075                       Vc::index_sequence<Indexes...>)
  1077     const auto &a_const = a;
  1078     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a_const)[0]))...>
  1079         tmp{decay_workaround(get_dispatcher<Indexes>(a_const)[i])...};
  1080     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(x), 0)...};
  1081     auto &&unused2 = {(get_dispatcher<Indexes>(x) = get_dispatcher<Indexes>(tmp), 0)...};
  1082     if (&unused == &unused2) {}
  1084 template <
typename S, 
typename T, std::size_t N, std::size_t... Indexes>
  1085 inline void swap_impl(Adapter<S, T, N> &a, std::size_t i, Adapter<S, T, N> &b,
  1086                       std::size_t j, Vc::index_sequence<Indexes...>)
  1088     const auto &a_const = a;
  1089     const auto &b_const = b;
  1090     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a_const)[0]))...>
  1091         tmp{decay_workaround(get_dispatcher<Indexes>(a_const)[i])...};
  1092     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(b_const)[j], 0)...};
  1093     auto &&unused2 = {(get_dispatcher<Indexes>(b)[j] = get_dispatcher<Indexes>(tmp), 0)...};
  1094     if (&unused == &unused2) {}
  1102 template <
typename S, 
typename T, std::
size_t N>
  1103 inline void swap(Adapter<S, T, N> &a, std::size_t i, S &x)
  1105     swap_impl(a, i, x, Vc::make_index_sequence<determine_tuple_size<T>()>());
  1107 template <
typename S, 
typename T, std::
size_t N>
  1108 inline void swap(Adapter<S, T, N> &a, std::size_t i, Adapter<S, T, N> &b, std::size_t j)
  1110     swap_impl(a, i, b, j, Vc::make_index_sequence<determine_tuple_size<T>()>());
  1113 template <
typename A> 
class Scalar  
  1115     using reference = 
typename std::add_lvalue_reference<A>::type;
  1116     using S = 
typename A::scalar_type;
  1117     using IndexSeq = Vc::make_index_sequence<determine_tuple_size<S>()>;
  1120     Scalar(reference aa, 
size_t ii) : a(aa), i(ii) {}
  1123     Scalar(
const Scalar &) = 
delete;
  1124     Scalar(Scalar &&) = 
delete;
  1125     Scalar &operator=(
const Scalar &) = 
delete;
  1126     Scalar &operator=(Scalar &&) = 
delete;
  1128     void operator=(
const S &x) { assign_impl(a, i, x, IndexSeq()); }
  1129     operator S()
 const { 
return extract_impl(a, i, IndexSeq()); }
  1131     template <
typename AA>
  1132     friend inline void swap(Scalar<AA> &&a, 
typename AA::scalar_type &b);
  1133     template <
typename AA>
  1134     friend inline void swap(
typename AA::scalar_type &b, Scalar<AA> &&a);
  1135     template <
typename AA> 
friend inline void swap(Scalar<AA> &&a, Scalar<AA> &&b);
  1144 template <
typename A> 
inline void swap(Scalar<A> &&a, 
typename A::scalar_type &b)
  1146     swap_impl(a.a, a.i, b, 
typename Scalar<A>::IndexSeq());
  1150 template <
typename A> 
inline void swap(
typename A::scalar_type &b, Scalar<A> &&a)
  1152     swap_impl(a.a, a.i, b, 
typename Scalar<A>::IndexSeq());
  1155 template <
typename A> 
inline void swap(Scalar<A> &&a, Scalar<A> &&b)
  1157     swap_impl(a.a, a.i, b.a, b.i, 
typename Scalar<A>::IndexSeq());
  1161 template <
class S, 
class T, 
size_t N, 
size_t... I>
  1162 inline void load_interleaved_impl(Vc::index_sequence<I...>, Adapter<S, T, N> &a,
  1165     const InterleavedMemoryWrapper<S, decltype(decay_workaround(get_dispatcher<0>(a)))>
  1166     wrapper(const_cast<S *>(mem));
  1167     Vc::tie(get_dispatcher<I>(a)...) = wrapper[0];
  1171 template <
class S, 
class T, 
size_t N, 
size_t... I>
  1172 inline void store_interleaved_impl(Vc::index_sequence<I...>, 
const Adapter<S, T, N> &a,
  1175     InterleavedMemoryWrapper<S, decltype(decay_workaround(get_dispatcher<0>(a)))> wrapper(
  1177     wrapper[0] = Vc::tie(get_dispatcher<I>(a)...);
  1180 template <
typename A> 
class Interface  
  1182     using reference = 
typename std::add_lvalue_reference<A>::type;
  1184         Vc::make_index_sequence<determine_tuple_size<typename A::scalar_type>()>;
  1187     Interface(reference aa) : a(aa) {}
  1189     Scalar<A> operator[](
size_t i)
  1193     typename A::scalar_type operator[](
size_t i)
 const  1195         return extract_impl(a, i, IndexSeq());
  1200         return shifted_impl(a, amount, IndexSeq());
  1203     void load(
const typename A::scalar_type *mem) { load_interleaved(*
this, mem); }
  1204     void store(
typename A::scalar_type *mem) { store_interleaved(*
this, mem); }
  1215 template <
typename S, 
typename T, 
size_t N>
  1216 inline void assign(SimdizeDetail::Adapter<S, T, N> &a, 
size_t i, 
const S &x)
  1218     SimdizeDetail::assign_impl(
  1219         a, i, x, Vc::make_index_sequence<SimdizeDetail::determine_tuple_size<T>()>());
  1224 template <typename V, typename = enable_if<Traits::is_simd_vector<V>::value>>
  1225 Vc_INTRINSIC 
void assign(V &v, 
size_t i, 
typename V::EntryType x)
  1235 template <
typename S, 
typename T, 
size_t N>
  1236 inline S 
extract(
const SimdizeDetail::Adapter<S, T, N> &a, 
size_t i)
  1238     return SimdizeDetail::extract_impl(
  1239         a, i, Vc::make_index_sequence<SimdizeDetail::determine_tuple_size<S>()>());
  1244 template <typename V, typename = enable_if<Traits::is_simd_vector<V>::value>>
  1245 Vc_INTRINSIC 
typename V::EntryType 
extract(
const V &v, 
size_t i)
  1251 template <
class S, 
class T, 
size_t N>
  1252 inline void load_interleaved(SimdizeDetail::Adapter<S, T, N> &a, 
const S *mem)
  1254     if (SimdizeDetail::homogeneous_sizeof<S>::value == 0) {
  1255         Common::unrolled_loop<std::size_t, 0, N>(
  1256             [&](std::size_t i) { 
assign(a, i, mem[i]); });
  1258         constexpr 
size_t TupleSize = SimdizeDetail::determine_tuple_size_<S>::value;
  1259         SimdizeDetail::load_interleaved_impl(Vc::make_index_sequence<TupleSize>(), a,
  1265     class = enable_if<Traits::is_simd_vector<V>::value && std::is_arithmetic<T>::value>>
  1266 Vc_INTRINSIC 
void load_interleaved(V &a, 
const T *mem)
  1272 template <
class S, 
class T, 
size_t N>
  1273 inline void store_interleaved(
const SimdizeDetail::Adapter<S, T, N> &a, S *mem)
  1275     if (SimdizeDetail::homogeneous_sizeof<S>::value == 0) {
  1276         Common::unrolled_loop<std::size_t, 0, N>(
  1277             [&](std::size_t i) { mem[i] = 
extract(a, i); });
  1279         constexpr 
size_t TupleSize = SimdizeDetail::determine_tuple_size_<S>::value;
  1280         SimdizeDetail::store_interleaved_impl(Vc::make_index_sequence<TupleSize>(), a,
  1286     class = enable_if<Traits::is_simd_vector<V>::value && std::is_arithmetic<T>::value>>
  1287 Vc_INTRINSIC 
void store_interleaved(
const V &a, T *mem)
  1293 template <
typename S, 
typename T, 
size_t N>
  1294 SimdizeDetail::Interface<SimdizeDetail::Adapter<S, T, N>> decorate(
  1295     SimdizeDetail::Adapter<S, T, N> &a)
  1299 template <
typename S, 
typename T, 
size_t N>
  1300 const SimdizeDetail::Interface<const SimdizeDetail::Adapter<S, T, N>> decorate(
  1301     const SimdizeDetail::Adapter<S, T, N> &a)
  1305 template <
class V, 
class = 
typename std::enable_if<
  1309     return std::forward<V>(v);
  1312 namespace SimdizeDetail
  1314 namespace IteratorDetails  
  1316 enum class Mutable { Yes, No };
  1318 template <
typename It, 
typename V, 
size_t I, 
size_t End>
  1319 Vc_INTRINSIC V fromIteratorImpl(enable_if<(I == End), It>)
  1323 template <
typename It, 
typename V, 
size_t I, 
size_t End>
  1324 Vc_INTRINSIC V fromIteratorImpl(enable_if<(I < End), It> it)
  1326     V r = fromIteratorImpl<It, V, I + 1, End>(it);
  1327     Traits::decay<decltype(get_dispatcher<I>(r))> tmp;
  1328     for (
size_t j = 0; j < V::size(); ++j, ++it) {
  1329         tmp[j] = get_dispatcher<I>(*it);
  1331     get_dispatcher<I>(r) = tmp;
  1334 template <
typename It, 
typename V>
  1337     return fromIteratorImpl<It, V, 0, determine_tuple_size<V>()>(it);
  1339 template <
typename It, 
typename V>
  1343     for (
size_t j = 0; j < V::size(); ++j, ++it) {
  1352 template <
typename T, 
typename value_vector, Mutable> 
class Pointer;
  1362 template <
typename T, 
typename value_vector> 
class Pointer<T, value_vector, Mutable::Yes>
  1364     static constexpr 
auto Size = value_vector::size();
  1368     value_vector *operator->() { 
return &data; }
  1375     Pointer(
const Pointer &) = 
delete;
  1376     Pointer &operator=(
const Pointer &) = 
delete;
  1377     Pointer &operator=(Pointer &&) = 
delete;
  1380     Pointer(Pointer &&) = 
default;
  1390         for (
size_t i = 0; i < Size; ++i, ++begin_iterator) {
  1391             *begin_iterator = 
extract(data, i);
  1396     Pointer(
const T &it) : data(fromIterator<T, value_vector>(it)), begin_iterator(it) {}
  1409 template <
typename T, 
typename value_vector> 
class Pointer<T, value_vector, Mutable::No>
  1411     static constexpr 
auto Size = value_vector::size();
  1414     const value_vector *operator->()
 const { 
return &data; }
  1417     Pointer(
const Pointer &) = 
delete;
  1418     Pointer &operator=(
const Pointer &) = 
delete;
  1419     Pointer &operator=(Pointer &&) = 
delete;
  1421     Pointer(Pointer &&) = 
default;  
  1423     Pointer(
const T &it) : data(fromIterator<T, value_vector>(it)) {}
  1441 template <
typename T, 
typename value_vector, Mutable M> 
class Reference;
  1444 template <
typename T, 
typename value_vector>
  1445 class Reference<T, value_vector, Mutable::Yes> : 
public value_vector
  1447     static constexpr 
auto Size = value_vector::size();
  1449     using reference = 
typename std::add_lvalue_reference<T>::type;
  1450     reference scalar_it;
  1455     Reference(reference first_it)
  1456         : value_vector(fromIterator<T, value_vector>(first_it)), scalar_it(first_it)
  1461     Reference(
const Reference &) = 
delete;
  1462     Reference(Reference &&) = 
default;
  1463     Reference &operator=(
const Reference &) = 
delete;
  1464     Reference &operator=(Reference &&) = 
delete;
  1471     void operator=(
const value_vector &x)
  1473         static_cast<value_vector &
>(*this) = x;
  1474         auto it = scalar_it;
  1475         for (
size_t i = 0; i < Size; ++i, ++it) {
  1480 #define Vc_OP(op_)                                                                       \  1481     template <typename T0, typename V0, typename T1, typename V1>                        \  1482     decltype(std::declval<const V0 &>() op_ std::declval<const V1 &>()) operator op_(    \  1483         const Reference<T0, V0, Mutable::Yes> &x,                                        \  1484         const Reference<T1, V1, Mutable::Yes> &y)                                        \  1486         return static_cast<const V0 &>(x) op_ static_cast<const V1 &>(y);                \  1488 Vc_ALL_COMPARES(Vc_OP);
  1489 Vc_ALL_ARITHMETICS(Vc_OP);
  1490 Vc_ALL_BINARY(Vc_OP);
  1491 Vc_ALL_LOGICAL(Vc_OP);
  1492 Vc_ALL_SHIFTS(Vc_OP);
  1496 template <
typename T, 
typename value_vector>
  1497 class Reference<T, value_vector, Mutable::No> : 
public value_vector
  1499     static constexpr 
auto Size = value_vector::size();
  1502     Reference(
const T &it) : value_vector(fromIterator<T, value_vector>(it)) {}
  1504     Reference(
const Reference &) = 
delete;
  1505     Reference(Reference &&) = 
default;
  1506     Reference &operator=(
const Reference &) = 
delete;
  1507     Reference &operator=(Reference &&) = 
delete;
  1510     void operator=(
const value_vector &x) = 
delete;
  1513 template <
typename T, 
size_t N,
  1514           IteratorDetails::Mutable M =
  1515               (Traits::is_output_iterator<T>::value ? Mutable::Yes : Mutable::No),
  1516           typename V = simdize<
typename std::iterator_traits<T>::value_type, N>,
  1517           size_t Size = V::Size,
  1518           typename = 
typename std::iterator_traits<T>::iterator_category>
  1521 template <
typename T, 
size_t N, IteratorDetails::Mutable M, 
typename V, 
size_t Size_>
  1522 class Iterator<T, N, M, V, Size_, std::forward_iterator_tag>
  1523     : 
public std::iterator<typename std::iterator_traits<T>::iterator_category, V,
  1524                            typename std::iterator_traits<T>::difference_type,
  1525                            IteratorDetails::Pointer<T, V, M>,
  1526                            IteratorDetails::Reference<T, V, M>>
  1529     using pointer = IteratorDetails::Pointer<T, V, M>;
  1530     using reference = IteratorDetails::Reference<T, V, M>;
  1531     using const_pointer = IteratorDetails::Pointer<T, V, IteratorDetails::Mutable::No>;
  1532     using const_reference =
  1533         IteratorDetails::Reference<T, V, IteratorDetails::Mutable::No>;
  1536     static constexpr std::size_t size() { 
return Size_; }
  1537     static constexpr std::size_t Size = Size_;
  1539     Iterator() = 
default;
  1547     Iterator(
const T &x) : scalar_it(x) {}
  1551     Iterator(T &&x) : scalar_it(std::move(x)) {}
  1555     Iterator &operator=(
const T &x)
  1563     Iterator &operator=(T &&x)
  1565         scalar_it = std::move(x);
  1570     Iterator(
const Iterator &) = 
default;
  1572     Iterator(Iterator &&) = 
default;
  1574     Iterator &operator=(
const Iterator &) = 
default;
  1576     Iterator &operator=(Iterator &&) = 
default;
  1579     Iterator &operator++()
  1581         std::advance(scalar_it, Size);
  1585     Iterator operator++(
int)
  1587         Iterator copy(*
this);
  1600     bool operator==(
const Iterator &rhs)
 const  1603         if (scalar_it == rhs.scalar_it) {
  1607             for (
size_t i = 1; i < Size; ++i) {
  1608                 Vc_ASSERT((++it != rhs.scalar_it));
  1613         return scalar_it == rhs.scalar_it;
  1624     bool operator!=(
const Iterator &rhs)
 const  1626         return !operator==(rhs);
  1629     pointer operator->() { 
return scalar_it; }
  1637     reference 
operator*() { 
return scalar_it; }
  1639     const_pointer operator->()
 const { 
return scalar_it; }
  1648     const_reference 
operator*()
 const { 
return scalar_it; }
  1663     operator const T &() 
const { 
return scalar_it; }
  1673 template <
typename T, 
size_t N, IteratorDetails::Mutable M, 
typename V, 
size_t Size>
  1674 class Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>
  1675     : 
public Iterator<T, N, M, V, Size, std::forward_iterator_tag>
  1677     using Base = Iterator<T, N, M, V, Size, std::forward_iterator_tag>;
  1680     using Base::scalar_it;
  1683     using pointer = 
typename Base::pointer;
  1684     using reference = 
typename Base::reference;
  1685     using const_pointer = 
typename Base::const_pointer;
  1686     using const_reference = 
typename Base::const_reference;
  1688     using Iterator<T, N, M, V, Size,
  1689                    std::forward_iterator_tag>::Iterator;  
  1695         std::advance(scalar_it, -Size);
  1701         Iterator copy(*
this);
  1711 template <
typename T, 
size_t N, IteratorDetails::Mutable M, 
typename V, 
size_t Size>
  1712 class Iterator<T, N, M, V, Size, std::random_access_iterator_tag>
  1713     : 
public Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>
  1718     using Base::scalar_it;
  1721     using pointer = 
typename Base::pointer;
  1722     using reference = 
typename Base::reference;
  1723     using const_pointer = 
typename Base::const_pointer;
  1724     using const_reference = 
typename Base::const_reference;
  1725     using difference_type = 
typename std::iterator_traits<T>::difference_type;
  1730     Iterator &operator+=(difference_type n)
  1732         scalar_it += n * difference_type(Size);
  1735     Iterator 
operator+(difference_type n)
 const { 
return Iterator(*
this) += n; }
  1737     Iterator &operator-=(difference_type n)
  1739         scalar_it -= n * difference_type(Size);
  1742     Iterator 
operator-(difference_type n)
 const { 
return Iterator(*
this) -= n; }
  1744     difference_type 
operator-(
const Iterator &rhs)
 const  1746         constexpr difference_type n = Size;
  1747         Vc_ASSERT((scalar_it - rhs.scalar_it) % n ==
  1753         return (scalar_it - rhs.scalar_it) / n;
  1762         return rhs.scalar_it - scalar_it >= difference_type(Size);
  1765     bool operator>(
const Iterator &rhs)
 const  1767         return scalar_it - rhs.scalar_it >= difference_type(Size);
  1770     bool operator<=(
const Iterator &rhs)
 const  1772         return rhs.scalar_it - scalar_it >= difference_type(Size) - 1;
  1775     bool operator>=(
const Iterator &rhs)
 const  1777         return scalar_it - rhs.scalar_it >= difference_type(Size) - 1;
  1780     reference operator[](difference_type i) { 
return *(*
this + i); }
  1781     const_reference operator[](difference_type i)
 const { 
return *(*
this + i); }
  1784 template <
typename T, 
size_t N, IteratorDetails::Mutable M, 
typename V, 
size_t Size>
  1786     typename Iterator<T, N, M, V, Size, std::random_access_iterator_tag>::difference_type
  1803 template <
typename T, 
size_t N, 
typename MT>
  1804 struct ReplaceTypes<T, N, MT, Category::ForwardIterator>
  1806     using type = IteratorDetails::Iterator<T, N>;
  1808 template <
typename T, 
size_t N, 
typename MT>
  1809 struct ReplaceTypes<T, N, MT, Category::BidirectionalIterator>
  1811     using type = IteratorDetails::Iterator<T, N>;
  1813 template <
typename T, 
size_t N, 
typename MT>
  1814 struct ReplaceTypes<T, N, MT, Category::RandomAccessIterator>
  1816     using type = IteratorDetails::Iterator<T, N>;
  1822 template <Vc::Operator Op, 
typename S, 
typename T, std::size_t N, 
typename M, 
typename U,
  1824 Vc_INTRINSIC Vc::enable_if<(Offset >= determine_tuple_size_<S>::value && M::Size == N), 
void>
  1825     conditional_assign(Adapter<S, T, N> &, 
const M &, 
const U &)
  1828 template <Vc::Operator Op, 
typename S, 
typename T, std::size_t N, 
typename M, 
typename U,
  1829           std::size_t Offset = 0>
  1830 Vc_INTRINSIC Vc::enable_if<(Offset < determine_tuple_size_<S>::value && M::Size == N), 
void>
  1831     conditional_assign(Adapter<S, T, N> &lhs, 
const M &mask, 
const U &rhs)
  1833     using V = 
typename std::decay<decltype(get_dispatcher<Offset>(lhs))>::type;
  1834     using M2 = 
typename V::mask_type;
  1835     conditional_assign<Op>(get_dispatcher<Offset>(lhs), simd_cast<M2>(mask), get_dispatcher<Offset>(rhs));
  1836     conditional_assign<Op, S, T, N, M, U, Offset + 1>(lhs, mask, rhs);
  1838 template <Vc::Operator Op, 
typename S, 
typename T, std::size_t N, 
typename M,
  1840 Vc_INTRINSIC Vc::enable_if<(Offset >= determine_tuple_size_<S>::value && M::Size == N), 
void>
  1841     conditional_assign(Adapter<S, T, N> &, 
const M &)
  1844 template <Vc::Operator Op, 
typename S, 
typename T, std::size_t N, 
typename M,
  1845           std::size_t Offset = 0>
  1846 Vc_INTRINSIC Vc::enable_if<(Offset < determine_tuple_size_<S>::value && M::Size == N), 
void>
  1847     conditional_assign(Adapter<S, T, N> &lhs, 
const M &mask)
  1849     using V = 
typename std::decay<decltype(get_dispatcher<Offset>(lhs))>::type;
  1850     using M2 = 
typename V::mask_type;
  1851     conditional_assign<Op>(get_dispatcher<Offset>(lhs), simd_cast<M2>(mask));
  1852     conditional_assign<Op, S, T, N, M, Offset + 1>(lhs, mask);
  1877 template <
typename T, 
size_t N = 0, 
typename MT = 
void>
  1878 using simdize = SimdizeDetail::simdize<T, N, MT>;
  1899 #define Vc_SIMDIZE_INTERFACE(MEMBERS_)                                                   \  1900     template <std::size_t N_>                                                            \  1901     inline auto vc_get_()->decltype(std::get<N_>(std::tie MEMBERS_))                     \  1903         return std::get<N_>(std::tie MEMBERS_);                                          \  1905     template <std::size_t N_>                                                            \  1906     inline auto vc_get_() const->decltype(std::get<N_>(std::tie MEMBERS_))               \  1908         return std::get<N_>(std::tie MEMBERS_);                                          \  1910     enum : std::size_t {                                                                 \  1911         tuple_size = std::tuple_size<decltype(std::make_tuple MEMBERS_)>::value          \  1918 using Vc::SimdizeDetail::swap;
  1921 #endif  // VC_COMMON_SIMDIZE_H_ void free(T *p)
Frees memory that was allocated with Vc::malloc. 
bool operator<(const Iterator &rhs) const 
Returns whether all entries accessed via iterator dereferencing come before the iterator rhs...
result_vector_type< L, R > operator-(L &&lhs, R &&rhs)
Applies - component-wise and concurrently. 
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently. 
SimdizeDetail::simdize< T, N, MT > simdize
Iterator operator--(int)
Postfix overload of the above. 
void assign(SimdizeDetail::Adapter< S, T, N > &a, size_t i, const S &x)
Assigns one scalar object x to a SIMD slot at offset i in the simdized object a. 
An allocator that uses global new and supports over-aligned types, as per [C++11 20.6.9]. 
Identifies any SIMD vector type (independent of implementation or whether it's SimdArray<T, N>). 
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently. 
Iterator & operator--()
Advances the iterator by one vector width, or respectively N scalar steps. 
Adapter< S, T, N > shifted(const Adapter< S, T, N > &a, int shift)
Returns a new vectorized object where each entry is shifted by shift. 
This is the iterator type created when applying simdize to a random access iterator type...
Vector Classes Namespace. 
This is the iterator type created when applying simdize to a bidirectional iterator type...
S extract(const SimdizeDetail::Adapter< S, T, N > &a, size_t i)
Extracts and returns one scalar object from a SIMD slot at offset i in the simdized object a...
constexpr UnalignedTag Unaligned
Use this object for a flags parameter to request unaligned loads and stores.