@@ -1000,10 +1000,6 @@ class concat_iterator
10001000 using reference_type =
10011001 typename std::conditional_t <ReturnsByValue, ValueT, ValueT &>;
10021002
1003- using handle_type =
1004- typename std::conditional_t <ReturnsByValue, std::optional<ValueT>,
1005- ValueT *>;
1006-
10071003 // / We store both the current and end iterators for each concatenated
10081004 // / sequence in a tuple of pairs.
10091005 // /
@@ -1013,66 +1009,46 @@ class concat_iterator
10131009 std::tuple<IterTs...> Begins;
10141010 std::tuple<IterTs...> Ends;
10151011
1016- // / Attempts to increment a specific iterator.
1017- // /
1018- // / Returns true if it was able to increment the iterator. Returns false if
1019- // / the iterator is already at the end iterator.
1020- template <size_t Index> bool incrementHelper () {
1012+ // / Attempts to increment the `Index`-th iterator. If the iterator is already
1013+ // / at end, recurse over iterators in `Others...`.
1014+ template <size_t Index, size_t ... Others> void incrementImpl () {
10211015 auto &Begin = std::get<Index>(Begins);
10221016 auto &End = std::get<Index>(Ends);
1023- if (Begin == End)
1024- return false ;
1025-
1017+ if (Begin == End) {
1018+ if constexpr (sizeof ...(Others) != 0 )
1019+ return incrementImpl<Others...>();
1020+ llvm_unreachable (" Attempted to increment an end concat iterator!" );
1021+ }
10261022 ++Begin;
1027- return true ;
10281023 }
10291024
10301025 // / Increments the first non-end iterator.
10311026 // /
10321027 // / It is an error to call this with all iterators at the end.
10331028 template <size_t ... Ns> void increment (std::index_sequence<Ns...>) {
1034- // Build a sequence of functions to increment each iterator if possible.
1035- bool (concat_iterator::*IncrementHelperFns[])() = {
1036- &concat_iterator::incrementHelper<Ns>...};
1037-
1038- // Loop over them, and stop as soon as we succeed at incrementing one.
1039- for (auto &IncrementHelperFn : IncrementHelperFns)
1040- if ((this ->*IncrementHelperFn)())
1041- return ;
1042-
1043- llvm_unreachable (" Attempted to increment an end concat iterator!" );
1029+ incrementImpl<Ns...>();
10441030 }
10451031
1046- // / Returns null if the specified iterator is at the end. Otherwise,
1047- // / dereferences the iterator and returns the address of the resulting
1048- // / reference.
1049- template <size_t Index> handle_type getHelper () const {
1032+ // / Dereferences the `Index`-th iterator and returns the resulting reference.
1033+ // / If `Index` is at end, recurse over iterators in `Others...`.
1034+ template <size_t Index, size_t ... Others> handle_type getImpl () const {
10501035 auto &Begin = std::get<Index>(Begins);
10511036 auto &End = std::get<Index>(Ends);
1052- if (Begin == End)
1053- return {};
1054-
1055- if constexpr (ReturnsByValue)
1056- return *Begin ;
1057- else
1058- return & *Begin;
1037+ if (Begin == End) {
1038+ if constexpr ( sizeof ...(Others) != 0 )
1039+ return getImpl<Others...>();
1040+ llvm_unreachable (
1041+ " Attempted to get a pointer from an end concat iterator! " ) ;
1042+ }
1043+ return *Begin;
10591044 }
10601045
10611046 // / Finds the first non-end iterator, dereferences, and returns the resulting
10621047 // / reference.
10631048 // /
10641049 // / It is an error to call this with all iterators at the end.
10651050 template <size_t ... Ns> reference_type get (std::index_sequence<Ns...>) const {
1066- // Build a sequence of functions to get from iterator if possible.
1067- handle_type (concat_iterator::*GetHelperFns[])()
1068- const = {&concat_iterator::getHelper<Ns>...};
1069-
1070- // Loop over them, and return the first result we find.
1071- for (auto &GetHelperFn : GetHelperFns)
1072- if (auto P = (this ->*GetHelperFn)())
1073- return *P;
1074-
1075- llvm_unreachable (" Attempted to get a pointer from an end concat iterator!" );
1051+ return getImpl<Ns...>();
10761052 }
10771053
10781054public:
0 commit comments