diff --git a/src/lib/fmt/ToBuffer.hxx b/src/lib/fmt/ToBuffer.hxx new file mode 100644 index 000000000..5ba36c068 --- /dev/null +++ b/src/lib/fmt/ToBuffer.hxx @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "util/StringBuffer.hxx" + +#include + +template +[[nodiscard]] [[gnu::pure]] +auto +VFmtBuffer(fmt::string_view format_str, fmt::format_args args) noexcept +{ + StringBuffer buffer; + auto [p, _] = fmt::vformat_to_n(buffer.data(), buffer.capacity() - 1, + format_str, args); + *p = 0; + return buffer; +} + +template +[[nodiscard]] [[gnu::pure]] +auto +FmtBuffer(const S &format_str, Args&&... args) noexcept +{ +#if FMT_VERSION >= 90000 + return VFmtBuffer(format_str, + fmt::make_format_args(args...)); +#else + return VFmtBuffer(fmt::to_string_view(format_str), + fmt::make_args_checked(format_str, + args...)); +#endif +} diff --git a/src/system/FmtError.cxx b/src/system/FmtError.cxx index 4ca2ddfc4..3645357bb 100644 --- a/src/system/FmtError.cxx +++ b/src/system/FmtError.cxx @@ -28,8 +28,7 @@ */ #include "FmtError.hxx" - -#include +#include "lib/fmt/ToBuffer.hxx" #include @@ -37,11 +36,8 @@ std::system_error VFmtSystemError(std::error_code code, fmt::string_view format_str, fmt::format_args args) noexcept { - std::array buffer; - auto [p, _] = fmt::vformat_to_n(buffer.begin(), buffer.size() - 1, - format_str, args); - *p = 0; - return std::system_error{code, buffer.data()}; + const auto msg = VFmtBuffer<512>(format_str, args); + return std::system_error{code, msg}; } #ifdef _WIN32