From b534bdb1ba6a16b41b0163b7f6b3c4953ec32d03 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 7 Jan 2020 16:07:02 -0700 Subject: [PATCH] Remove std::conditional from List.h The `std::conditional` utility is very convenient, but it unfortunately means that the compiler has to evaluate both the true and false types even though one is guaranteed to be thrown out. This is problematic because it requires the compiler to do a lot more work then necessary. It is especially dumb when introducing the conditionals to reduce the number of cases being evaluated, as was much of the case in List.h. --- vtkm/List.h | 189 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 151 insertions(+), 38 deletions(-) diff --git a/vtkm/List.h b/vtkm/List.h index 9c9af62c8..e2a73f6e6 100644 --- a/vtkm/List.h +++ b/vtkm/List.h @@ -151,22 +151,70 @@ namespace detail template struct FindFirstOfType; -// Not found; +// Not found template struct FindFirstOfType : std::integral_constant { }; // Basic search next one +template +struct FindFirstOfCheckHead; + +template +struct FindFirstOfCheckHead + : std::integral_constant +{ +}; + +template +struct FindFirstOfCheckHead + : FindFirstOfCheckHead::value, NumSearched + 1, Target, Remaining...> +{ +}; + +// Not found +template +struct FindFirstOfCheckHead + : std::integral_constant +{ +}; + template struct FindFirstOfType - : std::conditional::value, - std::integral_constant, - FindFirstOfType>::type + : FindFirstOfCheckHead::value, NumSearched, Target, Remaining...> { }; // If there are at least 6 entries, check the first 4 to quickly narrow down +template +struct FindFirstOfSplit4; + +template +struct FindFirstOfSplit4 + : FindFirstOfCheckHead::value, NumSearched, Target, T1, T2, T3> +{ +}; + +template +struct FindFirstOfSplit4 + : FindFirstOfCheckHead::value, NumSearched + 4, Target, Ts...> +{ +}; + template -struct FindFirstOfType - : std::conditional<(std::is_same::value || std::is_same::value || - std::is_same::value || - std::is_same::value), - FindFirstOfType, - FindFirstOfType>::type +struct FindFirstOfType + : FindFirstOfSplit4<(std::is_same::value || std::is_same::value || + std::is_same::value || + std::is_same::value), + NumSearched, + Target, + T0, + T1, + T2, + T3, + T4, + T5, + Ts...> { }; // If there are at least 12 entries, check the first 8 to quickly narrow down +template +struct FindFirstOfSplit8; + +template +struct FindFirstOfSplit8 + : FindFirstOfSplit4<(std::is_same::value || std::is_same::value || + std::is_same::value || + std::is_same::value), + NumSearched, + Target, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7> +{ +}; + +template +struct FindFirstOfSplit8 + : FindFirstOfType +{ +}; + template -struct FindFirstOfType - : std::conditional<(std::is_same::value || std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value), - FindFirstOfType, - FindFirstOfType>::type +struct FindFirstOfType + : FindFirstOfSplit8<(std::is_same::value || std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value), + NumSearched, + Target, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + Ts...> { }; @@ -308,12 +408,25 @@ using ListAppend = brigand::append...>; namespace detail { +template +struct ListIntersectTagsChoose; + +template +struct ListIntersectTagsChoose +{ + using type = brigand::push_back; +}; + +template +struct ListIntersectTagsChoose +{ + using type = State; +}; + template struct ListIntersectTags + : ListIntersectTagsChoose::value, State, Element> { - using has_u = vtkm::ListHas; - using type = - typename std::conditional, State>::type; }; template