Warning, file /include/Vc/common/simdize.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0018 
0019 
0020 
0021 
0022 
0023 
0024 
0025 
0026 
0027 
0028 #ifndef VC_COMMON_SIMDIZE_H_
0029 #define VC_COMMON_SIMDIZE_H_
0030 
0031 #include <tuple>
0032 #include <array>
0033 
0034 #include "../Allocator"
0035 #include "interleavedmemory.h"
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
0044 
0045 
0046 
0047 
0048 
0049 
0050 
0051 
0052 
0053 
0054 
0055 
0056 
0057 
0058 
0059 
0060 
0061 
0062 
0063 
0064 
0065 
0066 
0067 
0068 
0069 
0070 
0071 
0072 
0073 
0074 
0075 
0076 
0077 
0078 
0079 
0080 
0081 
0082 
0083 
0084 
0085 
0086 
0087 
0088 
0089 
0090 
0091 
0092 
0093 
0094 
0095 
0096 
0097 
0098 
0099 
0100 
0101 
0102 
0103 
0104 
0105 
0106 
0107 
0108 
0109 
0110 
0111 
0112 
0113 
0114 
0115 
0116 
0117 
0118 
0119 
0120 
0121 
0122 namespace Vc_VERSIONED_NAMESPACE
0123 {
0124 
0125 
0126 
0127 
0128 
0129 
0130 namespace SimdizeDetail  
0131 {
0132 
0133 
0134 
0135 
0136 using std::is_same;
0137 using std::is_base_of;
0138 using std::false_type;
0139 using std::true_type;
0140 using std::iterator_traits;
0141 using std::conditional;
0142 using std::size_t;
0143 
0144 
0145 
0146 
0147 
0148 template <typename... Ts> struct Typelist;
0149 
0150 
0151 
0152 
0153 enum class Category {
0154     
0155     NoTransformation,
0156     
0157     ArithmeticVectorizable,
0158     
0159     InputIterator,
0160     
0161     OutputIterator,
0162     
0163     ForwardIterator,
0164     
0165     BidirectionalIterator,
0166     
0167     RandomAccessIterator,
0168     
0169     ClassTemplate
0170 };
0171 
0172 
0173 
0174 
0175 
0176 template <typename T, typename ItCat = typename T::iterator_category>
0177 constexpr Category iteratorCategories(int, ItCat * = nullptr)
0178 {
0179     return is_base_of<std::random_access_iterator_tag, ItCat>::value
0180                ? Category::RandomAccessIterator
0181                : is_base_of<std::bidirectional_iterator_tag, ItCat>::value
0182                      ? Category::BidirectionalIterator
0183                      : is_base_of<std::forward_iterator_tag, ItCat>::value
0184                            ? Category::ForwardIterator
0185                            : is_base_of<std::output_iterator_tag, ItCat>::value
0186                                  ? Category::OutputIterator
0187                                  : is_base_of<std::input_iterator_tag, ItCat>::value
0188                                        ? Category::InputIterator
0189                                        : Category::NoTransformation;
0190 }
0191 
0192 
0193 
0194 template <typename T>
0195 constexpr enable_if<std::is_pointer<T>::value, Category> iteratorCategories(float)
0196 {
0197     return Category::RandomAccessIterator;
0198 }
0199 
0200 
0201 
0202 template <typename T> constexpr Category iteratorCategories(...)
0203 {
0204     return Category::NoTransformation;
0205 }
0206 
0207 
0208 
0209 
0210 template <typename T> struct is_class_template : public false_type
0211 {
0212 };
0213 template <template <typename...> class C, typename... Ts>
0214 struct is_class_template<C<Ts...>> : public true_type
0215 {
0216 };
0217 
0218 
0219 
0220 
0221 template <typename T> constexpr Category typeCategory()
0222 {
0223     return (is_same<T, bool>::value || is_same<T, short>::value ||
0224             is_same<T, unsigned short>::value || is_same<T, int>::value ||
0225             is_same<T, unsigned int>::value || is_same<T, float>::value ||
0226             is_same<T, double>::value)
0227                ? Category::ArithmeticVectorizable
0228                : iteratorCategories<T>(int()) != Category::NoTransformation
0229                      ? iteratorCategories<T>(int())
0230                      : is_class_template<T>::value ? Category::ClassTemplate
0231                                                    : Category::NoTransformation;
0232 }
0233 
0234 
0235 
0236 
0237 
0238 
0239 template <typename T, size_t TupleSize = std::tuple_size<T>::value>
0240 constexpr size_t determine_tuple_size()
0241 {
0242     return TupleSize;
0243 }
0244 template <typename T, size_t TupleSize = T::tuple_size>
0245 constexpr size_t determine_tuple_size(size_t = T::tuple_size)
0246 {
0247     return TupleSize;
0248 }
0249 
0250 
0251 
0252 template <typename T> struct determine_tuple_size_
0253 : public std::integral_constant<size_t, determine_tuple_size<T>()>
0254 {};
0255 
0256 namespace
0257 {
0258 template <typename T> struct The_simdization_for_the_requested_type_is_not_implemented;
0259 }  
0260 
0261 
0262 
0263 
0264 
0265 
0266 
0267 
0268 
0269 
0270 
0271 
0272 
0273 template <typename T, size_t N, typename MT, Category = typeCategory<T>()>
0274 struct ReplaceTypes : public The_simdization_for_the_requested_type_is_not_implemented<T>
0275 {
0276 };
0277 
0278 
0279 
0280 
0281 
0282 template <typename T, size_t N, typename MT> struct ReplaceTypes<T, N, MT, Category::NoTransformation>
0283 {
0284     typedef T type;
0285 };
0286 
0287 
0288 
0289 
0290 
0291 template <typename T, size_t N = 0, typename MT = void>
0292 using simdize = typename SimdizeDetail::ReplaceTypes<T, N, MT>::type;
0293 
0294 
0295 template <class T, size_t N,
0296           class Best = typename Common::select_best_vector_type<T, N>::type>
0297 using deduce_vector_t =
0298     typename std::conditional<Best::size() == N, Best, SimdArray<T, N>>::type;
0299 
0300 
0301 
0302 
0303 
0304 template <typename T, size_t N, typename MT>
0305 struct ReplaceTypes<T, N, MT, Category::ArithmeticVectorizable>
0306     : public conditional<N == 0, Vector<T>, deduce_vector_t<T, N>> {
0307 };
0308 
0309 
0310 
0311 
0312 
0313 template <size_t N, typename MT>
0314 struct ReplaceTypes<bool, N, MT, Category::ArithmeticVectorizable>
0315     : public std::enable_if<true, typename ReplaceTypes<MT, N, MT>::type::mask_type> {
0316 };
0317 
0318 
0319 
0320 template <size_t N>
0321 struct ReplaceTypes<bool, N, void, Category::ArithmeticVectorizable>
0322     : public ReplaceTypes<bool, N, float, Category::ArithmeticVectorizable>
0323 {
0324 };
0325 
0326 
0327 
0328 
0329 
0330 
0331 
0332 template <size_t N, typename MT, typename Replaced, typename... Remaining>
0333 struct SubstituteOneByOne;
0334 
0335 
0336 
0337 
0338 
0339 template <size_t N, typename MT, typename... Replaced, typename T,
0340           typename... Remaining>
0341 struct SubstituteOneByOne<N, MT, Typelist<Replaced...>, T, Remaining...>
0342 {
0343 private:
0344     
0345 
0346 
0347 
0348     template <typename U, size_t M = U::Size>
0349     static std::integral_constant<size_t, M> size_or_0(int);
0350     template <typename U> static std::integral_constant<size_t, 0> size_or_0(...);
0351 
0352     
0353     using V = simdize<T, N, MT>;
0354 
0355     
0356 
0357 
0358 
0359     static constexpr auto NewN = N != 0 ? N : decltype(size_or_0<V>(int()))::value;
0360 
0361     
0362 
0363 
0364 
0365 
0366     typedef conditional_t<(N != NewN && is_same<MT, void>::value),
0367                           conditional_t<is_same<T, bool>::value, float, T>, MT> NewMT;
0368 
0369 public:
0370     
0371 
0372 
0373     using type = typename SubstituteOneByOne<NewN, NewMT, Typelist<Replaced..., V>,
0374                                              Remaining...>::type;
0375 };
0376 
0377 
0378 
0379 template <size_t Size, typename... Replaced> struct SubstitutedBase;
0380 
0381 template <typename Replaced> struct SubstitutedBase<1, Replaced> {
0382     template <typename ValueT, template <typename, ValueT...> class C, ValueT... Values>
0383     using SubstitutedWithValues = C<Replaced, Values...>;
0384 };
0385 
0386 template <typename R0, typename R1> struct SubstitutedBase<2, R0, R1>
0387 {
0388     template <typename ValueT, template <typename, typename, ValueT...> class C,
0389               ValueT... Values>
0390     using SubstitutedWithValues = C<R0, R1, Values...>;
0391 };
0392 
0393 template <typename R0, typename R1, typename R2> struct SubstitutedBase<3, R0, R1, R2>
0394 {
0395     template <typename ValueT, template <typename, typename, typename, ValueT...> class C,
0396               ValueT... Values>
0397     using SubstitutedWithValues = C<R0, R1, R2, Values...>;
0398 };
0399 #if defined Vc_ICC || defined Vc_MSVC
0400 #define Vc_VALUE_PACK_EXPANSION_IS_BROKEN 1
0401 #endif
0402 
0403 template <typename... Replaced> struct SubstitutedBase<4, Replaced...> {
0404 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0405     template <typename ValueT,
0406               template <typename, typename, typename, typename, ValueT...> class C,
0407               ValueT... Values>
0408     using SubstitutedWithValues = C<Replaced..., Values...>;
0409 #endif 
0410 };
0411 
0412 template <typename... Replaced> struct SubstitutedBase<5, Replaced...> {
0413 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0414     template <typename ValueT, template <typename, typename, typename, typename, typename,
0415                                          ValueT...> class C,
0416               ValueT... Values>
0417     using SubstitutedWithValues = C<Replaced..., Values...>;
0418 #endif 
0419 };
0420 
0421 template <typename... Replaced> struct SubstitutedBase<6, Replaced...> {
0422 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0423     template <typename ValueT, template <typename, typename, typename, typename, typename,
0424                                          typename, ValueT...> class C,
0425               ValueT... Values>
0426     using SubstitutedWithValues = C<Replaced..., Values...>;
0427 #endif 
0428 };
0429 
0430 template <typename... Replaced> struct SubstitutedBase<7, Replaced...> {
0431 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0432     template <typename ValueT, template <typename, typename, typename, typename, typename,
0433                                          typename, typename, ValueT...> class C,
0434               ValueT... Values>
0435     using SubstitutedWithValues = C<Replaced..., Values...>;
0436 #endif 
0437 };
0438 
0439 template <typename... Replaced> struct SubstitutedBase<8, Replaced...> {
0440 #ifndef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0441     template <typename ValueT, template <typename, typename, typename, typename, typename,
0442                                          typename, typename, typename, ValueT...> class C,
0443               ValueT... Values>
0444     using SubstitutedWithValues = C<Replaced..., Values...>;
0445 #endif 
0446 };
0447 
0448 
0449 
0450 
0451 
0452 
0453 template <size_t N_, typename MT, typename Replaced0, typename... Replaced>
0454 struct SubstituteOneByOne<N_, MT, Typelist<Replaced0, Replaced...>>
0455 {
0456     
0457 
0458 
0459     struct type
0460         : public SubstitutedBase<sizeof...(Replaced) + 1, Replaced0, Replaced...> {
0461         static constexpr auto N = N_;
0462         
0463 
0464 
0465 
0466         template <template <typename...> class C>
0467         using Substituted = C<Replaced0, Replaced...>;
0468     };
0469 };
0470 
0471 
0472 
0473 
0474 
0475 
0476 
0477 
0478 
0479 
0480 
0481 
0482 
0483 
0484 
0485 
0486 
0487 template <typename Scalar, typename Base, size_t N> class Adapter;
0488 
0489 
0490 
0491 
0492 
0493 template <template <typename...> class C, typename... Ts, size_t N, typename MT>
0494 struct ReplaceTypes<C<Ts...>, N, MT, Category::ClassTemplate>
0495 {
0496     
0497     using SubstitutionResult =
0498         typename SubstituteOneByOne<N, MT, Typelist<>, Ts...>::type;
0499     
0500 
0501 
0502 
0503 
0504     using Vectorized = typename SubstitutionResult::template Substituted<C>;
0505     
0506 
0507 
0508 
0509 
0510     using type = conditional_t<is_same<C<Ts...>, Vectorized>::value, C<Ts...>,
0511                                Adapter<C<Ts...>, Vectorized, SubstitutionResult::N>>;
0512 };
0513 
0514 
0515 
0516 
0517 
0518 
0519 #ifdef Vc_VALUE_PACK_EXPANSION_IS_BROKEN
0520 
0521 #define Vc_DEFINE_NONTYPE_REPLACETYPES_(ValueType_)                                      \
0522     template <template <typename, ValueType_...> class C, typename T, ValueType_ Value0, \
0523               ValueType_... Values>                                                      \
0524     struct is_class_template<C<T, Value0, Values...>> : public true_type {               \
0525     };                                                                                   \
0526     template <template <typename, typename, ValueType_...> class C, typename T0,         \
0527               typename T1, ValueType_ Value0, ValueType_... Values>                      \
0528     struct is_class_template<C<T0, T1, Value0, Values...>> : public true_type {          \
0529     };                                                                                   \
0530     template <template <typename, typename, typename, ValueType_...> class C,            \
0531               typename T0, typename T1, typename T2, ValueType_ Value0,                  \
0532               ValueType_... Values>                                                      \
0533     struct is_class_template<C<T0, T1, T2, Value0, Values...>> : public true_type {      \
0534     };                                                                                   \
0535     template <template <typename, typename, typename, typename, ValueType_...> class C,  \
0536               typename T0, typename T1, typename T2, typename T3, ValueType_ Value0,     \
0537               ValueType_... Values>                                                      \
0538     struct is_class_template<C<T0, T1, T2, T3, Value0, Values...>> : public true_type {  \
0539     };                                                                                   \
0540     template <template <typename, typename, typename, typename, typename, ValueType_...> \
0541               class C,                                                                   \
0542               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0543               ValueType_ Value0, ValueType_... Values>                                   \
0544     struct is_class_template<C<T0, T1, T2, T3, T4, Value0, Values...>>                   \
0545         : public true_type {                                                             \
0546     };                                                                                   \
0547     template <template <typename, typename, typename, typename, typename, typename,      \
0548                         ValueType_...> class C,                                          \
0549               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0550               typename T5, ValueType_ Value0, ValueType_... Values>                      \
0551     struct is_class_template<C<T0, T1, T2, T3, T4, T5, Value0, Values...>>               \
0552         : public true_type {                                                             \
0553     };                                                                                   \
0554     template <template <typename, typename, typename, typename, typename, typename,      \
0555                         typename, ValueType_...> class C,                                \
0556               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0557               typename T5, typename T6, ValueType_ Value0, ValueType_... Values>         \
0558     struct is_class_template<C<T0, T1, T2, T3, T4, T5, T6, Value0, Values...>>           \
0559         : public true_type {                                                             \
0560     };                                                                                   \
0561     template <template <typename, ValueType_> class C, typename T0, ValueType_ Value0,   \
0562               size_t N, typename MT>                                                     \
0563     struct ReplaceTypes<C<T0, Value0>, N, MT, Category::ClassTemplate> {                 \
0564         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0>::type tmp;            \
0565         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \
0566             Substituted;                                                                 \
0567         static constexpr auto NN = tmp::N;                                               \
0568         typedef conditional_t<is_same<C<T0, Value0>, Substituted>::value, C<T0, Value0>, \
0569                               Adapter<C<T0, Value0>, Substituted, NN>> type;             \
0570     };                                                                                   \
0571     template <template <typename, typename, ValueType_> class C, typename T0,            \
0572               typename T1, ValueType_ Value0, size_t N, typename MT>                     \
0573     struct ReplaceTypes<C<T0, T1, Value0>, N, MT, Category::ClassTemplate> {             \
0574         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1>::type tmp;        \
0575         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \
0576             Substituted;                                                                 \
0577         static constexpr auto NN = tmp::N;                                               \
0578         typedef conditional_t<is_same<C<T0, T1, Value0>, Substituted>::value,            \
0579                               C<T0, T1, Value0>,                                         \
0580                               Adapter<C<T0, T1, Value0>, Substituted, NN>> type;         \
0581     };                                                                                   \
0582     template <template <typename, typename, typename, ValueType_> class C, typename T0,  \
0583               typename T1, typename T2, ValueType_ Value0, size_t N, typename MT>        \
0584     struct ReplaceTypes<C<T0, T1, T2, Value0>, N, MT, Category::ClassTemplate> {         \
0585         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1, T2>::type tmp;    \
0586         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0>      \
0587             Substituted;                                                                 \
0588         static constexpr auto NN = tmp::N;                                               \
0589         typedef conditional_t<is_same<C<T0, T1, T2, Value0>, Substituted>::value,        \
0590                               C<T0, T1, T2, Value0>,                                     \
0591                               Adapter<C<T0, T1, T2, Value0>, Substituted, NN>> type;     \
0592     }
0593 #else
0594 #define Vc_DEFINE_NONTYPE_REPLACETYPES_(ValueType_)                                      \
0595     template <template <typename, ValueType_...> class C, typename T, ValueType_ Value0, \
0596               ValueType_... Values>                                                      \
0597     struct is_class_template<C<T, Value0, Values...>> : public true_type {               \
0598     };                                                                                   \
0599     template <template <typename, typename, ValueType_...> class C, typename T0,         \
0600               typename T1, ValueType_ Value0, ValueType_... Values>                      \
0601     struct is_class_template<C<T0, T1, Value0, Values...>> : public true_type {          \
0602     };                                                                                   \
0603     template <template <typename, typename, typename, ValueType_...> class C,            \
0604               typename T0, typename T1, typename T2, ValueType_ Value0,                  \
0605               ValueType_... Values>                                                      \
0606     struct is_class_template<C<T0, T1, T2, Value0, Values...>> : public true_type {      \
0607     };                                                                                   \
0608     template <template <typename, typename, typename, typename, ValueType_...> class C,  \
0609               typename T0, typename T1, typename T2, typename T3, ValueType_ Value0,     \
0610               ValueType_... Values>                                                      \
0611     struct is_class_template<C<T0, T1, T2, T3, Value0, Values...>> : public true_type {  \
0612     };                                                                                   \
0613     template <template <typename, typename, typename, typename, typename, ValueType_...> \
0614               class C,                                                                   \
0615               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0616               ValueType_ Value0, ValueType_... Values>                                   \
0617     struct is_class_template<C<T0, T1, T2, T3, T4, Value0, Values...>>                   \
0618         : public true_type {                                                             \
0619     };                                                                                   \
0620     template <template <typename, typename, typename, typename, typename, typename,      \
0621                         ValueType_...> class C,                                          \
0622               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0623               typename T5, ValueType_ Value0, ValueType_... Values>                      \
0624     struct is_class_template<C<T0, T1, T2, T3, T4, T5, Value0, Values...>>               \
0625         : public true_type {                                                             \
0626     };                                                                                   \
0627     template <template <typename, typename, typename, typename, typename, typename,      \
0628                         typename, ValueType_...> class C,                                \
0629               typename T0, typename T1, typename T2, typename T3, typename T4,           \
0630               typename T5, typename T6, ValueType_ Value0, ValueType_... Values>         \
0631     struct is_class_template<C<T0, T1, T2, T3, T4, T5, T6, Value0, Values...>>           \
0632         : public true_type {                                                             \
0633     };                                                                                   \
0634     template <template <typename, ValueType_...> class C, typename T0,                   \
0635               ValueType_ Value0, ValueType_... Values, size_t N, typename MT>            \
0636     struct ReplaceTypes<C<T0, Value0, Values...>, N, MT, Category::ClassTemplate> {      \
0637         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0>::type tmp;            \
0638         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \
0639                                                              Values...> Substituted;     \
0640         static constexpr auto NN = tmp::N;                                               \
0641         typedef conditional_t<is_same<C<T0, Value0, Values...>, Substituted>::value,     \
0642                               C<T0, Value0, Values...>,                                  \
0643                               Adapter<C<T0, Value0, Values...>, Substituted, NN>> type;  \
0644     };                                                                                   \
0645     template <template <typename, typename, ValueType_...> class C, typename T0,         \
0646               typename T1, ValueType_ Value0, ValueType_... Values, size_t N,            \
0647               typename MT>                                                               \
0648     struct ReplaceTypes<C<T0, T1, Value0, Values...>, N, MT, Category::ClassTemplate> {  \
0649         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1>::type tmp;        \
0650         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \
0651                                                              Values...> Substituted;     \
0652         static constexpr auto NN = tmp::N;                                               \
0653         typedef conditional_t<is_same<C<T0, T1, Value0, Values...>, Substituted>::value, \
0654                               C<T0, T1, Value0, Values...>,                              \
0655                               Adapter<C<T0, T1, Value0, Values...>, Substituted, NN>>    \
0656             type;                                                                        \
0657     };                                                                                   \
0658     template <template <typename, typename, typename, ValueType_...> class C,            \
0659               typename T0, typename T1, typename T2, ValueType_ Value0,                  \
0660               ValueType_... Values, size_t N, typename MT>                               \
0661     struct ReplaceTypes<C<T0, T1, T2, Value0, Values...>, N, MT,                         \
0662                         Category::ClassTemplate> {                                       \
0663         typedef typename SubstituteOneByOne<N, MT, Typelist<>, T0, T1, T2>::type tmp;    \
0664         typedef typename tmp::template SubstitutedWithValues<ValueType_, C, Value0,      \
0665                                                              Values...> Substituted;     \
0666         static constexpr auto NN = tmp::N;                                               \
0667         typedef conditional_t<                                                           \
0668             is_same<C<T0, T1, T2, Value0, Values...>, Substituted>::value,               \
0669             C<T0, T1, T2, Value0, Values...>,                                            \
0670             Adapter<C<T0, T1, T2, Value0, Values...>, Substituted, NN>> type;            \
0671     }
0672 #endif  
0673 Vc_DEFINE_NONTYPE_REPLACETYPES_(bool);
0674 Vc_DEFINE_NONTYPE_REPLACETYPES_(wchar_t);
0675 Vc_DEFINE_NONTYPE_REPLACETYPES_(char);
0676 Vc_DEFINE_NONTYPE_REPLACETYPES_(  signed char);
0677 Vc_DEFINE_NONTYPE_REPLACETYPES_(unsigned char);
0678 Vc_DEFINE_NONTYPE_REPLACETYPES_(  signed short);
0679 Vc_DEFINE_NONTYPE_REPLACETYPES_(unsigned short);
0680 Vc_DEFINE_NONTYPE_REPLACETYPES_(  signed int);
0681 Vc_DEFINE_NONTYPE_REPLACETYPES_(unsigned int);
0682 Vc_DEFINE_NONTYPE_REPLACETYPES_(  signed long);
0683 Vc_DEFINE_NONTYPE_REPLACETYPES_(unsigned long);
0684 Vc_DEFINE_NONTYPE_REPLACETYPES_(  signed long long);
0685 Vc_DEFINE_NONTYPE_REPLACETYPES_(unsigned long long);
0686 #undef Vc_DEFINE_NONTYPE_REPLACETYPES_
0687 
0688 
0689 namespace preferred_construction_impl
0690 {
0691 template <typename T> T create();
0692 
0693 template <class Type, class... Init, class = decltype(Type(create<Init>()...))>
0694 constexpr std::integral_constant<int, 0> test(int);
0695 
0696 template <class Type, class... Init, class = decltype(Type{create<Init>()...})>
0697 constexpr std::integral_constant<int, 1> test(float);
0698 
0699 template <class Type, class... Init, class T, class = decltype(Type{{create<Init>()...}})>
0700 constexpr std::integral_constant<int, 2> test(T);
0701 
0702 template <class Type, class... Init> constexpr std::integral_constant<int, 3> test(...);
0703 }  
0704 
0705 template <class Type, class... Init>
0706 constexpr inline decltype(preferred_construction_impl::test<Type, Init...>(0))
0707 preferred_construction()
0708 {
0709     return {};
0710 }
0711 
0712 
0713 
0714 
0715 
0716 
0717 
0718 template <size_t I, typename T,
0719           typename R = decltype(std::declval<T &>().template vc_get_<I>())>
0720 R get_dispatcher(T &x, void * = nullptr)
0721 {
0722     return x.template vc_get_<I>();
0723 }
0724 template <size_t I, typename T,
0725           typename R = decltype(std::declval<const T &>().template vc_get_<I>())>
0726 R get_dispatcher(const T &x, void * = nullptr)
0727 {
0728     return x.template vc_get_<I>();
0729 }
0730 template <size_t I, typename T, typename R = decltype(std::get<I>(std::declval<T &>()))>
0731 R get_dispatcher(T &x, int = 0)
0732 {
0733     return std::get<I>(x);
0734 }
0735 template <size_t I, typename T,
0736           typename R = decltype(std::get<I>(std::declval<const T &>()))>
0737 R get_dispatcher(const T &x, int = 0)
0738 {
0739     return std::get<I>(x);
0740 }
0741 
0742 
0743 
0744 template <size_t I, class T, class = void>
0745 struct my_tuple_element : std::tuple_element<I, T> {
0746 };
0747 
0748 template <size_t I, class T>
0749 struct my_tuple_element<
0750     I, T, typename std::conditional<
0751               true, void, decltype(std::declval<T>().template vc_get_<I>())>::type> {
0752     using type =
0753         typename std::decay<decltype(std::declval<T>().template vc_get_<I>())>::type;
0754 };
0755 
0756 
0757 
0758 
0759 
0760 
0761 
0762 
0763 template <class... Ts> struct homogeneous_sizeof;
0764 template <class T, class = void> struct homogeneous_sizeof_one;
0765 template <class T>
0766 struct homogeneous_sizeof_one<T,
0767                               typename std::enable_if<std::is_arithmetic<T>::value>::type>
0768     : std::integral_constant<size_t, sizeof(T)> {
0769 };
0770 template <class T0> struct homogeneous_sizeof<T0> : homogeneous_sizeof_one<T0> {
0771 };
0772 
0773 template <class T0, class... Ts>
0774 struct homogeneous_sizeof<T0, Ts...>
0775     : std::integral_constant<size_t, homogeneous_sizeof<T0>::value ==
0776                                              homogeneous_sizeof<Ts...>::value
0777                                          ? homogeneous_sizeof<T0>::value
0778                                          : 0> {
0779 };
0780 
0781 template <class T, size_t... Is>
0782 std::integral_constant<
0783     size_t, homogeneous_sizeof<typename my_tuple_element<Is, T>::type...>::value>
0784     homogeneous_sizeof_helper(index_sequence<Is...>);
0785 
0786 template <class T>
0787 struct homogeneous_sizeof_one<T, typename std::enable_if<std::is_class<T>::value>::type>
0788     : decltype(homogeneous_sizeof_helper<T>(
0789           make_index_sequence<determine_tuple_size_<T>::value>())) {
0790 };
0791 
0792 
0793 
0794 template <typename Scalar, typename Base, size_t N> class Adapter : public Base
0795 {
0796 private:
0797     
0798     template <std::size_t... Indexes, int X>
0799     Adapter(Vc::index_sequence<Indexes...>, const Scalar,
0800             std::integral_constant<int, X>)
0801     {
0802         static_assert(
0803             X < 3, "Failed to construct an object of type Base. Neither via "
0804                    "parenthesis-init, brace-init, nor double-brace init appear to work.");
0805     }
0806 
0807     
0808     template <std::size_t... Indexes>
0809     Adapter(Vc::index_sequence<Indexes...>, const Scalar &x_,
0810             std::integral_constant<int, 2>)
0811         : Base{{get_dispatcher<Indexes>(x_)...}}
0812     {
0813     }
0814 
0815     
0816     template <std::size_t... Indexes>
0817     Adapter(Vc::index_sequence<Indexes...>, const Scalar &x_,
0818             std::integral_constant<int, 1>)
0819         : Base{get_dispatcher<Indexes>(x_)...}
0820     {
0821     }
0822 
0823     
0824     template <std::size_t... Indexes>
0825     Adapter(Vc::index_sequence<Indexes...>, const Scalar &x_,
0826             std::integral_constant<int, 0>)
0827         : Base(get_dispatcher<Indexes>(x_)...)
0828     {
0829     }
0830 
0831     template <std::size_t... Indexes>
0832     Adapter(Vc::index_sequence<Indexes...> seq_, const Scalar &x_)
0833         : Adapter(seq_, x_,
0834                   preferred_construction<Base, decltype(get_dispatcher<Indexes>(
0835                                                    std::declval<const Scalar &>()))...>())
0836     {
0837     }
0838 
0839 public:
0840     
0841     static constexpr size_t size() { return N; }
0842     static constexpr size_t Size = N;
0843 
0844     
0845     using base_type = Base;
0846     
0847     
0848     using scalar_type = Scalar;
0849 
0850     
0851     
0852     Adapter() = default;
0853 
0854     
0855 #if defined Vc_CLANG && Vc_CLANG < 0x30700
0856     Vc_INTRINSIC Adapter(const Adapter &x) : Base(x) {}
0857 #else
0858     Adapter(const Adapter &) = default;
0859 #endif
0860     
0861     Adapter(Adapter &&) = default;
0862     
0863     Adapter &operator=(const Adapter &) = default;
0864     
0865     Adapter &operator=(Adapter &&) = default;
0866 
0867     
0868     template <typename U, size_t TupleSize = determine_tuple_size_<Scalar>::value,
0869               typename Seq = Vc::make_index_sequence<TupleSize>,
0870               typename = enable_if<std::is_convertible<U, Scalar>::value>>
0871     Adapter(U &&x_)
0872         : Adapter(Seq(), static_cast<const Scalar &>(x_))
0873     {
0874     }
0875 
0876     
0877     template <class F,
0878               class = decltype(static_cast<Scalar>(std::declval<F>()(
0879                   size_t())))>  
0880     Adapter(F &&fun);           
0881 
0882     
0883     
0884     template <typename A0, typename... Args,
0885               typename = typename std::enable_if<
0886                   !Traits::is_index_sequence<A0>::value &&
0887                   (sizeof...(Args) > 0 || !std::is_convertible<A0, Scalar>::value)>::type>
0888     Adapter(A0 &&arg0_, Args &&... arguments_)
0889         : Base(std::forward<A0>(arg0_), std::forward<Args>(arguments_)...)
0890     {
0891     }
0892 
0893     
0894     template <typename T,
0895               typename = decltype(Base(std::declval<const std::initializer_list<T> &>()))>
0896     Adapter(const std::initializer_list<T> &l_)
0897         : Base(l_)
0898     {
0899     }
0900 
0901     
0902     
0903     void *operator new(size_t size)
0904     {
0905         return Vc::Common::aligned_malloc<alignof(Adapter)>(size);
0906     }
0907     void *operator new(size_t, void *p_) { return p_; }
0908     void *operator new[](size_t size)
0909     {
0910         return Vc::Common::aligned_malloc<alignof(Adapter)>(size);
0911     }
0912     void *operator new[](size_t , void *p_) { return p_; }
0913     void operator delete(void *ptr_, size_t) { Vc::Common::free(ptr_); }
0914     void operator delete(void *, void *) {}
0915     void operator delete[](void *ptr_, size_t) { Vc::Common::free(ptr_); }
0916     void operator delete[](void *, void *) {}
0917 };  
0918 
0919 
0920 
0921 
0922 
0923 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0924 inline void operator==(
0925     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0926     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0927 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0928 inline void operator!=(
0929     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0930     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0931 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0932 inline void operator<=(
0933     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0934     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0935 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0936 inline void operator>=(
0937     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0938     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0939 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0940 inline void operator<(
0941     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0942     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0943 template <class... TTypes, class... TTypesV, class... UTypes, class... UTypesV, size_t N>
0944 inline void operator>(
0945     const Adapter<std::tuple<TTypes...>, std::tuple<TTypesV...>, N> &t,
0946     const Adapter<std::tuple<UTypes...>, std::tuple<UTypesV...>, N> &u) = delete;
0947 
0948 
0949 }  
0950 }  
0951 
0952 namespace std  
0953 {
0954 
0955 
0956 
0957 template <typename Scalar, typename Base, size_t N>
0958 class tuple_size<Vc::SimdizeDetail::Adapter<Scalar, Base, N>> : public tuple_size<Base>
0959 {
0960 };
0961 
0962 
0963 
0964 template <size_t I, typename Scalar, typename Base, size_t N>
0965 class tuple_element<I, Vc::SimdizeDetail::Adapter<Scalar, Base, N>>
0966     : public tuple_element<I, Base>
0967 {
0968 };
0969 
0970 
0971 
0972 
0973 
0974 
0975 
0976 template <typename S, typename T, size_t N>
0977 class allocator<Vc::SimdizeDetail::Adapter<S, T, N>>
0978     : public Vc::Allocator<Vc::SimdizeDetail::Adapter<S, T, N>>
0979 {
0980 public:
0981     template <typename U> struct rebind
0982     {
0983         typedef std::allocator<U> other;
0984     };
0985 };
0986 }  
0987 
0988 namespace Vc_VERSIONED_NAMESPACE
0989 {
0990 namespace SimdizeDetail
0991 {
0992 
0993 
0994 
0995 
0996 
0997 
0998 
0999 
1000 template <typename T> static inline T decay_workaround(const T &x) { return x; }
1001 
1002 
1003 
1004 
1005 
1006 template <typename S, typename T, size_t N, size_t... Indexes>
1007 inline void assign_impl(Adapter<S, T, N> &a, size_t i, const S &x,
1008                         Vc::index_sequence<Indexes...>)
1009 {
1010     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(x)))...> tmp(
1011         decay_workaround(get_dispatcher<Indexes>(x))...);
1012     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(tmp), 0)...};
1013     if (&unused == &unused) {}
1014 }  
1015 
1016 template <class S, class... Args>
1017 S construct(std::integral_constant<int, 0>, Args &&... args)
1018 {
1019     return S(std::forward<Args>(args)...);
1020 }
1021 template <class S, class... Args>
1022 S construct(std::integral_constant<int, 1>, Args &&... args)
1023 {
1024     return S{std::forward<Args>(args)...};
1025 }
1026 template <class S, class... Args>
1027 S construct(std::integral_constant<int, 2>, Args &&... args)
1028 {
1029     return S{{std::forward<Args>(args)...}};
1030 }
1031 
1032 
1033 
1034 
1035 
1036 template <typename S, typename T, size_t N, size_t... Indexes>
1037 inline S extract_impl(const Adapter<S, T, N> &a, size_t i, Vc::index_sequence<Indexes...>)
1038 {
1039     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a)[i]))...> tmp(
1040         decay_workaround(get_dispatcher<Indexes>(a)[i])...);
1041     return construct<S>(
1042         preferred_construction<S, decltype(decay_workaround(
1043                                       get_dispatcher<Indexes>(a)[i]))...>(),
1044         decay_workaround(get_dispatcher<Indexes>(a)[i])...);
1045     
1046 }
1047 
1048 
1049 template <typename S, typename T, std::size_t N, std::size_t... Indexes>
1050 inline Adapter<S, T, N> shifted_impl(const Adapter<S, T, N> &a, int shift,
1051                                      Vc::index_sequence<Indexes...>)
1052 {
1053     Adapter<S, T, N> r;
1054     auto &&unused = {(get_dispatcher<Indexes>(r) = get_dispatcher<Indexes>(a).shifted(shift), 0)...};
1055     if (&unused == &unused) {}
1056     return r;
1057 }
1058 
1059 
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068 template <typename S, typename T, size_t N>
1069 inline Adapter<S, T, N> shifted(const Adapter<S, T, N> &a, int shift)
1070 {
1071     return shifted_impl(a, shift, Vc::make_index_sequence<determine_tuple_size<T>()>());
1072 }
1073 
1074 
1075 
1076 
1077 
1078 template <typename S, typename T, std::size_t N, std::size_t... Indexes>
1079 inline void swap_impl(Adapter<S, T, N> &a, std::size_t i, S &x,
1080                       Vc::index_sequence<Indexes...>)
1081 {
1082     const auto &a_const = a;
1083     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a_const)[0]))...>
1084         tmp{decay_workaround(get_dispatcher<Indexes>(a_const)[i])...};
1085     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(x), 0)...};
1086     auto &&unused2 = {(get_dispatcher<Indexes>(x) = get_dispatcher<Indexes>(tmp), 0)...};
1087     if (&unused == &unused2) {}
1088 }
1089 template <typename S, typename T, std::size_t N, std::size_t... Indexes>
1090 inline void swap_impl(Adapter<S, T, N> &a, std::size_t i, Adapter<S, T, N> &b,
1091                       std::size_t j, Vc::index_sequence<Indexes...>)
1092 {
1093     const auto &a_const = a;
1094     const auto &b_const = b;
1095     const std::tuple<decltype(decay_workaround(get_dispatcher<Indexes>(a_const)[0]))...>
1096         tmp{decay_workaround(get_dispatcher<Indexes>(a_const)[i])...};
1097     auto &&unused = {(get_dispatcher<Indexes>(a)[i] = get_dispatcher<Indexes>(b_const)[j], 0)...};
1098     auto &&unused2 = {(get_dispatcher<Indexes>(b)[j] = get_dispatcher<Indexes>(tmp), 0)...};
1099     if (&unused == &unused2) {}
1100 }
1101 
1102 
1103 
1104 
1105 
1106 
1107 template <typename S, typename T, std::size_t N>
1108 inline void swap(Adapter<S, T, N> &a, std::size_t i, S &x)
1109 {
1110     swap_impl(a, i, x, Vc::make_index_sequence<determine_tuple_size<T>()>());
1111 }
1112 template <typename S, typename T, std::size_t N>
1113 inline void swap(Adapter<S, T, N> &a, std::size_t i, Adapter<S, T, N> &b, std::size_t j)
1114 {
1115     swap_impl(a, i, b, j, Vc::make_index_sequence<determine_tuple_size<T>()>());
1116 }
1117 
1118 template <typename A> class Scalar  
1119 {
1120     using reference = typename std::add_lvalue_reference<A>::type;
1121     using S = typename A::scalar_type;
1122     using IndexSeq = Vc::make_index_sequence<determine_tuple_size<S>()>;
1123 
1124 public:
1125     Scalar(reference aa, size_t ii) : a(aa), i(ii) {}
1126 
1127     
1128     Scalar(const Scalar &) = delete;
1129     Scalar(Scalar &&) = delete;
1130     Scalar &operator=(const Scalar &) = delete;
1131     Scalar &operator=(Scalar &&) = delete;
1132 
1133     void operator=(const S &x) { assign_impl(a, i, x, IndexSeq()); }
1134     operator S() const { return extract_impl(a, i, IndexSeq()); }
1135 
1136     template <typename AA>
1137     friend inline void swap(Scalar<AA> &&a, typename AA::scalar_type &b);
1138     template <typename AA>
1139     friend inline void swap(typename AA::scalar_type &b, Scalar<AA> &&a);
1140     template <typename AA> friend inline void swap(Scalar<AA> &&a, Scalar<AA> &&b);
1141 
1142 private:
1143     reference a;
1144     size_t i;
1145 };  
1146 
1147 
1148 
1149 template <typename A> inline void swap(Scalar<A> &&a, typename A::scalar_type &b)
1150 {
1151     swap_impl(a.a, a.i, b, typename Scalar<A>::IndexSeq());
1152 }
1153 
1154 
1155 template <typename A> inline void swap(typename A::scalar_type &b, Scalar<A> &&a)
1156 {
1157     swap_impl(a.a, a.i, b, typename Scalar<A>::IndexSeq());
1158 }
1159 
1160 template <typename A> inline void swap(Scalar<A> &&a, Scalar<A> &&b)
1161 {
1162     swap_impl(a.a, a.i, b.a, b.i, typename Scalar<A>::IndexSeq());
1163 }
1164 
1165 
1166 template <class S, class T, size_t N, size_t... I>
1167 inline void load_interleaved_impl(Vc::index_sequence<I...>, Adapter<S, T, N> &a,
1168                                   const S *mem)
1169 {
1170     const InterleavedMemoryWrapper<S, decltype(decay_workaround(get_dispatcher<0>(a)))>
1171     wrapper(const_cast<S *>(mem));
1172     Vc::tie(get_dispatcher<I>(a)...) = wrapper[0];
1173 }
1174 
1175 
1176 template <class S, class T, size_t N, size_t... I>
1177 inline void store_interleaved_impl(Vc::index_sequence<I...>, const Adapter<S, T, N> &a,
1178                                    S *mem)
1179 {
1180     InterleavedMemoryWrapper<S, decltype(decay_workaround(get_dispatcher<0>(a)))> wrapper(
1181         mem);
1182     wrapper[0] = Vc::tie(get_dispatcher<I>(a)...);
1183 }
1184 
1185 template <typename A> class Interface  
1186 {
1187     using reference = typename std::add_lvalue_reference<A>::type;
1188     using IndexSeq =
1189         Vc::make_index_sequence<determine_tuple_size<typename A::scalar_type>()>;
1190 
1191 public:
1192     Interface(reference aa) : a(aa) {}
1193 
1194     Scalar<A> operator[](size_t i)
1195     {
1196         return {a, i};
1197     }
1198     typename A::scalar_type operator[](size_t i) const
1199     {
1200         return extract_impl(a, i, IndexSeq());
1201     }
1202 
1203     A shifted(int amount) const
1204     {
1205         return shifted_impl(a, amount, IndexSeq());
1206     }
1207 
1208     void load(const typename A::scalar_type *mem) { load_interleaved(*this, mem); }
1209     void store(typename A::scalar_type *mem) { store_interleaved(*this, mem); }
1210 
1211 private:
1212     reference a;
1213 };  
1214 }  
1215 
1216 
1217 
1218 
1219 
1220 template <typename S, typename T, size_t N>
1221 inline void assign(SimdizeDetail::Adapter<S, T, N> &a, size_t i, const S &x)
1222 {
1223     SimdizeDetail::assign_impl(
1224         a, i, x, Vc::make_index_sequence<SimdizeDetail::determine_tuple_size<T>()>());
1225 }
1226 
1227 
1228 
1229 template <typename V, typename = enable_if<Traits::is_simd_vector<V>::value>>
1230 Vc_INTRINSIC void assign(V &v, size_t i, typename V::EntryType x)
1231 {
1232     v[i] = x;
1233 }
1234 
1235 
1236 
1237 
1238 
1239 
1240 template <typename S, typename T, size_t N>
1241 inline S extract(const SimdizeDetail::Adapter<S, T, N> &a, size_t i)
1242 {
1243     return SimdizeDetail::extract_impl(
1244         a, i, Vc::make_index_sequence<SimdizeDetail::determine_tuple_size<S>()>());
1245 }
1246 
1247 
1248 
1249 template <typename V, typename = enable_if<Traits::is_simd_vector<V>::value>>
1250 Vc_INTRINSIC typename V::EntryType extract(const V &v, size_t i)
1251 {
1252     return v[i];
1253 }
1254 
1255 
1256 template <class S, class T, size_t N>
1257 inline void load_interleaved(SimdizeDetail::Adapter<S, T, N> &a, const S *mem)
1258 {
1259     if (SimdizeDetail::homogeneous_sizeof<S>::value == 0) {
1260         Common::unrolled_loop<std::size_t, 0, N>(
1261             [&](std::size_t i) { assign(a, i, mem[i]); });
1262     } else {
1263         constexpr size_t TupleSize = SimdizeDetail::determine_tuple_size_<S>::value;
1264         SimdizeDetail::load_interleaved_impl(Vc::make_index_sequence<TupleSize>(), a,
1265                                              mem);
1266     }
1267 }
1268 template <
1269     class V, class T,
1270     class = enable_if<Traits::is_simd_vector<V>::value && std::is_arithmetic<T>::value>>
1271 Vc_INTRINSIC void load_interleaved(V &a, const T *mem)
1272 {
1273     a.load(mem, Vc::Unaligned);
1274 }
1275 
1276 
1277 template <class S, class T, size_t N>
1278 inline void store_interleaved(const SimdizeDetail::Adapter<S, T, N> &a, S *mem)
1279 {
1280     if (SimdizeDetail::homogeneous_sizeof<S>::value == 0) {
1281         Common::unrolled_loop<std::size_t, 0, N>(
1282             [&](std::size_t i) { mem[i] = extract(a, i); });
1283     } else {
1284         constexpr size_t TupleSize = SimdizeDetail::determine_tuple_size_<S>::value;
1285         SimdizeDetail::store_interleaved_impl(Vc::make_index_sequence<TupleSize>(), a,
1286                                               mem);
1287     }
1288 }
1289 template <
1290     class V, class T,
1291     class = enable_if<Traits::is_simd_vector<V>::value && std::is_arithmetic<T>::value>>
1292 Vc_INTRINSIC void store_interleaved(const V &a, T *mem)
1293 {
1294     a.store(mem, Vc::Unaligned);
1295 }
1296 
1297 
1298 template <typename S, typename T, size_t N>
1299 SimdizeDetail::Interface<SimdizeDetail::Adapter<S, T, N>> decorate(
1300     SimdizeDetail::Adapter<S, T, N> &a)
1301 {
1302     return {a};
1303 }
1304 template <typename S, typename T, size_t N>
1305 const SimdizeDetail::Interface<const SimdizeDetail::Adapter<S, T, N>> decorate(
1306     const SimdizeDetail::Adapter<S, T, N> &a)
1307 {
1308     return {a};
1309 }
1310 template <class V, class = typename std::enable_if<
1311                        Traits::is_simd_vector<typename std::decay<V>::type>::value>>
1312 V &&decorate(V &&v)
1313 {
1314     return std::forward<V>(v);
1315 }
1316 
1317 namespace SimdizeDetail
1318 {
1319 
1320 template <typename Scalar, typename Base, size_t N>
1321 template <class F, class>
1322 Adapter<Scalar, Base, N>::Adapter(F &&fun)
1323 {
1324     for (size_t i = 0; i < N; ++i) {
1325         Vc::assign(*this, i, fun(i));
1326     }
1327 }
1328 
1329 namespace IteratorDetails  
1330 {
1331 enum class Mutable { Yes, No };
1332 
1333 template <typename It, typename V, size_t I, size_t End>
1334 Vc_INTRINSIC V fromIteratorImpl(enable_if<(I == End), It>)
1335 {
1336     return {};
1337 }
1338 template <typename It, typename V, size_t I, size_t End>
1339 Vc_INTRINSIC V fromIteratorImpl(enable_if<(I < End), It> it)
1340 {
1341     V r = fromIteratorImpl<It, V, I + 1, End>(it);
1342     Traits::decay<decltype(get_dispatcher<I>(r))> tmp;
1343     for (size_t j = 0; j < V::size(); ++j, ++it) {
1344         tmp[j] = get_dispatcher<I>(*it);
1345     }
1346     get_dispatcher<I>(r) = tmp;
1347     return r;
1348 }
1349 template <typename It, typename V>
1350 Vc_INTRINSIC V fromIterator(enable_if<!Traits::is_simd_vector<V>::value, const It &> it)
1351 {
1352     return fromIteratorImpl<It, V, 0, determine_tuple_size<V>()>(it);
1353 }
1354 
1355 template <typename It, typename V>
1356 Vc_INTRINSIC V fromIterator(
1357     enable_if<
1358         Traits::is_simd_vector<V>::value && Traits::has_contiguous_storage<It>::value, It>
1359         it)
1360 {
1361 #ifndef _MSC_VER
1362     
1363     
1364     Vc_ASSERT(&*it + 1 == &*(it + 1));
1365 #endif
1366     return V(&*it, Vc::Unaligned);
1367 }
1368 
1369 template <typename It, typename V>
1370 Vc_INTRINSIC V fromIterator(enable_if<Traits::is_simd_vector<V>::value &&
1371                                           !Traits::has_contiguous_storage<It>::value,
1372                                       It>
1373                                 it)
1374 {
1375     V r;
1376     for (size_t j = 0; j < V::size(); ++j, ++it) {
1377         r[j] = *it;
1378     }
1379     return r;
1380 }
1381 
1382 
1383 
1384 
1385 template <typename T, typename value_vector, Mutable> class Pointer;
1386 
1387 
1388 
1389 
1390 
1391 
1392 
1393 
1394 
1395 template <typename T, typename value_vector> class Pointer<T, value_vector, Mutable::Yes>
1396 {
1397     static constexpr auto Size = value_vector::size();
1398 
1399 public:
1400     
1401     value_vector *operator->() { return &data; }
1402 
1403     
1404 
1405 
1406 
1407     Pointer() = delete;
1408     Pointer(const Pointer &) = delete;
1409     Pointer &operator=(const Pointer &) = delete;
1410     Pointer &operator=(Pointer &&) = delete;
1411 
1412     
1413     Pointer(Pointer &&) = default;
1414 
1415     
1416 
1417 
1418 
1419 
1420     ~Pointer()
1421     {
1422         
1423         for (size_t i = 0; i < Size; ++i, ++begin_iterator) {
1424             *begin_iterator = extract(data, i);
1425         }
1426     }
1427 
1428     
1429     Pointer(const T &it) : data(fromIterator<T, value_vector>(it)), begin_iterator(it) {}
1430 
1431 private:
1432     
1433     value_vector data;
1434     
1435     T begin_iterator;
1436 };
1437 
1438 
1439 
1440 
1441 
1442 template <typename T, typename value_vector> class Pointer<T, value_vector, Mutable::No>
1443 {
1444     static constexpr auto Size = value_vector::size();
1445 
1446 public:
1447     const value_vector *operator->() const { return &data; }
1448 
1449     Pointer() = delete;
1450     Pointer(const Pointer &) = delete;
1451     Pointer &operator=(const Pointer &) = delete;
1452     Pointer &operator=(Pointer &&) = delete;
1453 
1454     Pointer(Pointer &&) = default;  
1455 
1456     Pointer(const T &it) : data(fromIterator<T, value_vector>(it)) {}
1457 
1458 private:
1459     value_vector data;
1460 };
1461 
1462 
1463 
1464 
1465 
1466 
1467 
1468 
1469 
1470 
1471 
1472 
1473 
1474 template <typename T, typename value_vector, Mutable M> class Reference;
1475 
1476 
1477 template <typename T, typename value_vector>
1478 class Reference<T, value_vector, Mutable::Yes> : public value_vector
1479 {
1480     static constexpr auto Size = value_vector::size();
1481 
1482     using reference = typename std::add_lvalue_reference<T>::type;
1483     reference scalar_it;
1484 
1485 public:
1486     
1487     
1488     Reference(reference first_it)
1489         : value_vector(fromIterator<T, value_vector>(first_it)), scalar_it(first_it)
1490     {
1491     }
1492 
1493     
1494     Reference(const Reference &) = delete;
1495     Reference(Reference &&) = default;
1496     Reference &operator=(const Reference &) = delete;
1497     Reference &operator=(Reference &&) = delete;
1498 
1499     
1500 
1501 
1502 
1503 
1504     void operator=(const value_vector &x)
1505     {
1506         static_cast<value_vector &>(*this) = x;
1507         auto it = scalar_it;
1508         for (size_t i = 0; i < Size; ++i, ++it) {
1509             *it = extract(x, i);
1510         }
1511     }
1512 };
1513 #define Vc_OP(op_)                                                                       \
1514     template <typename T0, typename V0, typename T1, typename V1>                        \
1515     decltype(std::declval<const V0 &>() op_ std::declval<const V1 &>()) operator op_(    \
1516         const Reference<T0, V0, Mutable::Yes> &x,                                        \
1517         const Reference<T1, V1, Mutable::Yes> &y)                                        \
1518     {                                                                                    \
1519         return static_cast<const V0 &>(x) op_ static_cast<const V1 &>(y);                \
1520     }
1521 Vc_ALL_COMPARES(Vc_OP);
1522 Vc_ALL_ARITHMETICS(Vc_OP);
1523 Vc_ALL_BINARY(Vc_OP);
1524 Vc_ALL_LOGICAL(Vc_OP);
1525 Vc_ALL_SHIFTS(Vc_OP);
1526 #undef Vc_OP
1527 
1528 
1529 template <typename T, typename value_vector>
1530 class Reference<T, value_vector, Mutable::No> : public value_vector
1531 {
1532     static constexpr auto Size = value_vector::size();
1533 
1534 public:
1535     Reference(const T &it) : value_vector(fromIterator<T, value_vector>(it)) {}
1536 
1537     Reference(const Reference &) = delete;
1538     Reference(Reference &&) = default;
1539     Reference &operator=(const Reference &) = delete;
1540     Reference &operator=(Reference &&) = delete;
1541 
1542     
1543     void operator=(const value_vector &x) = delete;
1544 };
1545 
1546 template <typename T, size_t N,
1547           IteratorDetails::Mutable M =
1548               (Traits::is_output_iterator<T>::value ? Mutable::Yes : Mutable::No),
1549           typename V = simdize<typename std::iterator_traits<T>::value_type, N>,
1550           size_t Size = V::Size,
1551           typename = typename std::iterator_traits<T>::iterator_category>
1552 class Iterator;
1553 
1554 template <typename T, size_t N, IteratorDetails::Mutable M, typename V, size_t Size_>
1555 class Iterator<T, N, M, V, Size_, std::forward_iterator_tag>
1556 {
1557 public:
1558     using iterator_category = typename std::iterator_traits<T>::iterator_category;
1559     using difference_type = typename std::iterator_traits<T>::difference_type;
1560     using value_type = V;
1561     using pointer = IteratorDetails::Pointer<T, V, M>;
1562     using reference = IteratorDetails::Reference<T, V, M>;
1563     using const_pointer = IteratorDetails::Pointer<T, V, IteratorDetails::Mutable::No>;
1564     using const_reference =
1565         IteratorDetails::Reference<T, V, IteratorDetails::Mutable::No>;
1566 
1567     
1568     static constexpr std::size_t size() { return Size_; }
1569     static constexpr std::size_t Size = Size_;
1570 
1571     Iterator() = default;
1572 
1573     
1574 
1575 
1576 
1577 
1578 
1579     Iterator(const T &x) : scalar_it(x) {}
1580     
1581 
1582 
1583     Iterator(T &&x) : scalar_it(std::move(x)) {}
1584     
1585 
1586 
1587     Iterator &operator=(const T &x)
1588     {
1589         scalar_it = x;
1590         return *this;
1591     }
1592     
1593 
1594 
1595     Iterator &operator=(T &&x)
1596     {
1597         scalar_it = std::move(x);
1598         return *this;
1599     }
1600 
1601     
1602     Iterator(const Iterator &) = default;
1603     
1604     Iterator(Iterator &&) = default;
1605     
1606     Iterator &operator=(const Iterator &) = default;
1607     
1608     Iterator &operator=(Iterator &&) = default;
1609 
1610     
1611     Iterator &operator++()
1612     {
1613         std::advance(scalar_it, Size);
1614         return *this;
1615     }
1616     
1617     Iterator operator++(int)
1618     {
1619         Iterator copy(*this);
1620         operator++();
1621         return copy;
1622     }
1623 
1624     
1625 
1626 
1627 
1628 
1629 
1630 
1631 
1632     bool operator==(const Iterator &rhs) const
1633     {
1634 #ifndef NDEBUG
1635         if (scalar_it == rhs.scalar_it) {
1636             return true;
1637         } else {
1638             T it(scalar_it);
1639             for (size_t i = 1; i < Size; ++i) {
1640                 Vc_ASSERT((++it != rhs.scalar_it));
1641             }
1642             return false;
1643         }
1644 #else
1645         return scalar_it == rhs.scalar_it;
1646 #endif
1647     }
1648     
1649 
1650 
1651 
1652 
1653 
1654 
1655 
1656     bool operator!=(const Iterator &rhs) const
1657     {
1658         return !operator==(rhs);
1659     }
1660 
1661     pointer operator->() { return scalar_it; }
1662 
1663     
1664 
1665 
1666 
1667 
1668 
1669     reference operator*() { return scalar_it; }
1670 
1671     const_pointer operator->() const { return scalar_it; }
1672 
1673     
1674 
1675 
1676 
1677 
1678 
1679 
1680     const_reference operator*() const { return scalar_it; }
1681 
1682     
1683 
1684 
1685 
1686 
1687 
1688 
1689 
1690 
1691 
1692 
1693 
1694 
1695     operator const T &() const { return scalar_it; }
1696 
1697 protected:
1698     T scalar_it;
1699 };
1700 
1701 
1702 
1703 
1704 
1705 template <typename T, size_t N, IteratorDetails::Mutable M, typename V, size_t Size>
1706 class Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>
1707     : public Iterator<T, N, M, V, Size, std::forward_iterator_tag>
1708 {
1709     using Base = Iterator<T, N, M, V, Size, std::forward_iterator_tag>;
1710 
1711 protected:
1712     using Base::scalar_it;
1713 
1714 public:
1715     using pointer = typename Base::pointer;
1716     using reference = typename Base::reference;
1717     using const_pointer = typename Base::const_pointer;
1718     using const_reference = typename Base::const_reference;
1719 
1720     using Iterator<T, N, M, V, Size,
1721                    std::forward_iterator_tag>::Iterator;  
1722                                                           
1723                                                           
1724     
1725     Iterator &operator--()
1726     {
1727         std::advance(scalar_it, -Size);
1728         return *this;
1729     }
1730     
1731     Iterator operator--(int)
1732     {
1733         Iterator copy(*this);
1734         operator--();
1735         return copy;
1736     }
1737 };
1738 
1739 
1740 
1741 
1742 
1743 template <typename T, size_t N, IteratorDetails::Mutable M, typename V, size_t Size>
1744 class Iterator<T, N, M, V, Size, std::random_access_iterator_tag>
1745     : public Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>
1746 {
1747     using Base = Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>;
1748 
1749 protected:
1750     using Base::scalar_it;
1751 
1752 public:
1753     using pointer = typename Base::pointer;
1754     using reference = typename Base::reference;
1755     using const_pointer = typename Base::const_pointer;
1756     using const_reference = typename Base::const_reference;
1757     using difference_type = typename std::iterator_traits<T>::difference_type;
1758 
1759     using Iterator<T, N, M, V, Size, std::bidirectional_iterator_tag>::
1760         Iterator;  
1761 
1762     Iterator &operator+=(difference_type n)
1763     {
1764         scalar_it += n * difference_type(Size);
1765         return *this;
1766     }
1767     Iterator operator+(difference_type n) const { return Iterator(*this) += n; }
1768 
1769     Iterator &operator-=(difference_type n)
1770     {
1771         scalar_it -= n * difference_type(Size);
1772         return *this;
1773     }
1774     Iterator operator-(difference_type n) const { return Iterator(*this) -= n; }
1775 
1776     difference_type operator-(const Iterator &rhs) const
1777     {
1778         constexpr difference_type n = Size;
1779         Vc_ASSERT((scalar_it - rhs.scalar_it) % n ==
1780                   0);  
1781                        
1782                        
1783                        
1784                        
1785         return (scalar_it - rhs.scalar_it) / n;
1786     }
1787 
1788     
1789 
1790 
1791 
1792     bool operator<(const Iterator &rhs) const
1793     {
1794         return rhs.scalar_it - scalar_it >= difference_type(Size);
1795     }
1796 
1797     bool operator>(const Iterator &rhs) const
1798     {
1799         return scalar_it - rhs.scalar_it >= difference_type(Size);
1800     }
1801 
1802     bool operator<=(const Iterator &rhs) const
1803     {
1804         return rhs.scalar_it - scalar_it >= difference_type(Size) - 1;
1805     }
1806 
1807     bool operator>=(const Iterator &rhs) const
1808     {
1809         return scalar_it - rhs.scalar_it >= difference_type(Size) - 1;
1810     }
1811 
1812     reference operator[](difference_type i) { return *(*this + i); }
1813     const_reference operator[](difference_type i) const { return *(*this + i); }
1814 };
1815 
1816 template <typename T, size_t N, IteratorDetails::Mutable M, typename V, size_t Size>
1817 Iterator<T, N, M, V, Size, std::random_access_iterator_tag> operator+(
1818     typename Iterator<T, N, M, V, Size, std::random_access_iterator_tag>::difference_type
1819         n,
1820     const Iterator<T, N, M, V, Size, std::random_access_iterator_tag> &i)
1821 {
1822     return i + n;
1823 }
1824 
1825 }  
1826 
1827 
1828 
1829 
1830 
1831 
1832 
1833 
1834 
1835 template <typename T, size_t N, typename MT>
1836 struct ReplaceTypes<T, N, MT, Category::ForwardIterator>
1837 {
1838     using type = IteratorDetails::Iterator<T, N>;
1839 };
1840 template <typename T, size_t N, typename MT>
1841 struct ReplaceTypes<T, N, MT, Category::BidirectionalIterator>
1842 {
1843     using type = IteratorDetails::Iterator<T, N>;
1844 };
1845 template <typename T, size_t N, typename MT>
1846 struct ReplaceTypes<T, N, MT, Category::RandomAccessIterator>
1847 {
1848     using type = IteratorDetails::Iterator<T, N>;
1849 };
1850 
1851 
1852 
1853 
1854 template <Vc::Operator Op, typename S, typename T, std::size_t N, typename M, typename U,
1855           std::size_t Offset>
1856 Vc_INTRINSIC Vc::enable_if<(Offset >= determine_tuple_size_<S>::value && M::Size == N), void>
1857     conditional_assign(Adapter<S, T, N> &, const M &, const U &)
1858 {
1859 }
1860 template <Vc::Operator Op, typename S, typename T, std::size_t N, typename M, typename U,
1861           std::size_t Offset = 0>
1862 Vc_INTRINSIC Vc::enable_if<(Offset < determine_tuple_size_<S>::value && M::Size == N), void>
1863     conditional_assign(Adapter<S, T, N> &lhs, const M &mask, const U &rhs)
1864 {
1865     using V = typename std::decay<decltype(get_dispatcher<Offset>(lhs))>::type;
1866     using M2 = typename V::mask_type;
1867     conditional_assign<Op>(get_dispatcher<Offset>(lhs), simd_cast<M2>(mask), get_dispatcher<Offset>(rhs));
1868     conditional_assign<Op, S, T, N, M, U, Offset + 1>(lhs, mask, rhs);
1869 }
1870 template <Vc::Operator Op, typename S, typename T, std::size_t N, typename M,
1871           std::size_t Offset>
1872 Vc_INTRINSIC Vc::enable_if<(Offset >= determine_tuple_size_<S>::value && M::Size == N), void>
1873     conditional_assign(Adapter<S, T, N> &, const M &)
1874 {
1875 }
1876 template <Vc::Operator Op, typename S, typename T, std::size_t N, typename M,
1877           std::size_t Offset = 0>
1878 Vc_INTRINSIC Vc::enable_if<(Offset < determine_tuple_size_<S>::value && M::Size == N), void>
1879     conditional_assign(Adapter<S, T, N> &lhs, const M &mask)
1880 {
1881     using V = typename std::decay<decltype(get_dispatcher<Offset>(lhs))>::type;
1882     using M2 = typename V::mask_type;
1883     conditional_assign<Op>(get_dispatcher<Offset>(lhs), simd_cast<M2>(mask));
1884     conditional_assign<Op, S, T, N, M, Offset + 1>(lhs, mask);
1885 }
1886 
1887 
1888 }  
1889 
1890 
1891 
1892 
1893 
1894 
1895 
1896 
1897 
1898 
1899 
1900 
1901 
1902 
1903 
1904 
1905 
1906 
1907 
1908 
1909 template <typename T, size_t N = 0, typename MT = void>
1910 using simdize = SimdizeDetail::simdize<T, N, MT>;
1911 
1912 
1913 
1914 
1915 
1916 
1917 
1918 
1919 
1920 
1921 
1922 
1923 
1924 
1925 
1926 
1927 
1928 
1929 
1930 
1931 #define Vc_SIMDIZE_INTERFACE(MEMBERS_)                                                   \
1932     template <std::size_t N_>                                                            \
1933     inline auto vc_get_()->decltype(std::get<N_>(std::tie MEMBERS_))                     \
1934     {                                                                                    \
1935         return std::get<N_>(std::tie MEMBERS_);                                          \
1936     }                                                                                    \
1937     template <std::size_t N_>                                                            \
1938     inline auto vc_get_() const->decltype(std::get<N_>(std::tie MEMBERS_))               \
1939     {                                                                                    \
1940         return std::get<N_>(std::tie MEMBERS_);                                          \
1941     }                                                                                    \
1942     enum : std::size_t {                                                                 \
1943         tuple_size = std::tuple_size<decltype(std::make_tuple MEMBERS_)>::value          \
1944     }
1945 
1946 }  
1947 
1948 namespace std  
1949 {
1950 using Vc::SimdizeDetail::swap;
1951 }  
1952 
1953 #endif  
1954 
1955