[PATCH] D22796: [ADT] Add make_scope_exit().

Tim Shen via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 8 19:16:11 PDT 2016


On Mon, Aug 1, 2016 at 2:25 PM Justin Bogner <mail at justinbogner.com> wrote:

> Tim Shen via llvm-commits <llvm-commits at lists.llvm.org> writes:
> > timshen created this revision.
> > timshen added a reviewer: chandlerc.
> > timshen added a subscriber: llvm-commits.
> >
> > make_scope_exit() is described in C++ proposal p0052r2, which uses
> > RAII to do cleanup works at scope exit.
>
> Do you need this for something in particular? We don't usually add
> utilities until we need them.
>

I did when I created the patch, but I don't need it anymore. However Kyle
Butt seems to have a need here.


>
> > https://reviews.llvm.org/D22796
> >
> > Files:
> >   include/llvm/ADT/ScopeExit.h
> >   unittests/ADT/CMakeLists.txt
> >   unittests/ADT/ScopeExitTest.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 "gtest/gtest.h"
> > +
> > +#include <functional>
> > +#include <vector>
> > +
> > +using namespace llvm;
> > +
> > +namespace {
> > +
> > +TEST(ScopeExitTest, Copy) {
> > +  std::vector<int> v;
> > +  const 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((std::vector<int>{1}), v);
> > +  }
> > +  EXPECT_EQ((std::vector<int>{1, 2, 0}), v);
> > +}
> > +
> > +TEST(ScopeExitTest, Move) {
> > +  bool succ = false;
> > +  std::function<void()> f([&succ] { succ = true; });
> > +  ASSERT_TRUE(static_cast<bool>(f));
> > +  {
> > +    auto g4 = make_scope_exit(std::move(f));
> > +    EXPECT_FALSE(f);
> > +    EXPECT_FALSE(succ);
> > +  }
> > +  EXPECT_TRUE(succ);
> > +}
> > +}
> > 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: include/llvm/ADT/ScopeExit.h
> > ===================================================================
> > --- /dev/null
> > +++ include/llvm/ADT/ScopeExit.h
> > @@ -0,0 +1,54 @@
> > +//===- 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.
>
> It's probably worth mentioning briefly what the function does here.
>

Done.


>
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_ADT_SCOPE_EXIT_H
> > +#define LLVM_ADT_SCOPE_EXIT_H
> > +
> > +#include "llvm/Support/Compiler.h"
> > +
> > +#include <type_traits>
> > +#include <utility>
> > +
> > +namespace llvm {
> > +namespace detail {
> > +
> > +template <typename Callable> class scope_exit {
> > +  Callable ExitFunction;
> > +
> > +public:
> > +  scope_exit() = delete;
> > +
> > +  template <typename Fp>
> > +  explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
> > +
> > +  ~scope_exit() { ExitFunction(); }
> > +};
> > +
> > +} // detail
>
> I think "end namespace detail" is more common.
>

Done.


>
> > +
> > +// 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 <typename Callable>
> > +LLVM_ATTRIBUTE_UNUSED_RESULT
> > +detail::scope_exit<typename std::decay<Callable>::type>
> > +make_scope_exit(Callable &&F) {
> > +  return detail::scope_exit<typename std::decay<Callable>::type>(
> > +      std::forward<Callable>(F));
> > +}
> > +
> > +} // llvm
> > +
> > +#endif
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160809/7ddb2f95/attachment.html>


More information about the llvm-commits mailing list