From af7882601aad93ada881486eeaabc562f1733961 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 23 Apr 2018 08:17:58 -0700 Subject: - fd5f3d7077270ffc5ea74cdb9e18bbae3b9b46aa Fix typo optional -> variant by Abseil Team - 9136c06dfa8dbfdde0a427ad3509e34763d607a6 Fix string_view_test and str_cat_test build under MSVC de... by Derek Mauro - a463820f9441888f4368aa87328599e3209f9b07 Removes constexpr optional::operator->(). This was don... by Abseil Team - 3bf78a7f126daafff329f7815d507422f1ca378d Remove dependencies on external CCTZ project. by Shaindel Schwartz - a4ae574a11b1ddf6e88459af3d638cf79aea7ecd Internal change by Jon Cohen GitOrigin-RevId: fd5f3d7077270ffc5ea74cdb9e18bbae3b9b46aa Change-Id: I6ab8ab99863716fe9b2745a12ef285f7a6da6d1e --- absl/types/optional.h | 12 +++++++----- absl/types/optional_test.cc | 47 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 15 deletions(-) (limited to 'absl/types') diff --git a/absl/types/optional.h b/absl/types/optional.h index 581321dc37a1..98b29e591d15 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -774,7 +774,9 @@ class optional : private optional_internal::optional_data, // // Accesses the underlying `T` value's member `m` of an `optional`. If the // `optional` is empty, behavior is undefined. - constexpr const T* operator->() const { return this->pointer(); } + // + // If you need myOpt->foo in constexpr, use (*myOpt).foo instead. + const T* operator->() const { return this->pointer(); } T* operator->() { assert(this->engaged_); return this->pointer(); @@ -870,12 +872,12 @@ class optional : private optional_internal::optional_data, private: // Private accessors for internal storage viewed as pointer to T. - constexpr const T* pointer() const { return &this->data_; } - T* pointer() { return &this->data_; } + const T* pointer() const { return std::addressof(this->data_); } + T* pointer() { return std::addressof(this->data_); } // Private accessors for internal storage viewed as reference to T. - constexpr const T& reference() const { return *this->pointer(); } - T& reference() { return *(this->pointer()); } + constexpr const T& reference() const { return this->data_; } + T& reference() { return this->data_; } // T constraint checks. You can't have an optional of nullopt_t, in_place_t // or a reference. diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index 5eedfcfd5223..179bfd66d2fe 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -263,7 +263,7 @@ TEST(optionalTest, CopyConstructor) { constexpr absl::optional o1(42); constexpr absl::optional o2 = o1; static_assert(o2, ""); - static_assert(o2->x == 42, ""); + static_assert((*o2).x == 42, ""); #ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG EXPECT_TRUE(absl::is_trivially_copy_constructible< absl::optional>::value); @@ -327,14 +327,14 @@ TEST(optionalTest, Destructor) { TEST(optionalTest, InPlaceConstructor) { constexpr absl::optional opt0{absl::in_place_t()}; static_assert(opt0, ""); - static_assert(opt0->x == ConstexprType::kCtorDefault, ""); + static_assert((*opt0).x == ConstexprType::kCtorDefault, ""); constexpr absl::optional opt1{absl::in_place_t(), 1}; static_assert(opt1, ""); - static_assert(opt1->x == ConstexprType::kCtorInt, ""); + static_assert((*opt1).x == ConstexprType::kCtorInt, ""); #ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST constexpr absl::optional opt2{absl::in_place_t(), {1, 2}}; static_assert(opt2, ""); - static_assert(opt2->x == ConstexprType::kCtorInitializerList, ""); + static_assert((*opt2).x == ConstexprType::kCtorInitializerList, ""); #endif // TODO(absl-team): uncomment these when std::is_constructible @@ -362,13 +362,13 @@ TEST(optionalTest, ValueConstructor) { // optional via ConstexprType::ConstexprType(const char*). constexpr absl::optional opt1 = {"abc"}; static_assert(opt1, ""); - static_assert(ConstexprType::kCtorConstChar == opt1->x, ""); + static_assert(ConstexprType::kCtorConstChar == (*opt1).x, ""); EXPECT_TRUE( (std::is_convertible>::value)); // direct initialization constexpr absl::optional opt2{2}; static_assert(opt2, ""); - static_assert(ConstexprType::kCtorInt == opt2->x, ""); + static_assert(ConstexprType::kCtorInt == (*opt2).x, ""); EXPECT_FALSE( (std::is_convertible>::value)); @@ -934,6 +934,33 @@ TEST(optionalTest, Swap) { EXPECT_TRUE(noexcept(swap(opt1, opt2))); } +template +struct DeletedOpAddr { + constexpr static const int value = v; + constexpr DeletedOpAddr() = default; + constexpr const DeletedOpAddr* operator&() const = delete; // NOLINT + DeletedOpAddr* operator&() = delete; // NOLINT +}; + +// The static_assert featuring a constexpr call to operator->() is commented out +// to document the fact that the current implementation of absl::optional +// expects such usecases to be malformed and not compile. +TEST(optionalTest, OperatorAddr) { + constexpr const int v = -1; + { // constexpr + constexpr const absl::optional> opt(absl::in_place_t{}); + static_assert(opt.has_value(), ""); + // static_assert(opt->value == v, ""); + static_assert((*opt).value == v, ""); + } + { // non-constexpr + const absl::optional> opt(absl::in_place_t{}); + EXPECT_TRUE(opt.has_value()); + EXPECT_TRUE(opt->value == v); + EXPECT_TRUE((*opt).value == v); + } +} + TEST(optionalTest, PointerStuff) { absl::optional opt(absl::in_place, "foo"); EXPECT_EQ("foo", *opt); @@ -943,7 +970,7 @@ TEST(optionalTest, PointerStuff) { EXPECT_EQ(opt_const->size(), 3); constexpr absl::optional opt1(1); - static_assert(opt1->x == ConstexprType::kCtorInt, ""); + static_assert((*opt1).x == ConstexprType::kCtorInt, ""); } // gcc has a bug pre 4.9.1 where it doesn't do correct overload resolution @@ -1123,13 +1150,13 @@ TEST(optionalTest, make_optional) { constexpr TrivialCopyable v; constexpr absl::optional c_opt0 = absl::make_optional(v); - static_assert(c_opt0->x == 0, ""); + static_assert((*c_opt0).x == 0, ""); constexpr absl::optional c_opt1 = absl::make_optional(); - static_assert(c_opt1->x == 0, ""); + static_assert((*c_opt1).x == 0, ""); constexpr absl::optional c_opt2 = absl::make_optional(42); - static_assert(c_opt2->x == 42, ""); + static_assert((*c_opt2).x == 42, ""); } } -- cgit 1.4.1