Skip to content

Commit e9533d3

Browse files
change constructor requirements
1 parent 231a1ea commit e9533d3

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

include/beman/scope/scope.hpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
#include <version>
1616

1717
#if (!(defined(__cpp_concepts) || !(defined(__cpp_lib_concepts))))
18-
static_assert(false, "C++20 Concepts Required");
18+
static_assert(false, "C++20 Concepts Required");
1919
#endif
2020

2121

22-
2322
#include <concepts>
2423
#include <functional>
2524
#include <exception>
@@ -112,56 +111,63 @@ template<scope_exit_function ScopeExitFunc, scope_invoke_checker InvokeChecker =
112111
class [[nodiscard]] scope_guard
113112
{
114113
public:
115-
explicit constexpr scope_guard(ScopeExitFunc&& exit_func)
116-
// Is the noexcept depending only on scope_exit construct or also on invoke_checker construct?
117-
noexcept(std::is_nothrow_constructible_v<ScopeExitFunc>)
118-
//noexcept(std::is_nothrow_constructible_v<ScopeExitFunc> && std::is_nothrow_constructible_v<InvokeChecker>)
119-
requires (!std::is_same_v<decltype(exit_func), scope_guard>)
114+
template<typename T, typename S>
115+
explicit constexpr scope_guard(T&& exit_func, S&& invoke_checker)
116+
noexcept(std::is_nothrow_constructible_v<ScopeExitFunc> && std::is_nothrow_constructible_v<InvokeChecker>)
120117
try
121-
: m_exit_func(std::forward<ScopeExitFunc>(exit_func))
118+
: m_exit_func(std::forward<T>(exit_func)),
119+
m_invoke_checker{ std::forward<S>(invoke_checker) }
122120
{}
123121
catch (...)
124122
{
125123
if constexpr (!std::is_nothrow_constructible_v<ScopeExitFunc>)
126124
{
127125
if constexpr (!HasDontInvokeOnCreationException<ScopeExitFunc>)
128126
{
129-
// Can we call the invoke_checker?? we don't know who threw the exception? (exit_func or invoke_checker default construct?)
130-
131127
exit_func();
132128
}
133129

134130
throw;
135131
}
136132
}
137133

138-
explicit constexpr scope_guard(ScopeExitFunc&& exit_func, InvokeChecker&& invoke_checker)
134+
135+
template<typename T>
136+
explicit constexpr scope_guard(T&& exit_func)
137+
// Is the noexcept depending only on scope_exit construct or also on invoke_checker construct?
138+
//noexcept(std::is_nothrow_constructible_v<ScopeExitFunc>)
139139
noexcept(std::is_nothrow_constructible_v<ScopeExitFunc> && std::is_nothrow_constructible_v<InvokeChecker>)
140+
requires (!std::is_same_v<decltype(exit_func), scope_guard>)
140141
try
141-
: m_exit_func(std::forward<ScopeExitFunc>(exit_func)),
142-
m_invoke_checker{ std::forward<InvokeChecker>(invoke_checker) }
142+
: m_exit_func(std::forward<T>(exit_func))
143143
{}
144144
catch (...)
145145
{
146146
if constexpr (!std::is_nothrow_constructible_v<ScopeExitFunc>)
147147
{
148148
if constexpr (!HasDontInvokeOnCreationException<ScopeExitFunc>)
149149
{
150+
// Can we call the invoke_checker?? we don't know who threw the exception? (exit_func or invoke_checker default construct?)
151+
150152
exit_func();
151153
}
152154

153155
throw;
154156
}
155157
}
156158

159+
157160
explicit constexpr scope_guard(scope_guard&& rhs) noexcept(std::is_nothrow_move_constructible_v<ScopeExitFunc>
158161
&& std::is_nothrow_move_constructible_v<InvokeChecker>)
162+
requires (HasRelease<InvokeChecker> || HasStaticRelease<InvokeChecker>)
159163
: m_exit_func { std::move(rhs.m_exit_func) },
160164
m_invoke_checker { std::move(rhs.m_invoke_checker) }
161165
{
166+
rhs.release();
162167
//rhs.m_invoke_checker = NeverExecute {};
163168
}
164169

170+
165171
scope_guard(const scope_guard&) = delete;
166172
scope_guard& operator=(const scope_guard&) = delete;
167173
scope_guard& operator=(scope_guard&&) = delete;
@@ -212,12 +218,12 @@ class [[nodiscard]] scope_guard
212218

213219
//==================================================================================================
214220

215-
template<std::invocable ExitFunc>
216-
scope_guard(ExitFunc&&) -> scope_guard<ExitFunc>;
217-
218221
template<std::invocable ExitFunc, scope_invoke_checker InvokeChecker>
219222
scope_guard(ExitFunc&&, InvokeChecker&&) -> scope_guard<ExitFunc, InvokeChecker>;
220223

224+
template<std::invocable ExitFunc>
225+
scope_guard(ExitFunc&&) -> scope_guard<ExitFunc>;
226+
221227
//==================================================================================================
222228

223229
class ExecuteAlways
@@ -329,15 +335,19 @@ class Releasable<InvokeChecker>
329335

330336
//==================================================================================================
331337

338+
332339
template<class ExitFunc>
333340
using scope_exit = scope_guard<ExitFunc, Releasable<>>;
334341

342+
335343
template<class ExitFunc>
336344
using scope_success = scope_guard<ExitFunc, Releasable<ExecuteWhenNoException>>;
337345

346+
338347
template<class ExitFunc>
339348
using scope_fail = scope_guard<ExitFunc, Releasable<ExecuteOnlyWhenException>>;
340349

350+
341351
//==================================================================================================
342352

343353
//

tests/beman/scope/scope.test.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ TEST_CASE("scope_guard")
7272

7373
beman::scope::Releasable<> releaser;
7474

75-
SECTION("Multiple exit guards disabled by releaser")
75+
SECTION("Multiple exit guards disabled by 1 releaser")
7676
{
7777
{
7878
auto exit_guard3_1 = beman::scope::scope_guard { exit_func_onj, releaser };
@@ -103,9 +103,13 @@ TEST_CASE("scope_guard")
103103
} exit_func_onj;
104104

105105

106-
auto guard = beman::scope::scope_guard { exit_func_onj };
106+
{
107+
auto guard = beman::scope::scope_guard { exit_func_onj,
108+
beman::scope::Releasable<>{} };
109+
107110

108-
// auto guard2(std::move(guard));
111+
auto guard2(std::move(guard));
112+
}
109113

110114
REQUIRE(exit_func_onj.invoked_count == 1);
111115
}
@@ -123,7 +127,7 @@ TEST_CASE("scope_exit")
123127

124128
auto exit_guard4 = beman::scope::scope_exit([] {});
125129

126-
auto exit_guard5 = beman::scope::scope_guard { [] {},
130+
auto exit_guard5 = beman::scope::scope_exit { [] {},
127131
[]
128132
{
129133
return true;

0 commit comments

Comments
 (0)