git repos / blockattack-game

blame: source/misc/embedded_libs/fmt-11.0.2/include/fmt/os.h

normal view · raw

47fd5c32 Poul Sander 2024-10-05 08:44 1
// Formatting library for C++ - optional OS-specific functionality
47fd5c32 Poul Sander 2024-10-05 08:44 2
//
47fd5c32 Poul Sander 2024-10-05 08:44 3
// Copyright (c) 2012 - present, Victor Zverovich
47fd5c32 Poul Sander 2024-10-05 08:44 4
// All rights reserved.
47fd5c32 Poul Sander 2024-10-05 08:44 5
//
47fd5c32 Poul Sander 2024-10-05 08:44 6
// For the license information refer to format.h.
47fd5c32 Poul Sander 2024-10-05 08:44 7
47fd5c32 Poul Sander 2024-10-05 08:44 8
#ifndef FMT_OS_H_
47fd5c32 Poul Sander 2024-10-05 08:44 9
#define FMT_OS_H_
47fd5c32 Poul Sander 2024-10-05 08:44 10
47fd5c32 Poul Sander 2024-10-05 08:44 11
#include "format.h"
47fd5c32 Poul Sander 2024-10-05 08:44 12
47fd5c32 Poul Sander 2024-10-05 08:44 13
#ifndef FMT_MODULE
47fd5c32 Poul Sander 2024-10-05 08:44 14
#  include <cerrno>
47fd5c32 Poul Sander 2024-10-05 08:44 15
#  include <cstddef>
47fd5c32 Poul Sander 2024-10-05 08:44 16
#  include <cstdio>
47fd5c32 Poul Sander 2024-10-05 08:44 17
#  include <system_error>  // std::system_error
47fd5c32 Poul Sander 2024-10-05 08:44 18
47fd5c32 Poul Sander 2024-10-05 08:44 19
#  if FMT_HAS_INCLUDE(<xlocale.h>)
47fd5c32 Poul Sander 2024-10-05 08:44 20
#    include <xlocale.h>  // LC_NUMERIC_MASK on macOS
47fd5c32 Poul Sander 2024-10-05 08:44 21
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 22
#endif  // FMT_MODULE
47fd5c32 Poul Sander 2024-10-05 08:44 23
47fd5c32 Poul Sander 2024-10-05 08:44 24
#ifndef FMT_USE_FCNTL
47fd5c32 Poul Sander 2024-10-05 08:44 25
// UWP doesn't provide _pipe.
47fd5c32 Poul Sander 2024-10-05 08:44 26
#  if FMT_HAS_INCLUDE("winapifamily.h")
47fd5c32 Poul Sander 2024-10-05 08:44 27
#    include <winapifamily.h>
47fd5c32 Poul Sander 2024-10-05 08:44 28
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 29
#  if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
47fd5c32 Poul Sander 2024-10-05 08:44 30
       defined(__linux__)) &&                              \
47fd5c32 Poul Sander 2024-10-05 08:44 31
      (!defined(WINAPI_FAMILY) ||                          \
47fd5c32 Poul Sander 2024-10-05 08:44 32
       (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
47fd5c32 Poul Sander 2024-10-05 08:44 33
#    include <fcntl.h>  // for O_RDONLY
47fd5c32 Poul Sander 2024-10-05 08:44 34
#    define FMT_USE_FCNTL 1
47fd5c32 Poul Sander 2024-10-05 08:44 35
#  else
47fd5c32 Poul Sander 2024-10-05 08:44 36
#    define FMT_USE_FCNTL 0
47fd5c32 Poul Sander 2024-10-05 08:44 37
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 38
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 39
47fd5c32 Poul Sander 2024-10-05 08:44 40
#ifndef FMT_POSIX
47fd5c32 Poul Sander 2024-10-05 08:44 41
#  if defined(_WIN32) && !defined(__MINGW32__)
47fd5c32 Poul Sander 2024-10-05 08:44 42
// Fix warnings about deprecated symbols.
47fd5c32 Poul Sander 2024-10-05 08:44 43
#    define FMT_POSIX(call) _##call
47fd5c32 Poul Sander 2024-10-05 08:44 44
#  else
47fd5c32 Poul Sander 2024-10-05 08:44 45
#    define FMT_POSIX(call) call
47fd5c32 Poul Sander 2024-10-05 08:44 46
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 47
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 48
47fd5c32 Poul Sander 2024-10-05 08:44 49
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
47fd5c32 Poul Sander 2024-10-05 08:44 50
#ifdef FMT_SYSTEM
47fd5c32 Poul Sander 2024-10-05 08:44 51
#  define FMT_HAS_SYSTEM
47fd5c32 Poul Sander 2024-10-05 08:44 52
#  define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
47fd5c32 Poul Sander 2024-10-05 08:44 53
#else
47fd5c32 Poul Sander 2024-10-05 08:44 54
#  define FMT_SYSTEM(call) ::call
47fd5c32 Poul Sander 2024-10-05 08:44 55
#  ifdef _WIN32
47fd5c32 Poul Sander 2024-10-05 08:44 56
// Fix warnings about deprecated symbols.
47fd5c32 Poul Sander 2024-10-05 08:44 57
#    define FMT_POSIX_CALL(call) ::_##call
47fd5c32 Poul Sander 2024-10-05 08:44 58
#  else
47fd5c32 Poul Sander 2024-10-05 08:44 59
#    define FMT_POSIX_CALL(call) ::call
47fd5c32 Poul Sander 2024-10-05 08:44 60
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 61
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 62
47fd5c32 Poul Sander 2024-10-05 08:44 63
// Retries the expression while it evaluates to error_result and errno
47fd5c32 Poul Sander 2024-10-05 08:44 64
// equals to EINTR.
47fd5c32 Poul Sander 2024-10-05 08:44 65
#ifndef _WIN32
47fd5c32 Poul Sander 2024-10-05 08:44 66
#  define FMT_RETRY_VAL(result, expression, error_result) \
47fd5c32 Poul Sander 2024-10-05 08:44 67
    do {                                                  \
47fd5c32 Poul Sander 2024-10-05 08:44 68
      (result) = (expression);                            \
47fd5c32 Poul Sander 2024-10-05 08:44 69
    } while ((result) == (error_result) && errno == EINTR)
47fd5c32 Poul Sander 2024-10-05 08:44 70
#else
47fd5c32 Poul Sander 2024-10-05 08:44 71
#  define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
47fd5c32 Poul Sander 2024-10-05 08:44 72
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 73
47fd5c32 Poul Sander 2024-10-05 08:44 74
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
47fd5c32 Poul Sander 2024-10-05 08:44 75
47fd5c32 Poul Sander 2024-10-05 08:44 76
FMT_BEGIN_NAMESPACE
47fd5c32 Poul Sander 2024-10-05 08:44 77
FMT_BEGIN_EXPORT
47fd5c32 Poul Sander 2024-10-05 08:44 78
47fd5c32 Poul Sander 2024-10-05 08:44 79
/**
47fd5c32 Poul Sander 2024-10-05 08:44 80
 * A reference to a null-terminated string. It can be constructed from a C
47fd5c32 Poul Sander 2024-10-05 08:44 81
 * string or `std::string`.
47fd5c32 Poul Sander 2024-10-05 08:44 82
 *
47fd5c32 Poul Sander 2024-10-05 08:44 83
 * You can use one of the following type aliases for common character types:
47fd5c32 Poul Sander 2024-10-05 08:44 84
 *
47fd5c32 Poul Sander 2024-10-05 08:44 85
 * +---------------+-----------------------------+
47fd5c32 Poul Sander 2024-10-05 08:44 86
 * | Type          | Definition                  |
47fd5c32 Poul Sander 2024-10-05 08:44 87
 * +===============+=============================+
47fd5c32 Poul Sander 2024-10-05 08:44 88
 * | cstring_view  | basic_cstring_view<char>    |
47fd5c32 Poul Sander 2024-10-05 08:44 89
 * +---------------+-----------------------------+
47fd5c32 Poul Sander 2024-10-05 08:44 90
 * | wcstring_view | basic_cstring_view<wchar_t> |
47fd5c32 Poul Sander 2024-10-05 08:44 91
 * +---------------+-----------------------------+
47fd5c32 Poul Sander 2024-10-05 08:44 92
 *
47fd5c32 Poul Sander 2024-10-05 08:44 93
 * This class is most useful as a parameter type for functions that wrap C APIs.
47fd5c32 Poul Sander 2024-10-05 08:44 94
 */
47fd5c32 Poul Sander 2024-10-05 08:44 95
template <typename Char> class basic_cstring_view {
47fd5c32 Poul Sander 2024-10-05 08:44 96
 private:
47fd5c32 Poul Sander 2024-10-05 08:44 97
  const Char* data_;
47fd5c32 Poul Sander 2024-10-05 08:44 98
47fd5c32 Poul Sander 2024-10-05 08:44 99
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 100
  /// Constructs a string reference object from a C string.
47fd5c32 Poul Sander 2024-10-05 08:44 101
  basic_cstring_view(const Char* s) : data_(s) {}
47fd5c32 Poul Sander 2024-10-05 08:44 102
47fd5c32 Poul Sander 2024-10-05 08:44 103
  /// Constructs a string reference from an `std::string` object.
47fd5c32 Poul Sander 2024-10-05 08:44 104
  basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
47fd5c32 Poul Sander 2024-10-05 08:44 105
47fd5c32 Poul Sander 2024-10-05 08:44 106
  /// Returns the pointer to a C string.
47fd5c32 Poul Sander 2024-10-05 08:44 107
  auto c_str() const -> const Char* { return data_; }
47fd5c32 Poul Sander 2024-10-05 08:44 108
};
47fd5c32 Poul Sander 2024-10-05 08:44 109
47fd5c32 Poul Sander 2024-10-05 08:44 110
using cstring_view = basic_cstring_view<char>;
47fd5c32 Poul Sander 2024-10-05 08:44 111
using wcstring_view = basic_cstring_view<wchar_t>;
47fd5c32 Poul Sander 2024-10-05 08:44 112
47fd5c32 Poul Sander 2024-10-05 08:44 113
#ifdef _WIN32
47fd5c32 Poul Sander 2024-10-05 08:44 114
FMT_API const std::error_category& system_category() noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 115
47fd5c32 Poul Sander 2024-10-05 08:44 116
namespace detail {
47fd5c32 Poul Sander 2024-10-05 08:44 117
FMT_API void format_windows_error(buffer<char>& out, int error_code,
47fd5c32 Poul Sander 2024-10-05 08:44 118
                                  const char* message) noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 119
}
47fd5c32 Poul Sander 2024-10-05 08:44 120
47fd5c32 Poul Sander 2024-10-05 08:44 121
FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
47fd5c32 Poul Sander 2024-10-05 08:44 122
                                         format_args args);
47fd5c32 Poul Sander 2024-10-05 08:44 123
47fd5c32 Poul Sander 2024-10-05 08:44 124
/**
47fd5c32 Poul Sander 2024-10-05 08:44 125
 * Constructs a `std::system_error` object with the description of the form
47fd5c32 Poul Sander 2024-10-05 08:44 126
 *
47fd5c32 Poul Sander 2024-10-05 08:44 127
 *     <message>: <system-message>
47fd5c32 Poul Sander 2024-10-05 08:44 128
 *
47fd5c32 Poul Sander 2024-10-05 08:44 129
 * where `<message>` is the formatted message and `<system-message>` is the
47fd5c32 Poul Sander 2024-10-05 08:44 130
 * system message corresponding to the error code.
47fd5c32 Poul Sander 2024-10-05 08:44 131
 * `error_code` is a Windows error code as given by `GetLastError`.
47fd5c32 Poul Sander 2024-10-05 08:44 132
 * If `error_code` is not a valid error code such as -1, the system message
47fd5c32 Poul Sander 2024-10-05 08:44 133
 * will look like "error -1".
47fd5c32 Poul Sander 2024-10-05 08:44 134
 *
47fd5c32 Poul Sander 2024-10-05 08:44 135
 * **Example**:
47fd5c32 Poul Sander 2024-10-05 08:44 136
 *
47fd5c32 Poul Sander 2024-10-05 08:44 137
 *     // This throws a system_error with the description
47fd5c32 Poul Sander 2024-10-05 08:44 138
 *     //   cannot open file 'madeup': The system cannot find the file
47fd5c32 Poul Sander 2024-10-05 08:44 139
 * specified.
47fd5c32 Poul Sander 2024-10-05 08:44 140
 *     // or similar (system message may vary).
47fd5c32 Poul Sander 2024-10-05 08:44 141
 *     const char *filename = "madeup";
47fd5c32 Poul Sander 2024-10-05 08:44 142
 *     LPOFSTRUCT of = LPOFSTRUCT();
47fd5c32 Poul Sander 2024-10-05 08:44 143
 *     HFILE file = OpenFile(filename, &of, OF_READ);
47fd5c32 Poul Sander 2024-10-05 08:44 144
 *     if (file == HFILE_ERROR) {
47fd5c32 Poul Sander 2024-10-05 08:44 145
 *       throw fmt::windows_error(GetLastError(),
47fd5c32 Poul Sander 2024-10-05 08:44 146
 *                                "cannot open file '{}'", filename);
47fd5c32 Poul Sander 2024-10-05 08:44 147
 *     }
47fd5c32 Poul Sander 2024-10-05 08:44 148
 */
47fd5c32 Poul Sander 2024-10-05 08:44 149
template <typename... Args>
47fd5c32 Poul Sander 2024-10-05 08:44 150
std::system_error windows_error(int error_code, string_view message,
47fd5c32 Poul Sander 2024-10-05 08:44 151
                                const Args&... args) {
47fd5c32 Poul Sander 2024-10-05 08:44 152
  return vwindows_error(error_code, message, fmt::make_format_args(args...));
47fd5c32 Poul Sander 2024-10-05 08:44 153
}
47fd5c32 Poul Sander 2024-10-05 08:44 154
47fd5c32 Poul Sander 2024-10-05 08:44 155
// Reports a Windows error without throwing an exception.
47fd5c32 Poul Sander 2024-10-05 08:44 156
// Can be used to report errors from destructors.
47fd5c32 Poul Sander 2024-10-05 08:44 157
FMT_API void report_windows_error(int error_code, const char* message) noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 158
#else
47fd5c32 Poul Sander 2024-10-05 08:44 159
inline auto system_category() noexcept -> const std::error_category& {
47fd5c32 Poul Sander 2024-10-05 08:44 160
  return std::system_category();
47fd5c32 Poul Sander 2024-10-05 08:44 161
}
47fd5c32 Poul Sander 2024-10-05 08:44 162
#endif  // _WIN32
47fd5c32 Poul Sander 2024-10-05 08:44 163
47fd5c32 Poul Sander 2024-10-05 08:44 164
// std::system is not available on some platforms such as iOS (#2248).
47fd5c32 Poul Sander 2024-10-05 08:44 165
#ifdef __OSX__
47fd5c32 Poul Sander 2024-10-05 08:44 166
template <typename S, typename... Args, typename Char = char_t<S>>
47fd5c32 Poul Sander 2024-10-05 08:44 167
void say(const S& format_str, Args&&... args) {
47fd5c32 Poul Sander 2024-10-05 08:44 168
  std::system(format("say \"{}\"", format(format_str, args...)).c_str());
47fd5c32 Poul Sander 2024-10-05 08:44 169
}
47fd5c32 Poul Sander 2024-10-05 08:44 170
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 171
47fd5c32 Poul Sander 2024-10-05 08:44 172
// A buffered file.
47fd5c32 Poul Sander 2024-10-05 08:44 173
class buffered_file {
47fd5c32 Poul Sander 2024-10-05 08:44 174
 private:
47fd5c32 Poul Sander 2024-10-05 08:44 175
  FILE* file_;
47fd5c32 Poul Sander 2024-10-05 08:44 176
47fd5c32 Poul Sander 2024-10-05 08:44 177
  friend class file;
47fd5c32 Poul Sander 2024-10-05 08:44 178
47fd5c32 Poul Sander 2024-10-05 08:44 179
  explicit buffered_file(FILE* f) : file_(f) {}
47fd5c32 Poul Sander 2024-10-05 08:44 180
47fd5c32 Poul Sander 2024-10-05 08:44 181
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 182
  buffered_file(const buffered_file&) = delete;
47fd5c32 Poul Sander 2024-10-05 08:44 183
  void operator=(const buffered_file&) = delete;
47fd5c32 Poul Sander 2024-10-05 08:44 184
47fd5c32 Poul Sander 2024-10-05 08:44 185
  // Constructs a buffered_file object which doesn't represent any file.
47fd5c32 Poul Sander 2024-10-05 08:44 186
  buffered_file() noexcept : file_(nullptr) {}
47fd5c32 Poul Sander 2024-10-05 08:44 187
47fd5c32 Poul Sander 2024-10-05 08:44 188
  // Destroys the object closing the file it represents if any.
47fd5c32 Poul Sander 2024-10-05 08:44 189
  FMT_API ~buffered_file() noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 190
47fd5c32 Poul Sander 2024-10-05 08:44 191
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 192
  buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
47fd5c32 Poul Sander 2024-10-05 08:44 193
    other.file_ = nullptr;
47fd5c32 Poul Sander 2024-10-05 08:44 194
  }
47fd5c32 Poul Sander 2024-10-05 08:44 195
47fd5c32 Poul Sander 2024-10-05 08:44 196
  auto operator=(buffered_file&& other) -> buffered_file& {
47fd5c32 Poul Sander 2024-10-05 08:44 197
    close();
47fd5c32 Poul Sander 2024-10-05 08:44 198
    file_ = other.file_;
47fd5c32 Poul Sander 2024-10-05 08:44 199
    other.file_ = nullptr;
47fd5c32 Poul Sander 2024-10-05 08:44 200
    return *this;
47fd5c32 Poul Sander 2024-10-05 08:44 201
  }
47fd5c32 Poul Sander 2024-10-05 08:44 202
47fd5c32 Poul Sander 2024-10-05 08:44 203
  // Opens a file.
47fd5c32 Poul Sander 2024-10-05 08:44 204
  FMT_API buffered_file(cstring_view filename, cstring_view mode);
47fd5c32 Poul Sander 2024-10-05 08:44 205
47fd5c32 Poul Sander 2024-10-05 08:44 206
  // Closes the file.
47fd5c32 Poul Sander 2024-10-05 08:44 207
  FMT_API void close();
47fd5c32 Poul Sander 2024-10-05 08:44 208
47fd5c32 Poul Sander 2024-10-05 08:44 209
  // Returns the pointer to a FILE object representing this file.
47fd5c32 Poul Sander 2024-10-05 08:44 210
  auto get() const noexcept -> FILE* { return file_; }
47fd5c32 Poul Sander 2024-10-05 08:44 211
47fd5c32 Poul Sander 2024-10-05 08:44 212
  FMT_API auto descriptor() const -> int;
47fd5c32 Poul Sander 2024-10-05 08:44 213
47fd5c32 Poul Sander 2024-10-05 08:44 214
  template <typename... T>
47fd5c32 Poul Sander 2024-10-05 08:44 215
  inline void print(string_view fmt, const T&... args) {
47fd5c32 Poul Sander 2024-10-05 08:44 216
    const auto& vargs = fmt::make_format_args(args...);
47fd5c32 Poul Sander 2024-10-05 08:44 217
    detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)
47fd5c32 Poul Sander 2024-10-05 08:44 218
                               : fmt::vprint(file_, fmt, vargs);
47fd5c32 Poul Sander 2024-10-05 08:44 219
  }
47fd5c32 Poul Sander 2024-10-05 08:44 220
};
47fd5c32 Poul Sander 2024-10-05 08:44 221
47fd5c32 Poul Sander 2024-10-05 08:44 222
#if FMT_USE_FCNTL
47fd5c32 Poul Sander 2024-10-05 08:44 223
47fd5c32 Poul Sander 2024-10-05 08:44 224
// A file. Closed file is represented by a file object with descriptor -1.
47fd5c32 Poul Sander 2024-10-05 08:44 225
// Methods that are not declared with noexcept may throw
47fd5c32 Poul Sander 2024-10-05 08:44 226
// fmt::system_error in case of failure. Note that some errors such as
47fd5c32 Poul Sander 2024-10-05 08:44 227
// closing the file multiple times will cause a crash on Windows rather
47fd5c32 Poul Sander 2024-10-05 08:44 228
// than an exception. You can get standard behavior by overriding the
47fd5c32 Poul Sander 2024-10-05 08:44 229
// invalid parameter handler with _set_invalid_parameter_handler.
47fd5c32 Poul Sander 2024-10-05 08:44 230
class FMT_API file {
47fd5c32 Poul Sander 2024-10-05 08:44 231
 private:
47fd5c32 Poul Sander 2024-10-05 08:44 232
  int fd_;  // File descriptor.
47fd5c32 Poul Sander 2024-10-05 08:44 233
47fd5c32 Poul Sander 2024-10-05 08:44 234
  // Constructs a file object with a given descriptor.
47fd5c32 Poul Sander 2024-10-05 08:44 235
  explicit file(int fd) : fd_(fd) {}
47fd5c32 Poul Sander 2024-10-05 08:44 236
47fd5c32 Poul Sander 2024-10-05 08:44 237
  friend struct pipe;
47fd5c32 Poul Sander 2024-10-05 08:44 238
47fd5c32 Poul Sander 2024-10-05 08:44 239
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 240
  // Possible values for the oflag argument to the constructor.
47fd5c32 Poul Sander 2024-10-05 08:44 241
  enum {
47fd5c32 Poul Sander 2024-10-05 08:44 242
    RDONLY = FMT_POSIX(O_RDONLY),  // Open for reading only.
47fd5c32 Poul Sander 2024-10-05 08:44 243
    WRONLY = FMT_POSIX(O_WRONLY),  // Open for writing only.
47fd5c32 Poul Sander 2024-10-05 08:44 244
    RDWR = FMT_POSIX(O_RDWR),      // Open for reading and writing.
47fd5c32 Poul Sander 2024-10-05 08:44 245
    CREATE = FMT_POSIX(O_CREAT),   // Create if the file doesn't exist.
47fd5c32 Poul Sander 2024-10-05 08:44 246
    APPEND = FMT_POSIX(O_APPEND),  // Open in append mode.
47fd5c32 Poul Sander 2024-10-05 08:44 247
    TRUNC = FMT_POSIX(O_TRUNC)     // Truncate the content of the file.
47fd5c32 Poul Sander 2024-10-05 08:44 248
  };
47fd5c32 Poul Sander 2024-10-05 08:44 249
47fd5c32 Poul Sander 2024-10-05 08:44 250
  // Constructs a file object which doesn't represent any file.
47fd5c32 Poul Sander 2024-10-05 08:44 251
  file() noexcept : fd_(-1) {}
47fd5c32 Poul Sander 2024-10-05 08:44 252
47fd5c32 Poul Sander 2024-10-05 08:44 253
  // Opens a file and constructs a file object representing this file.
47fd5c32 Poul Sander 2024-10-05 08:44 254
  file(cstring_view path, int oflag);
47fd5c32 Poul Sander 2024-10-05 08:44 255
47fd5c32 Poul Sander 2024-10-05 08:44 256
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 257
  file(const file&) = delete;
47fd5c32 Poul Sander 2024-10-05 08:44 258
  void operator=(const file&) = delete;
47fd5c32 Poul Sander 2024-10-05 08:44 259
47fd5c32 Poul Sander 2024-10-05 08:44 260
  file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
47fd5c32 Poul Sander 2024-10-05 08:44 261
47fd5c32 Poul Sander 2024-10-05 08:44 262
  // Move assignment is not noexcept because close may throw.
47fd5c32 Poul Sander 2024-10-05 08:44 263
  auto operator=(file&& other) -> file& {
47fd5c32 Poul Sander 2024-10-05 08:44 264
    close();
47fd5c32 Poul Sander 2024-10-05 08:44 265
    fd_ = other.fd_;
47fd5c32 Poul Sander 2024-10-05 08:44 266
    other.fd_ = -1;
47fd5c32 Poul Sander 2024-10-05 08:44 267
    return *this;
47fd5c32 Poul Sander 2024-10-05 08:44 268
  }
47fd5c32 Poul Sander 2024-10-05 08:44 269
47fd5c32 Poul Sander 2024-10-05 08:44 270
  // Destroys the object closing the file it represents if any.
47fd5c32 Poul Sander 2024-10-05 08:44 271
  ~file() noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 272
47fd5c32 Poul Sander 2024-10-05 08:44 273
  // Returns the file descriptor.
47fd5c32 Poul Sander 2024-10-05 08:44 274
  auto descriptor() const noexcept -> int { return fd_; }
47fd5c32 Poul Sander 2024-10-05 08:44 275
47fd5c32 Poul Sander 2024-10-05 08:44 276
  // Closes the file.
47fd5c32 Poul Sander 2024-10-05 08:44 277
  void close();
47fd5c32 Poul Sander 2024-10-05 08:44 278
47fd5c32 Poul Sander 2024-10-05 08:44 279
  // Returns the file size. The size has signed type for consistency with
47fd5c32 Poul Sander 2024-10-05 08:44 280
  // stat::st_size.
47fd5c32 Poul Sander 2024-10-05 08:44 281
  auto size() const -> long long;
47fd5c32 Poul Sander 2024-10-05 08:44 282
47fd5c32 Poul Sander 2024-10-05 08:44 283
  // Attempts to read count bytes from the file into the specified buffer.
47fd5c32 Poul Sander 2024-10-05 08:44 284
  auto read(void* buffer, size_t count) -> size_t;
47fd5c32 Poul Sander 2024-10-05 08:44 285
47fd5c32 Poul Sander 2024-10-05 08:44 286
  // Attempts to write count bytes from the specified buffer to the file.
47fd5c32 Poul Sander 2024-10-05 08:44 287
  auto write(const void* buffer, size_t count) -> size_t;
47fd5c32 Poul Sander 2024-10-05 08:44 288
47fd5c32 Poul Sander 2024-10-05 08:44 289
  // Duplicates a file descriptor with the dup function and returns
47fd5c32 Poul Sander 2024-10-05 08:44 290
  // the duplicate as a file object.
47fd5c32 Poul Sander 2024-10-05 08:44 291
  static auto dup(int fd) -> file;
47fd5c32 Poul Sander 2024-10-05 08:44 292
47fd5c32 Poul Sander 2024-10-05 08:44 293
  // Makes fd be the copy of this file descriptor, closing fd first if
47fd5c32 Poul Sander 2024-10-05 08:44 294
  // necessary.
47fd5c32 Poul Sander 2024-10-05 08:44 295
  void dup2(int fd);
47fd5c32 Poul Sander 2024-10-05 08:44 296
47fd5c32 Poul Sander 2024-10-05 08:44 297
  // Makes fd be the copy of this file descriptor, closing fd first if
47fd5c32 Poul Sander 2024-10-05 08:44 298
  // necessary.
47fd5c32 Poul Sander 2024-10-05 08:44 299
  void dup2(int fd, std::error_code& ec) noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 300
47fd5c32 Poul Sander 2024-10-05 08:44 301
  // Creates a buffered_file object associated with this file and detaches
47fd5c32 Poul Sander 2024-10-05 08:44 302
  // this file object from the file.
47fd5c32 Poul Sander 2024-10-05 08:44 303
  auto fdopen(const char* mode) -> buffered_file;
47fd5c32 Poul Sander 2024-10-05 08:44 304
47fd5c32 Poul Sander 2024-10-05 08:44 305
#  if defined(_WIN32) && !defined(__MINGW32__)
47fd5c32 Poul Sander 2024-10-05 08:44 306
  // Opens a file and constructs a file object representing this file by
47fd5c32 Poul Sander 2024-10-05 08:44 307
  // wcstring_view filename. Windows only.
47fd5c32 Poul Sander 2024-10-05 08:44 308
  static file open_windows_file(wcstring_view path, int oflag);
47fd5c32 Poul Sander 2024-10-05 08:44 309
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 310
};
47fd5c32 Poul Sander 2024-10-05 08:44 311
47fd5c32 Poul Sander 2024-10-05 08:44 312
struct FMT_API pipe {
47fd5c32 Poul Sander 2024-10-05 08:44 313
  file read_end;
47fd5c32 Poul Sander 2024-10-05 08:44 314
  file write_end;
47fd5c32 Poul Sander 2024-10-05 08:44 315
47fd5c32 Poul Sander 2024-10-05 08:44 316
  // Creates a pipe setting up read_end and write_end file objects for reading
47fd5c32 Poul Sander 2024-10-05 08:44 317
  // and writing respectively.
47fd5c32 Poul Sander 2024-10-05 08:44 318
  pipe();
47fd5c32 Poul Sander 2024-10-05 08:44 319
};
47fd5c32 Poul Sander 2024-10-05 08:44 320
47fd5c32 Poul Sander 2024-10-05 08:44 321
// Returns the memory page size.
47fd5c32 Poul Sander 2024-10-05 08:44 322
auto getpagesize() -> long;
47fd5c32 Poul Sander 2024-10-05 08:44 323
47fd5c32 Poul Sander 2024-10-05 08:44 324
namespace detail {
47fd5c32 Poul Sander 2024-10-05 08:44 325
47fd5c32 Poul Sander 2024-10-05 08:44 326
struct buffer_size {
47fd5c32 Poul Sander 2024-10-05 08:44 327
  buffer_size() = default;
47fd5c32 Poul Sander 2024-10-05 08:44 328
  size_t value = 0;
47fd5c32 Poul Sander 2024-10-05 08:44 329
  auto operator=(size_t val) const -> buffer_size {
47fd5c32 Poul Sander 2024-10-05 08:44 330
    auto bs = buffer_size();
47fd5c32 Poul Sander 2024-10-05 08:44 331
    bs.value = val;
47fd5c32 Poul Sander 2024-10-05 08:44 332
    return bs;
47fd5c32 Poul Sander 2024-10-05 08:44 333
  }
47fd5c32 Poul Sander 2024-10-05 08:44 334
};
47fd5c32 Poul Sander 2024-10-05 08:44 335
47fd5c32 Poul Sander 2024-10-05 08:44 336
struct ostream_params {
47fd5c32 Poul Sander 2024-10-05 08:44 337
  int oflag = file::WRONLY | file::CREATE | file::TRUNC;
47fd5c32 Poul Sander 2024-10-05 08:44 338
  size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
47fd5c32 Poul Sander 2024-10-05 08:44 339
47fd5c32 Poul Sander 2024-10-05 08:44 340
  ostream_params() {}
47fd5c32 Poul Sander 2024-10-05 08:44 341
47fd5c32 Poul Sander 2024-10-05 08:44 342
  template <typename... T>
47fd5c32 Poul Sander 2024-10-05 08:44 343
  ostream_params(T... params, int new_oflag) : ostream_params(params...) {
47fd5c32 Poul Sander 2024-10-05 08:44 344
    oflag = new_oflag;
47fd5c32 Poul Sander 2024-10-05 08:44 345
  }
47fd5c32 Poul Sander 2024-10-05 08:44 346
47fd5c32 Poul Sander 2024-10-05 08:44 347
  template <typename... T>
47fd5c32 Poul Sander 2024-10-05 08:44 348
  ostream_params(T... params, detail::buffer_size bs)
47fd5c32 Poul Sander 2024-10-05 08:44 349
      : ostream_params(params...) {
47fd5c32 Poul Sander 2024-10-05 08:44 350
    this->buffer_size = bs.value;
47fd5c32 Poul Sander 2024-10-05 08:44 351
  }
47fd5c32 Poul Sander 2024-10-05 08:44 352
47fd5c32 Poul Sander 2024-10-05 08:44 353
// Intel has a bug that results in failure to deduce a constructor
47fd5c32 Poul Sander 2024-10-05 08:44 354
// for empty parameter packs.
47fd5c32 Poul Sander 2024-10-05 08:44 355
#  if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
47fd5c32 Poul Sander 2024-10-05 08:44 356
  ostream_params(int new_oflag) : oflag(new_oflag) {}
47fd5c32 Poul Sander 2024-10-05 08:44 357
  ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {}
47fd5c32 Poul Sander 2024-10-05 08:44 358
#  endif
47fd5c32 Poul Sander 2024-10-05 08:44 359
};
47fd5c32 Poul Sander 2024-10-05 08:44 360
47fd5c32 Poul Sander 2024-10-05 08:44 361
class file_buffer final : public buffer<char> {
47fd5c32 Poul Sander 2024-10-05 08:44 362
 private:
47fd5c32 Poul Sander 2024-10-05 08:44 363
  file file_;
47fd5c32 Poul Sander 2024-10-05 08:44 364
47fd5c32 Poul Sander 2024-10-05 08:44 365
  FMT_API static void grow(buffer<char>& buf, size_t);
47fd5c32 Poul Sander 2024-10-05 08:44 366
47fd5c32 Poul Sander 2024-10-05 08:44 367
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 368
  FMT_API file_buffer(cstring_view path, const ostream_params& params);
47fd5c32 Poul Sander 2024-10-05 08:44 369
  FMT_API file_buffer(file_buffer&& other) noexcept;
47fd5c32 Poul Sander 2024-10-05 08:44 370
  FMT_API ~file_buffer();
47fd5c32 Poul Sander 2024-10-05 08:44 371
47fd5c32 Poul Sander 2024-10-05 08:44 372
  void flush() {
47fd5c32 Poul Sander 2024-10-05 08:44 373
    if (size() == 0) return;
47fd5c32 Poul Sander 2024-10-05 08:44 374
    file_.write(data(), size() * sizeof(data()[0]));
47fd5c32 Poul Sander 2024-10-05 08:44 375
    clear();
47fd5c32 Poul Sander 2024-10-05 08:44 376
  }
47fd5c32 Poul Sander 2024-10-05 08:44 377
47fd5c32 Poul Sander 2024-10-05 08:44 378
  void close() {
47fd5c32 Poul Sander 2024-10-05 08:44 379
    flush();
47fd5c32 Poul Sander 2024-10-05 08:44 380
    file_.close();
47fd5c32 Poul Sander 2024-10-05 08:44 381
  }
47fd5c32 Poul Sander 2024-10-05 08:44 382
};
47fd5c32 Poul Sander 2024-10-05 08:44 383
47fd5c32 Poul Sander 2024-10-05 08:44 384
}  // namespace detail
47fd5c32 Poul Sander 2024-10-05 08:44 385
47fd5c32 Poul Sander 2024-10-05 08:44 386
constexpr auto buffer_size = detail::buffer_size();
47fd5c32 Poul Sander 2024-10-05 08:44 387
47fd5c32 Poul Sander 2024-10-05 08:44 388
/// A fast output stream for writing from a single thread. Writing from
47fd5c32 Poul Sander 2024-10-05 08:44 389
/// multiple threads without external synchronization may result in a data race.
47fd5c32 Poul Sander 2024-10-05 08:44 390
class FMT_API ostream {
47fd5c32 Poul Sander 2024-10-05 08:44 391
 private:
47fd5c32 Poul Sander 2024-10-05 08:44 392
  FMT_MSC_WARNING(suppress : 4251)
47fd5c32 Poul Sander 2024-10-05 08:44 393
  detail::file_buffer buffer_;
47fd5c32 Poul Sander 2024-10-05 08:44 394
47fd5c32 Poul Sander 2024-10-05 08:44 395
  ostream(cstring_view path, const detail::ostream_params& params)
47fd5c32 Poul Sander 2024-10-05 08:44 396
      : buffer_(path, params) {}
47fd5c32 Poul Sander 2024-10-05 08:44 397
47fd5c32 Poul Sander 2024-10-05 08:44 398
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 399
  ostream(ostream&& other) : buffer_(std::move(other.buffer_)) {}
47fd5c32 Poul Sander 2024-10-05 08:44 400
47fd5c32 Poul Sander 2024-10-05 08:44 401
  ~ostream();
47fd5c32 Poul Sander 2024-10-05 08:44 402
47fd5c32 Poul Sander 2024-10-05 08:44 403
  void flush() { buffer_.flush(); }
47fd5c32 Poul Sander 2024-10-05 08:44 404
47fd5c32 Poul Sander 2024-10-05 08:44 405
  template <typename... T>
47fd5c32 Poul Sander 2024-10-05 08:44 406
  friend auto output_file(cstring_view path, T... params) -> ostream;
47fd5c32 Poul Sander 2024-10-05 08:44 407
47fd5c32 Poul Sander 2024-10-05 08:44 408
  void close() { buffer_.close(); }
47fd5c32 Poul Sander 2024-10-05 08:44 409
47fd5c32 Poul Sander 2024-10-05 08:44 410
  /// Formats `args` according to specifications in `fmt` and writes the
47fd5c32 Poul Sander 2024-10-05 08:44 411
  /// output to the file.
47fd5c32 Poul Sander 2024-10-05 08:44 412
  template <typename... T> void print(format_string<T...> fmt, T&&... args) {
47fd5c32 Poul Sander 2024-10-05 08:44 413
    vformat_to(appender(buffer_), fmt, fmt::make_format_args(args...));
47fd5c32 Poul Sander 2024-10-05 08:44 414
  }
47fd5c32 Poul Sander 2024-10-05 08:44 415
};
47fd5c32 Poul Sander 2024-10-05 08:44 416
47fd5c32 Poul Sander 2024-10-05 08:44 417
/**
47fd5c32 Poul Sander 2024-10-05 08:44 418
 * Opens a file for writing. Supported parameters passed in `params`:
47fd5c32 Poul Sander 2024-10-05 08:44 419
 *
47fd5c32 Poul Sander 2024-10-05 08:44 420
 * - `<integer>`: Flags passed to [open](
47fd5c32 Poul Sander 2024-10-05 08:44 421
 *   https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html)
47fd5c32 Poul Sander 2024-10-05 08:44 422
 *   (`file::WRONLY | file::CREATE | file::TRUNC` by default)
47fd5c32 Poul Sander 2024-10-05 08:44 423
 * - `buffer_size=<integer>`: Output buffer size
47fd5c32 Poul Sander 2024-10-05 08:44 424
 *
47fd5c32 Poul Sander 2024-10-05 08:44 425
 * **Example**:
47fd5c32 Poul Sander 2024-10-05 08:44 426
 *
47fd5c32 Poul Sander 2024-10-05 08:44 427
 *     auto out = fmt::output_file("guide.txt");
47fd5c32 Poul Sander 2024-10-05 08:44 428
 *     out.print("Don't {}", "Panic");
47fd5c32 Poul Sander 2024-10-05 08:44 429
 */
47fd5c32 Poul Sander 2024-10-05 08:44 430
template <typename... T>
47fd5c32 Poul Sander 2024-10-05 08:44 431
inline auto output_file(cstring_view path, T... params) -> ostream {
47fd5c32 Poul Sander 2024-10-05 08:44 432
  return {path, detail::ostream_params(params...)};
47fd5c32 Poul Sander 2024-10-05 08:44 433
}
47fd5c32 Poul Sander 2024-10-05 08:44 434
#endif  // FMT_USE_FCNTL
47fd5c32 Poul Sander 2024-10-05 08:44 435
47fd5c32 Poul Sander 2024-10-05 08:44 436
FMT_END_EXPORT
47fd5c32 Poul Sander 2024-10-05 08:44 437
FMT_END_NAMESPACE
47fd5c32 Poul Sander 2024-10-05 08:44 438
47fd5c32 Poul Sander 2024-10-05 08:44 439
#endif  // FMT_OS_H_
1970-01-01 00:00 440