Index: include/llvm/ADT/ScopeExit.h =================================================================== --- /dev/null +++ include/llvm/ADT/ScopeExit.h @@ -0,0 +1,52 @@ +//===- llvm/ADT/ScopeExit.h - Execute code at scope exit --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the make_scope_exit function, which executes user-defined +// cleanup logic at scope exit. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_SCOPE_EXIT_H +#define LLVM_ADT_SCOPE_EXIT_H + +#include "llvm/Support/Compiler.h" + +#include +#include + +namespace llvm { +namespace detail { + +template class LLVM_ATTRIBUTE_UNUSED_RESULT scope_exit { + Callable ExitFunction; + +public: + template + explicit scope_exit(Fp &&F) : ExitFunction(std::forward(F)) {} + + ~scope_exit() { ExitFunction(); } +}; + +} // end namespace detail + +// Keeps the callable object that is passed in, and execute it at the +// destruction of the returned object (usually at the scope exit where the +// returned object is kept). +// +// Interface is specified by p0052r2. +template +detail::scope_exit::type> +make_scope_exit(Callable &&F) { + return detail::scope_exit::type>( + std::forward(F)); +} + +} // end namespace llvm + +#endif Index: unittests/ADT/CMakeLists.txt =================================================================== --- unittests/ADT/CMakeLists.txt +++ unittests/ADT/CMakeLists.txt @@ -34,6 +34,7 @@ PriorityWorklistTest.cpp RangeAdapterTest.cpp SCCIteratorTest.cpp + ScopeExitTest.cpp SequenceTest.cpp SetVectorTest.cpp SmallPtrSetTest.cpp Index: unittests/ADT/ScopeExitTest.cpp =================================================================== --- /dev/null +++ unittests/ADT/ScopeExitTest.cpp @@ -0,0 +1,45 @@ +//===- llvm/unittest/ADT/ScopeExit.cpp - Scope exit unit tests --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SmallVector.h" +#include "gtest/gtest.h" + +#include + +using namespace llvm; + +namespace { + +TEST(ScopeExitTest, Copy) { + SmallVector v; + auto f = [&](int counter) { + return [&v, counter] { v.push_back(counter); }; + }; + { + auto g1 = make_scope_exit(f(0)); + { auto g2 = make_scope_exit(f(1)); } + auto g3 = make_scope_exit(f(2)); + EXPECT_EQ((SmallVector{1}), v); + } + EXPECT_EQ((SmallVector{1, 2, 0}), v); +} + +TEST(ScopeExitTest, Move) { + bool succ = false; + std::function f([&succ] { succ = true; }); + ASSERT_TRUE(static_cast(f)); + { + auto g4 = make_scope_exit(std::move(f)); + EXPECT_FALSE(f); + EXPECT_FALSE(succ); + } + EXPECT_TRUE(succ); +} +}