Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions orc-rt/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(ORC_RT_HEADERS
orc-rt/MemoryFlags.h
orc-rt/RTTI.h
orc-rt/WrapperFunction.h
orc-rt/ScopeExit.h
orc-rt/SimplePackedSerialization.h
orc-rt/SPSWrapperFunction.h
orc-rt/bind.h
Expand Down
53 changes: 53 additions & 0 deletions orc-rt/include/orc-rt/ScopeExit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===---------- ScopeExit.h - Execute code at scope exit --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// make_scope_exit and related APIs.
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_SCOPEEXIT_H
#define ORC_RT_SCOPEEXIT_H

#include <type_traits>
#include <utility>

namespace orc_rt {
namespace detail {

template <typename Fn> class ScopeExitRunner {
public:
ScopeExitRunner(Fn &&F) : F(F) {}
ScopeExitRunner(const ScopeExitRunner &) = delete;
ScopeExitRunner &operator=(const ScopeExitRunner &) = delete;
ScopeExitRunner(ScopeExitRunner &&) = delete;
ScopeExitRunner &operator=(ScopeExitRunner &&) = delete;
~ScopeExitRunner() {
if (Engaged)
F();
}
void release() { Engaged = false; }

private:
Fn F;
bool Engaged = true;
};

} // namespace detail

/// Creates an object that runs the given function object upon destruction.
/// Calling the object's release method prior to destruction will prevent the
/// function object from running.
template <typename Fn>
[[nodiscard]] detail::ScopeExitRunner<std::decay_t<Fn>>
make_scope_exit(Fn &&F) {
return detail::ScopeExitRunner<std::decay_t<Fn>>(std::forward<Fn>(F));
}

} // namespace orc_rt

#endif // ORC_RT_SCOPEEXIT_H
1 change: 1 addition & 0 deletions orc-rt/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_orc_rt_unittest(CoreTests
MathTest.cpp
MemoryFlagsTest.cpp
RTTITest.cpp
ScopeExitTest.cpp
SimplePackedSerializationTest.cpp
SPSWrapperFunctionTest.cpp
WrapperFunctionBufferTest.cpp
Expand Down
39 changes: 39 additions & 0 deletions orc-rt/unittests/ScopeExitTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===- ScopeExitTest.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for orc-rt's ScopeExit.h APIs.
//
//===----------------------------------------------------------------------===//

#include "orc-rt/ScopeExit.h"
#include "gtest/gtest.h"

using namespace orc_rt;

TEST(ScopeExitTest, Noop) {
auto _ = make_scope_exit([]() {});
}

TEST(ScopeExitTest, OnScopeExit) {
bool ScopeExitRun = false;
{
auto _ = make_scope_exit([&]() { ScopeExitRun = true; });
EXPECT_FALSE(ScopeExitRun);
}
EXPECT_TRUE(ScopeExitRun);
}

TEST(ScopeExitTest, Release) {
bool ScopeExitRun = false;
{
auto OnExit = make_scope_exit([&]() { ScopeExitRun = true; });
EXPECT_FALSE(ScopeExitRun);
OnExit.release();
}
EXPECT_FALSE(ScopeExitRun);
}
Loading