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, c++11, c++14
11
12 // XFAIL: with_system_cxx_lib=macosx10.12
13 // XFAIL: with_system_cxx_lib=macosx10.11
14 // XFAIL: with_system_cxx_lib=macosx10.10
15 // XFAIL: with_system_cxx_lib=macosx10.9
16 // XFAIL: with_system_cxx_lib=macosx10.7
17 // XFAIL: with_system_cxx_lib=macosx10.8
18
19 // <any>
20
21 // template <class Value> any(Value &&)
22
23 // Test construction from a value.
24 // Concerns:
25 // ---------
26 // 1. The value is properly move/copied depending on the value category.
27 // 2. Both small and large values are properly handled.
28
29
30 #include <any>
31 #include <cassert>
32
33 #include "any_helpers.h"
34 #include "count_new.hpp"
35 #include "test_macros.h"
36
37 using std::any;
38 using std::any_cast;
39
40 template <class Type>
test_copy_value_throws()41 void test_copy_value_throws()
42 {
43 #if !defined(TEST_HAS_NO_EXCEPTIONS)
44 assert(Type::count == 0);
45 {
46 Type const t(42);
47 assert(Type::count == 1);
48 try {
49 any const a2(t);
50 assert(false);
51 } catch (my_any_exception const &) {
52 // do nothing
53 } catch (...) {
54 assert(false);
55 }
56 assert(Type::count == 1);
57 assert(t.value == 42);
58 }
59 assert(Type::count == 0);
60 #endif
61 }
62
test_move_value_throws()63 void test_move_value_throws()
64 {
65 #if !defined(TEST_HAS_NO_EXCEPTIONS)
66 assert(throws_on_move::count == 0);
67 {
68 throws_on_move v;
69 assert(throws_on_move::count == 1);
70 try {
71 any const a(std::move(v));
72 assert(false);
73 } catch (my_any_exception const &) {
74 // do nothing
75 } catch (...) {
76 assert(false);
77 }
78 assert(throws_on_move::count == 1);
79 }
80 assert(throws_on_move::count == 0);
81 #endif
82 }
83
84 template <class Type>
test_copy_move_value()85 void test_copy_move_value() {
86 // constructing from a small type should perform no allocations.
87 DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
88 assert(Type::count == 0);
89 Type::reset();
90 {
91 Type t(42);
92 assert(Type::count == 1);
93
94 any a(t);
95
96 assert(Type::count == 2);
97 assert(Type::copied == 1);
98 assert(Type::moved == 0);
99 assertContains<Type>(a, 42);
100 }
101 assert(Type::count == 0);
102 Type::reset();
103 {
104 Type t(42);
105 assert(Type::count == 1);
106
107 any a(std::move(t));
108
109 assert(Type::count == 2);
110 assert(Type::copied == 0);
111 assert(Type::moved == 1);
112 assertContains<Type>(a, 42);
113 }
114 }
115
116 // Test that any(ValueType&&) is *never* selected for a std::in_place_type_t specialization.
test_sfinae_constraints()117 void test_sfinae_constraints() {
118 using BadTag = std::in_place_type_t<int>;
119 using OKTag = std::in_place_t;
120 // Test that the tag type is properly handled in SFINAE
121 BadTag t = std::in_place_type<int>;
122 OKTag ot = std::in_place;
123 {
124 std::any a(t);
125 assertContains<int>(a, 0);
126 }
127 {
128 std::any a(std::move(t));
129 assertContains<int>(a, 0);
130 }
131 {
132 std::any a(ot);
133 assert(containsType<OKTag>(a));
134 }
135 {
136 struct Dummy { Dummy() = delete; };
137 using T = std::in_place_type_t<Dummy>;
138 static_assert(!std::is_constructible<std::any, T>::value, "");
139 }
140 {
141 // Test that the ValueType&& constructor SFINAE's away when the
142 // argument is non-copyable
143 struct NoCopy {
144 NoCopy() = default;
145 NoCopy(NoCopy const&) = delete;
146 NoCopy(int) {}
147 };
148 static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
149 static_assert(!std::is_constructible<std::any, NoCopy&>::value, "");
150 static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
151 }
152 }
153
main()154 int main() {
155 test_copy_move_value<small>();
156 test_copy_move_value<large>();
157 test_copy_value_throws<small_throws_on_copy>();
158 test_copy_value_throws<large_throws_on_copy>();
159 test_move_value_throws();
160 test_sfinae_constraints();
161 }
162