From 61e5bcef2629e2d68b805a956a96fff264d4f74d Mon Sep 17 00:00:00 2001 From: untodesu Date: Sat, 28 Jun 2025 01:59:49 +0500 Subject: Restructure dependencies and update to C++20 - Nuked static_assert from almost everywhere in the project - Nuked binary dependency support. Might add one later though - Separated dependency headers into a separate include subdirectory - Grafted a thirdpartylegalnotices.txt generator from RITEG - Pushed development snapshot version to 2126 (26th week of 2025) --- deps/include/spdlog/fmt/bundled/printf.h | 656 ------------------------------- 1 file changed, 656 deletions(-) delete mode 100644 deps/include/spdlog/fmt/bundled/printf.h (limited to 'deps/include/spdlog/fmt/bundled/printf.h') diff --git a/deps/include/spdlog/fmt/bundled/printf.h b/deps/include/spdlog/fmt/bundled/printf.h deleted file mode 100644 index 7255c4b..0000000 --- a/deps/include/spdlog/fmt/bundled/printf.h +++ /dev/null @@ -1,656 +0,0 @@ -// Formatting library for C++ - legacy printf implementation -// -// Copyright (c) 2012 - 2016, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_PRINTF_H_ -#define FMT_PRINTF_H_ - -#ifndef FMT_MODULE -# include // std::max -# include // std::numeric_limits -#endif - -#include "format.h" - -FMT_BEGIN_NAMESPACE -FMT_BEGIN_EXPORT - -template struct printf_formatter { - printf_formatter() = delete; -}; - -template class basic_printf_context { - private: - basic_appender out_; - basic_format_args args_; - - static_assert(std::is_same::value || - std::is_same::value, - "Unsupported code unit type."); - - public: - using char_type = Char; - using parse_context_type = basic_format_parse_context; - template using formatter_type = printf_formatter; - - /// Constructs a `printf_context` object. References to the arguments are - /// stored in the context object so make sure they have appropriate lifetimes. - basic_printf_context(basic_appender out, - basic_format_args args) - : out_(out), args_(args) {} - - auto out() -> basic_appender { return out_; } - void advance_to(basic_appender) {} - - auto locale() -> detail::locale_ref { return {}; } - - auto arg(int id) const -> basic_format_arg { - return args_.get(id); - } -}; - -namespace detail { - -// Checks if a value fits in int - used to avoid warnings about comparing -// signed and unsigned integers. -template struct int_checker { - template static auto fits_in_int(T value) -> bool { - unsigned max = to_unsigned(max_value()); - return value <= max; - } - static auto fits_in_int(bool) -> bool { return true; } -}; - -template <> struct int_checker { - template static auto fits_in_int(T value) -> bool { - return value >= (std::numeric_limits::min)() && - value <= max_value(); - } - static auto fits_in_int(int) -> bool { return true; } -}; - -struct printf_precision_handler { - template ::value)> - auto operator()(T value) -> int { - if (!int_checker::is_signed>::fits_in_int(value)) - report_error("number is too big"); - return (std::max)(static_cast(value), 0); - } - - template ::value)> - auto operator()(T) -> int { - report_error("precision is not integer"); - return 0; - } -}; - -// An argument visitor that returns true iff arg is a zero integer. -struct is_zero_int { - template ::value)> - auto operator()(T value) -> bool { - return value == 0; - } - - template ::value)> - auto operator()(T) -> bool { - return false; - } -}; - -template struct make_unsigned_or_bool : std::make_unsigned {}; - -template <> struct make_unsigned_or_bool { - using type = bool; -}; - -template class arg_converter { - private: - using char_type = typename Context::char_type; - - basic_format_arg& arg_; - char_type type_; - - public: - arg_converter(basic_format_arg& arg, char_type type) - : arg_(arg), type_(type) {} - - void operator()(bool value) { - if (type_ != 's') operator()(value); - } - - template ::value)> - void operator()(U value) { - bool is_signed = type_ == 'd' || type_ == 'i'; - using target_type = conditional_t::value, U, T>; - if (const_check(sizeof(target_type) <= sizeof(int))) { - // Extra casts are used to silence warnings. - if (is_signed) { - auto n = static_cast(static_cast(value)); - arg_ = detail::make_arg(n); - } else { - using unsigned_type = typename make_unsigned_or_bool::type; - auto n = static_cast(static_cast(value)); - arg_ = detail::make_arg(n); - } - } else { - if (is_signed) { - // glibc's printf doesn't sign extend arguments of smaller types: - // std::printf("%lld", -42); // prints "4294967254" - // but we don't have to do the same because it's a UB. - auto n = static_cast(value); - arg_ = detail::make_arg(n); - } else { - auto n = static_cast::type>(value); - arg_ = detail::make_arg(n); - } - } - } - - template ::value)> - void operator()(U) {} // No conversion needed for non-integral types. -}; - -// Converts an integer argument to T for printf, if T is an integral type. -// If T is void, the argument is converted to corresponding signed or unsigned -// type depending on the type specifier: 'd' and 'i' - signed, other - -// unsigned). -template -void convert_arg(basic_format_arg& arg, Char type) { - arg.visit(arg_converter(arg, type)); -} - -// Converts an integer argument to char for printf. -template class char_converter { - private: - basic_format_arg& arg_; - - public: - explicit char_converter(basic_format_arg& arg) : arg_(arg) {} - - template ::value)> - void operator()(T value) { - auto c = static_cast(value); - arg_ = detail::make_arg(c); - } - - template ::value)> - void operator()(T) {} // No conversion needed for non-integral types. -}; - -// An argument visitor that return a pointer to a C string if argument is a -// string or null otherwise. -template struct get_cstring { - template auto operator()(T) -> const Char* { return nullptr; } - auto operator()(const Char* s) -> const Char* { return s; } -}; - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -class printf_width_handler { - private: - format_specs& specs_; - - public: - explicit printf_width_handler(format_specs& specs) : specs_(specs) {} - - template ::value)> - auto operator()(T value) -> unsigned { - auto width = static_cast>(value); - if (detail::is_negative(value)) { - specs_.align = align::left; - width = 0 - width; - } - unsigned int_max = to_unsigned(max_value()); - if (width > int_max) report_error("number is too big"); - return static_cast(width); - } - - template ::value)> - auto operator()(T) -> unsigned { - report_error("width is not integer"); - return 0; - } -}; - -// Workaround for a bug with the XL compiler when initializing -// printf_arg_formatter's base class. -template -auto make_arg_formatter(basic_appender iter, format_specs& s) - -> arg_formatter { - return {iter, s, locale_ref()}; -} - -// The `printf` argument formatter. -template -class printf_arg_formatter : public arg_formatter { - private: - using base = arg_formatter; - using context_type = basic_printf_context; - - context_type& context_; - - void write_null_pointer(bool is_string = false) { - auto s = this->specs; - s.type = presentation_type::none; - write_bytes(this->out, is_string ? "(null)" : "(nil)", s); - } - - public: - printf_arg_formatter(basic_appender iter, format_specs& s, - context_type& ctx) - : base(make_arg_formatter(iter, s)), context_(ctx) {} - - void operator()(monostate value) { base::operator()(value); } - - template ::value)> - void operator()(T value) { - // MSVC2013 fails to compile separate overloads for bool and Char so use - // std::is_same instead. - if (!std::is_same::value) { - base::operator()(value); - return; - } - format_specs s = this->specs; - if (s.type != presentation_type::none && s.type != presentation_type::chr) { - return (*this)(static_cast(value)); - } - s.sign = sign::none; - s.alt = false; - s.fill = ' '; // Ignore '0' flag for char types. - // align::numeric needs to be overwritten here since the '0' flag is - // ignored for non-numeric types - if (s.align == align::none || s.align == align::numeric) - s.align = align::right; - write(this->out, static_cast(value), s); - } - - template ::value)> - void operator()(T value) { - base::operator()(value); - } - - void operator()(const char* value) { - if (value) - base::operator()(value); - else - write_null_pointer(this->specs.type != presentation_type::pointer); - } - - void operator()(const wchar_t* value) { - if (value) - base::operator()(value); - else - write_null_pointer(this->specs.type != presentation_type::pointer); - } - - void operator()(basic_string_view value) { base::operator()(value); } - - void operator()(const void* value) { - if (value) - base::operator()(value); - else - write_null_pointer(); - } - - void operator()(typename basic_format_arg::handle handle) { - auto parse_ctx = basic_format_parse_context({}); - handle.format(parse_ctx, context_); - } -}; - -template -void parse_flags(format_specs& specs, const Char*& it, const Char* end) { - for (; it != end; ++it) { - switch (*it) { - case '-': - specs.align = align::left; - break; - case '+': - specs.sign = sign::plus; - break; - case '0': - specs.fill = '0'; - break; - case ' ': - if (specs.sign != sign::plus) specs.sign = sign::space; - break; - case '#': - specs.alt = true; - break; - default: - return; - } - } -} - -template -auto parse_header(const Char*& it, const Char* end, format_specs& specs, - GetArg get_arg) -> int { - int arg_index = -1; - Char c = *it; - if (c >= '0' && c <= '9') { - // Parse an argument index (if followed by '$') or a width possibly - // preceded with '0' flag(s). - int value = parse_nonnegative_int(it, end, -1); - if (it != end && *it == '$') { // value is an argument index - ++it; - arg_index = value != -1 ? value : max_value(); - } else { - if (c == '0') specs.fill = '0'; - if (value != 0) { - // Nonzero value means that we parsed width and don't need to - // parse it or flags again, so return now. - if (value == -1) report_error("number is too big"); - specs.width = value; - return arg_index; - } - } - } - parse_flags(specs, it, end); - // Parse width. - if (it != end) { - if (*it >= '0' && *it <= '9') { - specs.width = parse_nonnegative_int(it, end, -1); - if (specs.width == -1) report_error("number is too big"); - } else if (*it == '*') { - ++it; - specs.width = static_cast( - get_arg(-1).visit(detail::printf_width_handler(specs))); - } - } - return arg_index; -} - -inline auto parse_printf_presentation_type(char c, type t, bool& upper) - -> presentation_type { - using pt = presentation_type; - constexpr auto integral_set = sint_set | uint_set | bool_set | char_set; - switch (c) { - case 'd': - return in(t, integral_set) ? pt::dec : pt::none; - case 'o': - return in(t, integral_set) ? pt::oct : pt::none; - case 'X': - upper = true; - FMT_FALLTHROUGH; - case 'x': - return in(t, integral_set) ? pt::hex : pt::none; - case 'E': - upper = true; - FMT_FALLTHROUGH; - case 'e': - return in(t, float_set) ? pt::exp : pt::none; - case 'F': - upper = true; - FMT_FALLTHROUGH; - case 'f': - return in(t, float_set) ? pt::fixed : pt::none; - case 'G': - upper = true; - FMT_FALLTHROUGH; - case 'g': - return in(t, float_set) ? pt::general : pt::none; - case 'A': - upper = true; - FMT_FALLTHROUGH; - case 'a': - return in(t, float_set) ? pt::hexfloat : pt::none; - case 'c': - return in(t, integral_set) ? pt::chr : pt::none; - case 's': - return in(t, string_set | cstring_set) ? pt::string : pt::none; - case 'p': - return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none; - default: - return pt::none; - } -} - -template -void vprintf(buffer& buf, basic_string_view format, - basic_format_args args) { - using iterator = basic_appender; - auto out = iterator(buf); - auto context = basic_printf_context(out, args); - auto parse_ctx = basic_format_parse_context(format); - - // Returns the argument with specified index or, if arg_index is -1, the next - // argument. - auto get_arg = [&](int arg_index) { - if (arg_index < 0) - arg_index = parse_ctx.next_arg_id(); - else - parse_ctx.check_arg_id(--arg_index); - return detail::get_arg(context, arg_index); - }; - - const Char* start = parse_ctx.begin(); - const Char* end = parse_ctx.end(); - auto it = start; - while (it != end) { - if (!find(it, end, '%', it)) { - it = end; // find leaves it == nullptr if it doesn't find '%'. - break; - } - Char c = *it++; - if (it != end && *it == c) { - write(out, basic_string_view(start, to_unsigned(it - start))); - start = ++it; - continue; - } - write(out, basic_string_view(start, to_unsigned(it - 1 - start))); - - auto specs = format_specs(); - specs.align = align::right; - - // Parse argument index, flags and width. - int arg_index = parse_header(it, end, specs, get_arg); - if (arg_index == 0) report_error("argument not found"); - - // Parse precision. - if (it != end && *it == '.') { - ++it; - c = it != end ? *it : 0; - if ('0' <= c && c <= '9') { - specs.precision = parse_nonnegative_int(it, end, 0); - } else if (c == '*') { - ++it; - specs.precision = - static_cast(get_arg(-1).visit(printf_precision_handler())); - } else { - specs.precision = 0; - } - } - - auto arg = get_arg(arg_index); - // For d, i, o, u, x, and X conversion specifiers, if a precision is - // specified, the '0' flag is ignored - if (specs.precision >= 0 && arg.is_integral()) { - // Ignore '0' for non-numeric types or if '-' present. - specs.fill = ' '; - } - if (specs.precision >= 0 && arg.type() == type::cstring_type) { - auto str = arg.visit(get_cstring()); - auto str_end = str + specs.precision; - auto nul = std::find(str, str_end, Char()); - auto sv = basic_string_view( - str, to_unsigned(nul != str_end ? nul - str : specs.precision)); - arg = make_arg>(sv); - } - if (specs.alt && arg.visit(is_zero_int())) specs.alt = false; - if (specs.fill.template get() == '0') { - if (arg.is_arithmetic() && specs.align != align::left) - specs.align = align::numeric; - else - specs.fill = ' '; // Ignore '0' flag for non-numeric types or if '-' - // flag is also present. - } - - // Parse length and convert the argument to the required type. - c = it != end ? *it++ : 0; - Char t = it != end ? *it : 0; - switch (c) { - case 'h': - if (t == 'h') { - ++it; - t = it != end ? *it : 0; - convert_arg(arg, t); - } else { - convert_arg(arg, t); - } - break; - case 'l': - if (t == 'l') { - ++it; - t = it != end ? *it : 0; - convert_arg(arg, t); - } else { - convert_arg(arg, t); - } - break; - case 'j': - convert_arg(arg, t); - break; - case 'z': - convert_arg(arg, t); - break; - case 't': - convert_arg(arg, t); - break; - case 'L': - // printf produces garbage when 'L' is omitted for long double, no - // need to do the same. - break; - default: - --it; - convert_arg(arg, c); - } - - // Parse type. - if (it == end) report_error("invalid format string"); - char type = static_cast(*it++); - if (arg.is_integral()) { - // Normalize type. - switch (type) { - case 'i': - case 'u': - type = 'd'; - break; - case 'c': - arg.visit(char_converter>(arg)); - break; - } - } - bool upper = false; - specs.type = parse_printf_presentation_type(type, arg.type(), upper); - if (specs.type == presentation_type::none) - report_error("invalid format specifier"); - specs.upper = upper; - - start = it; - - // Format argument. - arg.visit(printf_arg_formatter(out, specs, context)); - } - write(out, basic_string_view(start, to_unsigned(it - start))); -} -} // namespace detail - -using printf_context = basic_printf_context; -using wprintf_context = basic_printf_context; - -using printf_args = basic_format_args; -using wprintf_args = basic_format_args; - -/// Constructs an `format_arg_store` object that contains references to -/// arguments and can be implicitly converted to `printf_args`. -template -inline auto make_printf_args(T&... args) - -> decltype(fmt::make_format_args>(args...)) { - return fmt::make_format_args>(args...); -} - -template struct vprintf_args { - using type = basic_format_args>; -}; - -template -inline auto vsprintf(basic_string_view fmt, - typename vprintf_args::type args) - -> std::basic_string { - auto buf = basic_memory_buffer(); - detail::vprintf(buf, fmt, args); - return to_string(buf); -} - -/** - * Formats `args` according to specifications in `fmt` and returns the result - * as as string. - * - * **Example**: - * - * std::string message = fmt::sprintf("The answer is %d", 42); - */ -template > -inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string { - return vsprintf(detail::to_string_view(fmt), - fmt::make_format_args>(args...)); -} - -template -inline auto vfprintf(std::FILE* f, basic_string_view fmt, - typename vprintf_args::type args) -> int { - auto buf = basic_memory_buffer(); - detail::vprintf(buf, fmt, args); - size_t size = buf.size(); - return std::fwrite(buf.data(), sizeof(Char), size, f) < size - ? -1 - : static_cast(size); -} - -/** - * Formats `args` according to specifications in `fmt` and writes the output - * to `f`. - * - * **Example**: - * - * fmt::fprintf(stderr, "Don't %s!", "panic"); - */ -template > -inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int { - return vfprintf(f, detail::to_string_view(fmt), - make_printf_args(args...)); -} - -template -FMT_DEPRECATED inline auto vprintf(basic_string_view fmt, - typename vprintf_args::type args) - -> int { - return vfprintf(stdout, fmt, args); -} - -/** - * Formats `args` according to specifications in `fmt` and writes the output - * to `stdout`. - * - * **Example**: - * - * fmt::printf("Elapsed time: %.2f seconds", 1.23); - */ -template -inline auto printf(string_view fmt, const T&... args) -> int { - return vfprintf(stdout, fmt, make_printf_args(args...)); -} -template -FMT_DEPRECATED inline auto printf(basic_string_view fmt, - const T&... args) -> int { - return vfprintf(stdout, fmt, make_printf_args(args...)); -} - -FMT_END_EXPORT -FMT_END_NAMESPACE - -#endif // FMT_PRINTF_H_ -- cgit