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