1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
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
22 // template <class Value> any(Value &&)
24 // Test construction from a value.
27 // 1. The value is properly move/copied depending on the value category.
28 // 2. Both small and large values are properly handled.
34 #include "any_helpers.h"
35 #include "count_new.hpp"
36 #include "test_macros.h"
42 void test_copy_value_throws()
44 #if !defined(TEST_HAS_NO_EXCEPTIONS)
45 assert(Type::count == 0);
48 assert(Type::count == 1);
52 } catch (my_any_exception const &) {
57 assert(Type::count == 1);
58 assert(t.value == 42);
60 assert(Type::count == 0);
64 void test_move_value_throws()
66 #if !defined(TEST_HAS_NO_EXCEPTIONS)
67 assert(throws_on_move::count == 0);
70 assert(throws_on_move::count == 1);
72 any const a(std::move(v));
74 } catch (my_any_exception const &) {
79 assert(throws_on_move::count == 1);
81 assert(throws_on_move::count == 0);
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);
93 assert(Type::count == 1);
97 assert(Type::count == 2);
98 assert(Type::copied == 1);
99 assert(Type::moved == 0);
100 assertContains<Type>(a, 42);
102 assert(Type::count == 0);
106 assert(Type::count == 1);
110 assert(Type::count == 2);
111 assert(Type::copied == 0);
112 assert(Type::moved == 1);
113 assertContains<Type>(a, 42);
117 // Test that any(ValueType&&) is *never* selected for a std::in_place_type_t specialization.
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;
126 assertContains<int>(a, 0);
129 std::any a(std::move(t));
130 assertContains<int>(a, 0);
134 assert(containsType<OKTag>(a));
137 struct Dummy { Dummy() = delete; };
138 using T = std::in_place_type_t<Dummy>;
139 static_assert(!std::is_constructible<std::any, T>::value, "");
142 // Test that the ValueType&& constructor SFINAE's away when the
143 // argument is non-copyable
146 NoCopy(NoCopy const&) = delete;
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, "");
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();