• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- SubsystemRAII.h ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
10 #define LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
11 
12 #include "llvm/Support/Error.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gtest/gtest.h"
15 #include <type_traits>
16 
17 namespace lldb_private {
18 
19 namespace detail {
20 /// Initializes and deinitializes a single subsystem.
21 /// @see SubsystemRAII
22 template <typename T> struct SubsystemRAIICase {
23 
24   /// Calls ::Initialize if it has a void return type.
25   template <typename U = T>
26   typename std::enable_if<
27       std::is_same<decltype(U::Initialize()), void>::value>::type
CallInitializeSubsystemRAIICase28   CallInitialize() {
29     T::Initialize();
30   }
31 
32   /// Calls ::Initialize if it has a llvm::Error return type and checks
33   /// the Error instance for success.
34   template <typename U = T>
35   typename std::enable_if<
36       std::is_same<decltype(U::Initialize()), llvm::Error>::value>::type
CallInitializeSubsystemRAIICase37   CallInitialize() {
38     ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded());
39   }
40 
SubsystemRAIICaseSubsystemRAIICase41   SubsystemRAIICase() { CallInitialize(); }
~SubsystemRAIICaseSubsystemRAIICase42   ~SubsystemRAIICase() { T::Terminate(); }
43 };
44 } // namespace detail
45 
46 template <typename... T> class SubsystemRAII {};
47 
48 /// RAII for initializing and deinitializing LLDB subsystems.
49 ///
50 /// This RAII takes care of calling the Initialize and Terminate functions for
51 /// the subsystems specified by its template arguments. The ::Initialize
52 /// functions are called on construction for each subsystem template parameter
53 /// in the order in which they are passed as template parameters.
54 /// The ::Terminate functions are called in the reverse order at destruction
55 /// time.
56 ///
57 /// If the ::Initialize function returns an llvm::Error this function handles
58 /// the Error instance (by checking that there is no error).
59 ///
60 /// Constructing this RAII in a scope like this:
61 ///
62 ///   @code{.cpp}
63 ///   {
64 ///     SubsystemRAII<FileSystem, HostInfo, Socket> Subsystems;
65 ///     DoingTestWork();
66 ///   }
67 ///   @endcode
68 ///
69 /// is equivalent to the following code:
70 ///
71 ///   @code{.cpp}
72 ///   {
73 ///     FileSystem::Initialize();
74 ///     HostInfo::Initialize();
75 ///     ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
76 ///
77 ///     DoingTestWork();
78 ///
79 ///     Socket::Terminate();
80 ///     FileSystem::Terminate();
81 ///     HostInfo::Terminate();
82 ///   }
83 ///   @endcode
84 template <typename T, typename... Ts> class SubsystemRAII<T, Ts...> {
85   detail::SubsystemRAIICase<T> CurrentSubsystem;
86   SubsystemRAII<Ts...> RemainingSubsystems;
87 };
88 } // namespace lldb_private
89 
90 #endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
91