@@ -52,12 +52,12 @@ class [[nodiscard]] UnaryFuture {
5252 ) noexcept ;
5353 // / @endcond
5454
55- UnaryFuture (UnaryFuture&&) noexcept = default ;
55+ UnaryFuture (UnaryFuture&&) noexcept ;
5656 UnaryFuture& operator =(UnaryFuture&&) noexcept ;
5757 UnaryFuture (const UnaryFuture&) = delete ;
5858 UnaryFuture& operator =(const UnaryFuture&) = delete ;
5959
60- ~UnaryFuture () noexcept ;
60+ ~UnaryFuture ();
6161
6262 // / @brief Await response
6363 // /
@@ -92,7 +92,7 @@ class [[nodiscard]] UnaryFuture {
9292 // / @endcond
9393
9494private:
95- impl::FutureImpl impl_ ;
95+ impl::RpcData* data_{} ;
9696 std::function<void (impl::RpcData& data, const grpc::Status& status)> post_finish_;
9797};
9898
@@ -109,10 +109,12 @@ class [[nodiscard]] StreamReadFuture {
109109 ) noexcept ;
110110 // / @endcond
111111
112- StreamReadFuture (StreamReadFuture&& other) noexcept = default ;
112+ StreamReadFuture (StreamReadFuture&& other) noexcept ;
113113 StreamReadFuture& operator =(StreamReadFuture&& other) noexcept ;
114+ StreamReadFuture (const StreamReadFuture&) = delete ;
115+ StreamReadFuture& operator =(const StreamReadFuture&) = delete ;
114116
115- ~StreamReadFuture () noexcept ;
117+ ~StreamReadFuture ();
116118
117119 // / @brief Await response
118120 // /
@@ -131,8 +133,8 @@ class [[nodiscard]] StreamReadFuture {
131133 [[nodiscard]] bool IsReady () const noexcept ;
132134
133135private:
134- impl::FutureImpl impl_ ;
135- typename RPC::RawStream* stream_;
136+ impl::RpcData* data_{} ;
137+ typename RPC::RawStream* stream_{} ;
136138 std::function<void (impl::RpcData& data)> post_recv_message_;
137139 std::function<void (impl::RpcData& data, const grpc::Status& status)> post_finish_;
138140};
@@ -424,53 +426,57 @@ class [[nodiscard]] BidirectionalStream final : public CallAnyBase {
424426 impl::RawReaderWriter<Request, Response> stream_;
425427};
426428
427- // ========================== Implementation follows ==========================
428-
429429template <typename RPC>
430430StreamReadFuture<RPC>::StreamReadFuture(
431431 impl::RpcData& data,
432432 typename RPC::RawStream& stream,
433433 std::function<void (impl::RpcData& data)> post_recv_message,
434434 std::function<void (impl::RpcData& data, const grpc::Status& status)> post_finish
435435) noexcept
436- : impl_( data),
436+ : data_(& data),
437437 stream_ (&stream),
438438 post_recv_message_(std::move(post_recv_message)),
439439 post_finish_(std::move(post_finish)) {}
440440
441441template <typename RPC>
442- StreamReadFuture<RPC>::~StreamReadFuture () noexcept {
443- if (auto * const data = impl_.GetData ()) {
444- impl::RpcData::AsyncMethodInvocationGuard guard (*data);
445- const auto wait_status = impl::Wait (data->GetAsyncMethodInvocation (), data->GetContext ());
446- if (wait_status != impl::AsyncMethodInvocation::WaitStatus::kOk ) {
447- if (wait_status == impl::AsyncMethodInvocation::WaitStatus::kCancelled ) {
448- data->GetStatsScope ().OnCancelled ();
449- }
450- impl::Finish (*stream_, *data, post_finish_, false );
451- } else {
452- post_recv_message_ (*data);
453- }
454- }
455- }
442+ StreamReadFuture<RPC>::StreamReadFuture(StreamReadFuture&& other) noexcept
443+ : data_{std::exchange (other.data_ , nullptr )},
444+ stream_{other.stream_ },
445+ post_recv_message_{std::move (other.post_recv_message_ )},
446+ post_finish_{std::move (other.post_finish_ )} {}
456447
457448template <typename RPC>
458449StreamReadFuture<RPC>& StreamReadFuture<RPC>::operator =(StreamReadFuture<RPC>&& other) noexcept {
459450 if (this == &other) return *this ;
460451 [[maybe_unused]] auto for_destruction = std::move (*this );
461- impl_ = std::move (other.impl_ );
452+ data_ = std::exchange (other.data_ , nullptr );
462453 stream_ = other.stream_ ;
463454 post_recv_message_ = std::move (other.post_recv_message_ );
464455 post_finish_ = std::move (other.post_finish_ );
465456 return *this ;
466457}
467458
459+ template <typename RPC>
460+ StreamReadFuture<RPC>::~StreamReadFuture () {
461+ if (data_) {
462+ impl::RpcData::AsyncMethodInvocationGuard guard (*data_);
463+ const auto wait_status = impl::Wait (data_->GetAsyncMethodInvocation (), data_->GetContext ());
464+ if (wait_status != impl::AsyncMethodInvocation::WaitStatus::kOk ) {
465+ if (wait_status == impl::AsyncMethodInvocation::WaitStatus::kCancelled ) {
466+ data_->GetStatsScope ().OnCancelled ();
467+ }
468+ impl::Finish (*stream_, *data_, post_finish_, false );
469+ } else {
470+ post_recv_message_ (*data_);
471+ }
472+ }
473+ }
474+
468475template <typename RPC>
469476bool StreamReadFuture<RPC>::Get() {
470- auto * const data = impl_.GetData ();
471- UINVARIANT (data, " 'Get' must be called only once" );
472- impl::RpcData::AsyncMethodInvocationGuard guard (*data);
473- impl_.ClearData ();
477+ UINVARIANT (data_, " 'Get' must be called only once" );
478+ impl::RpcData::AsyncMethodInvocationGuard guard (*data_);
479+ auto * const data = std::exchange (data_, nullptr );
474480 const auto result = impl::Wait (data->GetAsyncMethodInvocation (), data->GetContext ());
475481 if (result == impl::AsyncMethodInvocation::WaitStatus::kCancelled ) {
476482 data->GetStatsScope ().OnCancelled ();
@@ -487,9 +493,8 @@ bool StreamReadFuture<RPC>::Get() {
487493
488494template <typename RPC>
489495bool StreamReadFuture<RPC>::IsReady() const noexcept {
490- auto * const data = impl_.GetData ();
491- UINVARIANT (data, " IsReady should be called only before 'Get'" );
492- auto & method = data->GetAsyncMethodInvocation ();
496+ UINVARIANT (data_, " IsReady should be called only before 'Get'" );
497+ auto & method = data_->GetAsyncMethodInvocation ();
493498 return method.IsReady ();
494499}
495500
0 commit comments