• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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