mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Merge pull request #720 from menuet/fix-finally
Fix finally when passing a non const lvalue invokable thing
This commit is contained in:
commit
e426750695
@ -52,6 +52,8 @@ template <class F>
|
|||||||
class final_action
|
class final_action
|
||||||
{
|
{
|
||||||
public:
|
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(F f) noexcept : f_(std::move(f)) {}
|
explicit final_action(F f) noexcept : f_(std::move(f)) {}
|
||||||
|
|
||||||
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) {}
|
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) {}
|
||||||
@ -73,15 +75,9 @@ private:
|
|||||||
|
|
||||||
// finally() - convenience function to generate a final_action
|
// finally() - convenience function to generate a final_action
|
||||||
template <class F>
|
template <class F>
|
||||||
GSL_NODISCARD final_action<F> finally(const F& f) noexcept
|
GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type> finally(F&& f) noexcept
|
||||||
{
|
{
|
||||||
return final_action<F>(f);
|
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(std::forward<F>(f));
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
GSL_NODISCARD final_action<F> finally(F&& f) noexcept
|
|
||||||
{
|
|
||||||
return final_action<F>(std::forward<F>(f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// narrow_cast(): a searchable way to do narrowing casts of values
|
// narrow_cast(): a searchable way to do narrowing casts of values
|
||||||
|
@ -70,6 +70,28 @@ TEST(utils_tests, finally_lambda_move)
|
|||||||
EXPECT_TRUE(i == 1);
|
EXPECT_TRUE(i == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(utils_tests, finally_const_lvalue_lambda)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
const auto const_lvalue_lambda = [&]() { f(i); };
|
||||||
|
auto _ = finally(const_lvalue_lambda);
|
||||||
|
EXPECT_TRUE(i == 0);
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(i == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_tests, finally_mutable_lvalue_lambda)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
auto mutable_lvalue_lambda = [&]() { f(i); };
|
||||||
|
auto _ = finally(mutable_lvalue_lambda);
|
||||||
|
EXPECT_TRUE(i == 0);
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(i == 1);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(utils_tests, finally_function_with_bind)
|
TEST(utils_tests, finally_function_with_bind)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user