brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 76dcdee Raw
86 lines · c
1//===-- raw-ostream.h - Support for printing using raw_ostream --*- 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// This file is not part of gtest, but extends it to support LLVM libraries.9// This is not a public API for testing - it's a detail of LLVM's gtest.10//11// gtest allows providing printers for custom types by defining operator<<.12// In LLVM, operator<< usually takes llvm:raw_ostream& instead of std::ostream&.13//14// This file defines a template printable(V), which returns a version of V that15// can be streamed into a std::ostream.16//17// This interface is chosen so that in the default case (printable(V) is V),18// the main gtest code calls operator<<(OS, V) itself. gtest-printers carefully19// controls the lookup to enable fallback printing (see testing::internal2).20//===----------------------------------------------------------------------===//21 22#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_23#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_24 25namespace llvm_gtest {26// StreamSwitch is a trait that tells us how to stream a T into a std::ostream.27// By default, we just stream the T directly. We'll specialize this later.28template <typename T, typename Enable = void> struct StreamSwitch {29  static const T& printable(const T& V) { return V; }30};31 32// printable() returns a version of its argument that can be streamed into a33// std::ostream. This may be the argument itself, or some other representation.34template <typename T> decltype(auto) printable(const T &V) {35  // We delegate to the trait, to allow partial specialization.36  return StreamSwitch<T>::printable(V);37}38} // namespace llvm_gtest39 40// If raw_ostream support is enabled, we specialize for types with operator<<41// that takes a raw_ostream.42#if !GTEST_NO_LLVM_SUPPORT43#include "llvm/Support/raw_os_ostream.h"44#include "llvm/Support/raw_ostream.h"45#include <optional>46#include <ostream>47namespace llvm_gtest {48 49// The printable() of a raw_ostream-enabled type T is a RawStreamProxy<T>.50// It uses raw_os_ostream to write the wrapped value to a std::ostream.51template <typename T>52struct RawStreamProxy {53  const T& V;54  friend std::ostream &operator<<(std::ostream &S, const RawStreamProxy<T> &V) {55    llvm::raw_os_ostream OS(S);56    OS << V.V;57    return S;58  }59};60 61// We enable raw_ostream treatment if `(raw_ostream&) << (const T&)` is valid.62// We don't want implicit conversions on the RHS (e.g. to bool!), so "consume"63// the possible conversion by passing something convertible to const T& instead.64template <typename T> struct ConvertibleTo { operator T(); };65template <typename T>66struct StreamSwitch<T, decltype((void)(std::declval<llvm::raw_ostream &>()67                                       << ConvertibleTo<const T &>()))> {68  static const RawStreamProxy<T> printable(const T &V) { return {V}; }69};70 71// std::optional has a template operator<<, which means it will not accept any72// implicit conversions, so we need to special-case it here.73template <typename T>74struct StreamSwitch<std::optional<T>,75                    decltype((void)(std::declval<llvm::raw_ostream &>()76                                    << std::declval<std::optional<T>>()))> {77  static const RawStreamProxy<std::optional<T>>78  printable(const std::optional<T> &V) {79    return {V};80  }81};82} // namespace llvm_gtest83#endif  // !GTEST_NO_LLVM_SUPPORT84 85#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_86