14 #include <system_error>
18 #if defined __APPLE__ || defined(__FreeBSD__)
19 # if FMT_HAS_INCLUDE(<xlocale.h>)
26 # if FMT_HAS_INCLUDE("winapifamily.h")
27 # include <winapifamily.h>
29 # if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
30 defined(__linux__)) && \
31 (!defined(WINAPI_FAMILY) || \
32 (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
34 # define FMT_USE_FCNTL 1
36 # define FMT_USE_FCNTL 0
41 # if defined(_WIN32) && !defined(__MINGW32__)
43 # define FMT_POSIX(call) _##call
45 # define FMT_POSIX(call) call
51 # define FMT_HAS_SYSTEM
52 # define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
54 # define FMT_SYSTEM(call) ::call
57 # define FMT_POSIX_CALL(call) ::_##call
59 # define FMT_POSIX_CALL(call) ::call
66 # define FMT_RETRY_VAL(result, expression, error_result) \
68 (result) = (expression); \
69 } while ((result) == (error_result) && errno == EINTR)
71 # define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
74 #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
131 const char* message) noexcept;
165 template <
typename... Args>
167 const Args&...
args) {
182 template <
typename S,
typename... Args,
typename Char =
char_t<S>>
183 void say(
const S& format_str, Args&&...
args) {
209 other.file_ =
nullptr;
215 other.file_ =
nullptr;
226 auto get() const noexcept -> FILE* {
return file_; }
234 template <
typename... Args>
252 explicit file(
int fd) : fd_(fd) {}
266 file() noexcept : fd_(-1) {}
272 file(
const file&) =
delete;
273 void operator=(
const file&) =
delete;
275 file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
278 auto operator=(file&& other) ->
file& {
289 auto descriptor() const noexcept ->
int {
return fd_; }
296 auto size() const ->
long long;
299 auto read(
void* buffer,
size_t count) ->
size_t;
302 auto
write(const
void* buffer,
size_t count) ->
size_t;
306 static auto dup(
int fd) -> file;
319 static
void pipe(file& read_end, file& write_end);
325 # if defined(_WIN32) && !defined(__MINGW32__)
333 auto getpagesize() -> long;
338 buffer_size() =
default;
340 auto operator=(
size_t val)
const -> buffer_size {
341 auto bs = buffer_size();
347 struct ostream_params {
348 int oflag = file::WRONLY | file::CREATE | file::TRUNC;
349 size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
353 template <
typename... T>
354 ostream_params(T... params,
int new_oflag) : ostream_params(params...) {
358 template <
typename... T>
359 ostream_params(T... params, detail::buffer_size bs)
360 : ostream_params(params...) {
361 this->buffer_size = bs.value;
366 # if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
367 ostream_params(
int new_oflag) : oflag(new_oflag) {}
368 ostream_params(detail::buffer_size bs) : buffer_size(bs.
value) {}
372 class file_buffer final :
public buffer<char> {
375 FMT_API void grow(
size_t)
override;
379 FMT_API file_buffer(file_buffer&& other);
383 if (
size() == 0)
return;
398 constexpr detail::buffer_size buffer_size{};
404 detail::file_buffer buffer_;
406 ostream(
cstring_view path,
const detail::ostream_params& params)
407 : buffer_(path, params) {}
410 ostream(ostream&& other) : buffer_(
std::
move(other.buffer_)) {}
414 void flush() { buffer_.flush(); }
416 template <
typename... T>
417 friend auto output_file(
cstring_view path, T... params) -> ostream;
419 void close() { buffer_.close(); }
446 template <
typename... T>
447 inline auto output_file(
cstring_view path, T... params) -> ostream {
448 return {path, detail::ostream_params(params...)};
450 #endif // FMT_USE_FCNTL