llvm/llvm/include/llvm/Support/raw_ostream.h

//===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the raw_ostream class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
#define LLVM_SUPPORT_RAW_OSTREAM_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>

namespace llvm {

class Duration;
class formatv_object_base;
class format_object_base;
class FormattedString;
class FormattedNumber;
class FormattedBytes;
template <class T> class [[nodiscard]] Expected;

namespace sys {
namespace fs {
enum FileAccess : unsigned;
enum OpenFlags : unsigned;
enum CreationDisposition : unsigned;
class FileLocker;
} // end namespace fs
} // end namespace sys

/// This class implements an extremely fast bulk output stream that can *only*
/// output to a stream.  It does not support seeking, reopening, rewinding, line
/// buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {};

/// Call the appropriate insertion operator, given an rvalue reference to a
/// raw_ostream object and return a stream of the same type as the argument.
template <typename OStream, typename T>
std::enable_if_t<!std::is_reference_v<OStream> &&
                     std::is_base_of_v<raw_ostream, OStream>,
                 OStream &&>
operator<<(OStream &&OS, const T &Value) {}

/// An abstract base class for streams implementations that also support a
/// pwrite operation. This is useful for code that can mostly stream out data,
/// but needs to patch in a header that needs to know the output size.
class raw_pwrite_stream : public raw_ostream {};

//===----------------------------------------------------------------------===//
// File Output Streams
//===----------------------------------------------------------------------===//

/// A raw_ostream that writes to a file descriptor.
///
class raw_fd_ostream : public raw_pwrite_stream {};

/// This returns a reference to a raw_fd_ostream for standard output. Use it
/// like: outs() << "foo" << "bar";
raw_fd_ostream &outs();

/// This returns a reference to a raw_ostream for standard error.
/// Use it like: errs() << "foo" << "bar";
/// By default, the stream is tied to stdout to ensure stdout is flushed before
/// stderr is written, to ensure the error messages are written in their
/// expected place.
raw_fd_ostream &errs();

/// This returns a reference to a raw_ostream which simply discards output.
raw_ostream &nulls();

//===----------------------------------------------------------------------===//
// File Streams
//===----------------------------------------------------------------------===//

/// A raw_ostream of a file for reading/writing/seeking.
///
class raw_fd_stream : public raw_fd_ostream {};

//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//

/// A raw_ostream that writes to an std::string.  This is a simple adaptor
/// class. This class does not encounter output errors.
/// raw_string_ostream operates without a buffer, delegating all memory
/// management to the std::string. Thus the std::string is always up-to-date,
/// may be used directly and there is no need to call flush().
class raw_string_ostream : public raw_ostream {};

/// A raw_ostream that writes to an SmallVector or SmallString.  This is a
/// simple adaptor class. This class does not encounter output errors.
/// raw_svector_ostream operates without a buffer, delegating all memory
/// management to the SmallString. Thus the SmallString is always up-to-date,
/// may be used directly and there is no need to call flush().
class raw_svector_ostream : public raw_pwrite_stream {};

/// A raw_ostream that discards all output.
class raw_null_ostream : public raw_pwrite_stream {};

class buffer_ostream : public raw_svector_ostream {};

class buffer_unique_ostream : public raw_svector_ostream {};

// Helper struct to add indentation to raw_ostream. Instead of
// OS.indent(6) << "more stuff";
// you can use
// OS << indent(6) << "more stuff";
// which has better ergonomics (and clang-formats better as well).
//
// If indentation is always in increments of a fixed value, you can use Scale
// to set that value once. So indent(1, 2) will add 2 spaces and
// indent(1,2) + 1 will add 4 spaces.
struct indent {};

inline raw_ostream &operator<<(raw_ostream &OS, const indent &Indent) {}

class Error;

/// This helper creates an output stream and then passes it to \p Write.
/// The stream created is based on the specified \p OutputFileName:
/// llvm::outs for "-", raw_null_ostream for "/dev/null", and raw_fd_ostream
/// for other names. For raw_fd_ostream instances, the stream writes to
/// a temporary file. The final output file is atomically replaced with the
/// temporary file after the \p Write function is finished.
Error writeToOutput(StringRef OutputFileName,
                    std::function<Error(raw_ostream &)> Write);

raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);

template <typename T, typename = decltype(std::declval<raw_ostream &>()
                                          << std::declval<const T &>())>
raw_ostream &operator<<(raw_ostream &OS, const std::optional<T> &O) {}

} // end namespace llvm

#endif // LLVM_SUPPORT_RAW_OSTREAM_H