xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/unittests/optional/cons/value.cc (revision eceb233b9bd0dfebb902ed73b531ae6964fa3f9b)
1 // Copyright (C) 2013-2019 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 namespace cons_value {
19 
20 struct tracker
21 {
22   tracker(int value) : value(value) { ++count; }
23   ~tracker() { --count; }
24 
25   tracker(tracker const& other) : value(other.value) { ++count; }
26   tracker(tracker&& other) : value(other.value)
27   {
28     other.value = -1;
29     ++count;
30   }
31 
32   tracker& operator=(tracker const&) = default;
33   tracker& operator=(tracker&&) = default;
34 
35   int value;
36 
37   static int count;
38 };
39 
40 int tracker::count = 0;
41 
42 struct exception { };
43 
44 struct throwing_construction
45 {
46   explicit throwing_construction(bool propagate) : propagate(propagate) { }
47 
48   throwing_construction(throwing_construction const& other)
49   : propagate(other.propagate)
50   {
51     if(propagate)
52       throw exception {};
53   }
54 
55   bool propagate;
56 };
57 
58 void test()
59 {
60   // [20.5.4.1] Constructors
61 
62   {
63     auto i = 0x1234ABCD;
64     gdb::optional<long> o { i };
65     VERIFY( o );
66     VERIFY( *o == 0x1234ABCD );
67     VERIFY( i == 0x1234ABCD );
68   }
69 
70   {
71     auto i = 0x1234ABCD;
72     gdb::optional<long> o = i;
73     VERIFY( o );
74     VERIFY( *o == 0x1234ABCD );
75     VERIFY( i == 0x1234ABCD );
76   }
77 
78   {
79     auto i = 0x1234ABCD;
80     gdb::optional<long> o = { i };
81     VERIFY( o );
82     VERIFY( *o == 0x1234ABCD );
83     VERIFY( i == 0x1234ABCD );
84   }
85 
86   {
87     auto i = 0x1234ABCD;
88     gdb::optional<long> o { std::move(i) };
89     VERIFY( o );
90     VERIFY( *o == 0x1234ABCD );
91     VERIFY( i == 0x1234ABCD );
92   }
93 
94   {
95     auto i = 0x1234ABCD;
96     gdb::optional<long> o = std::move(i);
97     VERIFY( o );
98     VERIFY( *o == 0x1234ABCD );
99     VERIFY( i == 0x1234ABCD );
100   }
101 
102   {
103     auto i = 0x1234ABCD;
104     gdb::optional<long> o = { std::move(i) };
105     VERIFY( o );
106     VERIFY( *o == 0x1234ABCD );
107     VERIFY( i == 0x1234ABCD );
108   }
109 
110 #ifndef GDB_OPTIONAL
111   {
112     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
113     gdb::optional<std::vector<int>> o { v };
114     VERIFY( !v.empty() );
115     VERIFY( o->size() == 6 );
116   }
117 #endif
118 
119   {
120     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
121     gdb::optional<std::vector<int>> o = v;
122     VERIFY( !v.empty() );
123     VERIFY( o->size() == 6 );
124   }
125 
126   {
127     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
128     gdb::optional<std::vector<int>> o { v };
129     VERIFY( !v.empty() );
130     VERIFY( o->size() == 6 );
131   }
132 
133   {
134     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
135     gdb::optional<std::vector<int>> o { std::move(v) };
136     VERIFY( v.empty() );
137     VERIFY( o->size() == 6 );
138   }
139 
140   {
141     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
142     gdb::optional<std::vector<int>> o = std::move(v);
143     VERIFY( v.empty() );
144     VERIFY( o->size() == 6 );
145   }
146 
147   {
148     std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
149     gdb::optional<std::vector<int>> o { std::move(v) };
150     VERIFY( v.empty() );
151     VERIFY( o->size() == 6 );
152   }
153 
154   {
155     tracker t { 333 };
156     gdb::optional<tracker> o = t;
157     VERIFY( o->value == 333 );
158     VERIFY( tracker::count == 2 );
159     VERIFY( t.value == 333 );
160   }
161 
162   {
163     tracker t { 333 };
164     gdb::optional<tracker> o = std::move(t);
165     VERIFY( o->value == 333 );
166     VERIFY( tracker::count == 2 );
167     VERIFY( t.value == -1 );
168   }
169 
170   enum outcome { nothrow, caught, bad_catch };
171 
172   {
173     outcome result = nothrow;
174     throwing_construction t { false };
175 
176     try
177     {
178       gdb::optional<throwing_construction> o { t };
179     }
180     catch(exception const&)
181     { result = caught; }
182     catch(...)
183     { result = bad_catch; }
184 
185     VERIFY( result == nothrow );
186   }
187 
188   {
189     outcome result = nothrow;
190     throwing_construction t { true };
191 
192     try
193     {
194       gdb::optional<throwing_construction> o { t };
195     }
196     catch(exception const&)
197     { result = caught; }
198     catch(...)
199     { result = bad_catch; }
200 
201     VERIFY( result == caught );
202   }
203 
204   {
205     outcome result = nothrow;
206     throwing_construction t { false };
207 
208     try
209     {
210       gdb::optional<throwing_construction> o { std::move(t) };
211     }
212     catch(exception const&)
213     { result = caught; }
214     catch(...)
215     { result = bad_catch; }
216 
217     VERIFY( result == nothrow );
218   }
219 
220   {
221     outcome result = nothrow;
222     throwing_construction t { true };
223 
224     try
225     {
226       gdb::optional<throwing_construction> o { std::move(t) };
227     }
228     catch(exception const&)
229     { result = caught; }
230     catch(...)
231     { result = bad_catch; }
232 
233     VERIFY( result == caught );
234   }
235 
236   {
237 #ifndef GDB_OPTIONAL
238     gdb::optional<std::string> os = "foo";
239 #endif
240     struct X
241     {
242       explicit X(int) {}
243       X& operator=(int) {return *this;}
244     };
245 #ifndef GDB_OPTIONAL
246     gdb::optional<X> ox{42};
247 #endif
248     gdb::optional<int> oi{42};
249 #ifndef GDB_OPTIONAL
250     gdb::optional<X> ox2{oi};
251 #endif
252     gdb::optional<std::string> os2;
253     os2 = "foo";
254 #ifndef GDB_OPTIONAL
255     gdb::optional<X> ox3;
256     ox3 = 42;
257     gdb::optional<X> ox4;
258     ox4 = oi;
259 #endif
260   }
261   {
262     // no converting construction.
263 #ifndef GDB_OPTIONAL
264     gdb::optional<int> oi = gdb::optional<short>();
265     VERIFY(!bool(oi));
266     gdb::optional<std::string> os = gdb::optional<const char*>();
267     VERIFY(!bool(os));
268 #endif
269     gdb::optional<gdb::optional<int>> ooi = gdb::optional<int>();
270     VERIFY(bool(ooi));
271     ooi = gdb::optional<int>();
272     VERIFY(bool(ooi));
273     ooi = gdb::optional<int>(42);
274     VERIFY(bool(ooi));
275     VERIFY(bool(*ooi));
276 #ifndef GDB_OPTIONAL
277     gdb::optional<gdb::optional<int>> ooi2 = gdb::optional<short>();
278     VERIFY(bool(ooi2));
279     ooi2 = gdb::optional<short>();
280     VERIFY(bool(ooi2));
281     ooi2 = gdb::optional<short>(6);
282     VERIFY(bool(ooi2));
283     VERIFY(bool(*ooi2));
284     gdb::optional<gdb::optional<int>> ooi3 = gdb::optional<int>(42);
285     VERIFY(bool(ooi3));
286     VERIFY(bool(*ooi3));
287     gdb::optional<gdb::optional<int>> ooi4 = gdb::optional<short>(6);
288     VERIFY(bool(ooi4));
289     VERIFY(bool(*ooi4));
290 #endif
291   }
292 }
293 
294 } // namespace cons_value
295