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>);
100 using iterator_category = std::input_iterator_tag;
101 using value_type = U;
102 using difference_type = std::size_t;
103 using reference = value_type&;
104 using pointer = value_type*;
105 using const_reference = value_type
const&;
106 using const_pointer = value_type
const*;
113 const_reference
operator*()
const {
return owner_->current_; }
114 const_pointer
operator->()
const {
return &owner_->current_; }
118 is_end_ = owner_->is_end_;
129 return a.is_end_ == b.is_end_;
138 explicit IteratorImpl(StreamRange* owner)
139 : owner_(owner), is_end_(owner_->is_end_) {}
144 using value_type = StatusOr<T>;
146 using difference_type =
typename iterator::difference_type;
147 using reference =
typename iterator::reference;
148 using pointer =
typename iterator::pointer;
149 using const_reference =
typename iterator::const_reference;
150 using const_pointer =
typename iterator::const_pointer;
158 internal::OptionsSpan span(options_);
165 StreamRange&
operator=(StreamRange
const&) =
delete;
172 iterator
begin() {
return iterator(
this); }
173 iterator
end() {
return iterator(); }
178 if (!is_end_ && !current_ok_) {
182 struct UnpackVariant {
184 void operator()(
Status&& status) {
185 sr.is_end_ = status
.ok();
186 sr.current_ok_ = status
.ok();
187 if (!status
.ok()) sr.current_ = std::move(status);
189 void operator()(T&& t) {
191 sr.current_ok_ =
true;
192 sr.current_ = std::move(t);
195 internal::OptionsSpan span(options_);
197 absl::visit(UnpackVariant{*
this}, std::move(v));
200 template <
typename U>
201 friend StreamRange<U> internal::MakeStreamRange(internal::StreamReader<U>);
229 explicit StreamRange(internal::StreamReader<T> reader)
230 : reader_(std::move(reader)) {
234 Options options_
= internal::CurrentOptions();
235 internal::StreamReader<T> reader_;
236 StatusOr<T> current_;
237 bool current_ok_ =
false;
254 template <
typename T>
255 StreamRange<T> MakeStreamRange(StreamReader<T> reader) {
256 return StreamRange<T>{std::move(reader)};