11// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
22
3- #include < beman/scope/scope .hpp>
3+ #include < beman/scope/scope_guard_demo .hpp>
44
55#include < cstdlib>
66#include < iostream>
77#include < string_view>
88
9- namespace scope = beman::scope;
9+ namespace scope = beman::scope::demo ;
1010
1111void print_exit_status (std::string_view name, bool exit_status, bool did_throw) {
1212 std::cout << name << " :\n " ;
13- std::cout << " Throwed exception " << (did_throw ? " yes" : " no" ) << " \n " ;
14- std::cout << " Exit status " << (exit_status ? " finished " : " pending " ) << " \n\n " ;
13+ std::cout << " Exception thrown: " << (did_throw ? " yes" : " no" ) << " \n " ;
14+ std::cout << " Exit status: " << (exit_status ? " handled " : " no handling " ) << " \n\n " ;
1515}
1616
1717// Randomly throw an exception (50% chance)
1818void maybe_throw () {
19- if (std::rand () >= RAND_MAX / 2 )
19+ if (std::rand () >= RAND_MAX / 2 ) {
2020 throw std::exception{};
21+ }
2122}
2223
23- int main () {
24- bool exit_status{false }, did_throw{false };
24+ void standard_exit () {
25+ bool exit_status{false };
26+ bool did_throw{false };
2527
2628 // Manual handling at "end of scope"
2729 try {
@@ -35,7 +37,7 @@ int main() {
3537 // Using scope_exit: runs on scope exit (success or exception)
3638 exit_status = did_throw = false ;
3739 try {
38- auto guard = scope::scope_exit{ [&] { exit_status = true ; }} ;
40+ auto guard = scope::scope_exit ( [&] { exit_status = true ; }) ;
3941 maybe_throw ();
4042 } catch (...) {
4143 did_throw = true ;
@@ -45,7 +47,7 @@ int main() {
4547 // Using scope_fail: runs only if an exception occurs
4648 exit_status = did_throw = false ;
4749 try {
48- auto guard = scope::scope_fail{ [&] { exit_status = true ; }} ;
50+ auto guard = scope::scope_fail ( [&] { exit_status = true ; }) ;
4951 maybe_throw ();
5052 } catch (...) {
5153 did_throw = true ;
@@ -55,10 +57,91 @@ int main() {
5557 // Using scope_success: runs only if no exception occurs
5658 exit_status = did_throw = false ;
5759 try {
58- auto guard = scope::scope_success{ [&] { exit_status = true ; }} ;
60+ auto guard = scope::scope_success ( [&] { exit_status = true ; }) ;
5961 maybe_throw ();
6062 } catch (...) {
6163 did_throw = true ;
6264 }
6365 print_exit_status (" scope_success" , exit_status, did_throw);
6466}
67+
68+ void releasable_exit () {
69+ bool exit_status{false };
70+ bool did_throw{false };
71+
72+ // Manual handling at "end of scope"
73+ try {
74+ maybe_throw ();
75+ exit_status = true ;
76+ } catch (...) {
77+ did_throw = true ;
78+ }
79+ print_exit_status (" Manual handling" , exit_status, did_throw);
80+
81+ // Using scope_exit: runs on scope exit (success or exception)
82+ exit_status = did_throw = false ;
83+ try {
84+ auto guard = scope::scope_exit_releasable ([&] { exit_status = true ; });
85+ guard.release ();
86+ maybe_throw ();
87+ } catch (...) {
88+ did_throw = true ;
89+ }
90+ print_exit_status (" scope_exit" , exit_status, did_throw);
91+
92+ // Using scope_fail: runs only if an exception occurs
93+ exit_status = did_throw = false ;
94+ try {
95+ auto guard = scope::scope_fail_releasable ([&] { exit_status = true ; });
96+ guard.release ();
97+ maybe_throw ();
98+ } catch (...) {
99+ did_throw = true ;
100+ }
101+ print_exit_status (" scope_fail" , exit_status, did_throw);
102+
103+ // Using scope_success: runs only if no exception occurs
104+ exit_status = did_throw = false ;
105+ try {
106+ auto guard = scope::scope_success_releasable ([&] { exit_status = true ; });
107+ guard.release ();
108+ maybe_throw ();
109+ } catch (...) {
110+ did_throw = true ;
111+ }
112+ print_exit_status (" scope_success" , exit_status, did_throw);
113+ }
114+
115+ class CancelableAction {
116+ bool m_can_invoke = true ;
117+
118+ public:
119+ void cancel () { m_can_invoke = false ; }
120+
121+ void uncancel () { m_can_invoke = true ; }
122+
123+ bool can_invoke () const { return m_can_invoke; }
124+ };
125+
126+ void cancelable_exit () {
127+
128+ bool exit_status{false };
129+ bool did_throw{false };
130+
131+ try {
132+ auto guard = scope::scope_guard ([&] { exit_status = true ; }, CancelableAction{});
133+ guard.cancel ();
134+ maybe_throw ();
135+ } catch (...) {
136+ did_throw = true ;
137+ }
138+
139+ print_exit_status (" cancelable" , exit_status, did_throw);
140+ }
141+
142+ int main () {
143+ standard_exit ();
144+ releasable_exit ();
145+
146+ cancelable_exit ();
147+ }
0 commit comments