15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STREAM_RANGE_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STREAM_RANGE_H
18 #include "google/cloud/options.h"
19 #include "google/cloud/status.h"
20 #include "google/cloud/status_or.h"
21 #include "google/cloud/version.h"
22 #include "absl/types/variant.h"
56 using StreamReader = std::function<absl::variant<
Status, T>()>;
60 StreamRange<T> MakeStreamRange(StreamReader<T>);
103 template <
typename U>
106 using iterator_category = std::input_iterator_tag;
107 using value_type = U;
108 using difference_type = std::size_t;
109 using reference = value_type&;
110 using pointer = value_type*;
111 using const_reference = value_type
const&;
112 using const_pointer = value_type
const*;
119 const_reference
operator*()
const {
return owner_->current_; }
120 const_pointer
operator->()
const {
return &owner_->current_; }
124 is_end_ = owner_->is_end_;
135 return a.is_end_ == b.is_end_;
144 explicit IteratorImpl(StreamRange* owner)
145 : owner_(owner), is_end_(owner_->is_end_) {}
150 using value_type = StatusOr<T>;
152 using difference_type =
typename iterator::difference_type;
153 using reference =
typename iterator::reference;
154 using pointer =
typename iterator::pointer;
155 using const_reference =
typename iterator::const_reference;
156 using const_pointer =
typename iterator::const_pointer;
164 internal::OptionsSpan span(options_);
171 StreamRange&
operator=(StreamRange
const&) =
delete;
178 iterator
begin() {
return iterator(
this); }
179 iterator
end() {
return iterator(); }
184 if (!is_end_ && !current_ok_) {
188 struct UnpackVariant {
190 void operator()(
Status&& status) {
191 sr.is_end_ = status
.ok();
192 sr.current_ok_ = status
.ok();
193 if (!status
.ok()) sr.current_ = std::move(status);
195 void operator()(T&& t) {
197 sr.current_ok_ =
true;
198 sr.current_ = std::move(t);
201 internal::OptionsSpan span(options_);
203 absl::visit(UnpackVariant{*
this}, std::move(v));
206 template <
typename U>
207 friend StreamRange<U> internal::MakeStreamRange(internal::StreamReader<U>);
235 explicit StreamRange(internal::StreamReader<T> reader)
236 : reader_(std::move(reader)) {
240 Options options_
= internal::CurrentOptions();
241 internal::StreamReader<T> reader_;
242 StatusOr<T> current_;
243 bool current_ok_ =
false;
260 template <
typename T>
261 StreamRange<T> MakeStreamRange(StreamReader<T> reader) {
262 return StreamRange<T>{std::move(reader)};