Skip to content

Commit

Permalink
Add scope_exit helper. (#78) (#103)
Browse files Browse the repository at this point in the history
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>

Co-authored-by: Michel Hidalgo <michel@ekumenlabs.com>
  • Loading branch information
ahcorde and hidmic authored Oct 9, 2020
1 parent 7c825e9 commit 59ff654
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ if(BUILD_TESTING)
)
ament_target_dependencies(test_get_env rcutils)

ament_add_gtest(test_scope_exit test/test_scope_exit.cpp)
target_link_libraries(test_scope_exit ${PROJECT_NAME})

ament_add_gtest(test_split test/test_split.cpp)

ament_add_gtest(test_filesystem_helper test/test_filesystem_helper.cpp
Expand Down
68 changes: 68 additions & 0 deletions include/rcpputils/scope_exit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2015-2020 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef RCPPUTILS__SCOPE_EXIT_HPP_
#define RCPPUTILS__SCOPE_EXIT_HPP_

#include <utility>

#include "rcutils/macros.h"

namespace rcpputils
{

template<typename CallableT>
struct scope_exit final
{
explicit scope_exit(CallableT && callable)
: callable_(std::forward<CallableT>(callable))
{
}

scope_exit(const scope_exit &) = delete;
scope_exit(scope_exit &&) = default;

scope_exit & operator=(const scope_exit &) = delete;
scope_exit & operator=(scope_exit &&) = default;

~scope_exit()
{
if (!cancelled_) {
callable_();
}
}

void cancel()
{
cancelled_ = true;
}

private:
CallableT callable_;
bool cancelled_{false};
};

template<typename CallableT>
scope_exit<CallableT>
make_scope_exit(CallableT && callable)
{
return scope_exit<CallableT>(std::forward<CallableT>(callable));
}

} // namespace rcpputils

#define RCPPUTILS_SCOPE_EXIT(code) \
auto RCUTILS_JOIN(scope_exit_, __LINE__) = rcpputils::make_scope_exit([&]() {code;})

#endif // RCPPUTILS__SCOPE_EXIT_HPP_
64 changes: 64 additions & 0 deletions test/test_scope_exit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2020 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>

#include "rcpputils/scope_exit.hpp"

TEST(test_scope_exit, should_run) {
bool called = false;

{
auto on_exit =
rcpputils::make_scope_exit(
[&called]() {
called = true;
});
(void)on_exit;
}

EXPECT_TRUE(called);
}

TEST(test_scope_exit, should_not_run) {
bool called = false;

{
auto on_exit =
rcpputils::make_scope_exit(
[&called]() {
called = true;
});
on_exit.cancel();
}

EXPECT_FALSE(called);
}

TEST(test_scope_exit, code_types) {
auto code = []() {};
rcpputils::make_scope_exit(code);

const auto const_code = []() {};
rcpputils::make_scope_exit(const_code);

struct NonCopyableCode
{
NonCopyableCode() = default;
NonCopyableCode(const NonCopyableCode &) = delete;
NonCopyableCode(NonCopyableCode &&) = default;
void operator()() {}
};
rcpputils::make_scope_exit(NonCopyableCode());
}

0 comments on commit 59ff654

Please sign in to comment.