This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGaf5247c9347d: [ADT] Factor out in_place_t and expose in 
Optional ctor (authored by scott.linder).

Changed prior to commit:
  https://reviews.llvm.org/D100671?vs=345475&id=346003#toc

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,25 @@
 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;
+};
+
+template <std::size_t I>
+struct in_place_index_t // NOLINT(readability-identifier-naming)
+{
+  explicit in_place_index_t() = default;
+};
+
 //===----------------------------------------------------------------------===//
 //     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

Reply via email to