1 // { dg-do run { target c++14 } }
2 
3 // Copyright (C) 2014-2018 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 #include <experimental/any>
21 #include <string>
22 #include <cstring>
23 #include <testsuite_hooks.h>
24 
25 using std::experimental::any;
26 using std::experimental::any_cast;
27 using std::experimental::bad_any_cast;
28 
test01()29 void test01()
30 {
31   using std::string;
32   using std::strcmp;
33 
34   // taken from example in N3804 proposal
35 
36   any x(5);                                   // x holds int
37   VERIFY(any_cast<int>(x) == 5);              // cast to value
38   any_cast<int&>(x) = 10;                     // cast to reference
39   VERIFY(any_cast<int>(x) == 10);
40 
41   x = "Meow";                                 // x holds const char*
42   VERIFY(strcmp(any_cast<const char*>(x), "Meow") == 0);
43   any_cast<const char*&>(x) = "Harry";
44   VERIFY(strcmp(any_cast<const char*>(x), "Harry") == 0);
45 
46   x = string("Meow");                         // x holds string
47   string s, s2("Jane");
48   s = move(any_cast<string&>(x));             // move from any
49   VERIFY(s == "Meow");
50   any_cast<string&>(x) = move(s2);            // move to any
51   VERIFY(any_cast<const string&>(x) == "Jane");
52 
53   string cat("Meow");
54   const any y(cat);                           // const y holds string
55   VERIFY(any_cast<const string&>(y) == cat);
56 }
57 
test02()58 void test02()
59 {
60   any x(1);
61   auto p = any_cast<double>(&x);
62   VERIFY(p == nullptr);
63 
64   x = 1.0;
65   p = any_cast<double>(&x);
66   VERIFY(p != nullptr);
67 
68   x = any();
69   p = any_cast<double>(&x);
70   VERIFY(p == nullptr);
71 
72   try {
73     any_cast<double>(x);
74     VERIFY(false);
75   } catch (const bad_any_cast&) {
76   }
77 }
78 
79 static int move_count = 0;
80 
test03()81 void test03()
82 {
83   struct MoveEnabled
84   {
85     MoveEnabled(MoveEnabled&&)
86     {
87       ++move_count;
88     }
89     MoveEnabled() = default;
90     MoveEnabled(const MoveEnabled&) = default;
91   };
92   MoveEnabled m;
93   MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
94   VERIFY(move_count == 1);
95   MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
96   VERIFY(move_count == 1);
97   struct MoveDeleted
98   {
99     MoveDeleted(MoveDeleted&&) = delete;
100     MoveDeleted() = default;
101     MoveDeleted(const MoveDeleted&) = default;
102   };
103   MoveDeleted md;
104   MoveDeleted&& md2 = any_cast<MoveDeleted>(any(std::move(md)));
105   MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
106 }
107 
test05()108 void test05()
109 {
110   // PR libstdc++/69321
111   struct noncopyable {
112     noncopyable(noncopyable const&) = delete;
113   };
114 
115   any a;
116   auto p = any_cast<noncopyable>(&a);
117   VERIFY( p == nullptr );
118 }
119 
test06()120 void test06()
121 {
122   // The contained value of a std::any is always an object type,
123   // but any_cast does not forbid checking for function types.
124 
125   any a(1);
126   void (*p1)() = any_cast<void()>(&a);
127   VERIFY( p1 == nullptr );
128   int (*p2)(int) = any_cast<int(int)>(&a);
129   VERIFY( p2 == nullptr );
130   int (*p3)() = any_cast<int()>(&const_cast<const any&>(a));
131   VERIFY( p3 == nullptr );
132 
133   try {
134     any_cast<int(&)()>(a);
135     VERIFY( false );
136   } catch (const bad_any_cast&) {
137   }
138 
139   try {
140     any_cast<int(&)()>(std::move(a));
141     VERIFY( false );
142   } catch (const bad_any_cast&) {
143   }
144 
145   try {
146     any_cast<int(&)()>(const_cast<const any&>(a));
147     VERIFY( false );
148   } catch (const bad_any_cast&) {
149   }
150 }
151 
test07()152 void test07()
153 {
154   int arr[3];
155   any a(arr);
156   VERIFY( a.type() == typeid(int*) );	// contained value is decayed
157 
158   int (*p1)[3] = any_cast<int[3]>(&a);
159   VERIFY( a.type() != typeid(int[3]) ); // so any_cast should return nullptr
160   VERIFY( p1 == nullptr );
161   int (*p2)[] = any_cast<int[]>(&a);
162   VERIFY( a.type() != typeid(int[]) );	// so any_cast should return nullptr
163   VERIFY( p2 == nullptr );
164   const int (*p3)[] = any_cast<int[]>(&const_cast<const any&>(a));
165   VERIFY( p3 == nullptr );
166 }
167 
main()168 int main()
169 {
170   test01();
171   test02();
172   test03();
173   test05();
174   test06();
175   test07();
176 }
177