scott.linder updated this revision to Diff 345475. scott.linder added a comment.
Add constexpr convenience variables Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D100671/new/ https://reviews.llvm.org/D100671 Files: clang/include/clang/Basic/DirectoryEntry.h llvm/include/llvm/ADT/Optional.h llvm/include/llvm/ADT/STLForwardCompat.h llvm/unittests/ADT/OptionalTest.cpp
Index: llvm/unittests/ADT/OptionalTest.cpp =================================================================== --- llvm/unittests/ADT/OptionalTest.cpp +++ llvm/unittests/ADT/OptionalTest.cpp @@ -195,6 +195,14 @@ EXPECT_EQ(0u, NonDefaultConstructible::Destructions); } +TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) { + NonDefaultConstructible::ResetCounts(); + { Optional<NonDefaultConstructible> A{in_place, 1}; } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); +} + TEST(OptionalTest, GetValueOr) { Optional<int> A; EXPECT_EQ(42, A.getValueOr(42)); @@ -214,6 +222,11 @@ MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; + friend bool operator==(const MultiArgConstructor &LHS, + const MultiArgConstructor &RHS) { + return LHS.x == RHS.x && LHS.y == RHS.y; + } + static unsigned Destructions; ~MultiArgConstructor() { ++Destructions; @@ -244,6 +257,34 @@ EXPECT_EQ(1u, MultiArgConstructor::Destructions); } +TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) { + MultiArgConstructor::ResetCounts(); + { + Optional<MultiArgConstructor> A{in_place, 1, 2}; + EXPECT_TRUE(A.hasValue()); + EXPECT_EQ(1, A->x); + EXPECT_EQ(2, A->y); + Optional<MultiArgConstructor> B{in_place, 5, false}; + EXPECT_TRUE(B.hasValue()); + EXPECT_EQ(5, B->x); + EXPECT_EQ(-5, B->y); + EXPECT_EQ(0u, MultiArgConstructor::Destructions); + } + EXPECT_EQ(2u, MultiArgConstructor::Destructions); +} + +TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) { + MultiArgConstructor::ResetCounts(); + { + Optional<MultiArgConstructor> A{in_place, 1, 2}; + Optional<MultiArgConstructor> B; + B.emplace(1, 2); + EXPECT_EQ(0u, MultiArgConstructor::Destructions); + ASSERT_EQ(A, B); + } + EXPECT_EQ(2u, MultiArgConstructor::Destructions); +} + struct MoveOnly { static unsigned MoveConstructions; static unsigned Destructions; @@ -391,6 +432,15 @@ EXPECT_EQ(0u, Immovable::Destructions); } +TEST(OptionalTest, ImmovableInPlaceConstruction) { + Immovable::ResetCounts(); + Optional<Immovable> A{in_place, 4}; + EXPECT_TRUE((bool)A); + EXPECT_EQ(4, A->val); + EXPECT_EQ(1u, Immovable::Constructions); + EXPECT_EQ(0u, Immovable::Destructions); +} + // Craft a class which is_trivially_copyable, but not // is_trivially_copy_constructible. struct NonTCopy { Index: llvm/include/llvm/ADT/STLForwardCompat.h =================================================================== --- llvm/include/llvm/ADT/STLForwardCompat.h +++ llvm/include/llvm/ADT/STLForwardCompat.h @@ -44,6 +44,33 @@ struct disjunction<B1, Bn...> : std::conditional<bool(B1::value), B1, disjunction<Bn...>>::type {}; +struct in_place_t // NOLINT(readability-identifier-naming) +{ + explicit in_place_t() = default; +}; +/// \warning This must not be odr-used, as it cannot be made \c inline in C++14. +constexpr in_place_t in_place; // NOLINT(readability-identifier-naming) + +template <typename T> +struct in_place_type_t // NOLINT(readability-identifier-naming) +{ + explicit in_place_type_t() = default; +}; +/// \warning This must not be odr-used, as it cannot be made \c inline in C++14. +template <typename T> +constexpr in_place_type_t<T> + in_place_type; // NOLINT(readability-identifier-naming) + +template <std::size_t I> +struct in_place_index_t // NOLINT(readability-identifier-naming) +{ + explicit in_place_index_t() = default; +}; +/// \warning This must not be odr-used, as it cannot be made \c inline in C++14. +template <std::size_t I> +constexpr in_place_index_t<I> + in_place_index; // NOLINT(readability-identifier-naming) + //===----------------------------------------------------------------------===// // Features from C++20 //===----------------------------------------------------------------------===// Index: llvm/include/llvm/ADT/Optional.h =================================================================== --- llvm/include/llvm/ADT/Optional.h +++ llvm/include/llvm/ADT/Optional.h @@ -17,6 +17,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include <cassert> @@ -30,8 +31,6 @@ namespace optional_detail { -struct in_place_t {}; - /// Storage for any type. // // The specialization condition intentionally uses @@ -245,13 +244,16 @@ constexpr Optional() {} constexpr Optional(NoneType) {} - constexpr Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {} + constexpr Optional(const T &y) : Storage(in_place, y) {} constexpr Optional(const Optional &O) = default; - constexpr Optional(T &&y) - : Storage(optional_detail::in_place_t{}, std::move(y)) {} + constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {} constexpr Optional(Optional &&O) = default; + template <typename... ArgTypes> + constexpr Optional(in_place_t, ArgTypes &&...Args) + : Storage(in_place, std::forward<ArgTypes>(Args)...) {} + Optional &operator=(T &&y) { Storage = std::move(y); return *this; Index: clang/include/clang/Basic/DirectoryEntry.h =================================================================== --- clang/include/clang/Basic/DirectoryEntry.h +++ clang/include/clang/Basic/DirectoryEntry.h @@ -120,8 +120,7 @@ MapEntryOptionalStorage() : MaybeRef(optional_none_tag()) {} template <class... ArgTypes> - explicit MapEntryOptionalStorage(llvm::optional_detail::in_place_t, - ArgTypes &&...Args) + explicit MapEntryOptionalStorage(llvm::in_place_t, ArgTypes &&...Args) : MaybeRef(std::forward<ArgTypes>(Args)...) {} void reset() { MaybeRef = optional_none_tag(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits