18 #ifndef viskores_List_h
19 #define viskores_List_h
34 #define VISKORES_CHECK_LIST_SIZE(size) \
35 static_assert((size) <= 512, \
36 "A viskores::List with more than 512 elements is not supported." \
37 " A list this long is problematic for compilers." \
38 " Compilers often have a recursive template instantiation limit of around 1024," \
39 " so operations on lists this large can lead to confusing and misleading errors.")
46 template <
typename... Ts>
58 using type = std::false_type;
61 template <
typename... Ts>
62 struct IsListImpl<
viskores::List<Ts...>>
64 using type = std::true_type;
68 using IsList =
typename viskores::internal::IsListImpl<T>::type;
77 #define VISKORES_IS_LIST(type) \
78 VISKORES_STATIC_ASSERT_MSG((::viskores::internal::IsList<type>::value), \
79 "Provided type is not a valid Viskores list type.")
85 struct UniversalTypeTag
89 UniversalTypeTag() =
delete;
107 template <
typename L>
110 template <
typename... Ts>
121 template <
typename List>
122 using ListSize =
typename detail::ListSizeImpl<List>::type;
127 template <
typename T,
template <
typename...>
class Target>
128 struct ListApplyImpl;
129 template <
typename... Ts,
template <
typename...>
class Target>
132 using type = Target<Ts...>;
135 template <
template <
typename...>
class Target>
145 template <typename List, template <typename...> class Target>
146 using
ListApply = typename detail::ListApplyImpl<List, Target>::type;
151 template <
typename... Ls>
152 struct ListAppendImpl;
155 struct ListAppendImpl<>
160 template <
typename L>
161 struct ListAppendImpl<L>
166 template <
typename... T0s,
typename... T1s>
173 template <
typename... T0s,
typename... T1s,
typename... T2s>
180 template <
typename... T0s,
typename... T1s,
typename... T2s,
typename... T3s>
190 template <
typename... T0s,
typename... T1s,
typename... T2s,
typename... T3s,
typename... T4s>
197 using type =
viskores::List<T0s..., T1s..., T2s..., T3s..., T4s...>;
201 template <
typename... T0s,
214 using type =
viskores::List<T0s..., T1s..., T2s..., T3s..., T4s..., T5s...>;
218 template <
typename... T0s,
233 using type =
viskores::List<T0s..., T1s..., T2s..., T3s..., T4s..., T5s..., T6s...>;
237 template <
typename... T0s,
254 using type =
viskores::List<T0s..., T1s..., T2s..., T3s..., T4s..., T5s..., T6s..., T7s...>;
258 template <
typename... T0s,
277 using type =
typename ListAppendImpl<
278 viskores::List<T0s..., T1s..., T2s..., T3s..., T4s..., T5s..., T6s..., T7s...>,
288 template <
typename... Lists>
289 using ListAppend =
typename detail::ListAppendImpl<Lists...>::type;
294 template <
typename T, viskores::IdComponent N>
297 using type =
typename ListAppendImpl<
typename ListFillImpl<T, (N / 2)>::type,
298 typename ListFillImpl<T, (N - (N / 2))>::type>::type;
301 template <
typename T>
302 struct ListFillImpl<T, 1>
307 template <
typename T>
308 struct ListFillImpl<T, 0>
317 template <
typename T, viskores::IdComponent N>
318 using ListFill =
typename detail::ListFillImpl<T, N>::type;
323 template <
typename T>
324 struct ListAtImplFunc;
326 template <
typename... VoidTypes>
337 template <
typename T,
class... Other>
338 static T at(VoidTypes..., T*, Other...);
341 template <
typename T, viskores::IdComponent Index>
348 static_cast<Ts*
>(
nullptr)...));
357 template <
typename List, viskores::IdComponent Index>
358 using ListAt =
typename detail::ListAtImpl<List, Index>::type;
364 struct FindFirstOfType;
367 template <viskores::IdComponent NumSearched,
typename Target>
368 struct FindFirstOfType<NumSearched, Target> : std::integral_constant<viskores::IdComponent, -1>
373 template <
bool NextIsTarget,
376 typename... Remaining>
377 struct FindFirstOfCheckHead;
380 struct FindFirstOfCheckHead<true, NumSearched, Target, Ts...>
381 : std::integral_constant<viskores::IdComponent, NumSearched>
386 struct FindFirstOfCheckHead<false, NumSearched, Target, Next, Remaining...>
387 : FindFirstOfCheckHead<std::is_same<Target, Next>::value, NumSearched + 1, Target, Remaining...>
392 template <viskores::IdComponent NumSearched,
typename Target>
393 struct FindFirstOfCheckHead<false, NumSearched, Target>
394 : std::integral_constant<viskores::IdComponent, -1>
399 struct FindFirstOfType<NumSearched, Target, Next, Remaining...>
400 : FindFirstOfCheckHead<std::is_same<Target, Next>::value, NumSearched, Target, Remaining...>
405 template <
bool OneInFirst4Matches,
409 struct FindFirstOfSplit4;
418 struct FindFirstOfSplit4<true, NumSearched, Target, T0, T1, T2, T3, Ts...>
419 : FindFirstOfCheckHead<std::is_same<Target, T0>::value, NumSearched, Target, T1, T2, T3>
431 struct FindFirstOfSplit4<false, NumSearched, Target, T0, T1, T2, T3, T4, Ts...>
432 : FindFirstOfCheckHead<std::is_same<Target, T4>::value, NumSearched + 4, Target, Ts...>
445 struct FindFirstOfType<NumSearched, Target, T0, T1, T2, T3, T4, T5, Ts...>
446 : FindFirstOfSplit4<(std::is_same<Target, T0>::value || std::is_same<Target, T1>::value ||
447 std::is_same<Target, T2>::value || std::is_same<Target, T3>::value),
461 template <
bool OneInFirst8Matches,
465 struct FindFirstOfSplit8;
478 struct FindFirstOfSplit8<true, NumSearched, Target, T0, T1, T2, T3, T4, T5, T6, T7, Ts...>
479 : FindFirstOfSplit4<(std::is_same<Target, T0>::value || std::is_same<Target, T1>::value ||
480 std::is_same<Target, T2>::value || std::is_same<Target, T3>::value),
505 struct FindFirstOfSplit8<false, NumSearched, Target, T0, T1, T2, T3, T4, T5, T6, T7, Ts...>
506 : FindFirstOfType<NumSearched + 8, Target, Ts...>
525 struct FindFirstOfType<NumSearched, Target, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, Ts...>
526 : FindFirstOfSplit8<(std::is_same<Target, T0>::value || std::is_same<Target, T1>::value ||
527 std::is_same<Target, T2>::value || std::is_same<Target, T3>::value ||
528 std::is_same<Target, T4>::value || std::is_same<Target, T5>::value ||
529 std::is_same<Target, T6>::value || std::is_same<Target, T7>::value),
548 template <
typename List,
typename Target>
549 struct ListIndexOfImpl;
550 template <
typename... Ts,
typename Target>
556 template <
typename Target>
560 std::is_same<Target, int>::value),
561 "Cannot get indices in a universal list.");
571 template <
typename List,
typename T>
572 using ListIndexOf =
typename detail::ListIndexOfImpl<List, T>::type;
577 template <
typename List,
typename T>
583 template <
typename T>
586 using type = std::true_type;
595 template <
typename List,
typename T>
596 using ListHas =
typename detail::ListHasImpl<List, T>::type;
601 template <
typename T,
template <
typename>
class Target>
602 struct ListTransformImpl;
603 template <
typename... Ts,
template <
typename>
class Target>
609 template <
template <
typename>
class Target>
616 template <typename List, template <typename> class Transform>
617 using
ListTransform = typename detail::ListTransformImpl<List, Transform>::type;
622 #if defined(VISKORES_MSVC) && (_MSC_VER < 1920)
625 template <
typename Passed,
631 struct ListRemoveIfCheckNext;
633 template <
typename Passed,
typename Rest,
template <
typename>
class Predicate>
634 struct ListRemoveIfGetNext;
636 template <
typename Passed,
typename Next,
typename Rest,
template <
typename>
class Predicate>
637 struct ListRemoveIfCheckNext<Passed, Next, true, Rest, Predicate>
639 using type =
typename ListRemoveIfGetNext<Passed, Rest, Predicate>::type;
642 template <
typename... PassedTs,
typename Next,
typename Rest,
template <
typename>
class Predicate>
643 struct ListRemoveIfCheckNext<
viskores::
List<PassedTs...>, Next, false, Rest, Predicate>
646 typename ListRemoveIfGetNext<
viskores::List<PassedTs..., Next>, Rest, Predicate>::type;
649 template <
typename Passed,
typename Next,
typename... RestTs,
template <
typename>
class Predicate>
650 struct ListRemoveIfGetNext<Passed,
viskores::
List<Next, RestTs...>, Predicate>
652 using type =
typename ListRemoveIfCheckNext<Passed,
654 Predicate<Next>::value,
659 template <
typename Passed,
template <
typename>
class Predicate>
660 struct ListRemoveIfGetNext<Passed,
viskores::
List<>, Predicate>
665 template <
typename L,
template <
typename>
class Predicate>
666 struct ListRemoveIfImpl
668 using type =
typename ListRemoveIfGetNext<viskores::List<>, L, Predicate>::type;
673 template <
typename L,
template <
typename>
class Predicate>
674 struct ListRemoveIfImpl;
676 template <
typename... Ts,
template <
typename>
class Predicate>
677 struct ListRemoveIfImpl<
viskores::
List<Ts...>, Predicate>
679 using type =
typename ListAppendImpl<
699 template <
typename List,
template <
typename>
class Predicate>
700 using ListRemoveIf =
typename detail::ListRemoveIfImpl<List, Predicate>::type;
705 template <
typename List1,
typename List2>
706 struct ListIntersectImpl
708 template <
typename T>
717 template <
typename List1>
722 template <
typename List2>
737 template <
typename List1,
typename List2>
738 using ListIntersect =
typename detail::ListIntersectImpl<List1, List2>::type;
744 template <
typename Functor,
typename... Ts,
typename... Args>
748 "Cannot call ListFor on viskores::ListUniversal.");
749 auto init_list = { (f(Ts{}, std::forward<Args>(args)...),
false)... };
752 template <
typename Functor,
typename... Args>
761 template <
typename List1,
typename List2>
762 struct ListCrossImpl;
764 template <
typename... T0s,
typename... T1s>
767 template <
typename T>
782 template <
typename List1,
typename List2>
783 using ListCross =
typename detail::ListCrossImpl<List1, List2>::type;
788 template <
typename L,
template <
typename T1,
typename T2>
class Operator,
typename Result>
789 struct ListReduceImpl;
791 template <
template <
typename T1,
typename T2>
class Operator,
typename Result>
792 struct ListReduceImpl<
viskores::
List<>, Operator, Result>
797 template <
typename T0,
799 template <
typename O1,
typename O2>
802 struct ListReduceImpl<
viskores::
List<T0, Ts...>, Operator, Result>
804 using type =
typename ListReduceImpl<
viskores::List<Ts...>, Operator, Operator<Result, T0>>::type;
807 template <
typename T0,
817 template <
typename O1,
typename O2>
820 struct ListReduceImpl<
viskores::
List<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>, Operator, Result>
825 typename ListReduceImpl<viskores::List<T0, T1, T2, T3, T4, T5, T6, T7>,
827 Result>::type>::type;
839 template <
typename List,
template <
typename T1,
typename T2>
class Operator,
typename Initial>
840 using ListReduce =
typename detail::ListReduceImpl<List, Operator, Initial>::type;
862 template <
typename List,
template <
typename>
class Predicate = viskores::internal::meta::Identity>
864 viskores::internal::meta::And,
888 template <
typename List,
template <
typename>
class Predicate = viskores::internal::meta::Identity>
890 viskores::internal::meta::Or,
893 #undef VISKORES_CHECK_LIST_SIZE
897 #endif //viskores_List_h