]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/unittests/optional/assignment/2.cc
Update copyright year range in all GDB files
[thirdparty/binutils-gdb.git] / gdb / unittests / optional / assignment / 2.cc
CommitLineData
e2882c85 1// Copyright (C) 2013-2018 Free Software Foundation, Inc.
d35d1958
PA
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
18namespace assign_2 {
19
20struct exception {};
21
22int counter = 0;
23
24struct mixin_counter
25{
26 mixin_counter() { ++counter; }
27 mixin_counter(mixin_counter const&) { ++counter; }
28 ~mixin_counter() { --counter; }
29};
30
31struct value_type : private mixin_counter
32{
33 enum state_type
34 {
35 zero,
36 moved_from,
37 throwing_construction,
38 throwing_copy,
39 throwing_copy_assignment,
40 throwing_move,
41 throwing_move_assignment,
42 threw,
43 };
44
45 value_type() = default;
46
47 explicit value_type(state_type state_)
48 : state(state_)
49 {
50 throw_if(throwing_construction);
51 }
52
53 value_type(value_type const& other)
54 : state(other.state)
55 {
56 throw_if(throwing_copy);
57 }
58
59 value_type&
60 operator=(value_type const& other)
61 {
62 state = other.state;
63 throw_if(throwing_copy_assignment);
64 return *this;
65 }
66
67 value_type(value_type&& other)
68 : state(other.state)
69 {
70 other.state = moved_from;
71 throw_if(throwing_move);
72 }
73
74 value_type&
75 operator=(value_type&& other)
76 {
77 state = other.state;
78 other.state = moved_from;
79 throw_if(throwing_move_assignment);
80 return *this;
81 }
82
83 void throw_if(state_type match)
84 {
85 if(state == match)
86 {
87 state = threw;
88 throw exception {};
89 }
90 }
91
92 state_type state = zero;
93};
94
95void test()
96{
97 using O = gdb::optional<value_type>;
98 using S = value_type::state_type;
99 auto const make = [](S s = S::zero) { return O { gdb::in_place, s }; };
100
101 enum outcome_type { nothrow, caught, bad_catch };
102
103 // Check copy/move assignment for engaged optional
104
105 // From disengaged optional
106 {
107 O o = make(S::zero);
108 VERIFY( o );
109 O p;
110 o = p;
111 VERIFY( !o );
112 VERIFY( !p );
113 }
114
115 {
116 O o = make(S::zero);
117 VERIFY( o );
118 O p;
119 o = std::move(p);
120 VERIFY( !o );
121 VERIFY( !p );
122 }
123
124#ifndef GDB_OPTIONAL
125 {
126 O o = make(S::zero);
127 VERIFY( o );
128 o = {};
129 VERIFY( !o );
130 }
131#endif
132
133 // From engaged optional
134 {
135 O o = make(S::zero);
136 VERIFY( o );
137 O p = make(S::throwing_copy);
138 o = p;
139 VERIFY( o && o->state == S::throwing_copy);
140 VERIFY( p && p->state == S::throwing_copy);
141 }
142
143 {
144 O o = make(S::zero);
145 VERIFY( o );
146 O p = make(S::throwing_move);
147 o = std::move(p);
148 VERIFY( o && o->state == S::throwing_move);
149 VERIFY( p && p->state == S::moved_from);
150 }
151
152 {
153 ATTRIBUTE_UNUSED outcome_type outcome {};
154 O o = make(S::zero);
155 VERIFY( o );
156 O p = make(S::throwing_copy_assignment);
157
158 try
159 {
160 o = p;
161 }
162 catch(exception const&)
163 { outcome = caught; }
164 catch(...)
165 { outcome = bad_catch; }
166
167 VERIFY( o && o->state == S::threw);
168 VERIFY( p && p->state == S::throwing_copy_assignment);
169 }
170
171 {
172 ATTRIBUTE_UNUSED outcome_type outcome {};
173 O o = make(S::zero);
174 VERIFY( o );
175 O p = make(S::throwing_move_assignment);
176
177 try
178 {
179 o = std::move(p);
180 }
181 catch(exception const&)
182 { outcome = caught; }
183 catch(...)
184 { outcome = bad_catch; }
185
186 VERIFY( o && o->state == S::threw);
187 VERIFY( p && p->state == S::moved_from);
188 }
189
190 VERIFY( counter == 0 );
191}
192
193} // namespace assign_2