CaseyCarter updated this revision to Diff 97834.
CaseyCarter added a comment.

The constexpr variant tests were enabled separate commit 
(https://reviews.llvm.org/rL302158). This differential now contains only the 
fine-grained SMF triviality extension test.


https://reviews.llvm.org/D32671

Files:
  test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
  test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
===================================================================
--- test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -197,10 +197,30 @@
 #endif
 }
 
+template<class...Ts>
+constexpr bool triviality_test =
+  std::is_trivially_move_constructible<std::variant<Ts...>>::value ==
+    std::conjunction<std::is_trivially_move_constructible<Ts>...>::value;
+
+void test_triviality_extension() {
+#if defined(_MSVC_STL_VER)
+  static_assert(triviality_test<int>, "");
+  static_assert(triviality_test<MoveOnly>, "");
+  static_assert(triviality_test<MoveOnlyNT>, "");
+  static_assert(triviality_test<int, long>, "");
+  static_assert(triviality_test<int, MoveOnly>, "");
+  static_assert(triviality_test<int, MoveOnlyNT>, "");
+  static_assert(triviality_test<int, ThrowsMove>, "");
+  static_assert(triviality_test<int, NoCopy>, "");
+  static_assert(triviality_test<int, MakeEmptyT>, "");
+#endif
+}
+
 int main() {
   test_move_ctor_basic();
   test_move_ctor_valueless_by_exception();
   test_move_noexcept();
   test_move_ctor_sfinae();
   test_constexpr_move_ctor_extension();
+  test_triviality_extension();
 }
Index: test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
===================================================================
--- test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -159,9 +159,27 @@
 #endif
 }
 
+template<class...Ts>
+constexpr bool triviality_test =
+  std::is_trivially_copy_constructible<std::variant<Ts...>>::value ==
+    std::conjunction<std::is_trivially_copy_constructible<Ts>...>::value;
+
+void test_triviality_extension() {
+#if defined(_MSVC_STL_VER)
+  static_assert(triviality_test<int>, "");
+  static_assert(triviality_test<NonT>, "");
+  static_assert(triviality_test<int, long>, "");
+  static_assert(triviality_test<int, NoCopy>, "");
+  static_assert(triviality_test<int, MoveOnly>, "");
+  static_assert(triviality_test<int, MoveOnlyNT>, "");
+  static_assert(triviality_test<int, MakeEmptyT>, "");
+#endif
+}
+
 int main() {
   test_copy_ctor_basic();
   test_copy_ctor_valueless_by_exception();
   test_copy_ctor_sfinae();
   test_constexpr_copy_ctor_extension();
+  test_triviality_extension();
 }
Index: test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
===================================================================
--- test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
@@ -308,12 +308,63 @@
 #endif
 }
 
+template<class...Ts>
+constexpr bool triviality_test =
+  // move assignment of variant<Ts...> is trivial when
+  std::is_trivially_move_assignable<std::variant<Ts...>>::value ==
+    std::conjunction<
+      // All Ts are trivially destructible and
+      std::is_trivially_destructible<Ts>...,
+      // either
+      std::disjunction<
+        // All Ts are trivially move (constructible and assignable) so that
+        // variant's move assignment operator is non-deleted and trivial, or
+        std::conjunction<
+          std::is_trivially_move_constructible<Ts>...,
+          std::is_trivially_move_assignable<Ts>...>,
+        // At least one of the Ts is not move (constructible or assignable) so
+        // that variant's move assignment operator is *implicitly* deleted but
+        // all of the Ts are trivially *copy* (constructible and assignable) so
+        // that move assignment actually invokes the trivial copy assignment
+        // operator.
+        std::conjunction<
+          std::disjunction<
+            std::negation<std::is_move_constructible<Ts>>...,
+            std::negation<std::is_move_assignable<Ts>>...>,
+          std::is_trivially_copy_constructible<Ts>...,
+          std::is_trivially_copy_assignable<Ts>...>>>::value;
+
+void test_triviality_extension() {
+#if defined(_MSVC_STL_VER)
+  struct TrivialCopyNontrivialMove {
+    TrivialCopyNontrivialMove(TrivialCopyNontrivialMove const&) = default;
+    TrivialCopyNontrivialMove(TrivialCopyNontrivialMove&&) noexcept {}
+    TrivialCopyNontrivialMove& operator=(TrivialCopyNontrivialMove const&) = default;
+    TrivialCopyNontrivialMove& operator=(TrivialCopyNontrivialMove&&) noexcept {
+      return *this;
+    }
+  };
+
+  static_assert(triviality_test<int>, "");
+  static_assert(triviality_test<std::string>, "");
+  static_assert(triviality_test<int, long>, "");
+  static_assert(triviality_test<int, std::string>, "");
+  static_assert(triviality_test<int, NoCopy>, "");
+  static_assert(triviality_test<int, CopyOnly>, "");
+  static_assert(triviality_test<int, MoveOnly>, "");
+  static_assert(triviality_test<int, MoveAssign>, "");
+  static_assert(triviality_test<int, MoveAssignOnly>, "");
+  static_assert(triviality_test<int, TrivialCopyNontrivialMove>, "");
+#endif
+}
+
 int main() {
   test_move_assignment_empty_empty();
   test_move_assignment_non_empty_empty();
   test_move_assignment_empty_non_empty();
   test_move_assignment_same_index();
   test_move_assignment_different_index();
   test_move_assignment_sfinae();
   test_move_assignment_noexcept();
+  test_triviality_extension();
 }
Index: test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
===================================================================
--- test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
@@ -385,6 +385,27 @@
 #endif
 }
 
+template<class...Ts>
+constexpr bool triviality_test =
+  std::is_trivially_copy_assignable<std::variant<Ts...>>::value ==
+    std::conjunction<
+      std::is_trivially_destructible<Ts>...,
+      std::is_trivially_copy_constructible<Ts>...,
+      std::is_trivially_copy_assignable<Ts>...>::value;
+
+void test_triviality_extension() {
+#if defined(_MSVC_STL_VER)
+  static_assert(triviality_test<int>, "");
+  static_assert(triviality_test<std::string>, "");
+  static_assert(triviality_test<int, long>, "");
+  static_assert(triviality_test<int, std::string>, "");
+  static_assert(triviality_test<int, NoCopy>, "");
+  static_assert(triviality_test<int, NothrowCopy>, "");
+  static_assert(triviality_test<int, CopyOnly>, "");
+  static_assert(triviality_test<int, MoveOnly>, "");
+  static_assert(triviality_test<int, CopyAssign>, "");
+#endif
+}
 
 int main() {
   test_copy_assignment_empty_empty();
@@ -394,4 +415,5 @@
   test_copy_assignment_different_index();
   test_copy_assignment_sfinae();
   test_copy_assignment_not_noexcept();
+  test_triviality_extension();
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to