aboutsummaryrefslogtreecommitdiff
path: root/test/std
diff options
context:
space:
mode:
Diffstat (limited to 'test/std')
-rw-r--r--test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp14
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp18
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp25
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp21
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp18
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp26
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp19
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp17
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp28
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp17
-rw-r--r--test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp17
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp18
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp63
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp67
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp138
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp39
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp6
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp6
-rw-r--r--test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp4
19 files changed, 521 insertions, 40 deletions
diff --git a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp b/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
index 1f27b45e8ab8..df77be9643db 100644
--- a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
+++ b/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
@@ -11,13 +11,27 @@
// pointer_safety get_pointer_safety();
+// UNSUPPORTED: c++98, c++03
+
#include <memory>
#include <cassert>
+
+void test_pr26961() {
+ std::pointer_safety d;
+ d = std::get_pointer_safety();
+ assert(d == std::get_pointer_safety());
+}
+
int main()
{
+ {
std::pointer_safety r = std::get_pointer_safety();
assert(r == std::pointer_safety::relaxed ||
r == std::pointer_safety::preferred ||
r == std::pointer_safety::strict);
+ }
+ {
+ test_pr26961();
+ }
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp
index 8a8f4b1c0d9b..702c38d2d4a9 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp
@@ -11,15 +11,31 @@
// duration
-// duration& operator++();
+// constexpr duration& operator++(); // constexpr in c++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::hours h(3);
+ return (++h).count() == 4;
+}
+#endif
+
int main()
{
+ {
std::chrono::hours h(3);
std::chrono::hours& href = ++h;
assert(&href == &h);
assert(h.count() == 4);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp
index cf5028281007..49b8c76ee8ee 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp
@@ -11,15 +11,32 @@
// duration
-// duration operator++(int);
+// constexpr duration operator++(int); // constexpr in c++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::hours h1(3);
+ std::chrono::hours h2 = h1++;
+ return h1.count() == 4 && h2.count() == 3;
+}
+#endif
+
int main()
{
- std::chrono::hours h(3);
- std::chrono::hours h2 = h++;
- assert(h.count() == 4);
+ {
+ std::chrono::hours h1(3);
+ std::chrono::hours h2 = h1++;
+ assert(h1.count() == 4);
assert(h2.count() == 3);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp
index 8d8cf4539c16..bec8effbe220 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp
@@ -11,16 +11,35 @@
// duration
-// duration& operator+=(const duration& d);
+// constexpr duration& operator+=(const duration& d); // constexpr in c++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::seconds s(3);
+ s += std::chrono::seconds(2);
+ if (s.count() != 5) return false;
+ s += std::chrono::minutes(2);
+ return s.count() == 125;
+}
+#endif
+
int main()
{
+ {
std::chrono::seconds s(3);
s += std::chrono::seconds(2);
assert(s.count() == 5);
s += std::chrono::minutes(2);
assert(s.count() == 125);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp
index 0aadfbcd5991..98b22a7b18bd 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp
@@ -11,15 +11,31 @@
// duration
-// duration& operator--();
+// constexpr duration& operator--(); // constexpr in C++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::hours h(3);
+ return (--h).count() == 2;
+}
+#endif
+
int main()
{
+ {
std::chrono::hours h(3);
std::chrono::hours& href = --h;
assert(&href == &h);
assert(h.count() == 2);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp
index 7fc6a1df603f..a908c44dda85 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp
@@ -11,15 +11,33 @@
// duration
-// duration operator--(int);
+// constexpr duration operator--(int); // constexpr in C++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::hours h1(3);
+ std::chrono::hours h2 = h1--;
+ return h1.count() == 2 && h2.count() == 3;
+}
+#endif
+
+
int main()
{
- std::chrono::hours h(3);
- std::chrono::hours h2 = h--;
- assert(h.count() == 2);
+ {
+ std::chrono::hours h1(3);
+ std::chrono::hours h2 = h1--;
+ assert(h1.count() == 2);
assert(h2.count() == 3);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp
index a0a7aed202b1..185db177882e 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp
@@ -16,11 +16,30 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::seconds s(3);
+ s -= std::chrono::seconds(2);
+ if (s.count() != 1) return false;
+ s -= std::chrono::minutes(2);
+ return s.count() == -119;
+}
+#endif
+
int main()
{
+ {
std::chrono::seconds s(3);
s -= std::chrono::seconds(2);
assert(s.count() == 1);
s -= std::chrono::minutes(2);
assert(s.count() == -119);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp
index 09786bcd8cf8..4ae774b6c1f1 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp
@@ -16,9 +16,26 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::seconds s(15);
+ s /= 5;
+ return s.count() == 3;
+}
+#endif
+
int main()
{
+ {
std::chrono::nanoseconds ns(15);
ns /= 5;
assert(ns.count() == 3);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp
index 8a4a2b472324..624468671244 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp
@@ -16,12 +16,30 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::microseconds us1(11);
+ std::chrono::microseconds us2(3);
+ us1 %= us2;
+ return us1.count() == 2;
+}
+#endif
+
int main()
{
- std::chrono::microseconds us(11);
+ {
+ std::chrono::microseconds us1(11);
std::chrono::microseconds us2(3);
- us %= us2;
- assert(us.count() == 2);
- us %= std::chrono::milliseconds(3);
- assert(us.count() == 2);
+ us1 %= us2;
+ assert(us1.count() == 2);
+ us1 %= std::chrono::milliseconds(3);
+ assert(us1.count() == 2);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp
index 8758e17ba6af..a4852d261f7e 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp
@@ -16,9 +16,26 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::seconds s(11);
+ s %= 3;
+ return s.count() == 2;
+}
+#endif
+
int main()
{
+ {
std::chrono::microseconds us(11);
us %= 3;
assert(us.count() == 2);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp
index b97534a3615a..0f76788c00ef 100644
--- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp
@@ -16,9 +16,26 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool test_constexpr()
+{
+ std::chrono::seconds s(3);
+ s *= 5;
+ return s.count() == 15;
+}
+#endif
+
int main()
{
+ {
std::chrono::nanoseconds ns(3);
ns *= 5;
assert(ns.count() == 15);
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(test_constexpr(), "");
+#endif
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
index 3e4145c79cb5..49b4215a1956 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
@@ -20,13 +20,6 @@
#include <tuple>
#include <type_traits>
-template <class T, class = decltype(std::tuple_size<T>::value)>
-constexpr bool has_value(int) { return true; }
-template <class> constexpr bool has_value(long) { return false; }
-template <class T> constexpr bool has_value() { return has_value<T>(0); }
-
-struct Dummy {};
-
template <class T, std::size_t N>
void test()
{
@@ -40,21 +33,10 @@ void test()
std::tuple_size<const volatile T> >::value), "");
}
-void test_tuple_size_value_sfinae() {
- // Test that the ::value member does not exist
- static_assert(has_value<std::tuple<int> const>(), "");
- static_assert(has_value<std::pair<int, long> volatile>(), "");
- static_assert(!has_value<int>(), "");
- static_assert(!has_value<const int>(), "");
- static_assert(!has_value<volatile void>(), "");
- static_assert(!has_value<const volatile std::tuple<int>&>(), "");
-}
-
int main()
{
test<std::tuple<>, 0>();
test<std::tuple<int>, 1>();
test<std::tuple<char, int>, 2>();
test<std::tuple<char, char*, int>, 3>();
- test_tuple_size_value_sfinae();
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp
new file mode 100644
index 000000000000..818001833995
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class... Types>
+// class tuple_size<tuple<Types...>>
+// : public integral_constant<size_t, sizeof...(Types)> { };
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <array>
+#include <type_traits>
+
+struct Dummy1 {};
+struct Dummy2 {};
+struct Dummy3 {};
+
+template <>
+class std::tuple_size<Dummy1> {
+public:
+ static size_t value;
+};
+
+template <>
+class std::tuple_size<Dummy2> {
+public:
+ static void value() {}
+};
+
+template <>
+class std::tuple_size<Dummy3> {};
+
+int main()
+{
+ // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value
+ // is well-formed but not a constant expression.
+ {
+ // expected-error@__tuple:* 1 {{is not a constant expression}}
+ (void)std::tuple_size<const Dummy1>::value; // expected-note {{here}}
+ }
+ // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value
+ // is well-formed but not convertible to size_t.
+ {
+ // expected-error@__tuple:* 1 {{value of type 'void ()' is not implicitly convertible to}}
+ (void)std::tuple_size<const Dummy2>::value; // expected-note {{here}}
+ }
+ // Test that tuple_size<const T> generates an error when tuple_size<T> is
+ // complete but ::value isn't a constant expression convertible to size_t.
+ {
+ // expected-error@__tuple:* 1 {{no member named 'value'}}
+ (void)std::tuple_size<const Dummy3>::value; // expected-note {{here}}
+ }
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp
new file mode 100644
index 000000000000..ccdd48e4c11d
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class... Types>
+// class tuple_size<tuple<Types...>>
+// : public integral_constant<size_t, sizeof...(Types)> { };
+
+// XFAIL: gcc-4.9
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <array>
+#include <type_traits>
+
+template <class T, size_t Size = sizeof(std::tuple_size<T>)>
+constexpr bool is_complete(int) { static_assert(Size > 0, ""); return true; }
+template <class> constexpr bool is_complete(long) { return false; }
+template <class T> constexpr bool is_complete() { return is_complete<T>(0); }
+
+struct Dummy1 {};
+struct Dummy2 {};
+
+namespace std {
+template <> class tuple_size<Dummy1> : public integral_constant<size_t, 0> {};
+}
+
+template <class T>
+void test_complete() {
+ static_assert(is_complete<T>(), "");
+ static_assert(is_complete<const T>(), "");
+ static_assert(is_complete<volatile T>(), "");
+ static_assert(is_complete<const volatile T>(), "");
+}
+
+template <class T>
+void test_incomplete() {
+ static_assert(!is_complete<T>(), "");
+ static_assert(!is_complete<const T>(), "");
+ static_assert(!is_complete<volatile T>(), "");
+ static_assert(!is_complete<const volatile T>(), "");
+}
+
+
+int main()
+{
+ test_complete<std::tuple<> >();
+ test_complete<std::tuple<int&> >();
+ test_complete<std::tuple<int&&, int&, void*>>();
+ test_complete<std::pair<int, long> >();
+ test_complete<std::array<int, 5> >();
+ test_complete<Dummy1>();
+
+ test_incomplete<void>();
+ test_incomplete<int>();
+ test_incomplete<std::tuple<int>&>();
+ test_incomplete<Dummy2>();
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp
new file mode 100644
index 000000000000..aadbf3d5a369
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class... Types>
+// class tuple_size<tuple<Types...>>
+// : public integral_constant<size_t, sizeof...(Types)> { };
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-structured-bindings
+
+#include <tuple>
+#include <array>
+#include <type_traits>
+#include <cassert>
+
+struct S { int x; };
+
+void test_decomp_user_type() {
+ {
+ S s{99};
+ auto [m1] = s;
+ auto& [r1] = s;
+ assert(m1 == 99);
+ assert(&r1 == &s.x);
+ }
+ {
+ S const s{99};
+ auto [m1] = s;
+ auto& [r1] = s;
+ assert(m1 == 99);
+ assert(&r1 == &s.x);
+ }
+}
+
+void test_decomp_tuple() {
+ typedef std::tuple<int> T;
+ {
+ T s{99};
+ auto [m1] = s;
+ auto& [r1] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+ {
+ T const s{99};
+ auto [m1] = s;
+ auto& [r1] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+}
+
+
+void test_decomp_pair() {
+ typedef std::pair<int, double> T;
+ {
+ T s{99, 42.1};
+ auto [m1, m2] = s;
+ auto& [r1, r2] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+ {
+ T const s{99, 42.1};
+ auto [m1, m2] = s;
+ auto& [r1, r2] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+}
+
+void test_decomp_array() {
+ typedef std::array<int, 3> T;
+ {
+ T s{{99, 42, -1}};
+ auto [m1, m2, m3] = s;
+ auto& [r1, r2, r3] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+ {
+ T const s{{99, 42, -1}};
+ auto [m1, m2, m3] = s;
+ auto& [r1, r2, r3] = s;
+ assert(m1 == 99);
+ assert(&r1 == &std::get<0>(s));
+ }
+}
+
+struct Test {
+ int x;
+};
+
+template <size_t N>
+int get(Test const&) { static_assert(N == 0, ""); return -1; }
+
+template <>
+class std::tuple_element<0, Test> {
+public:
+ typedef int type;
+};
+
+void test_before_tuple_size_specialization() {
+ Test const t{99};
+ auto& [p] = t;
+ assert(p == 99);
+}
+
+template <>
+class std::tuple_size<Test> {
+public:
+ static const size_t value = 1;
+};
+
+void test_after_tuple_size_specialization() {
+ Test const t{99};
+ auto& [p] = t;
+ assert(p == -1);
+}
+
+int main() {
+ test_decomp_user_type();
+ test_decomp_tuple();
+ test_decomp_pair();
+ test_decomp_array();
+ test_before_tuple_size_specialization();
+ test_after_tuple_size_specialization();
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp
new file mode 100644
index 000000000000..31ebe5878379
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class... Types>
+// class tuple_size<tuple<Types...>>
+// : public integral_constant<size_t, sizeof...(Types)> { };
+
+// XFAIL: gcc-4.9
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <type_traits>
+
+template <class T, class = decltype(std::tuple_size<T>::value)>
+constexpr bool has_value(int) { return true; }
+template <class> constexpr bool has_value(long) { return false; }
+template <class T> constexpr bool has_value() { return has_value<T>(0); }
+
+struct Dummy {};
+
+int main() {
+ // Test that the ::value member does not exist
+ static_assert(has_value<std::tuple<int> const>(), "");
+ static_assert(has_value<std::pair<int, long> volatile>(), "");
+ static_assert(!has_value<int>(), "");
+ static_assert(!has_value<const int>(), "");
+ static_assert(!has_value<volatile void>(), "");
+ static_assert(!has_value<const volatile std::tuple<int>&>(), "");
+}
diff --git a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
index 4b30188ce6ff..6675b5f2b2ba 100644
--- a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
@@ -10,8 +10,10 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// Clang 3.8 doesn't allow constexpr variables of non-literal type
-// XFAIL: clang-3.8, apple-clang-7, apple-clang-8
+// The following compilers don't allow constexpr variables of non-literal type.
+// XFAIL: gcc-5, gcc-6
+// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
+// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
index 8546beb1319c..a0c57e132403 100644
--- a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
@@ -10,8 +10,10 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// Clang 3.8 doesn't allow constexpr variables of non-literal type
-// XFAIL: clang-3.8, apple-clang-7, apple-clang-8
+// The following compilers don't allow constexpr variables of non-literal type.
+// XFAIL: gcc-5, gcc-6
+// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
+// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
index 416c6b4e334d..48cda222083f 100644
--- a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -489,7 +489,7 @@ void test_swap_sfinae() {
// but is still swappable via the generic swap algorithm, since the
// variant is move constructible and move assignable.
using V = std::variant<int, NotSwappable>;
- LIBCPP_STATIC_ASSERT(!has_swap_member<V>());
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), "");
static_assert(std::is_swappable_v<V>, "");
}
{
@@ -569,7 +569,7 @@ void test_swap_noexcept() {
// but is still swappable via the generic swap algorithm, since the
// variant is move constructible and move assignable.
using V = std::variant<int, NotSwappable>;
- LIBCPP_STATIC_ASSERT(!has_swap_member<V>());
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), "");
static_assert(std::is_swappable_v<V>, "");
static_assert(std::is_nothrow_swappable_v<V>, "");
V v1, v2;