@@ -1023,6 +1023,16 @@ class concat_iterator
10231023 std::forward_iterator_tag, ValueT> {
10241024 using BaseT = typename concat_iterator::iterator_facade_base;
10251025
1026+ static constexpr bool ReturnsByValue =
1027+ !(std::is_reference_v<decltype (*std::declval<IterTs>())> && ...);
1028+
1029+ using reference_type =
1030+ typename std::conditional_t <ReturnsByValue, ValueT, ValueT &>;
1031+
1032+ using handle_type =
1033+ typename std::conditional_t <ReturnsByValue, std::optional<ValueT>,
1034+ ValueT *>;
1035+
10261036 // / We store both the current and end iterators for each concatenated
10271037 // / sequence in a tuple of pairs.
10281038 // /
@@ -1065,27 +1075,30 @@ class concat_iterator
10651075 // / Returns null if the specified iterator is at the end. Otherwise,
10661076 // / dereferences the iterator and returns the address of the resulting
10671077 // / reference.
1068- template <size_t Index> ValueT * getHelper () const {
1078+ template <size_t Index> handle_type getHelper () const {
10691079 auto &Begin = std::get<Index>(Begins);
10701080 auto &End = std::get<Index>(Ends);
10711081 if (Begin == End)
1072- return nullptr ;
1082+ return {} ;
10731083
1074- return &*Begin;
1084+ if constexpr (ReturnsByValue)
1085+ return *Begin;
1086+ else
1087+ return &*Begin;
10751088 }
10761089
10771090 // / Finds the first non-end iterator, dereferences, and returns the resulting
10781091 // / reference.
10791092 // /
10801093 // / It is an error to call this with all iterators at the end.
1081- template <size_t ... Ns> ValueT & get (std::index_sequence<Ns...>) const {
1094+ template <size_t ... Ns> reference_type get (std::index_sequence<Ns...>) const {
10821095 // Build a sequence of functions to get from iterator if possible.
1083- ValueT * (concat_iterator::*GetHelperFns[])() const = {
1084- &concat_iterator::getHelper<Ns>...};
1096+ handle_type (concat_iterator::*GetHelperFns[])()
1097+ const = { &concat_iterator::getHelper<Ns>...};
10851098
10861099 // Loop over them, and return the first result we find.
10871100 for (auto &GetHelperFn : GetHelperFns)
1088- if (ValueT * P = (this ->*GetHelperFn)())
1101+ if (auto P = (this ->*GetHelperFn)())
10891102 return *P;
10901103
10911104 llvm_unreachable (" Attempted to get a pointer from an end concat iterator!" );
@@ -1107,7 +1120,7 @@ class concat_iterator
11071120 return *this ;
11081121 }
11091122
1110- ValueT & operator *() const {
1123+ reference_type operator *() const {
11111124 return get (std::index_sequence_for<IterTs...>());
11121125 }
11131126
0 commit comments