Compare commits

...

11 Commits

Author SHA1 Message Date
Casey Carter d9ffa118c5 Properly handle finally(actual_function) (#1056)
`finally` needs to use `decay_t` instead of `remove_cvref_t` so it can properly accept non-object function arguments by decaying to function pointer type. Adds test coverage for this use case which was previously missing.
2022-09-29 08:59:05 -07:00
Dmitry Kobets 8840d87199 Merge remote-tracking branch 'origin/main' into final_action-revision 2022-09-26 15:27:01 -07:00
Herb Sutter d569ed65d0 Add remove_cv too per Casey's suggestion
Co-authored-by: Casey Carter <Casey@Carter.net>
2022-08-31 16:48:13 -07:00
Herb Sutter 352f73df92 Applying Casey's an Dmitry's changes... 2022-08-31 16:24:05 -07:00
Herb Sutter 3865bac469 Made noexcept-consistent 2022-08-30 16:08:07 -07:00
Herb Sutter 6b284bf500 Applying Casey's suggestions
Applying @CaseyCarter's suggested forwarding changes
And adding `[[nodiscard]]` on `finally`

Thanks Casey -- somehow this slipped through the cracks for a year.
2022-08-30 16:05:09 -07:00
Herb Sutter 020ddc40c5 Fine, make it move-constructible (only)
To satisfy some compilers.
And might as well reinstate that test case.
2021-02-24 16:49:57 -08:00
Herb Sutter f59cb795a0 Figured out test failures, removed move test
We shouldn't be moving these `final_action`s around, that wasn't part of the C++CG design requirements.
Went back to the simple version of `final_action`.
2021-02-24 16:42:58 -08:00
Herb Sutter e9c575300e Defaulted copying 2021-02-24 16:12:13 -08:00
Herb Sutter 39e956b9b1 Restored copyability to final_action 2021-02-24 16:08:02 -08:00
Herb Sutter 4cd8873d3e Clean up final_act and finally, closes #752 and #846 2021-02-24 15:51:29 -08:00
2 changed files with 22 additions and 23 deletions
+12 -23
View File
@@ -65,40 +65,29 @@ template <class F>
class final_action
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
explicit final_action(const F& ff) noexcept : f{ff} { }
explicit final_action(F&& ff) noexcept : f{std::move(ff)} { }
explicit final_action(F f) noexcept : f_(std::move(f)) {}
~final_action() noexcept { if (invoke) f(); }
final_action(final_action&& other) noexcept
: f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
{}
: f(std::move(other.f)), invoke(std::exchange(other.invoke, false))
{ }
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
// clang-format off
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws
// clang-format on
~final_action() noexcept
{
if (invoke_) f_();
}
final_action(const final_action&) = delete;
void operator=(const final_action&) = delete;
void operator=(final_action&&) = delete;
private:
F f_;
bool invoke_{true};
F f;
bool invoke = true;
};
// finally() - convenience function to generate a final_action
template <class F>
GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
finally(F&& f) noexcept
GSL_NODISCARD auto finally(F&& f) noexcept
{
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
return final_action<std::decay_t<F>>{std::forward<F>(f)};
}
// narrow_cast(): a searchable way to do narrowing casts of values
+10
View File
@@ -112,6 +112,16 @@ TEST(utils_tests, finally_function_ptr)
EXPECT_TRUE(j == 1);
}
TEST(utils_tests, finally_function)
{
j = 0;
{
auto _ = finally(g);
EXPECT_TRUE(j == 0);
}
EXPECT_TRUE(j == 1);
}
TEST(utils_tests, narrow_cast)
{
int n = 120;