From 50253ed1c67b75c71c8ec2d24ed915c032b11822 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sun, 16 Oct 2016 02:51:50 +0000 Subject: [PATCH] Update issue status for LWG 2744 llvm-svn: 284322 --- libcxx/include/any | 7 ++--- libcxx/include/utility | 18 ++++++++--- .../utility.inplace/__is_inplace_tag.pass.cpp | 36 ++++++++++++++++++++++ .../utility.inplace/__is_inplace_type.pass.cpp | 27 ---------------- .../any/any.class/any.assign/copy.pass.cpp | 6 ++-- .../any/any.class/any.assign/value.pass.cpp | 6 ++-- .../any/any.class/any.cons/value.pass.cpp | 28 +++++++++++------ .../any/any.class/any.modifiers/reset.pass.cpp | 2 +- libcxx/test/support/any_helpers.h | 19 +++++++++--- libcxx/www/upcoming_meeting.html | 4 +-- 10 files changed, 93 insertions(+), 60 deletions(-) create mode 100644 libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_tag.pass.cpp delete mode 100644 libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_type.pass.cpp diff --git a/libcxx/include/any b/libcxx/include/any index 8fe9e8f..7f2cf1e 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -200,7 +200,7 @@ public: , class _Tp = decay_t<_ValueType> , class = enable_if_t< !is_same<_Tp, any>::value && - !__is_inplace_type<_ValueType>::value && + !__is_inplace_type_tag<_ValueType>::value && is_copy_constructible<_Tp>::value> > _LIBCPP_INLINE_VISIBILITY @@ -241,15 +241,12 @@ public: return *this; } - // TODO: Should this be constrained to disallow in_place types like the - // ValueType constructor? template < class _ValueType , class _Tp = decay_t<_ValueType> , class = enable_if_t< !is_same<_Tp, any>::value - && is_copy_constructible<_Tp>::value - && !__is_inplace_type<_ValueType>::value> + && is_copy_constructible<_Tp>::value> > _LIBCPP_INLINE_VISIBILITY any & operator=(_ValueType && __rhs); diff --git a/libcxx/include/utility b/libcxx/include/utility index cfab350..5e55506 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -928,10 +928,20 @@ inline in_place_tag in_place(__in_place_index_tag<_Nx>) { return in_place_tag(__in_place_tag{}); } -template struct __is_inplace_type : false_type {}; -template <> struct __is_inplace_type : true_type {}; -template struct __is_inplace_type> : true_type {}; -template struct __is_inplace_type> : true_type {}; +template struct __is_inplace_tag_imp : false_type {}; +template <> struct __is_inplace_tag_imp : true_type {}; +template struct __is_inplace_tag_imp)> : true_type {}; +template struct __is_inplace_tag_imp)> : true_type {}; + +template +using __is_inplace_tag = __is_inplace_tag_imp>>; + +template struct __is_inplace_type_tag_imp : false_type {}; +template struct __is_inplace_type_tag_imp)> : true_type {}; + +template +using __is_inplace_type_tag = __is_inplace_type_tag_imp>>; + #endif // _LIBCPP_STD_VER > 14 diff --git a/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_tag.pass.cpp b/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_tag.pass.cpp new file mode 100644 index 0000000..057bcf5 --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_tag.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// template +// struct __is_inplace_tag; + +#include +#include + +template > +void do_test() { + static_assert(std::__is_inplace_tag::value == Expect, ""); + static_assert(std::__is_inplace_tag::value == Expect, ""); + static_assert(std::__is_inplace_tag>::value == Expect, ""); + static_assert(std::__is_inplace_tag::value == Expect, ""); +} + +int main() { + do_test(); + do_test>(); + do_test>(); + do_test(); + do_test(); + do_test(); + do_test(); +} \ No newline at end of file diff --git a/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_type.pass.cpp b/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_type.pass.cpp deleted file mode 100644 index bfa4c33..0000000 --- a/libcxx/test/libcxx/utilities/utility/utility.inplace/__is_inplace_type.pass.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -// - -// template -// struct __is_inplace_type; - -#include -#include - -int main() { - static_assert(std::__is_inplace_type::value, ""); - static_assert(std::__is_inplace_type>::value, ""); - static_assert(std::__is_inplace_type(-1)>>::value, ""); - static_assert(!std::__is_inplace_type::value, ""); - static_assert(!std::__is_inplace_type::value, ""); - static_assert(!std::__is_inplace_type::value, ""); -} \ No newline at end of file diff --git a/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp index fc76a2d..eba9bc6 100644 --- a/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp +++ b/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp @@ -153,7 +153,7 @@ void test_copy_assign_throws() assert(Tp::count == 1); assertEmpty(lhs); - assertContains(rhs); + assertContains(rhs, 1); } { any lhs((small(2))); @@ -166,7 +166,7 @@ void test_copy_assign_throws() assert(small::count == 1); assert(Tp::count == 1); assertContains(lhs, 2); - assertContains(rhs); + assertContains(rhs, 1); } { any lhs((large(2))); @@ -179,7 +179,7 @@ void test_copy_assign_throws() assert(large::count == 1); assert(Tp::count == 1); assertContains(lhs, 2); - assertContains(rhs); + assertContains(rhs, 1); } #endif } diff --git a/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp index cb8dd4c..6af4817 100644 --- a/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp +++ b/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp @@ -172,15 +172,15 @@ void test_assign_throws() { // * std::in_place type. // * Non-copyable types void test_sfinae_constraints() { - { + { // Only the constructors are required to SFINAE on in_place_t using Tag = std::in_place_type_t; using RawTag = std::remove_reference_t; - static_assert(!std::is_assignable::value, ""); + static_assert(std::is_assignable::value, ""); } { struct Dummy { Dummy() = delete; }; using T = std::in_place_type_t; - static_assert(!std::is_assignable::value, ""); + static_assert(std::is_assignable::value, ""); } { // Test that the ValueType&& constructor SFINAE's away when the diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp index e39f139..24160dc 100644 --- a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp +++ b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp @@ -108,17 +108,12 @@ void test_copy_move_value() { // Test that any(ValueType&&) is *never* selected for a std::in_place type. void test_sfinae_constraints() { - using Tag = std::in_place_type_t; -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wignored-qualifiers" -#endif - static_assert(std::is_same::value, ""); -#if defined(__clang__) -#pragma clang diagnostic pop -#endif + using BadTag = std::in_place_type_t; + using OKTag = std::in_place_t; + using OKDecay = std::decay_t; // Test that the tag type is properly handled in SFINAE - Tag t = std::in_place; + BadTag t = std::in_place; + OKTag ot = std::in_place; { std::any a(t); assertContains(a, 0); @@ -128,11 +123,24 @@ void test_sfinae_constraints() { assertContains(a, 0); } { + std::any a(ot); + assertContains(a, ot); + } + { + OKDecay d = ot; + std::any a(d); + assertContains(a, ot); + } + { struct Dummy { Dummy() = delete; }; using T = std::in_place_type_t; static_assert(!std::is_constructible::value, ""); } { + using DecayTag = std::decay_t; + static_assert(!std::is_constructible::value, ""); + } + { // Test that the ValueType&& constructor SFINAE's away when the // argument is non-copyable struct NoCopy { diff --git a/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp index 31648a0..45bc70f 100644 --- a/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp +++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp @@ -53,7 +53,7 @@ int main() { any a(large(1)); assert(large::count == 1); - assertContains(a); + assertContains(a, 1); a.reset(); diff --git a/libcxx/test/support/any_helpers.h b/libcxx/test/support/any_helpers.h index ae332d5..a720ecd 100644 --- a/libcxx/test/support/any_helpers.h +++ b/libcxx/test/support/any_helpers.h @@ -59,21 +59,30 @@ void assertEmpty(std::any const& a) { assert(any_cast(&a) == nullptr); } +template +constexpr auto has_value_member(int) -> decltype(std::declval().value, true) +{ return true; } +template constexpr bool has_value_member(long) { return false; } + + // Assert that an 'any' object stores the specified 'Type' and 'value'. template -void assertContains(std::any const& a, int value = 1) { +std::enable_if_t(0)> +assertContains(std::any const& a, int value) { assert(a.has_value()); assert(containsType(a)); assert(std::any_cast(a).value == value); } -template <> -void assertContains(std::any const& a, int value) { +template +std::enable_if_t(0)> +assertContains(std::any const& a, Value value) { assert(a.has_value()); - assert(containsType(a)); - assert(std::any_cast(a) == value); + assert(containsType(a)); + assert(std::any_cast(a) == value); } + // Modify the value of a "test type" stored within an any to the specified // 'value'. template diff --git a/libcxx/www/upcoming_meeting.html b/libcxx/www/upcoming_meeting.html index ec447b1..36c9a74 100644 --- a/libcxx/www/upcoming_meeting.html +++ b/libcxx/www/upcoming_meeting.html @@ -111,7 +111,7 @@ 2739Issue with time_point non-member subtraction with an unsigned durationIssaquahPatch Ready 2740constexpr optional::operator->Issaquah 2742Inconsistent string interface taking string_viewIssaquahPatch Ready - 2744any's in_place constructorsIssaquah + 2744any's in_place constructorsIssaquahImplemented in trunk 2745[fund.ts.v2] Implementability of LWG 2451Issaquah 2747Possibly redundant std::move in [alg.foreach]IssaquahPatch ready 2748swappable traits for optionalsIssaquah @@ -189,7 +189,7 @@
  • 2739 - Patch and tests ready
  • 2740 - std::optional
  • 2742 - Patch and tests ready
  • -
  • 2744 - std::any
  • +
  • 2744 - std::any: We already do this. We also check for a decayed in_place_type_t.
  • 2745 - std::optional for LFTS -- should be considered for C++17
  • 2747 - Patch ready, but I can't think of any way to test it.
  • 2748 - std::optional
  • -- 2.7.4