91 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H10#define LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H11 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 SubsystemRAII22template <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>::type28 CallInitialize() {29 T::Initialize();30 }31 32 /// Calls ::Initialize if it has a llvm::Error return type and checks33 /// 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>::type37 CallInitialize() {38 ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded());39 }40 41 SubsystemRAIICase() { CallInitialize(); }42 ~SubsystemRAIICase() { T::Terminate(); }43};44} // namespace detail45 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 for51/// the subsystems specified by its template arguments. The ::Initialize52/// functions are called on construction for each subsystem template parameter53/// in the order in which they are passed as template parameters.54/// The ::Terminate functions are called in the reverse order at destruction55/// time.56///57/// If the ::Initialize function returns an llvm::Error this function handles58/// 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/// @endcode68///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/// @endcode84template <typename T, typename... Ts> class SubsystemRAII<T, Ts...> {85 detail::SubsystemRAIICase<T> CurrentSubsystem;86 SubsystemRAII<Ts...> RemainingSubsystems;87};88} // namespace lldb_private89 90#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H91