]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp
Vendor import of libc++ release_39 branch r276489:
[FreeBSD/FreeBSD.git] / test / std / utilities / tuple / tuple.tuple / tuple.cnstr / PR23256_constrain_UTypes_ctor.pass.cpp
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // UNSUPPORTED: c++98, c++03
11
12 // <tuple>
13
14 // template <class... Types> class tuple;
15
16 // template <class ...UTypes>
17 //    EXPLICIT(...) tuple(UTypes&&...)
18
19 // Check that the UTypes... ctor is properly disabled before evaluating any
20 // SFINAE when the tuple-like copy/move ctor should *clearly* be selected
21 // instead. This happens 'sizeof...(UTypes) == 1' and the first element of
22 // 'UTypes...' is an instance of the tuple itself. See PR23256.
23
24 #include <tuple>
25 #include <memory>
26 #include <type_traits>
27
28
29 struct UnconstrainedCtor {
30   int value_;
31
32   UnconstrainedCtor() : value_(0) {}
33
34   // Blows up when instantiated for any type other than int. Because the ctor
35   // is constexpr it is instantiated by 'is_constructible' and 'is_convertible'
36   // for Clang based compilers. GCC does not instantiate the ctor body
37   // but it does instantiate the noexcept specifier and it will blow up there.
38   template <typename T>
39   constexpr UnconstrainedCtor(T value) noexcept(noexcept(value_ = value))
40       : value_(static_cast<int>(value))
41   {
42       static_assert(std::is_same<int, T>::value, "");
43   }
44 };
45
46 struct ExplicitUnconstrainedCtor {
47   int value_;
48
49   ExplicitUnconstrainedCtor() : value_(0) {}
50
51   template <typename T>
52   constexpr explicit ExplicitUnconstrainedCtor(T value)
53     noexcept(noexcept(value_ = value))
54       : value_(static_cast<int>(value))
55   {
56       static_assert(std::is_same<int, T>::value, "");
57   }
58
59 };
60
61 int main() {
62     typedef UnconstrainedCtor A;
63     typedef ExplicitUnconstrainedCtor ExplicitA;
64     {
65         static_assert(std::is_copy_constructible<std::tuple<A>>::value, "");
66         static_assert(std::is_move_constructible<std::tuple<A>>::value, "");
67         static_assert(std::is_copy_constructible<std::tuple<ExplicitA>>::value, "");
68         static_assert(std::is_move_constructible<std::tuple<ExplicitA>>::value, "");
69     }
70     {
71         static_assert(std::is_constructible<
72             std::tuple<A>,
73             std::allocator_arg_t, std::allocator<void>,
74             std::tuple<A> const&
75         >::value, "");
76         static_assert(std::is_constructible<
77             std::tuple<A>,
78             std::allocator_arg_t, std::allocator<void>,
79             std::tuple<A> &&
80         >::value, "");
81         static_assert(std::is_constructible<
82             std::tuple<ExplicitA>,
83             std::allocator_arg_t, std::allocator<void>,
84             std::tuple<ExplicitA> const&
85         >::value, "");
86         static_assert(std::is_constructible<
87             std::tuple<ExplicitA>,
88             std::allocator_arg_t, std::allocator<void>,
89             std::tuple<ExplicitA> &&
90         >::value, "");
91     }
92     {
93         std::tuple<A&&> t(std::forward_as_tuple(A{}));
94         std::tuple<ExplicitA&&> t2(std::forward_as_tuple(ExplicitA{}));
95     }
96 }