Update copyright year range in header of all files managed by GDB
[binutils-gdb.git] / gdb / unittests / optional / assignment / 2.cc
blob2e63a49192005438692bb57978b5597b53e8bf1f
1 // Copyright (C) 2013-2023 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.
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.
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/>.
18 namespace assign_2 {
20 struct exception {};
22 static int counter = 0;
24 struct mixin_counter
26 mixin_counter() { ++counter; }
27 mixin_counter(mixin_counter const&) { ++counter; }
28 ~mixin_counter() { --counter; }
31 struct value_type : private mixin_counter
33 enum state_type
35 zero,
36 moved_from,
37 throwing_construction,
38 throwing_copy,
39 throwing_copy_assignment,
40 throwing_move,
41 throwing_move_assignment,
42 threw,
45 value_type() = default;
47 explicit value_type(state_type state_)
48 : state(state_)
50 throw_if(throwing_construction);
53 value_type(value_type const& other)
54 : state(other.state)
56 throw_if(throwing_copy);
59 value_type&
60 operator=(value_type const& other)
62 state = other.state;
63 throw_if(throwing_copy_assignment);
64 return *this;
67 value_type(value_type&& other)
68 : state(other.state)
70 other.state = moved_from;
71 throw_if(throwing_move);
74 value_type&
75 operator=(value_type&& other)
77 state = other.state;
78 other.state = moved_from;
79 throw_if(throwing_move_assignment);
80 return *this;
83 void throw_if(state_type match)
85 if(state == match)
87 state = threw;
88 throw exception {};
92 state_type state = zero;
95 static void
96 test ()
98 using O = gdb::optional<value_type>;
99 using S = value_type::state_type;
100 auto const make = [](S s = S::zero) { return O { gdb::in_place, s }; };
102 enum outcome_type { nothrow, caught, bad_catch };
104 // Check copy/move assignment for engaged optional
106 // From disengaged optional
108 O o = make(S::zero);
109 VERIFY( o );
110 O p;
111 o = p;
112 VERIFY( !o );
113 VERIFY( !p );
117 O o = make(S::zero);
118 VERIFY( o );
119 O p;
120 o = std::move(p);
121 VERIFY( !o );
122 VERIFY( !p );
125 #ifndef GDB_OPTIONAL
127 O o = make(S::zero);
128 VERIFY( o );
129 o = {};
130 VERIFY( !o );
132 #endif
134 // From engaged optional
136 O o = make(S::zero);
137 VERIFY( o );
138 O p = make(S::throwing_copy);
139 o = p;
140 VERIFY( o && o->state == S::throwing_copy);
141 VERIFY( p && p->state == S::throwing_copy);
145 O o = make(S::zero);
146 VERIFY( o );
147 O p = make(S::throwing_move);
148 o = std::move(p);
149 VERIFY( o && o->state == S::throwing_move);
150 VERIFY( p && p->state == S::moved_from);
154 ATTRIBUTE_UNUSED outcome_type outcome {};
155 O o = make(S::zero);
156 VERIFY( o );
157 O p = make(S::throwing_copy_assignment);
161 o = p;
163 catch(exception const&)
164 { outcome = caught; }
165 catch(...)
166 { outcome = bad_catch; }
168 VERIFY( o && o->state == S::threw);
169 VERIFY( p && p->state == S::throwing_copy_assignment);
173 ATTRIBUTE_UNUSED outcome_type outcome {};
174 O o = make(S::zero);
175 VERIFY( o );
176 O p = make(S::throwing_move_assignment);
180 o = std::move(p);
182 catch(exception const&)
183 { outcome = caught; }
184 catch(...)
185 { outcome = bad_catch; }
187 VERIFY( o && o->state == S::threw);
188 VERIFY( p && p->state == S::moved_from);
191 VERIFY( counter == 0 );
194 } // namespace assign_2