[zbitl] Use std::variant instead of fitx::result for View::error_
fitx::result is not meant for storing values.
Change-Id: Ibcf78296fa4797775f42085c1ac20626ce67d41e
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/412742
Commit-Queue: Roland McGrath <mcgrathr@google.com>
Reviewed-by: Corey Tabaka <eieio@google.com>
Reviewed-by: Joshua Seaton <joshuaseaton@google.com>
Testability-Review: Corey Tabaka <eieio@google.com>
diff --git a/zircon/system/ulib/zbitl/include/lib/zbitl/view.h b/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
index 42541c6..78d28df 100644
--- a/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
+++ b/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
@@ -11,6 +11,7 @@
#include <functional>
#include <type_traits>
+#include <variant>
#include "checking.h"
#include "storage_traits.h"
@@ -66,12 +67,12 @@
// moved-from View can be destroyed without checking it.
View(View&& other)
: error_(std::move(other.error_)), storage_(std::move(other.storage_)), limit_(other.limit_) {
- other.error_ = fitx::ok(kUnused);
+ other.error_ = Unused{};
other.limit_ = 0;
}
View& operator=(View&& other) {
error_ = std::move(other.error_);
- other.error_ = fitx::ok(kUnused);
+ other.error_ = Unused{};
storage_ = std::move(other.storage_);
limit_ = other.limit_;
other.limit_ = 0;
@@ -81,8 +82,9 @@
explicit View(storage_type storage) : storage_(std::move(storage)) {}
~View() {
- ZX_ASSERT_MSG(error_.is_ok(), "zbitl::View destroyed after error without check");
- ZX_ASSERT_MSG(error_.value() != kOk,
+ ZX_ASSERT_MSG(!std::holds_alternative<Error>(error_),
+ "zbitl::View destroyed after error without check");
+ ZX_ASSERT_MSG(!std::holds_alternative<NoError>(error_),
"zbtil::View destroyed after successful iteration without check");
}
@@ -203,12 +205,13 @@
/// consumed and take_error() cannot be called again until another begin() or
/// iterator::operator++() call has been made.
[[nodiscard]] fitx::result<Error> take_error() {
- decltype(error_) result{fitx::ok(kTaken)};
- std::swap(error_, result);
- if (result.is_error()) {
- return fitx::error{std::move(result.error_value())};
+ decltype(error_) result = std::move(error_);
+ error_ = Taken{};
+ if (std::holds_alternative<Error>(result)) {
+ return fitx::error{std::move(std::get<Error>(result))};
}
- ZX_ASSERT_MSG(result.value() != kTaken, "zbitl::View::take_error() was already called");
+ ZX_ASSERT_MSG(!std::holds_alternative<Taken>(result),
+ "zbitl::View::take_error() was already called");
return fitx::ok();
}
@@ -414,7 +417,7 @@
/// destroying the View object. An iteration that encounters an error will
/// simply end early, i.e. begin() or operator++() will yield an iterator
/// that equals end(). At the end of a loop, call take_error() to check for
- /// errors. It's also acceptable to call take_error() during and iteration
+ /// errors. It's also acceptable to call take_error() during an iteration
/// that hasn't reached end() yet, but it cannot be called again before the
/// next begin() or operator++() call.
@@ -434,7 +437,7 @@
iterator end() { return {this, true}; }
size_t size_bytes() {
- if (error_.is_ok() && error_.value() == kUnused) {
+ if (std::holds_alternative<Unused>(error_)) {
ZX_ASSERT(limit_ == 0);
// Taking the size before doing begin() takes extra work.
@@ -456,26 +459,30 @@
}
private:
+ struct Unused {};
+ struct NoError {};
+ struct Taken {};
enum ErrorState {
kUnused,
kOk,
kTaken,
};
- fitx::result<Error, ErrorState> error_{fitx::ok(kUnused)};
+ std::variant<Unused, NoError, Error, Taken> error_;
storage_type storage_;
uint32_t limit_ = 0;
void StartIteration() {
- ZX_ASSERT_MSG(!error_.is_error(), "zbitl:View iterators used without taking prior error");
- error_ = fitx::success{kOk};
+ ZX_ASSERT_MSG(!std::holds_alternative<Error>(error_),
+ "zbitl:View iterators used without taking prior error");
+ error_ = NoError{};
}
void Fail(Error error) {
- ZX_DEBUG_ASSERT_MSG(error_.is_ok(),
+ ZX_DEBUG_ASSERT_MSG(!std::holds_alternative<Error>(error_),
"Fail in error state: missing zbitl::View::StartIteration() call?");
- ZX_DEBUG_ASSERT_MSG(error_.value() != kUnused,
- "Fail in kUnused: missing zbitl::View::StartIteration() call?");
- error_ = fitx::error{std::move(error)};
+ ZX_DEBUG_ASSERT_MSG(!std::holds_alternative<Unused>(error_),
+ "Fail in Unused: missing zbitl::View::StartIteration() call?");
+ error_ = std::move(error);
}
};