@@ -1023,6 +1023,16 @@ class concat_iterator
1023
1023
std::forward_iterator_tag, ValueT> {
1024
1024
using BaseT = typename concat_iterator::iterator_facade_base;
1025
1025
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
+
1026
1036
// / We store both the current and end iterators for each concatenated
1027
1037
// / sequence in a tuple of pairs.
1028
1038
// /
@@ -1065,27 +1075,30 @@ class concat_iterator
1065
1075
// / Returns null if the specified iterator is at the end. Otherwise,
1066
1076
// / dereferences the iterator and returns the address of the resulting
1067
1077
// / reference.
1068
- template <size_t Index> ValueT * getHelper () const {
1078
+ template <size_t Index> handle_type getHelper () const {
1069
1079
auto &Begin = std::get<Index>(Begins);
1070
1080
auto &End = std::get<Index>(Ends);
1071
1081
if (Begin == End)
1072
- return nullptr ;
1082
+ return {} ;
1073
1083
1074
- return &*Begin;
1084
+ if constexpr (ReturnsByValue)
1085
+ return *Begin;
1086
+ else
1087
+ return &*Begin;
1075
1088
}
1076
1089
1077
1090
// / Finds the first non-end iterator, dereferences, and returns the resulting
1078
1091
// / reference.
1079
1092
// /
1080
1093
// / 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 {
1082
1095
// 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>...};
1085
1098
1086
1099
// Loop over them, and return the first result we find.
1087
1100
for (auto &GetHelperFn : GetHelperFns)
1088
- if (ValueT * P = (this ->*GetHelperFn)())
1101
+ if (auto P = (this ->*GetHelperFn)())
1089
1102
return *P;
1090
1103
1091
1104
llvm_unreachable (" Attempted to get a pointer from an end concat iterator!" );
@@ -1107,7 +1120,7 @@ class concat_iterator
1107
1120
return *this ;
1108
1121
}
1109
1122
1110
- ValueT & operator *() const {
1123
+ reference_type operator *() const {
1111
1124
return get (std::index_sequence_for<IterTs...>());
1112
1125
}
1113
1126
0 commit comments