]> Git Repo - binutils.git/blob - gdb/unittests/optional/assignment/4.cc
Automatic date update in version.in
[binutils.git] / gdb / unittests / optional / assignment / 4.cc
1 // Copyright (C) 2013-2022 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 assign_4 {
19
20 struct exception {};
21
22 static int counter = 0;
23
24 struct mixin_counter
25 {
26   mixin_counter() { ++counter; }
27   mixin_counter(mixin_counter const&) { ++counter; }
28   ~mixin_counter() { --counter; }
29 };
30
31 struct 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
95 static void
96 test ()
97 {
98   using O = gdb::optional<value_type>;
99   using S = value_type::state_type;
100   auto const make = [](S s = S::zero) { return value_type { s }; };
101
102   enum outcome_type { nothrow, caught, bad_catch };
103
104   // Check value assignment for engaged optional
105
106   {
107     O o = make();
108     value_type v = make(S::throwing_copy);
109     o = v;
110     VERIFY( o && o->state == S::throwing_copy);
111   }
112
113   {
114     O o = make();
115     value_type v = make(S::throwing_move);
116     o = std::move(v);
117     VERIFY( o && o->state == S::throwing_move);
118   }
119
120   {
121     ATTRIBUTE_UNUSED outcome_type outcome {};
122     O o = make();
123     value_type v = make(S::throwing_copy_assignment);
124
125     try
126     {
127       o = v;
128     }
129     catch(exception const&)
130     { outcome = caught; }
131     catch(...)
132     { outcome = bad_catch; }
133
134     VERIFY( o && o->state == S::threw );
135   }
136
137   {
138     ATTRIBUTE_UNUSED outcome_type outcome {};
139     O o = make();
140     value_type v = make(S::throwing_move_assignment);
141
142     try
143     {
144       o = std::move(v);
145     }
146     catch(exception const&)
147     { outcome = caught; }
148     catch(...)
149     { outcome = bad_catch; }
150
151     VERIFY( o && o->state == S::threw );
152   }
153
154   VERIFY( counter == 0 );
155 }
156
157 } // namespace assign_4
This page took 0.033282 seconds and 4 git commands to generate.