diff options
-rw-r--r-- | include/gsl/gsl_util | 12 | ||||
-rw-r--r-- | tests/utils_tests.cpp | 22 |
2 files changed, 26 insertions, 8 deletions
diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index 585b3f9..ca733ac 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -52,6 +52,8 @@ 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(F f) noexcept : f_(std::move(f)) {} 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 template <class F> -GSL_NODISCARD final_action<F> finally(const F& f) noexcept -{ - return final_action<F>(f); -} - -template <class F> -GSL_NODISCARD final_action<F> finally(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>(std::forward<F>(f)); + return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(std::forward<F>(f)); } // narrow_cast(): a searchable way to do narrowing casts of values diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index fae48f5..430788e 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -70,6 +70,28 @@ TEST(utils_tests, finally_lambda_move) 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) { int i = 0; |