1 //===- SubsystemRAII.h ------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
10 #define LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
12 #include "llvm/Support/Error.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gtest/gtest.h"
15 #include <type_traits>
17 namespace lldb_private
{
20 /// Initializes and deinitializes a single subsystem.
21 /// @see SubsystemRAII
22 template <typename T
> struct SubsystemRAIICase
{
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
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
38 ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded());
41 SubsystemRAIICase() { CallInitialize(); }
42 ~SubsystemRAIICase() { T::Terminate(); }
46 template <typename
... T
> class SubsystemRAII
{};
48 /// RAII for initializing and deinitializing LLDB subsystems.
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
57 /// If the ::Initialize function returns an llvm::Error this function handles
58 /// the Error instance (by checking that there is no error).
60 /// Constructing this RAII in a scope like this:
64 /// SubsystemRAII<FileSystem, HostInfo, Socket> Subsystems;
69 /// is equivalent to the following code:
73 /// FileSystem::Initialize();
74 /// HostInfo::Initialize();
75 /// ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
79 /// Socket::Terminate();
80 /// FileSystem::Terminate();
81 /// HostInfo::Terminate();
84 template <typename T
, typename
... Ts
> class SubsystemRAII
<T
, Ts
...> {
85 detail::SubsystemRAIICase
<T
> CurrentSubsystem
;
86 SubsystemRAII
<Ts
...> RemainingSubsystems
;
88 } // namespace lldb_private
90 #endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H