[PATCH] D32515: [libcxx] [test] Changes to accommodate LWG 2904 "Make variant move-assignment more exception safe"

2017-04-28 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter added a comment.

Added some inline notes for reviewers.




Comment at: 
test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp:195
 }
-assert(v.valueless_by_exception());
+assert(v.index() == 0);
+assert(std::get<0>(v) == "hello");

Reviewer note: After LWG 2904, the assignment on 191 uses a new "emplace from 
temporary" path. The temporary creation now throws *before* v becomes valueless.



Comment at: 
test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp:168
-// variant only provides copy assignment when both the copy and move
-// constructors are well formed
 using V = std::variant;

Reviewer note: This comment is no longer true after LWG 2904 copy assignment no 
longer requires move constructible alternatives.



Comment at: 
test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp:121
-// variant only provides move assignment when both the move constructor
-// and move assignment operator are well formed.
 using V = std::variant;

Reviewer note: this comment is technically true even after LWG 2904, but no 
longer significant. `variant` *does* have an implicitly deleted 
move assignment operator, but `is_move_assignable_v>` is 
nonetheless true after LWG 2904 since `variant` now has a viable 
*copy* assignment operator.


https://reviews.llvm.org/D32515



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32515: [libcxx] [test] Changes to accommodate LWG 2904 "Make variant move-assignment more exception safe"

2017-04-25 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

NOTE: TEST CHANGES ONLY.

These tests will not pass with the current implementation of `variant`, but 
should give the implementor of LWG2904 a head start.

Details:

test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp:

- Make `CopyAssign`'s move operations noexcept so uses in variants continue to 
prefer copy-and-move over direct construction.
- Fix `makeEmpty`: Copy assignment syntax no longer invokes `MakeEmptyT`'s 
throwing move constructor, move assignment syntax still does.
- `test_copy_assignment_sfinae`: `variant` is now copy 
assignable.
- `test_copy_assignment_different_index`:
  - `CopyThrows` and `MoveThrows` have potentially-throwing move construction, 
so they are now copy constructed directly into variants instead of via indirect 
copy-and-move.
  - implement new `CopyCannotThrow` and verify that direct copy construction of 
such in variants is preferred over indirect copy-and-move when neither method 
throws.

test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp:

- `test_move_assignment_sfinae`: `variant` is now move 
assignable.

test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp:

- `test_T_assignment_performs_construction`:
  - assigning `ThrowsCtorT` into a variant now constructs a temporary and moves 
into the variant; the variant keeps its old value if the temporary construction 
throws.
  - test that direct construction is preferred to temporary-and-move when 
neither can throw.
  - test that direct construction is preferred to temporary-and-move when both 
can throw.

test/support/variant_test_helpers.hpp:
test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp:
test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp:

- Fix `makeEmpty`: Copy assignment syntax no longer invokes `MakeEmptyT`'s 
throwing move constructor, move assignment syntax still does.


https://reviews.llvm.org/D32515

Files:
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  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
  test/support/variant_test_helpers.hpp

Index: test/support/variant_test_helpers.hpp
===
--- test/support/variant_test_helpers.hpp
+++ test/support/variant_test_helpers.hpp
@@ -69,9 +69,9 @@
 void makeEmpty(Variant& v) {
 Variant v2(std::in_place_type);
 try {
-v = v2;
+v = std::move(v2);
 assert(false);
-}  catch (...) {
+} catch (...) {
 assert(v.valueless_by_exception());
 }
 }
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
@@ -65,7 +65,7 @@
 template  void makeEmpty(Variant ) {
   Variant v2(std::in_place_type);
   try {
-v = v2;
+v = std::move(v2);
 assert(false);
   } catch (...) {
 assert(v.valueless_by_exception());
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
@@ -63,7 +63,7 @@
 template  void makeEmpty(Variant ) {
   Variant v2(std::in_place_type);
   try {
-v = v2;
+v = std::move(v2);
 assert(false);
   } catch (...) {
 assert(v.valueless_by_exception());
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
@@ -117,10 +117,8 @@
 static_assert(std::is_move_assignable::value, "");
   }
   {
-// variant only provides move assignment when both the move constructor
-// and move assignment operator are well formed.
 using V = std::variant;
-static_assert(!std::is_move_assignable::value, "");
+static_assert(std::is_move_assignable::value, "");
   }
   {
 using V = std::variant;
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
@@ -66,7 +66,7 @@
 ++alive;
 ++copy_construct;
   }
-  CopyAssign(CopyAssign 

[PATCH] D32510: [libcxx] Fix C1XX implementation of DoNotOptimize

2017-04-25 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

...in test_macros.h


https://reviews.llvm.org/D32510

Files:
  test/support/test_macros.h


Index: test/support/test_macros.h
===
--- test/support/test_macros.h
+++ test/support/test_macros.h
@@ -209,7 +209,8 @@
 #include 
 template 
 inline void DoNotOptimize(Tp const& value) {
-  const volatile void* volatile = __builtin_addressof(value);
+  const volatile void* volatile unused = __builtin_addressof(value);
+  static_cast(unused);
   _ReadWriteBarrier();
 }
 #endif


Index: test/support/test_macros.h
===
--- test/support/test_macros.h
+++ test/support/test_macros.h
@@ -209,7 +209,8 @@
 #include 
 template 
 inline void DoNotOptimize(Tp const& value) {
-  const volatile void* volatile = __builtin_addressof(value);
+  const volatile void* volatile unused = __builtin_addressof(value);
+  static_cast(unused);
   _ReadWriteBarrier();
 }
 #endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32385: [libcxx] Implement LWG 2900 "The copy and move constructors of optional are not constexpr"

2017-04-25 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter updated this revision to Diff 96644.
CaseyCarter added a comment.

Assigning an empty optional to a non-empty optional needs to destroy the 
contained value, so we need to also require `is_trivially_destructible` to 
implement trivial assignments.


https://reviews.llvm.org/D32385

Files:
  include/optional
  test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
  test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp

Index: test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -10,7 +10,10 @@
 // UNSUPPORTED: c++98, c++03, c++11, c++14
 // 
 
-// optional(optional&& rhs);
+// constexpr optional(const optional&& rhs);
+//   If is_trivially_move_constructible_v is true,
+//this constructor shall be a constexpr constructor.
+
 
 #include 
 #include 
@@ -131,6 +134,31 @@
 #endif
 }
 
+constexpr bool test_constexpr()
+{
+{
+using T = int;
+optional o1{};
+optional o2 = std::move(o1);
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = std::move(o3);
+static_cast(o4);
+}
+{
+struct T {
+constexpr T(int) {}
+T(T&&) = default;
+};
+optional o1{};
+optional o2 = std::move(o1);
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = std::move(o3);
+static_cast(o4);
+}
+return true;
+}
 
 int main()
 {
@@ -198,4 +226,7 @@
 {
 test_reference_extension();
 }
+{
+static_assert(test_constexpr(), "");
+}
 }
Index: test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -10,7 +10,9 @@
 // UNSUPPORTED: c++98, c++03, c++11, c++14
 // 
 
-// optional(const optional& rhs);
+// constexpr optional(const optional& rhs);
+//   If is_trivially_copy_constructible_v is true,
+//this constructor shall be a constexpr constructor.
 
 #include 
 #include 
@@ -104,6 +106,31 @@
 #endif
 }
 
+constexpr bool test_constexpr()
+{
+{
+using T = int;
+optional o1{};
+optional o2 = o1;
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = o3;
+static_cast(o4);
+}
+{
+struct T {
+constexpr T(int) {}
+};
+optional o1{};
+optional o2 = o1;
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = o3;
+static_cast(o4);
+}
+return true;
+}
+
 int main()
 {
 test();
@@ -152,4 +179,7 @@
 {
 test_reference_extension();
 }
+{
+static_assert(test_constexpr(), "");
+}
 }
Index: include/optional
===
--- include/optional
+++ include/optional
@@ -436,46 +436,122 @@
 }
 };
 
-template ::value>
-struct __optional_storage;
-
-template 
-struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
+template ::value>
+struct __optional_copy_base : __optional_storage_base<_Tp>
 {
 using __optional_storage_base<_Tp>::__optional_storage_base;
 };
 
 template 
-struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
+struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
 {
-using value_type = _Tp;
 using __optional_storage_base<_Tp>::__optional_storage_base;
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage() = default;
+__optional_copy_base() = default;
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage(const __optional_storage& __opt)
+__optional_copy_base(const __optional_copy_base& __opt)
 {
 this->__construct_from(__opt);
 }
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage(__optional_storage&& __opt)
+__optional_copy_base(__optional_copy_base&&) = default;
+_LIBCPP_INLINE_VISIBILITY
+__optional_copy_base& operator=(const __optional_copy_base&) = default;
+_LIBCPP_INLINE_VISIBILITY
+__optional_copy_base& operator=(__optional_copy_base&&) = default;
+};
+
+template ::value>
+struct __optional_move_base : __optional_copy_base<_Tp>
+{
+using __optional_copy_base<_Tp>::__optional_copy_base;
+};
+
+template 
+struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
+{
+using value_type = _Tp;
+using __optional_copy_base<_Tp>::__optional_copy_base;
+
+_LIBCPP_INLINE_VISIBILITY
+__optional_move_base() = default;
+_LIBCPP_INLINE_VISIBILITY
+__optional_move_base(const __optional_move_base&) = default;

[PATCH] D32385: [libcxx] Implement LWG 2900 "The copy and move constructors of optional are not constexpr"

2017-04-21 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

.. by injecting base classes that differentiate between trivial/non-trivial 
implementation of each copy/move constructor/assignment. This actually goes a 
bit beyond the PR by also making the copy/move assignment operators trivial 
when the base type has corresponding trivial construction and assignment.


https://reviews.llvm.org/D32385

Files:
  include/optional
  test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
  test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp

Index: test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -10,7 +10,10 @@
 // UNSUPPORTED: c++98, c++03, c++11, c++14
 // 
 
-// optional(optional&& rhs);
+// constexpr optional(const optional&& rhs);
+//   If is_trivially_move_constructible_v is true,
+//this constructor shall be a constexpr constructor.
+
 
 #include 
 #include 
@@ -131,6 +134,31 @@
 #endif
 }
 
+constexpr bool test_constexpr()
+{
+{
+using T = int;
+optional o1{};
+optional o2 = std::move(o1);
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = std::move(o3);
+static_cast(o4);
+}
+{
+struct T {
+constexpr T(int) {}
+T(T&&) = default;
+};
+optional o1{};
+optional o2 = std::move(o1);
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = std::move(o3);
+static_cast(o4);
+}
+return true;
+}
 
 int main()
 {
@@ -198,4 +226,7 @@
 {
 test_reference_extension();
 }
+{
+static_assert(test_constexpr(), "");
+}
 }
Index: test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -10,7 +10,9 @@
 // UNSUPPORTED: c++98, c++03, c++11, c++14
 // 
 
-// optional(const optional& rhs);
+// constexpr optional(const optional& rhs);
+//   If is_trivially_copy_constructible_v is true,
+//this constructor shall be a constexpr constructor.
 
 #include 
 #include 
@@ -104,6 +106,31 @@
 #endif
 }
 
+constexpr bool test_constexpr()
+{
+{
+using T = int;
+optional o1{};
+optional o2 = o1;
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = o3;
+static_cast(o4);
+}
+{
+struct T {
+constexpr T(int) {}
+};
+optional o1{};
+optional o2 = o1;
+static_cast(o2);
+optional o3{T{42}};
+optional o4 = o3;
+static_cast(o4);
+}
+return true;
+}
+
 int main()
 {
 test();
@@ -152,4 +179,7 @@
 {
 test_reference_extension();
 }
+{
+static_assert(test_constexpr(), "");
+}
 }
Index: include/optional
===
--- include/optional
+++ include/optional
@@ -436,46 +436,118 @@
 }
 };
 
-template ::value>
-struct __optional_storage;
-
-template 
-struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
+template ::value>
+struct __optional_copy_base : __optional_storage_base<_Tp>
 {
 using __optional_storage_base<_Tp>::__optional_storage_base;
 };
 
 template 
-struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
+struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
 {
-using value_type = _Tp;
 using __optional_storage_base<_Tp>::__optional_storage_base;
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage() = default;
+__optional_copy_base() = default;
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage(const __optional_storage& __opt)
+__optional_copy_base(const __optional_copy_base& __opt)
 {
 this->__construct_from(__opt);
 }
 
 _LIBCPP_INLINE_VISIBILITY
-__optional_storage(__optional_storage&& __opt)
+__optional_copy_base(__optional_copy_base&&) = default;
+_LIBCPP_INLINE_VISIBILITY
+__optional_copy_base& operator=(const __optional_copy_base&) = default;
+_LIBCPP_INLINE_VISIBILITY
+__optional_copy_base& operator=(__optional_copy_base&&) = default;
+};
+
+template ::value>
+struct __optional_move_base : __optional_copy_base<_Tp>
+{
+using __optional_copy_base<_Tp>::__optional_copy_base;
+};
+
+template 
+struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
+{
+using value_type = _Tp;
+using __optional_copy_base<_Tp>::__optional_copy_base;
+
+_LIBCPP_INLINE_VISIBILITY
+__optional_move_base() = default;
+

[PATCH] D32106: [libcxx][test] Expand LWG2857 coverage

2017-04-21 Thread Casey Carter via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL301055: Expand test coverage for LWG2857 (authored by 
CaseyCarter).

Changed prior to commit:
  https://reviews.llvm.org/D32106?vs=95368=96260#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32106

Files:
  libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
  
libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
  
libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp

Index: libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
===
--- libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
+++ libcxx/trunk/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -44,7 +44,7 @@
 
 auto  = a.emplace();
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -60,7 +60,7 @@
 
 auto  = a.emplace(101);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -76,7 +76,7 @@
 
 auto  = a.emplace(-1, 42, -1);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -97,7 +97,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace();
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -107,7 +107,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace(-1, 42, -1);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -118,7 +118,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace({-1, 42, -1});
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -129,7 +129,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace({-1, 42, -1}, x);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -159,7 +159,8 @@
 std::any a(small{42});
 assert(small::count == 1);
 try {
-a.emplace(101);
+auto  = a.emplace(101);
+static_assert( std::is_same_v, "" );
 assert(false);
 } catch (int const&) {
 }
@@ -169,7 +170,8 @@
 std::any a(small{42});
 assert(small::count == 1);
 try {
-a.emplace({1, 2, 3}, 101);
+auto  = a.emplace({1, 2, 3}, 101);
+static_assert( std::is_same_v, "" );
 assert(false);
 } catch (int const&) {
 }
@@ -180,7 +182,8 @@
 std::any a(large{42});
 assert(large::count == 1);
 try {
-a.emplace(101);
+auto  = a.emplace(101);
+static_assert( std::is_same_v, "" );
 assert(false);
 } catch (int const&) {
 }
@@ -190,7 +193,8 @@
 std::any a(large{42});
 assert(large::count == 1);
 try {
-a.emplace({1, 2, 3}, 101);
+auto  = a.emplace({1, 2, 3}, 101);
+static_assert( std::is_same_v, "" );
 assert(false);
 } catch (int const&) {
 }
Index: libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
===
--- libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
+++ libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
@@ -254,7 +254,9 @@
 {
 assert(static_cast(opt) == true);
 assert(Y::dtor_called == false);
-opt.emplace(1);
+auto  = opt.emplace(1);
+static_assert( std::is_same_v, "" );
+assert(false);
 }
 catch (int i)
 {
Index: 

[PATCH] D32107: [libc++][test] LWG2857 test coverage for variant

2017-04-14 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter added a comment.

In https://reviews.llvm.org/D32107#727751, @EricWF wrote:

> Give me a day to implement this in variant and then this should be ready to 
> land.


No rush; the patch isn't going anywhere ;)


https://reviews.llvm.org/D32107



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32107: [libc++][test] LWG2857 test coverage for variant

2017-04-14 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

As the saying goes, "works on my machine."

NOTE: libc++ variant does not yet implement LWG2857 and will not pass these 
tests; MSVC variant does.

Changes under `TEST_VARIANT_HAS_NO_REFERENCES` are dry-coded; I figure that's 
better than nothing.


https://reviews.llvm.org/D32107

Files:
  
test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
  
test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
  
test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
  
test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
@@ -15,7 +15,7 @@
 // template  class variant;
 
 // template 
-// void emplace(initializer_list il,Args&&... args);
+//   T& emplace(initializer_list il,Args&&... args);
 
 #include 
 #include 
@@ -70,13 +70,19 @@
 void test_basic() {
   using V = std::variant;
   V v;
-  v.emplace({1, 2, 3});
+  auto& ref1 = v.emplace({1, 2, 3});
+  static_assert(std::is_same_v, "");
   assert(std::get(v).size == 3);
-  v.emplace({1, 2, 3, 4}, 42);
+  assert( == ::get(v));
+  auto& ref2 = v.emplace({1, 2, 3, 4}, 42);
+  static_assert(std::is_same_v, "");
   assert(std::get(v).size == 4);
   assert(std::get(v).value == 42);
-  v.emplace({1});
+  assert( == ::get(v));
+  auto& ref3 = v.emplace({1});
+  static_assert(std::is_same_v, "");
   assert(std::get(v).size == 1);
+  assert( == ::get(v));
 }
 
 int main() {
Index: test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
@@ -14,7 +14,7 @@
 
 // template  class variant;
 
-// template  void emplace(Args&&... args);
+// template  T& emplace(Args&&... args);
 
 #include 
 #include 
@@ -86,24 +86,34 @@
   {
 using V = std::variant;
 V v(42);
-v.emplace();
+auto& ref1 = v.emplace();
+static_assert(std::is_same_v, "");
 assert(std::get<0>(v) == 0);
-v.emplace(42);
+assert( == ::get<0>(v));
+auto& ref2 = v.emplace(42);
+static_assert(std::is_same_v, "");
 assert(std::get<0>(v) == 42);
+assert( == ::get<0>(v));
   }
   {
 using V =
 std::variant;
 const int x = 100;
 V v(std::in_place_type, -1);
 // default emplace a value
-v.emplace();
+auto& ref1 = v.emplace();
+static_assert(std::is_same_v, "");
 assert(std::get<1>(v) == 0);
-v.emplace();
+assert( == ::get<1>(v));
+auto& ref2 = v.emplace();
+static_assert(std::is_same_v, "");
 assert(std::get<2>(v) == );
+assert( == ::get<2>(v));
 // emplace with multiple args
-v.emplace(3, 'a');
+auto& ref3 = v.emplace(3, 'a');
+static_assert(std::is_same_v, "");
 assert(std::get<4>(v) == "aaa");
+assert( == ::get<4>(v));
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
@@ -114,20 +124,30 @@
 int z = 43;
 V v(std::in_place_index<0>, -1);
 // default emplace a value
-v.emplace();
+auto& ref1 = v.emplace();
+static_assert(std::is_same_v, "");
 assert(std::get(v) == 0);
+assert( == ::get(v));
 // emplace a reference
-v.emplace(x);
+auto& ref2 = v.emplace(x);
+static_assert(std::is_same_v, "");
 assert(::get(v) == );
+assert( == ::get(v));
 // emplace an rvalue reference
-v.emplace(std::move(y));
+auto& ref3 = v.emplace(std::move(y));
+static_assert(std::is_same_v, "");
 assert(::get(v) == );
+assert( == ::get(v));
 // re-emplace a new reference over the active member
-v.emplace(std::move(z));
+auto& ref4 = v.emplace(std::move(z));
+static_assert(std::is_same_v, "");
 assert(::get(v) == );
+assert( == ::get(v));
 // emplace with multiple args
-v.emplace(3, 'a');
+auto& ref5 = v.emplace(3, 'a');
+static_assert(std::is_same_v, "");
 assert(std::get(v) == "aaa");
+assert( == ::get(v));
   }
 #endif
 }
Index: test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp

[PATCH] D32106: [libcxx][test] Expand LWG2857 coverage

2017-04-14 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

- Cover `optional`'s emplace-from-`initializer_list` overload
- Verify that `any::emplace` and `optional::emplace` return a reference to the 
correct type even for throwing cases


https://reviews.llvm.org/D32106

Files:
  test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
  
test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
  
test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp

Index: test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp
@@ -11,7 +11,7 @@
 // 
 
 // template 
-//   void optional::emplace(initializer_list il, Args&&... args);
+//   T& optional::emplace(initializer_list il, Args&&... args);
 
 #include 
 #include 
@@ -76,21 +76,27 @@
 X x;
 optional opt(x);
 assert(X::dtor_called == false);
-opt.emplace({1, 2});
+auto  = opt.emplace({1, 2});
+static_assert( std::is_same_v, "" );
 assert(X::dtor_called == true);
 assert(*opt == X({1, 2}));
+assert( == &*opt);
 }
 {
 optional opt;
-opt.emplace({1, 2, 3}, std::allocator());
+auto  = opt.emplace({1, 2, 3}, std::allocator());
+static_assert( std::is_same_v, "" );
 assert(static_cast(opt) == true);
 assert(*opt == std::vector({1, 2, 3}));
+assert( == &*opt);
 }
 {
 optional opt;
-opt.emplace({1, 2});
+auto  = opt.emplace({1, 2});
+static_assert( std::is_same_v, "" );
 assert(static_cast(opt) == true);
 assert(*opt == Y({1, 2}));
+assert( == &*opt);
 }
 #ifndef TEST_HAS_NO_EXCEPTIONS
 {
@@ -100,7 +106,9 @@
 {
 assert(static_cast(opt) == true);
 assert(Z::dtor_called == false);
-opt.emplace({1, 2});
+auto  = opt.emplace({1, 2});
+static_assert( std::is_same_v, "" );
+assert(false);
 }
 catch (int i)
 {
Index: test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
===
--- test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
+++ test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
@@ -254,7 +254,9 @@
 {
 assert(static_cast(opt) == true);
 assert(Y::dtor_called == false);
-opt.emplace(1);
+auto  = opt.emplace(1);
+static_assert( std::is_same_v, "" );
+assert(false);
 }
 catch (int i)
 {
Index: test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
===
--- test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
+++ test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -44,7 +44,7 @@
 
 auto  = a.emplace();
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -60,7 +60,7 @@
 
 auto  = a.emplace(101);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -76,7 +76,7 @@
 
 auto  = a.emplace(-1, 42, -1);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assert(Type::count == 1);
@@ -97,7 +97,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace();
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -107,7 +107,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace(-1, 42, -1);
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+assert( == std::any_cast());
 
 assert(Tracked::count == 0);
 assertArgsMatch(a);
@@ -118,7 +118,7 @@
 assert(Tracked::count == 1);
 auto  = a.emplace({-1, 42, -1});
 static_assert( std::is_same_v, "" );
-		assert( == std::any_cast());
+ 

[PATCH] D31260: [libc++] Work around C1XX bug which breaks poisoned hash tests.

2017-03-22 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter added a comment.

I also have no problem with this change.




Comment at: test/support/poisoned_hash_helper.hpp:53
 using LibraryHashTypes = TypeList<
+#if !defined(TEST_WORKAROUND_C1XX_BROKEN_NULLPTR_CONVERSION_OPERATOR)
 #if TEST_STD_VER > 14

I would merge these conditionals since they have identical extent. YMMV ;)



Comment at: 
test/support/test.workarounds/c1xx_broken_nullptr_conversion_operator.pass.cpp:16
+
+#include 
+

IIRC, including "" headers before <> headers is not conventional for the test 
suite.


https://reviews.llvm.org/D31260



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27436: [libcxx] [test] std::get<0>([std::variant constant expression]) *is* noexcept

2016-12-05 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter updated this revision to Diff 80365.
CaseyCarter added a comment.

Address review comments:

- Annotate the clang bug which the conditional compilation is avoiding.
- Assure the expression in question is not noexcept when not a constant 
expression.
- Cover get_type


https://reviews.llvm.org/D27436

Files:
  test/std/utilities/variant/variant.get/get_index.pass.cpp
  test/std/utilities/variant/variant.get/get_type.pass.cpp


Index: test/std/utilities/variant/variant.get/get_type.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_type.pass.cpp
+++ test/std/utilities/variant/variant.get/get_type.pass.cpp
@@ -30,16 +30,35 @@
   {
 using V = std::variant;
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get(v));
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
 static_assert(std::get(v) == 42, "");
   }
   {
 using V = std::variant;
+const V v(42);
+ASSERT_NOT_NOEXCEPT(std::get(v));
+ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+assert(std::get(v) == 42);
+  }
+  {
+using V = std::variant;
 constexpr V v(42l);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get(v)), const long &);
 static_assert(std::get(v) == 42, "");
   }
+  {
+using V = std::variant;
+const V v(42l);
+ASSERT_NOT_NOEXCEPT(std::get(v));
+ASSERT_SAME_TYPE(decltype(std::get(v)), const long &);
+assert(std::get(v) == 42);
+  }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
Index: test/std/utilities/variant/variant.get/get_index.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_index.pass.cpp
+++ test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -36,16 +36,35 @@
   {
 using V = std::variant;
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get<0>(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
 static_assert(std::get<0>(v) == 42, "");
   }
   {
 using V = std::variant;
+const V v(42);
+ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+assert(std::get<0>(v) == 42);
+  }
+  {
+using V = std::variant;
 constexpr V v(42l);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get<1>(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+using V = std::variant;
+const V v(42l);
+ASSERT_NOT_NOEXCEPT(std::get<1>(v));
+ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
+assert(std::get<1>(v) == 42);
+  }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {


Index: test/std/utilities/variant/variant.get/get_type.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_type.pass.cpp
+++ test/std/utilities/variant/variant.get/get_type.pass.cpp
@@ -30,16 +30,35 @@
   {
 using V = std::variant;
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get(v));
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
 static_assert(std::get(v) == 42, "");
   }
   {
 using V = std::variant;
+const V v(42);
+ASSERT_NOT_NOEXCEPT(std::get(v));
+ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+assert(std::get(v) == 42);
+  }
+  {
+using V = std::variant;
 constexpr V v(42l);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ASSERT_NOEXCEPT(std::get(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get(v)), const long &);
 static_assert(std::get(v) == 42, "");
   }
+  {
+using V = std::variant;
+const V v(42l);
+ASSERT_NOT_NOEXCEPT(std::get(v));
+ASSERT_SAME_TYPE(decltype(std::get(v)), const long &);
+assert(std::get(v) == 42);
+  }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
Index: test/std/utilities/variant/variant.get/get_index.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_index.pass.cpp

[PATCH] D27436: [libcxx] [test] std::get<0>([std::variant constant expression]) *is* noexcept

2016-12-05 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter added inline comments.



Comment at: test/std/utilities/variant/variant.get/get_index.pass.cpp:39
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+#ifndef __clang__
+ASSERT_NOEXCEPT(std::get<0>(v));

THAT'S RIGHT, A CLANG BUG (https://llvm.org/bugs/show_bug.cgi?id=15481) THAT 
C1XX GETS CORRECT. You saw it here first.


https://reviews.llvm.org/D27436



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27436: [libcxx] [test] std::get<0>([std::variant constant expression]) *is* noexcept

2016-12-05 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.
CaseyCarter added reviewers: EricWF, mclow.lists.
CaseyCarter added a subscriber: cfe-commits.

noexcept(foo) is true when foo is a constant expression.


https://reviews.llvm.org/D27436

Files:
  test/std/utilities/variant/variant.get/get_index.pass.cpp


Index: test/std/utilities/variant/variant.get/get_index.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_index.pass.cpp
+++ test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -36,7 +36,9 @@
   {
 using V = std::variant;
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+#ifndef __clang__
+ASSERT_NOEXCEPT(std::get<0>(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
 static_assert(std::get<0>(v) == 42, "");
   }


Index: test/std/utilities/variant/variant.get/get_index.pass.cpp
===
--- test/std/utilities/variant/variant.get/get_index.pass.cpp
+++ test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -36,7 +36,9 @@
   {
 using V = std::variant;
 constexpr V v(42);
-ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+#ifndef __clang__
+ASSERT_NOEXCEPT(std::get<0>(v));
+#endif
 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
 static_assert(std::get<0>(v) == 42, "");
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


<    1   2