1 // { dg-options "-std=gnu++14" }
2 // { dg-do run }
3 
4 // Copyright (C) 2014-2016 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 #include <experimental/any>
22 #include <string>
23 #include <cstring>
24 #include <testsuite_hooks.h>
25 
26 using std::experimental::any;
27 using std::experimental::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   using std::experimental::bad_any_cast;
61   any x(1);
62   auto p = any_cast<double>(&x);
63   VERIFY(p == nullptr);
64 
65   x = 1.0;
66   p = any_cast<double>(&x);
67   VERIFY(p != nullptr);
68 
69   x = any();
70   p = any_cast<double>(&x);
71   VERIFY(p == nullptr);
72 
73   try {
74     any_cast<double>(x);
75     VERIFY(false);
76   } catch (const bad_any_cast&) {
77   }
78 }
79 
80 static int move_count = 0;
81 
test03()82 void test03()
83 {
84   struct MoveEnabled
85   {
86     MoveEnabled(MoveEnabled&&)
87     {
88       ++move_count;
89     }
90     MoveEnabled() = default;
91     MoveEnabled(const MoveEnabled&) = default;
92   };
93   MoveEnabled m;
94   MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
95   VERIFY(move_count == 1);
96   MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
97   VERIFY(move_count == 1);
98   struct MoveDeleted
99   {
100     MoveDeleted(MoveDeleted&&) = delete;
101     MoveDeleted() = default;
102     MoveDeleted(const MoveDeleted&) = default;
103   };
104   MoveDeleted md;
105   MoveDeleted&& md2 = any_cast<MoveDeleted>(any(std::move(md)));
106   MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
107 }
108 
test04()109 void test04()
110 {
111   // PR libstdc++/69321
112   struct noncopyable {
113     noncopyable(noncopyable const&) = delete;
114   };
115 
116   any a;
117   auto p = any_cast<noncopyable>(&a);
118   VERIFY( p == nullptr );
119 }
120 
main()121 int main()
122 {
123   test01();
124   test02();
125   test03();
126   test04();
127 }
128