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// <any>
13
14// template <class T, class ...Args> any make_any(Args&&...);
15// template <class T, class U, class ...Args>
16// any make_any(initializer_list<U>, Args&&...);
17
18#include <any>
19#include <cassert>
20
21#include "any_helpers.h"
22#include "count_new.hpp"
23#include "test_macros.h"
24
25using std::any;
26using std::any_cast;
27
28
29template <class Type>
30void test_make_any_type() {
31    // constructing from a small type should perform no allocations.
32    DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
33    assert(Type::count == 0);
34    Type::reset();
35    {
36        any a = std::make_any<Type>();
37
38        assert(Type::count == 1);
39        assert(Type::copied == 0);
40        assert(Type::moved == 0);
41        assertContains<Type>(a, 0);
42    }
43    assert(Type::count == 0);
44    Type::reset();
45    {
46        any a = std::make_any<Type>(101);
47
48        assert(Type::count == 1);
49        assert(Type::copied == 0);
50        assert(Type::moved == 0);
51        assertContains<Type>(a, 101);
52    }
53    assert(Type::count == 0);
54    Type::reset();
55    {
56        any a = std::make_any<Type>(-1, 42, -1);
57
58        assert(Type::count == 1);
59        assert(Type::copied == 0);
60        assert(Type::moved == 0);
61        assertContains<Type>(a, 42);
62    }
63    assert(Type::count == 0);
64    Type::reset();
65}
66
67template <class Type>
68void test_make_any_type_tracked() {
69    // constructing from a small type should perform no allocations.
70    DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
71    {
72        any a = std::make_any<Type>();
73        assertArgsMatch<Type>(a);
74    }
75    {
76        any a = std::make_any<Type>(-1, 42, -1);
77        assertArgsMatch<Type, int, int, int>(a);
78    }
79    // initializer_list constructor tests
80    {
81        any a = std::make_any<Type>({-1, 42, -1});
82        assertArgsMatch<Type, std::initializer_list<int>>(a);
83    }
84    {
85        int x = 42;
86        any a  = std::make_any<Type>({-1, 42, -1}, x);
87        assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
88    }
89}
90
91#ifndef TEST_HAS_NO_EXCEPTIONS
92
93struct SmallThrows {
94  SmallThrows(int) { throw 42; }
95  SmallThrows(std::initializer_list<int>, int) { throw 42; }
96};
97static_assert(IsSmallObject<SmallThrows>::value, "");
98
99struct LargeThrows {
100  LargeThrows(int) { throw 42; }
101  LargeThrows(std::initializer_list<int>, int) { throw 42; }
102  int data[sizeof(std::any)];
103};
104static_assert(!IsSmallObject<LargeThrows>::value, "");
105
106template <class Type>
107void test_make_any_throws()
108{
109    {
110        try {
111            std::make_any<Type>(101);
112            assert(false);
113        } catch (int const&) {
114        }
115    }
116    {
117        try {
118            std::make_any<Type>({1, 2, 3}, 101);
119            assert(false);
120        } catch (int const&) {
121        }
122    }
123}
124
125#endif
126
127int main() {
128    test_make_any_type<small>();
129    test_make_any_type<large>();
130    test_make_any_type<small_throws_on_copy>();
131    test_make_any_type<large_throws_on_copy>();
132    test_make_any_type<throws_on_move>();
133    test_make_any_type_tracked<small_tracked_t>();
134    test_make_any_type_tracked<large_tracked_t>();
135#ifndef TEST_HAS_NO_EXCEPTIONS
136    test_make_any_throws<SmallThrows>();
137    test_make_any_throws<LargeThrows>();
138
139#endif
140}
141