diff options
author | Winfidonarleyan <dowlandtop@yandex.com> | 2023-11-05 13:15:45 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-05 13:15:45 +0700 |
commit | c5564e1363a2a751eaac5f37c5e82307269de1c3 (patch) | |
tree | b944d0caeb26372156033039b634f40ec0c55fd7 /deps/fmt/src | |
parent | fb83c22dd292b16ea1adf51bc9329f6224ed1607 (diff) |
feat(Deps/Fmt): update fmt lib to 10.1.1 (#17643)
Diffstat (limited to 'deps/fmt/src')
-rw-r--r-- | deps/fmt/src/fmt.cc | 69 | ||||
-rw-r--r-- | deps/fmt/src/format.cc | 111 | ||||
-rw-r--r-- | deps/fmt/src/os.cc | 197 |
3 files changed, 172 insertions, 205 deletions
diff --git a/deps/fmt/src/fmt.cc b/deps/fmt/src/fmt.cc index 80e77e26af..a02167c659 100644 --- a/deps/fmt/src/fmt.cc +++ b/deps/fmt/src/fmt.cc @@ -1,49 +1,44 @@ module; -#ifndef __cpp_modules -# error Module not supported. -#endif - -// put all implementation-provided headers into the global module fragment -// to prevent attachment to this module -#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER) -# define _CRT_SECURE_NO_WARNINGS -#endif -#if !defined(WIN32_LEAN_AND_MEAN) && defined(_WIN32) -# define WIN32_LEAN_AND_MEAN -#endif +// Put all implementation-provided headers into the global module fragment +// to prevent attachment to this module. #include <algorithm> -#include <cctype> #include <cerrno> #include <chrono> #include <climits> -#include <clocale> #include <cmath> -#include <cstdarg> #include <cstddef> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> -#include <cwchar> #include <exception> +#include <filesystem> +#include <fstream> #include <functional> #include <iterator> #include <limits> #include <locale> #include <memory> +#include <optional> #include <ostream> -#include <sstream> #include <stdexcept> #include <string> #include <string_view> #include <system_error> +#include <thread> #include <type_traits> +#include <typeinfo> #include <utility> +#include <variant> #include <vector> +#include <version> -#if _MSC_VER +#if __has_include(<cxxabi.h>) +# include <cxxabi.h> +#endif +#if defined(_MSC_VER) || defined(__MINGW32__) # include <intrin.h> #endif #if defined __APPLE__ || defined(__FreeBSD__) @@ -65,22 +60,33 @@ module; # endif #endif #ifdef _WIN32 +# if defined(__GLIBCXX__) +# include <ext/stdio_filebuf.h> +# include <ext/stdio_sync_filebuf.h> +# elif defined(_LIBCPP_VERSION) +# include <__std_stream> +# endif +# define WIN32_LEAN_AND_MEAN # include <windows.h> #endif export module fmt; -#define FMT_MODULE_EXPORT export -#define FMT_MODULE_EXPORT_BEGIN export { -#define FMT_MODULE_EXPORT_END } -#define FMT_BEGIN_DETAIL_NAMESPACE \ - } \ - namespace detail { -#define FMT_END_DETAIL_NAMESPACE \ - } \ - export { -// all library-provided declarations and definitions -// must be in the module purview to be exported +#define FMT_EXPORT export +#define FMT_BEGIN_EXPORT export { +#define FMT_END_EXPORT } + +// If you define FMT_ATTACH_TO_GLOBAL_MODULE +// - all declarations are detached from module 'fmt' +// - the module behaves like a traditional static library, too +// - all library symbols are mangled traditionally +// - you can mix TUs with either importing or #including the {fmt} API +#ifdef FMT_ATTACH_TO_GLOBAL_MODULE +extern "C++" { +#endif + +// All library-provided declarations and definitions must be in the module +// purview to be exported. #include "fmt/args.h" #include "fmt/chrono.h" #include "fmt/color.h" @@ -88,8 +94,13 @@ export module fmt; #include "fmt/format.h" #include "fmt/os.h" #include "fmt/printf.h" +#include "fmt/std.h" #include "fmt/xchar.h" +#ifdef FMT_ATTACH_TO_GLOBAL_MODULE +} +#endif + // gcc doesn't yet implement private module fragments #if !FMT_GCC_VERSION module : private; diff --git a/deps/fmt/src/format.cc b/deps/fmt/src/format.cc index ecb8cc79a6..391d3a248c 100644 --- a/deps/fmt/src/format.cc +++ b/deps/fmt/src/format.cc @@ -10,115 +10,34 @@ FMT_BEGIN_NAMESPACE namespace detail { -// DEPRECATED! -template <typename T = void> struct basic_data { - FMT_API static constexpr const char digits[100][2] = { - {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, - {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, - {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, - {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, - {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, - {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'}, - {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, - {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, - {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, - {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, - {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'}, - {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'}, - {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'}, - {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, - {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, - {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, - {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; - FMT_API static constexpr const char hex_digits[] = "0123456789abcdef"; - FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '}; - FMT_API static constexpr const char left_padding_shifts[5] = {31, 31, 0, 1, - 0}; - FMT_API static constexpr const char right_padding_shifts[5] = {0, 31, 0, 1, - 0}; - FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+', - 0x1000000u | ' '}; -}; - -#ifdef FMT_SHARED -// Required for -flto, -fivisibility=hidden and -shared to work -extern template struct basic_data<void>; -#endif - -#if __cplusplus < 201703L -// DEPRECATED! These are here only for ABI compatiblity. -template <typename T> constexpr const char basic_data<T>::digits[][2]; -template <typename T> constexpr const char basic_data<T>::hex_digits[]; -template <typename T> constexpr const char basic_data<T>::signs[]; -template <typename T> constexpr const char basic_data<T>::left_padding_shifts[]; -template <typename T> -constexpr const char basic_data<T>::right_padding_shifts[]; -template <typename T> constexpr const unsigned basic_data<T>::prefixes[]; -#endif - -template <typename T> -int format_float(char* buf, std::size_t size, const char* format, int precision, - T value) { -#ifdef FMT_FUZZ - if (precision > 100000) - throw std::runtime_error( - "fuzz mode - avoid large allocation inside snprintf"); -#endif - // Suppress the warning about nonliteral format string. - int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; - return precision < 0 ? snprintf_ptr(buf, size, format, value) - : snprintf_ptr(buf, size, format, precision, value); -} - -template FMT_API dragonbox::decimal_fp<float> dragonbox::to_decimal(float x) - FMT_NOEXCEPT; -template FMT_API dragonbox::decimal_fp<double> dragonbox::to_decimal(double x) - FMT_NOEXCEPT; -} // namespace detail - -// Workaround a bug in MSVC2013 that prevents instantiation of format_float. -int (*instantiate_format_float)(double, int, detail::float_specs, - detail::buffer<char>&) = detail::format_float; +template FMT_API auto dragonbox::to_decimal(float x) noexcept + -> dragonbox::decimal_fp<float>; +template FMT_API auto dragonbox::to_decimal(double x) noexcept + -> dragonbox::decimal_fp<double>; #ifndef FMT_STATIC_THOUSANDS_SEPARATOR -template FMT_API detail::locale_ref::locale_ref(const std::locale& loc); -template FMT_API std::locale detail::locale_ref::get<std::locale>() const; +template FMT_API locale_ref::locale_ref(const std::locale& loc); +template FMT_API auto locale_ref::get<std::locale>() const -> std::locale; #endif // Explicit instantiations for char. -template FMT_API auto detail::thousands_sep_impl(locale_ref) +template FMT_API auto thousands_sep_impl(locale_ref) -> thousands_sep_result<char>; -template FMT_API char detail::decimal_point_impl(locale_ref); +template FMT_API auto decimal_point_impl(locale_ref) -> char; -template FMT_API void detail::buffer<char>::append(const char*, const char*); +template FMT_API void buffer<char>::append(const char*, const char*); -// DEPRECATED! -// There is no correspondent extern template in format.h because of -// incompatibility between clang and gcc (#2377). -template FMT_API void detail::vformat_to( - detail::buffer<char>&, string_view, - basic_format_args<FMT_BUFFER_CONTEXT(char)>, detail::locale_ref); - -template FMT_API int detail::snprintf_float(double, int, detail::float_specs, - detail::buffer<char>&); -template FMT_API int detail::snprintf_float(long double, int, - detail::float_specs, - detail::buffer<char>&); -template FMT_API int detail::format_float(double, int, detail::float_specs, - detail::buffer<char>&); -template FMT_API int detail::format_float(long double, int, detail::float_specs, - detail::buffer<char>&); +template FMT_API void vformat_to(buffer<char>&, string_view, + typename vformat_args<>::type, locale_ref); // Explicit instantiations for wchar_t. -template FMT_API auto detail::thousands_sep_impl(locale_ref) +template FMT_API auto thousands_sep_impl(locale_ref) -> thousands_sep_result<wchar_t>; -template FMT_API wchar_t detail::decimal_point_impl(locale_ref); - -template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*, - const wchar_t*); +template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; -template struct detail::basic_data<void>; +template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*); +} // namespace detail FMT_END_NAMESPACE diff --git a/deps/fmt/src/os.cc b/deps/fmt/src/os.cc index 04b4dc5060..bca410e945 100644 --- a/deps/fmt/src/os.cc +++ b/deps/fmt/src/os.cc @@ -18,6 +18,10 @@ # include <sys/stat.h> # include <sys/types.h> +# ifdef _WRS_KERNEL // VxWorks7 kernel +# include <ioLib.h> // getpagesize +# endif + # ifndef _WIN32 # include <unistd.h> # else @@ -35,9 +39,15 @@ # ifndef S_IRGRP # define S_IRGRP 0 # endif +# ifndef S_IWGRP +# define S_IWGRP 0 +# endif # ifndef S_IROTH # define S_IROTH 0 # endif +# ifndef S_IWOTH +# define S_IWOTH 0 +# endif # endif // _WIN32 #endif // FMT_USE_FCNTL @@ -45,10 +55,6 @@ # include <windows.h> #endif -#ifdef fileno -# undef fileno -#endif - namespace { #ifdef _WIN32 // Return type of read and write functions. @@ -70,34 +76,6 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; } FMT_BEGIN_NAMESPACE #ifdef _WIN32 -detail::utf16_to_utf8::utf16_to_utf8(basic_string_view<wchar_t> s) { - if (int error_code = convert(s)) { - FMT_THROW(windows_error(error_code, - "cannot convert string from UTF-16 to UTF-8")); - } -} - -int detail::utf16_to_utf8::convert(basic_string_view<wchar_t> s) { - if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; - int s_size = static_cast<int>(s.size()); - if (s_size == 0) { - // WideCharToMultiByte does not support zero length, handle separately. - buffer_.resize(1); - buffer_[0] = 0; - return 0; - } - - int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0, - nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_.resize(length + 1); - length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0], - length, nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_[length] = 0; - return 0; -} - namespace detail { class system_message { @@ -107,7 +85,7 @@ class system_message { unsigned long result_; wchar_t* message_; - static bool is_whitespace(wchar_t c) FMT_NOEXCEPT { + static bool is_whitespace(wchar_t c) noexcept { return c == L' ' || c == L'\n' || c == L'\r' || c == L'\t' || c == L'\0'; } @@ -126,20 +104,20 @@ class system_message { } } ~system_message() { LocalFree(message_); } - explicit operator bool() const FMT_NOEXCEPT { return result_ != 0; } - operator basic_string_view<wchar_t>() const FMT_NOEXCEPT { + explicit operator bool() const noexcept { return result_ != 0; } + operator basic_string_view<wchar_t>() const noexcept { return basic_string_view<wchar_t>(message_, result_); } }; class utf8_system_category final : public std::error_category { public: - const char* name() const FMT_NOEXCEPT override { return "system"; } + const char* name() const noexcept override { return "system"; } std::string message(int error_code) const override { - system_message msg(error_code); + auto&& msg = system_message(error_code); if (msg) { - utf16_to_utf8 utf8_message; - if (utf8_message.convert(msg) == ERROR_SUCCESS) { + auto utf8_message = to_utf8<wchar_t>(); + if (utf8_message.convert(msg)) { return utf8_message.str(); } } @@ -149,7 +127,7 @@ class utf8_system_category final : public std::error_category { } // namespace detail -FMT_API const std::error_category& system_category() FMT_NOEXCEPT { +FMT_API const std::error_category& system_category() noexcept { static const detail::utf8_system_category category; return category; } @@ -161,13 +139,14 @@ std::system_error vwindows_error(int err_code, string_view format_str, } void detail::format_windows_error(detail::buffer<char>& out, int error_code, - const char* message) FMT_NOEXCEPT { + const char* message) noexcept { FMT_TRY { - system_message msg(error_code); + auto&& msg = system_message(error_code); if (msg) { - utf16_to_utf8 utf8_message; - if (utf8_message.convert(msg) == ERROR_SUCCESS) { - format_to(buffer_appender<char>(out), "{}: {}", message, utf8_message); + auto utf8_message = to_utf8<wchar_t>(); + if (utf8_message.convert(msg)) { + fmt::format_to(appender(out), FMT_STRING("{}: {}"), message, + string_view(utf8_message)); return; } } @@ -176,12 +155,12 @@ void detail::format_windows_error(detail::buffer<char>& out, int error_code, format_error_code(out, error_code, message); } -void report_windows_error(int error_code, const char* message) FMT_NOEXCEPT { +void report_windows_error(int error_code, const char* message) noexcept { report_error(detail::format_windows_error, error_code, message); } #endif // _WIN32 -buffered_file::~buffered_file() FMT_NOEXCEPT { +buffered_file::~buffered_file() noexcept { if (file_ && FMT_SYSTEM(fclose(file_)) != 0) report_system_error(errno, "cannot close file"); } @@ -190,42 +169,50 @@ buffered_file::buffered_file(cstring_view filename, cstring_view mode) { FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), nullptr); if (!file_) - FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str())); + FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"), + filename.c_str())); } void buffered_file::close() { if (!file_) return; int result = FMT_SYSTEM(fclose(file_)); file_ = nullptr; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot close file"))); } -// A macro used to prevent expansion of fileno on broken versions of MinGW. -#define FMT_ARGS - -int buffered_file::fileno() const { - int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_)); - if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor")); +int buffered_file::descriptor() const { +#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL. + int fd = fileno(file_); +#else + int fd = FMT_POSIX_CALL(fileno(file_)); +#endif + if (fd == -1) + FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor"))); return fd; } #if FMT_USE_FCNTL -file::file(cstring_view path, int oflag) { # ifdef _WIN32 - using mode_t = int; +using mode_t = int; # endif - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; +constexpr mode_t default_open_mode = + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + +file::file(cstring_view path, int oflag) { # if defined(_WIN32) && !defined(__MINGW32__) fd_ = -1; - FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); + auto converted = detail::utf8_to_utf16(string_view(path.c_str())); + *this = file::open_windows_file(converted.c_str(), oflag); # else - FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); -# endif + FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode))); if (fd_ == -1) - FMT_THROW(system_error(errno, "cannot open file {}", path.c_str())); + FMT_THROW( + system_error(errno, FMT_STRING("cannot open file {}"), path.c_str())); +# endif } -file::~file() FMT_NOEXCEPT { +file::~file() noexcept { // Don't retry close in case of EINTR! // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) @@ -238,7 +225,8 @@ void file::close() { // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html int result = FMT_POSIX_CALL(close(fd_)); fd_ = -1; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot close file"))); } long long file::size() const { @@ -260,7 +248,7 @@ long long file::size() const { using Stat = struct stat; Stat file_stat = Stat(); if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) - FMT_THROW(system_error(errno, "cannot get file attributes")); + FMT_THROW(system_error(errno, FMT_STRING("cannot get file attributes"))); static_assert(sizeof(long long) >= sizeof(file_stat.st_size), "return type of file::size is not large enough"); return file_stat.st_size; @@ -270,14 +258,16 @@ long long file::size() const { std::size_t file::read(void* buffer, std::size_t count) { rwresult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot read from file")); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot read from file"))); return detail::to_unsigned(result); } std::size_t file::write(const void* buffer, std::size_t count) { rwresult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot write to file")); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); return detail::to_unsigned(result); } @@ -286,7 +276,8 @@ file file::dup(int fd) { // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html int new_fd = FMT_POSIX_CALL(dup(fd)); if (new_fd == -1) - FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd)); + FMT_THROW(system_error( + errno, FMT_STRING("cannot duplicate file descriptor {}"), fd)); return file(new_fd); } @@ -294,12 +285,13 @@ void file::dup2(int fd) { int result = 0; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); if (result == -1) { - FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}", - fd_, fd)); + FMT_THROW(system_error( + errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_, + fd)); } } -void file::dup2(int fd, std::error_code& ec) FMT_NOEXCEPT { +void file::dup2(int fd, std::error_code& ec) noexcept { int result = 0; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); if (result == -1) ec = std::error_code(errno, std::generic_category()); @@ -320,7 +312,8 @@ void file::pipe(file& read_end, file& write_end) { // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html int result = FMT_POSIX_CALL(pipe(fds)); # endif - if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe")); + if (result != 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe"))); // The following assignments don't throw because read_fd and write_fd // are closed. read_end = file(fds[0]); @@ -334,28 +327,72 @@ buffered_file file::fdopen(const char* mode) { # else FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode)); # endif - if (!f) - FMT_THROW( - system_error(errno, "cannot associate stream with file descriptor")); + if (!f) { + FMT_THROW(system_error( + errno, FMT_STRING("cannot associate stream with file descriptor"))); + } buffered_file bf(f); fd_ = -1; return bf; } +# if defined(_WIN32) && !defined(__MINGW32__) +file file::open_windows_file(wcstring_view path, int oflag) { + int fd = -1; + auto err = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO, default_open_mode); + if (fd == -1) { + FMT_THROW(system_error(err, FMT_STRING("cannot open file {}"), + detail::to_utf8<wchar_t>(path.c_str()).c_str())); + } + return file(fd); +} +# endif + +# if !defined(__MSDOS__) long getpagesize() { -# ifdef _WIN32 +# ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); return si.dwPageSize; -# else +# else +# ifdef _WRS_KERNEL + long size = FMT_POSIX_CALL(getpagesize()); +# else long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); - if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size")); +# endif + + if (size < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot get memory page size"))); return size; -# endif +# endif } +# endif + +namespace detail { -FMT_API void ostream::grow(size_t) { +void file_buffer::grow(size_t) { if (this->size() == this->capacity()) flush(); } + +file_buffer::file_buffer(cstring_view path, + const detail::ostream_params& params) + : file_(path, params.oflag) { + set(new char[params.buffer_size], params.buffer_size); +} + +file_buffer::file_buffer(file_buffer&& other) + : detail::buffer<char>(other.data(), other.size(), other.capacity()), + file_(std::move(other.file_)) { + other.clear(); + other.set(nullptr, 0); +} + +file_buffer::~file_buffer() { + flush(); + delete[] data(); +} +} // namespace detail + +ostream::~ostream() = default; #endif // FMT_USE_FCNTL FMT_END_NAMESPACE |