0

Change base::expected to use std::variant under the hood

It previously used absl::variant, which appears not to be as constexpr
friendly. E.g., it is possible for a constexpr function to return
base::expected<void, std::string> when using std::variant, but not when
using absl::variant.

Additionally adds the include for absl::variant to a few files that were
previously relying on it being included transitively via
base/types/expected.h so they continue to compile, and removes one
instance of an unused variable that the compiler can properly detect now
that std::variant is used.

Change-Id: Ibab13382202c69fd45c5aff318e8f56b3ac0d30f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6345816
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Erik Jensen <rkjnsn@chromium.org>
Owners-Override: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1431735}
This commit is contained in:
Erik Jensen
2025-03-12 13:59:06 -07:00
committed by Chromium LUCI CQ
parent bd53fe1602
commit 548d7c3f70
6 changed files with 27 additions and 28 deletions
base/types
components/web_package
signed_web_bundles
test_support
signed_web_bundles
device/bluetooth/floss
media/mojo/clients

@ -9,12 +9,12 @@
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>
#include "base/check.h"
#include "base/strings/strcat.h"
#include "base/strings/to_string.h"
#include "base/types/expected_internal.h" // IWYU pragma: export
#include "third_party/abseil-cpp/absl/utility/utility.h"
// Class template `expected<T, E>` is a vocabulary type which contains an
// expected value of type `T`, or an error `E`. The class skews towards behaving
@ -560,7 +560,7 @@ class [[nodiscard]] expected final {
//
// `f`'s return type U needs to be a valid value_type for expected, i.e. any
// type for which `remove_cv_t` is either void, or a complete non-array object
// type that is not `absl::in_place_t`, `base::unexpect_t`, or a
// type that is not `std::in_place_t`, `base::unexpect_t`, or a
// specialization of `base::ok` or `base::unexpected`.
//
// Returns an instance of base::expected<remove_cv_t<U>, E> that is
@ -598,7 +598,7 @@ class [[nodiscard]] expected final {
//
// `f`'s return type G needs to be a valid error_type for expected, i.e. any
// type for which `remove_cv_t` is a complete non-array object type that is
// not `absl::in_place_t`, `base::unexpect_t`, or a specialization of
// not `std::in_place_t`, `base::unexpect_t`, or a specialization of
// `base::ok` or `base::unexpected`.
//
// Returns an instance of base::expected<T, remove_cv_t<G>> that is
@ -847,7 +847,7 @@ class [[nodiscard]] expected<T, E> final {
//
// `f`'s return type U needs to be a valid value_type for expected, i.e. any
// type for which `remove_cv_t` is either void, or a complete non-array object
// type that is not `absl::in_place_t`, `base::unexpect_t`, or a
// type that is not `std::in_place_t`, `base::unexpect_t`, or a
// specialization of `base::ok` or `base::unexpected`.
//
// Returns an instance of base::expected<remove_cv_t<U>, E> that is
@ -885,7 +885,7 @@ class [[nodiscard]] expected<T, E> final {
//
// `f`'s return type G needs to be a valid error_type for expected, i.e. any
// type for which `remove_cv_t` is a complete non-array object type that is
// not `absl::in_place_t`, `base::unexpect_t`, or a specialization of
// not `std::in_place_t`, `base::unexpect_t`, or a specialization of
// `base::ok` or `base::unexpected`.
//
// Returns an instance of base::expected<cv void, remove_cv_t<G>> that is
@ -925,8 +925,8 @@ class [[nodiscard]] expected<T, E> final {
}
private:
// Note: Since we can't store void types we use absl::monostate instead.
using Impl = internal::ExpectedImpl<absl::monostate, E>;
// Note: Since we can't store void types we use std::monostate instead.
using Impl = internal::ExpectedImpl<std::monostate, E>;
static constexpr auto kErrTag = Impl::kErrTag;
Impl impl_;

@ -10,10 +10,9 @@
#include <functional>
#include <type_traits>
#include <utility>
#include <variant>
#include "base/check.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/abseil-cpp/absl/utility/utility.h"
// This header defines type traits and aliases used for the implementation of
// base::expected.
@ -105,20 +104,20 @@ inline constexpr bool IsValidVoidConversion =
template <typename T, typename E, typename U>
inline constexpr bool IsValidValueConstruction =
std::is_constructible_v<T, U> &&
!std::is_same_v<std::remove_cvref_t<U>, absl::in_place_t> &&
!std::is_same_v<std::remove_cvref_t<U>, std::in_place_t> &&
!std::is_same_v<std::remove_cvref_t<U>, expected<T, E>> && !IsOk<U> &&
!IsUnexpected<U>;
template <typename T, typename U>
inline constexpr bool IsOkValueConstruction =
!std::is_same_v<std::remove_cvref_t<U>, ok<T>> &&
!std::is_same_v<std::remove_cvref_t<U>, absl::in_place_t> &&
!std::is_same_v<std::remove_cvref_t<U>, std::in_place_t> &&
std::is_constructible_v<T, U>;
template <typename T, typename U>
inline constexpr bool IsUnexpectedValueConstruction =
!std::is_same_v<std::remove_cvref_t<U>, unexpected<T>> &&
!std::is_same_v<std::remove_cvref_t<U>, absl::in_place_t> &&
!std::is_same_v<std::remove_cvref_t<U>, std::in_place_t> &&
std::is_constructible_v<T, U>;
template <typename T, typename E, typename U>
@ -132,8 +131,8 @@ class ExpectedImpl {
public:
static constexpr size_t kValIdx = 1;
static constexpr size_t kErrIdx = 2;
static constexpr absl::in_place_index_t<1> kValTag{};
static constexpr absl::in_place_index_t<2> kErrTag{};
static constexpr std::in_place_index_t<1> kValTag{};
static constexpr std::in_place_index_t<2> kErrTag{};
template <typename U, typename G>
friend class ExpectedImpl;
@ -235,17 +234,13 @@ class ExpectedImpl {
return data_.index() == kValIdx;
}
// Note: No `CHECK()` here and below, since absl::get already checks that
// Note: No `CHECK()` here and below, since std::get already checks that
// the passed in index is active.
constexpr T& value() noexcept { return absl::get<kValIdx>(data_); }
constexpr const T& value() const noexcept {
return absl::get<kValIdx>(data_);
}
constexpr T& value() noexcept { return std::get<kValIdx>(data_); }
constexpr const T& value() const noexcept { return std::get<kValIdx>(data_); }
constexpr E& error() noexcept { return absl::get<kErrIdx>(data_); }
constexpr const E& error() const noexcept {
return absl::get<kErrIdx>(data_);
}
constexpr E& error() noexcept { return std::get<kErrIdx>(data_); }
constexpr const E& error() const noexcept { return std::get<kErrIdx>(data_); }
private:
static constexpr size_t kNulIdx = 0;
@ -260,7 +255,7 @@ class ExpectedImpl {
data_.template emplace<kNulIdx>();
}
absl::variant<absl::monostate, T, E> data_;
std::variant<std::monostate, T, E> data_;
};
template <typename Exp, typename F>
@ -329,9 +324,9 @@ constexpr auto Transform(Exp&& exp, F&& f) noexcept {
static_assert(!std::is_array_v<U>,
"expected<T, E>::transform: Result of f() should "
"not be an Array");
static_assert(!std::is_same_v<U, absl::in_place_t>,
static_assert(!std::is_same_v<U, std::in_place_t>,
"expected<T, E>::transform: Result of f() should "
"not be absl::in_place_t");
"not be std::in_place_t");
static_assert(!std::is_same_v<U, unexpect_t>,
"expected<T, E>::transform: Result of f() should "
"not be unexpect_t");
@ -367,9 +362,9 @@ constexpr auto TransformError(Exp&& exp, F&& f) noexcept {
static_assert(
!std::is_array_v<G>,
"expected<T, E>::transform_error: Result of f() should not be an Array");
static_assert(!std::is_same_v<G, absl::in_place_t>,
static_assert(!std::is_same_v<G, std::in_place_t>,
"expected<T, E>::transform_error: Result of f() should not be "
"absl::in_place_t");
"std::in_place_t");
static_assert(!std::is_same_v<G, unexpect_t>,
"expected<T, E>::transform_error: Result of f() should not be "
"unexpect_t");

@ -11,6 +11,7 @@
#include "components/web_package/signed_web_bundles/ecdsa_p256_sha256_signature.h"
#include "components/web_package/signed_web_bundles/ed25519_public_key.h"
#include "components/web_package/signed_web_bundles/ed25519_signature.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
namespace web_package {

@ -8,6 +8,7 @@
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "components/web_package/test_support/signed_web_bundles/ecdsa_p256_key_pair.h"
#include "components/web_package/test_support/signed_web_bundles/ed25519_key_pair.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
namespace web_package::test {

@ -9,6 +9,7 @@
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
namespace floss {

@ -8,6 +8,7 @@
#include "gpu/ipc/common/gpu_surface_lookup.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
namespace media {