18#include "lib/stdcompat/type_traits.h"
19#include "pw_async2/internal/poll_internal.h"
20#include "pw_polyfill/language_feature_macros.h"
21#include "pw_preprocessor/compiler.h"
22#include "pw_string/to_string.h"
42#define PW_ASYNC2_POLL_NODISCARD \
44 "`Poll`-returning functions may or may not have completed. Their " \
45 "return value should be examined.")
54template <
typename T =
void>
55class PW_ASYNC2_POLL_NODISCARD
Poll;
65class PW_ASYNC2_POLL_NODISCARD
Poll<void> {
67 using value_type = void;
71 constexpr Poll(
const Poll&) =
default;
72 constexpr Poll& operator=(
const Poll&) =
default;
74 constexpr Poll& operator=(
Poll&&) =
default;
91 constexpr bool IsReady()
const noexcept {
return ready_; }
92 constexpr bool IsPending()
const noexcept {
return !ready_; }
94 constexpr Poll Readiness()
const noexcept {
return *
this; }
111 constexpr void IgnorePoll()
const {}
114 return lhs.ready_ == rhs.ready_;
118 return lhs.ready_ != rhs.ready_;
138class PW_ASYNC2_POLL_NODISCARD
Poll {
140 using value_type = T;
144 constexpr Poll(
const Poll&) =
default;
145 constexpr Poll& operator=(
const Poll&) =
default;
147 constexpr Poll& operator=(
Poll&&) =
default;
159 internal_poll::EnableIfImplicitlyConvertible<value_type, const U&> = 0>
163 internal_poll::EnableIfExplicitlyConvertible<value_type, const U&> = 0>
164 explicit constexpr Poll(
const Poll<U>& other) : value_(other.value_) {}
166 template <
typename U,
167 internal_poll::EnableIfImplicitlyConvertible<value_type, U&&> = 0>
168 constexpr Poll(Poll<U>&& other)
169 : value_(std::move(other.value_)) {}
170 template <
typename U,
171 internal_poll::EnableIfExplicitlyConvertible<value_type, U&&> = 0>
172 explicit constexpr Poll(Poll<U>&& other) : value_(std::move(other.value_)) {}
181 template <
typename U = value_type,
182 internal_poll::EnableIfImplicitlyInitializable<value_type, U> = 0>
183 constexpr Poll(U&& u)
184 : Poll(std::in_place, std::forward<U>(u)) {}
186 template <
typename U = value_type,
187 internal_poll::EnableIfExplicitlyInitializable<value_type, U> = 0>
188 explicit constexpr Poll(U&& u)
189 : Poll(std::in_place, std::forward<U>(u)) {}
192 template <
typename... Args>
193 constexpr Poll(std::in_place_t, Args&&... args)
194 : value_(std::in_place, std::move(args)...) {}
197 constexpr Poll(value_type&& value) : value_(std::move(value)) {}
198 constexpr Poll& operator=(value_type&& value) {
199 value_ = std::optional<value_type>(std::move(value));
204 constexpr Poll(PendingType) noexcept : value_() {}
205 constexpr Poll& operator=(PendingType)
noexcept {
206 value_ = std::nullopt;
211 constexpr bool IsReady() const noexcept {
return value_.has_value(); }
214 constexpr bool IsPending() const noexcept {
return !value_.has_value(); }
228 constexpr value_type&
value() &
noexcept {
return *value_; }
229 constexpr const value_type& value() const& noexcept {
return *value_; }
230 constexpr value_type&& value() &&
noexcept {
return std::move(*value_); }
231 constexpr const value_type&& value() const&& noexcept {
232 return std::move(*value_);
238 constexpr const value_type*
operator->() const noexcept {
return &*value_; }
239 constexpr value_type* operator->() noexcept {
return &*value_; }
244 constexpr const value_type&
operator*() const& noexcept {
return *value_; }
245 constexpr value_type& operator*() &
noexcept {
return *value_; }
246 constexpr const value_type&& operator*() const&& noexcept {
247 return std::move(*value_);
249 constexpr value_type&& operator*() &&
noexcept {
return std::move(*value_); }
258 static_assert(!std::is_same_v<cpp20::remove_cvref_t<T>,
ReadyType>,
259 "Poll<ReadyType> is not permitted; use Poll<void> instead");
261 template <
typename U>
263 std::optional<value_type> value_;
266#undef PW_ASYNC2_POLL_NODISCARD
270Poll(T value) -> Poll<T>;
300 return !(lhs == rhs);
329constexpr bool operator==(ReadyType, ReadyType) {
return true; }
330constexpr bool operator!=(ReadyType, ReadyType) {
return false; }
333constexpr bool operator==(PendingType, PendingType) {
return true; }
334constexpr bool operator!=(PendingType, PendingType) {
return false; }
341template <
typename T,
typename... Args>
343 return Poll<T>(std::in_place, std::forward<Args>(args)...);
371 return ToString(
"Ready", buffer);
375inline StatusWithSize ToString(
const async2::PendingType&, span<char> buffer) {
376 return ToString(
"Pending", buffer);
381inline StatusWithSize ToString(
const async2::Poll<T>& poll, span<char> buffer) {
382 if (poll.IsReady()) {
385 s.UpdateAndAdd(ToString(*poll, buffer.subspan(s.size())));
386 s.UpdateAndAdd(ToString(
")", buffer.subspan(s.size())));
390 return ToString(async2::PendingType{}, buffer);
394inline StatusWithSize ToString(
const async2::Poll<>& poll, span<char> buffer) {
395 if (poll.IsReady()) {
396 return ToString(async2::ReadyType{}, buffer);
398 return ToString(async2::PendingType{}, buffer);
Definition: status_with_size.h:51
constexpr void UpdateAndAdd(StatusWithSize new_status_with_size)
Definition: status_with_size.h:128
Definition: span_impl.h:235
friend constexpr bool operator!=(const Poll &lhs, const Poll &rhs)
Definition: poll.h:117
constexpr ReadyType & operator*() noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:109
constexpr const value_type & operator*() const &noexcept
Definition: poll.h:244
constexpr bool operator!=(const Poll< T > &lhs, const Poll< T > &rhs)
Definition: poll.h:299
constexpr ReadyType & value() noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:97
constexpr bool IsReady() const noexcept
Returns whether or not this value is Ready.
Definition: poll.h:211
constexpr bool operator==(const Poll< T > &lhs, const Poll< T > &rhs)
Definition: poll.h:286
constexpr const ReadyType * operator->() const noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:102
constexpr const ReadyType & value() const noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:99
constexpr Poll Readiness() const noexcept
Definition: poll.h:218
constexpr const value_type * operator->() const noexcept
Definition: poll.h:238
constexpr bool IsPending() const noexcept
Returns whether or not this value is Pending.
Definition: poll.h:214
friend constexpr bool operator==(const Poll &lhs, const Poll &rhs)
Definition: poll.h:113
constexpr Poll(const Poll< U > &other)
Definition: poll.h:160
constexpr ReadyType * operator->() noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:104
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353
constexpr const ReadyType & operator*() const noexcept
Returns a ReadyType for compatibility with non-void Poll.
Definition: poll.h:107
constexpr value_type & value() &noexcept
Definition: poll.h:228
Poll()=delete
Basic constructors.
constexpr void IgnorePoll() const
Definition: poll.h:255
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:337
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
Result(T value) -> Result< T >
Deduction guide to allow Result(v) rather than Result<T>(v).
The Pigweed namespace.
Definition: alignment.h:27