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
17namespace lldb_private {
18
19namespace detail {
20/// Initializes and deinitializes a single subsystem.
21/// @see SubsystemRAII
22template <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
28 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
37 CallInitialize() {
38 ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded());
39 }
40
41 SubsystemRAIICase() { CallInitialize(); }
42 ~SubsystemRAIICase() { T::Terminate(); }
43};
44} // namespace detail
45
46template <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
84template <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

source code of lldb/unittests/TestingSupport/SubsystemRAII.h