diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-04-08 15:03:00 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-04-08 15:13:07 +0300 |
commit | cafb490be5f77760f2612e70ec174dd1e8fb8651 (patch) | |
tree | 59e7d0fa20e5ecae3fe0b824fbfab4b4f6617e07 | |
parent | 5d00501105db37fd7faf22cb093779332416207f (diff) | |
download | ydb-cafb490be5f77760f2612e70ec174dd1e8fb8651.tar.gz |
Intermediate changes
57 files changed, 5 insertions, 14980 deletions
diff --git a/contrib/libs/fmt/include/fmt/args.h b/contrib/libs/fmt/include/fmt/args.h deleted file mode 100644 index 9a8e4ed2ce..0000000000 --- a/contrib/libs/fmt/include/fmt/args.h +++ /dev/null @@ -1,234 +0,0 @@ -// Formatting library for C++ - dynamic format arguments -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_ARGS_H_ -#define FMT_ARGS_H_ - -#include <functional> // std::reference_wrapper -#include <memory> // std::unique_ptr -#include <vector> - -#include "core.h" - -FMT_BEGIN_NAMESPACE - -namespace detail { - -template <typename T> struct is_reference_wrapper : std::false_type {}; -template <typename T> -struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {}; - -template <typename T> const T& unwrap(const T& v) { return v; } -template <typename T> const T& unwrap(const std::reference_wrapper<T>& v) { - return static_cast<const T&>(v); -} - -class dynamic_arg_list { - // Workaround for clang's -Wweak-vtables. Unlike for regular classes, for - // templates it doesn't complain about inability to deduce single translation - // unit for placing vtable. So storage_node_base is made a fake template. - template <typename = void> struct node { - virtual ~node() = default; - std::unique_ptr<node<>> next; - }; - - template <typename T> struct typed_node : node<> { - T value; - - template <typename Arg> - FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {} - - template <typename Char> - FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg) - : value(arg.data(), arg.size()) {} - }; - - std::unique_ptr<node<>> head_; - - public: - template <typename T, typename Arg> const T& push(const Arg& arg) { - auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg)); - auto& value = new_node->value; - new_node->next = std::move(head_); - head_ = std::move(new_node); - return value; - } -}; -} // namespace detail - -/** - \rst - A dynamic version of `fmt::format_arg_store`. - It's equipped with a storage to potentially temporary objects which lifetimes - could be shorter than the format arguments object. - - It can be implicitly converted into `~fmt::basic_format_args` for passing - into type-erased formatting functions such as `~fmt::vformat`. - \endrst - */ -template <typename Context> -class dynamic_format_arg_store -#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 - // Workaround a GCC template argument substitution bug. - : public basic_format_args<Context> -#endif -{ - private: - using char_type = typename Context::char_type; - - template <typename T> struct need_copy { - static constexpr detail::type mapped_type = - detail::mapped_type_constant<T, Context>::value; - - enum { - value = !(detail::is_reference_wrapper<T>::value || - std::is_same<T, basic_string_view<char_type>>::value || - std::is_same<T, detail::std_string_view<char_type>>::value || - (mapped_type != detail::type::cstring_type && - mapped_type != detail::type::string_type && - mapped_type != detail::type::custom_type)) - }; - }; - - template <typename T> - using stored_type = conditional_t<detail::is_string<T>::value && - !has_formatter<T, Context>::value && - !detail::is_reference_wrapper<T>::value, - std::basic_string<char_type>, T>; - - // Storage of basic_format_arg must be contiguous. - std::vector<basic_format_arg<Context>> data_; - std::vector<detail::named_arg_info<char_type>> named_info_; - - // Storage of arguments not fitting into basic_format_arg must grow - // without relocation because items in data_ refer to it. - detail::dynamic_arg_list dynamic_args_; - - friend class basic_format_args<Context>; - - unsigned long long get_types() const { - return detail::is_unpacked_bit | data_.size() | - (named_info_.empty() - ? 0ULL - : static_cast<unsigned long long>(detail::has_named_args_bit)); - } - - const basic_format_arg<Context>* data() const { - return named_info_.empty() ? data_.data() : data_.data() + 1; - } - - template <typename T> void emplace_arg(const T& arg) { - data_.emplace_back(detail::make_arg<Context>(arg)); - } - - template <typename T> - void emplace_arg(const detail::named_arg<char_type, T>& arg) { - if (named_info_.empty()) { - constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr}; - data_.insert(data_.begin(), {zero_ptr, 0}); - } - data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value))); - auto pop_one = [](std::vector<basic_format_arg<Context>>* data) { - data->pop_back(); - }; - std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)> - guard{&data_, pop_one}; - named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)}); - data_[0].value_.named_args = {named_info_.data(), named_info_.size()}; - guard.release(); - } - - public: - constexpr dynamic_format_arg_store() = default; - - /** - \rst - Adds an argument into the dynamic store for later passing to a formatting - function. - - Note that custom types and string types (but not string views) are copied - into the store dynamically allocating memory if necessary. - - **Example**:: - - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(42); - store.push_back("abc"); - store.push_back(1.5f); - std::string result = fmt::vformat("{} and {} and {}", store); - \endrst - */ - template <typename T> void push_back(const T& arg) { - if (detail::const_check(need_copy<T>::value)) - emplace_arg(dynamic_args_.push<stored_type<T>>(arg)); - else - emplace_arg(detail::unwrap(arg)); - } - - /** - \rst - Adds a reference to the argument into the dynamic store for later passing to - a formatting function. - - **Example**:: - - fmt::dynamic_format_arg_store<fmt::format_context> store; - char band[] = "Rolling Stones"; - store.push_back(std::cref(band)); - band[9] = 'c'; // Changing str affects the output. - std::string result = fmt::vformat("{}", store); - // result == "Rolling Scones" - \endrst - */ - template <typename T> void push_back(std::reference_wrapper<T> arg) { - static_assert( - need_copy<T>::value, - "objects of built-in types and string views are always copied"); - emplace_arg(arg.get()); - } - - /** - Adds named argument into the dynamic store for later passing to a formatting - function. ``std::reference_wrapper`` is supported to avoid copying of the - argument. The name is always copied into the store. - */ - template <typename T> - void push_back(const detail::named_arg<char_type, T>& arg) { - const char_type* arg_name = - dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str(); - if (detail::const_check(need_copy<T>::value)) { - emplace_arg( - fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value))); - } else { - emplace_arg(fmt::arg(arg_name, arg.value)); - } - } - - /** Erase all elements from the store */ - void clear() { - data_.clear(); - named_info_.clear(); - dynamic_args_ = detail::dynamic_arg_list(); - } - - /** - \rst - Reserves space to store at least *new_cap* arguments including - *new_cap_named* named arguments. - \endrst - */ - void reserve(size_t new_cap, size_t new_cap_named) { - FMT_ASSERT(new_cap >= new_cap_named, - "Set of arguments includes set of named arguments"); - data_.reserve(new_cap); - named_info_.reserve(new_cap_named); - } -}; - -FMT_END_NAMESPACE - -#endif // FMT_ARGS_H_ diff --git a/contrib/libs/fmt/include/fmt/chrono.h b/contrib/libs/fmt/include/fmt/chrono.h deleted file mode 100644 index 682efd8d21..0000000000 --- a/contrib/libs/fmt/include/fmt/chrono.h +++ /dev/null @@ -1,2067 +0,0 @@ -// Formatting library for C++ - chrono support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_CHRONO_H_ -#define FMT_CHRONO_H_ - -#include <algorithm> -#include <chrono> -#include <ctime> -#include <iterator> -#include <locale> -#include <ostream> -#include <type_traits> - -#include "format.h" - -FMT_BEGIN_NAMESPACE - -// Enable tzset. -#ifndef FMT_USE_TZSET -// UWP doesn't provide _tzset. -# if FMT_HAS_INCLUDE("winapifamily.h") -# include <winapifamily.h> -# endif -# if defined(_WIN32) && (!defined(WINAPI_FAMILY) || \ - (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) -# define FMT_USE_TZSET 1 -# else -# define FMT_USE_TZSET 0 -# endif -#endif - -// Enable safe chrono durations, unless explicitly disabled. -#ifndef FMT_SAFE_DURATION_CAST -# define FMT_SAFE_DURATION_CAST 1 -#endif -#if FMT_SAFE_DURATION_CAST - -// For conversion between std::chrono::durations without undefined -// behaviour or erroneous results. -// This is a stripped down version of duration_cast, for inclusion in fmt. -// See https://github.com/pauldreik/safe_duration_cast -// -// Copyright Paul Dreik 2019 -namespace safe_duration_cast { - -template <typename To, typename From, - FMT_ENABLE_IF(!std::is_same<From, To>::value && - std::numeric_limits<From>::is_signed == - std::numeric_limits<To>::is_signed)> -FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { - ec = 0; - using F = std::numeric_limits<From>; - using T = std::numeric_limits<To>; - static_assert(F::is_integer, "From must be integral"); - static_assert(T::is_integer, "To must be integral"); - - // A and B are both signed, or both unsigned. - if (detail::const_check(F::digits <= T::digits)) { - // From fits in To without any problem. - } else { - // From does not always fit in To, resort to a dynamic check. - if (from < (T::min)() || from > (T::max)()) { - // outside range. - ec = 1; - return {}; - } - } - return static_cast<To>(from); -} - -/** - * converts From to To, without loss. If the dynamic value of from - * can't be converted to To without loss, ec is set. - */ -template <typename To, typename From, - FMT_ENABLE_IF(!std::is_same<From, To>::value && - std::numeric_limits<From>::is_signed != - std::numeric_limits<To>::is_signed)> -FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { - ec = 0; - using F = std::numeric_limits<From>; - using T = std::numeric_limits<To>; - static_assert(F::is_integer, "From must be integral"); - static_assert(T::is_integer, "To must be integral"); - - if (detail::const_check(F::is_signed && !T::is_signed)) { - // From may be negative, not allowed! - if (fmt::detail::is_negative(from)) { - ec = 1; - return {}; - } - // From is positive. Can it always fit in To? - if (detail::const_check(F::digits > T::digits) && - from > static_cast<From>(detail::max_value<To>())) { - ec = 1; - return {}; - } - } - - if (detail::const_check(!F::is_signed && T::is_signed && - F::digits >= T::digits) && - from > static_cast<From>(detail::max_value<To>())) { - ec = 1; - return {}; - } - return static_cast<To>(from); // Lossless conversion. -} - -template <typename To, typename From, - FMT_ENABLE_IF(std::is_same<From, To>::value)> -FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { - ec = 0; - return from; -} // function - -// clang-format off -/** - * converts From to To if possible, otherwise ec is set. - * - * input | output - * ---------------------------------|--------------- - * NaN | NaN - * Inf | Inf - * normal, fits in output | converted (possibly lossy) - * normal, does not fit in output | ec is set - * subnormal | best effort - * -Inf | -Inf - */ -// clang-format on -template <typename To, typename From, - FMT_ENABLE_IF(!std::is_same<From, To>::value)> -FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) { - ec = 0; - using T = std::numeric_limits<To>; - static_assert(std::is_floating_point<From>::value, "From must be floating"); - static_assert(std::is_floating_point<To>::value, "To must be floating"); - - // catch the only happy case - if (std::isfinite(from)) { - if (from >= T::lowest() && from <= (T::max)()) { - return static_cast<To>(from); - } - // not within range. - ec = 1; - return {}; - } - - // nan and inf will be preserved - return static_cast<To>(from); -} // function - -template <typename To, typename From, - FMT_ENABLE_IF(std::is_same<From, To>::value)> -FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) { - ec = 0; - static_assert(std::is_floating_point<From>::value, "From must be floating"); - return from; -} - -/** - * safe duration cast between integral durations - */ -template <typename To, typename FromRep, typename FromPeriod, - FMT_ENABLE_IF(std::is_integral<FromRep>::value), - FMT_ENABLE_IF(std::is_integral<typename To::rep>::value)> -To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from, - int& ec) { - using From = std::chrono::duration<FromRep, FromPeriod>; - ec = 0; - // the basic idea is that we need to convert from count() in the from type - // to count() in the To type, by multiplying it with this: - struct Factor - : std::ratio_divide<typename From::period, typename To::period> {}; - - static_assert(Factor::num > 0, "num must be positive"); - static_assert(Factor::den > 0, "den must be positive"); - - // the conversion is like this: multiply from.count() with Factor::num - // /Factor::den and convert it to To::rep, all this without - // overflow/underflow. let's start by finding a suitable type that can hold - // both To, From and Factor::num - using IntermediateRep = - typename std::common_type<typename From::rep, typename To::rep, - decltype(Factor::num)>::type; - - // safe conversion to IntermediateRep - IntermediateRep count = - lossless_integral_conversion<IntermediateRep>(from.count(), ec); - if (ec) return {}; - // multiply with Factor::num without overflow or underflow - if (detail::const_check(Factor::num != 1)) { - const auto max1 = detail::max_value<IntermediateRep>() / Factor::num; - if (count > max1) { - ec = 1; - return {}; - } - const auto min1 = - (std::numeric_limits<IntermediateRep>::min)() / Factor::num; - if (count < min1) { - ec = 1; - return {}; - } - count *= Factor::num; - } - - if (detail::const_check(Factor::den != 1)) count /= Factor::den; - auto tocount = lossless_integral_conversion<typename To::rep>(count, ec); - return ec ? To() : To(tocount); -} - -/** - * safe duration_cast between floating point durations - */ -template <typename To, typename FromRep, typename FromPeriod, - FMT_ENABLE_IF(std::is_floating_point<FromRep>::value), - FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)> -To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from, - int& ec) { - using From = std::chrono::duration<FromRep, FromPeriod>; - ec = 0; - if (std::isnan(from.count())) { - // nan in, gives nan out. easy. - return To{std::numeric_limits<typename To::rep>::quiet_NaN()}; - } - // maybe we should also check if from is denormal, and decide what to do about - // it. - - // +-inf should be preserved. - if (std::isinf(from.count())) { - return To{from.count()}; - } - - // the basic idea is that we need to convert from count() in the from type - // to count() in the To type, by multiplying it with this: - struct Factor - : std::ratio_divide<typename From::period, typename To::period> {}; - - static_assert(Factor::num > 0, "num must be positive"); - static_assert(Factor::den > 0, "den must be positive"); - - // the conversion is like this: multiply from.count() with Factor::num - // /Factor::den and convert it to To::rep, all this without - // overflow/underflow. let's start by finding a suitable type that can hold - // both To, From and Factor::num - using IntermediateRep = - typename std::common_type<typename From::rep, typename To::rep, - decltype(Factor::num)>::type; - - // force conversion of From::rep -> IntermediateRep to be safe, - // even if it will never happen be narrowing in this context. - IntermediateRep count = - safe_float_conversion<IntermediateRep>(from.count(), ec); - if (ec) { - return {}; - } - - // multiply with Factor::num without overflow or underflow - if (detail::const_check(Factor::num != 1)) { - constexpr auto max1 = detail::max_value<IntermediateRep>() / - static_cast<IntermediateRep>(Factor::num); - if (count > max1) { - ec = 1; - return {}; - } - constexpr auto min1 = std::numeric_limits<IntermediateRep>::lowest() / - static_cast<IntermediateRep>(Factor::num); - if (count < min1) { - ec = 1; - return {}; - } - count *= static_cast<IntermediateRep>(Factor::num); - } - - // this can't go wrong, right? den>0 is checked earlier. - if (detail::const_check(Factor::den != 1)) { - using common_t = typename std::common_type<IntermediateRep, intmax_t>::type; - count /= static_cast<common_t>(Factor::den); - } - - // convert to the to type, safely - using ToRep = typename To::rep; - - const ToRep tocount = safe_float_conversion<ToRep>(count, ec); - if (ec) { - return {}; - } - return To{tocount}; -} -} // namespace safe_duration_cast -#endif - -// Prevents expansion of a preceding token as a function-style macro. -// Usage: f FMT_NOMACRO() -#define FMT_NOMACRO - -namespace detail { -template <typename T = void> struct null {}; -inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); } -inline null<> localtime_s(...) { return null<>(); } -inline null<> gmtime_r(...) { return null<>(); } -inline null<> gmtime_s(...) { return null<>(); } - -inline const std::locale& get_classic_locale() { - static const auto& locale = std::locale::classic(); - return locale; -} - -template <typename CodeUnit> struct codecvt_result { - static constexpr const size_t max_size = 32; - CodeUnit buf[max_size]; - CodeUnit* end; -}; -template <typename CodeUnit> -constexpr const size_t codecvt_result<CodeUnit>::max_size; - -template <typename CodeUnit> -void write_codecvt(codecvt_result<CodeUnit>& out, string_view in_buf, - const std::locale& loc) { - using codecvt = std::codecvt<CodeUnit, char, std::mbstate_t>; -#if FMT_CLANG_VERSION -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated" - auto& f = std::use_facet<codecvt>(loc); -# pragma clang diagnostic pop -#else - auto& f = std::use_facet<codecvt>(loc); -#endif - auto mb = std::mbstate_t(); - const char* from_next = nullptr; - auto result = f.in(mb, in_buf.begin(), in_buf.end(), from_next, - std::begin(out.buf), std::end(out.buf), out.end); - if (result != std::codecvt_base::ok) - FMT_THROW(format_error("failed to format time")); -} - -template <typename OutputIt> -auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) - -> OutputIt { - if (detail::is_utf8() && loc != get_classic_locale()) { - // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and - // gcc-4. -#if FMT_MSC_VER != 0 || \ - (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)) - // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 - // and newer. - using code_unit = wchar_t; -#else - using code_unit = char32_t; -#endif - - using unit_t = codecvt_result<code_unit>; - unit_t unit; - write_codecvt(unit, in, loc); - // In UTF-8 is used one to four one-byte code units. - auto&& buf = basic_memory_buffer<char, unit_t::max_size * 4>(); - for (code_unit* p = unit.buf; p != unit.end; ++p) { - uint32_t c = static_cast<uint32_t>(*p); - if (sizeof(code_unit) == 2 && c >= 0xd800 && c <= 0xdfff) { - // surrogate pair - ++p; - if (p == unit.end || (c & 0xfc00) != 0xd800 || - (*p & 0xfc00) != 0xdc00) { - FMT_THROW(format_error("failed to format time")); - } - c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00; - } - if (c < 0x80) { - buf.push_back(static_cast<char>(c)); - } else if (c < 0x800) { - buf.push_back(static_cast<char>(0xc0 | (c >> 6))); - buf.push_back(static_cast<char>(0x80 | (c & 0x3f))); - } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { - buf.push_back(static_cast<char>(0xe0 | (c >> 12))); - buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6))); - buf.push_back(static_cast<char>(0x80 | (c & 0x3f))); - } else if (c >= 0x10000 && c <= 0x10ffff) { - buf.push_back(static_cast<char>(0xf0 | (c >> 18))); - buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12))); - buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6))); - buf.push_back(static_cast<char>(0x80 | (c & 0x3f))); - } else { - FMT_THROW(format_error("failed to format time")); - } - } - return copy_str<char>(buf.data(), buf.data() + buf.size(), out); - } - return copy_str<char>(in.data(), in.data() + in.size(), out); -} - -template <typename Char, typename OutputIt, - FMT_ENABLE_IF(!std::is_same<Char, char>::value)> -auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) - -> OutputIt { - codecvt_result<Char> unit; - write_codecvt(unit, sv, loc); - return copy_str<Char>(unit.buf, unit.end, out); -} - -template <typename Char, typename OutputIt, - FMT_ENABLE_IF(std::is_same<Char, char>::value)> -auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) - -> OutputIt { - return write_encoded_tm_str(out, sv, loc); -} - -template <typename Char> -inline void do_write(buffer<Char>& buf, const std::tm& time, - const std::locale& loc, char format, char modifier) { - auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf); - auto&& os = std::basic_ostream<Char>(&format_buf); - os.imbue(loc); - using iterator = std::ostreambuf_iterator<Char>; - const auto& facet = std::use_facet<std::time_put<Char, iterator>>(loc); - auto end = facet.put(os, os, Char(' '), &time, format, modifier); - if (end.failed()) FMT_THROW(format_error("failed to format time")); -} - -template <typename Char, typename OutputIt, - FMT_ENABLE_IF(!std::is_same<Char, char>::value)> -auto write(OutputIt out, const std::tm& time, const std::locale& loc, - char format, char modifier = 0) -> OutputIt { - auto&& buf = get_buffer<Char>(out); - do_write<Char>(buf, time, loc, format, modifier); - return buf.out(); -} - -template <typename Char, typename OutputIt, - FMT_ENABLE_IF(std::is_same<Char, char>::value)> -auto write(OutputIt out, const std::tm& time, const std::locale& loc, - char format, char modifier = 0) -> OutputIt { - auto&& buf = basic_memory_buffer<Char>(); - do_write<char>(buf, time, loc, format, modifier); - return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc); -} - -} // namespace detail - -FMT_MODULE_EXPORT_BEGIN - -/** - Converts given time since epoch as ``std::time_t`` value into calendar time, - expressed in local time. Unlike ``std::localtime``, this function is - thread-safe on most platforms. - */ -inline std::tm localtime(std::time_t time) { - struct dispatcher { - std::time_t time_; - std::tm tm_; - - dispatcher(std::time_t t) : time_(t) {} - - bool run() { - using namespace fmt::detail; - return handle(localtime_r(&time_, &tm_)); - } - - bool handle(std::tm* tm) { return tm != nullptr; } - - bool handle(detail::null<>) { - using namespace fmt::detail; - return fallback(localtime_s(&tm_, &time_)); - } - - bool fallback(int res) { return res == 0; } - -#if !FMT_MSC_VER - bool fallback(detail::null<>) { - using namespace fmt::detail; - std::tm* tm = std::localtime(&time_); - if (tm) tm_ = *tm; - return tm != nullptr; - } -#endif - }; - dispatcher lt(time); - // Too big time values may be unsupported. - if (!lt.run()) FMT_THROW(format_error("time_t value out of range")); - return lt.tm_; -} - -inline std::tm localtime( - std::chrono::time_point<std::chrono::system_clock> time_point) { - return localtime(std::chrono::system_clock::to_time_t(time_point)); -} - -/** - Converts given time since epoch as ``std::time_t`` value into calendar time, - expressed in Coordinated Universal Time (UTC). Unlike ``std::gmtime``, this - function is thread-safe on most platforms. - */ -inline std::tm gmtime(std::time_t time) { - struct dispatcher { - std::time_t time_; - std::tm tm_; - - dispatcher(std::time_t t) : time_(t) {} - - bool run() { - using namespace fmt::detail; - return handle(gmtime_r(&time_, &tm_)); - } - - bool handle(std::tm* tm) { return tm != nullptr; } - - bool handle(detail::null<>) { - using namespace fmt::detail; - return fallback(gmtime_s(&tm_, &time_)); - } - - bool fallback(int res) { return res == 0; } - -#if !FMT_MSC_VER - bool fallback(detail::null<>) { - std::tm* tm = std::gmtime(&time_); - if (tm) tm_ = *tm; - return tm != nullptr; - } -#endif - }; - dispatcher gt(time); - // Too big time values may be unsupported. - if (!gt.run()) FMT_THROW(format_error("time_t value out of range")); - return gt.tm_; -} - -inline std::tm gmtime( - std::chrono::time_point<std::chrono::system_clock> time_point) { - return gmtime(std::chrono::system_clock::to_time_t(time_point)); -} - -FMT_BEGIN_DETAIL_NAMESPACE - -// Writes two-digit numbers a, b and c separated by sep to buf. -// The method by Pavel Novikov based on -// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/. -inline void write_digit2_separated(char* buf, unsigned a, unsigned b, - unsigned c, char sep) { - unsigned long long digits = - a | (b << 24) | (static_cast<unsigned long long>(c) << 48); - // Convert each value to BCD. - // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b. - // The difference is - // y - x = a * 6 - // a can be found from x: - // a = floor(x / 10) - // then - // y = x + a * 6 = x + floor(x / 10) * 6 - // floor(x / 10) is (x * 205) >> 11 (needs 16 bits). - digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6; - // Put low nibbles to high bytes and high nibbles to low bytes. - digits = ((digits & 0x00f00000f00000f0) >> 4) | - ((digits & 0x000f00000f00000f) << 8); - auto usep = static_cast<unsigned long long>(sep); - // Add ASCII '0' to each digit byte and insert separators. - digits |= 0x3030003030003030 | (usep << 16) | (usep << 40); - - constexpr const size_t len = 8; - if (const_check(is_big_endian())) { - char tmp[len]; - memcpy(tmp, &digits, len); - std::reverse_copy(tmp, tmp + len, buf); - } else { - memcpy(buf, &digits, len); - } -} - -template <typename Period> FMT_CONSTEXPR inline const char* get_units() { - if (std::is_same<Period, std::atto>::value) return "as"; - if (std::is_same<Period, std::femto>::value) return "fs"; - if (std::is_same<Period, std::pico>::value) return "ps"; - if (std::is_same<Period, std::nano>::value) return "ns"; - if (std::is_same<Period, std::micro>::value) return "µs"; - if (std::is_same<Period, std::milli>::value) return "ms"; - if (std::is_same<Period, std::centi>::value) return "cs"; - if (std::is_same<Period, std::deci>::value) return "ds"; - if (std::is_same<Period, std::ratio<1>>::value) return "s"; - if (std::is_same<Period, std::deca>::value) return "das"; - if (std::is_same<Period, std::hecto>::value) return "hs"; - if (std::is_same<Period, std::kilo>::value) return "ks"; - if (std::is_same<Period, std::mega>::value) return "Ms"; - if (std::is_same<Period, std::giga>::value) return "Gs"; - if (std::is_same<Period, std::tera>::value) return "Ts"; - if (std::is_same<Period, std::peta>::value) return "Ps"; - if (std::is_same<Period, std::exa>::value) return "Es"; - if (std::is_same<Period, std::ratio<60>>::value) return "m"; - if (std::is_same<Period, std::ratio<3600>>::value) return "h"; - return nullptr; -} - -enum class numeric_system { - standard, - // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale. - alternative -}; - -// Parses a put_time-like format string and invokes handler actions. -template <typename Char, typename Handler> -FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, - const Char* end, - Handler&& handler) { - auto ptr = begin; - while (ptr != end) { - auto c = *ptr; - if (c == '}') break; - if (c != '%') { - ++ptr; - continue; - } - if (begin != ptr) handler.on_text(begin, ptr); - ++ptr; // consume '%' - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case '%': - handler.on_text(ptr - 1, ptr); - break; - case 'n': { - const Char newline[] = {'\n'}; - handler.on_text(newline, newline + 1); - break; - } - case 't': { - const Char tab[] = {'\t'}; - handler.on_text(tab, tab + 1); - break; - } - // Year: - case 'Y': - handler.on_year(numeric_system::standard); - break; - case 'y': - handler.on_short_year(numeric_system::standard); - break; - case 'C': - handler.on_century(numeric_system::standard); - break; - case 'G': - handler.on_iso_week_based_year(); - break; - case 'g': - handler.on_iso_week_based_short_year(); - break; - // Day of the week: - case 'a': - handler.on_abbr_weekday(); - break; - case 'A': - handler.on_full_weekday(); - break; - case 'w': - handler.on_dec0_weekday(numeric_system::standard); - break; - case 'u': - handler.on_dec1_weekday(numeric_system::standard); - break; - // Month: - case 'b': - case 'h': - handler.on_abbr_month(); - break; - case 'B': - handler.on_full_month(); - break; - case 'm': - handler.on_dec_month(numeric_system::standard); - break; - // Day of the year/month: - case 'U': - handler.on_dec0_week_of_year(numeric_system::standard); - break; - case 'W': - handler.on_dec1_week_of_year(numeric_system::standard); - break; - case 'V': - handler.on_iso_week_of_year(numeric_system::standard); - break; - case 'j': - handler.on_day_of_year(); - break; - case 'd': - handler.on_day_of_month(numeric_system::standard); - break; - case 'e': - handler.on_day_of_month_space(numeric_system::standard); - break; - // Hour, minute, second: - case 'H': - handler.on_24_hour(numeric_system::standard); - break; - case 'I': - handler.on_12_hour(numeric_system::standard); - break; - case 'M': - handler.on_minute(numeric_system::standard); - break; - case 'S': - handler.on_second(numeric_system::standard); - break; - // Other: - case 'c': - handler.on_datetime(numeric_system::standard); - break; - case 'x': - handler.on_loc_date(numeric_system::standard); - break; - case 'X': - handler.on_loc_time(numeric_system::standard); - break; - case 'D': - handler.on_us_date(); - break; - case 'F': - handler.on_iso_date(); - break; - case 'r': - handler.on_12_hour_time(); - break; - case 'R': - handler.on_24_hour_time(); - break; - case 'T': - handler.on_iso_time(); - break; - case 'p': - handler.on_am_pm(); - break; - case 'Q': - handler.on_duration_value(); - break; - case 'q': - handler.on_duration_unit(); - break; - case 'z': - handler.on_utc_offset(); - break; - case 'Z': - handler.on_tz_name(); - break; - // Alternative representation: - case 'E': { - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case 'Y': - handler.on_year(numeric_system::alternative); - break; - case 'y': - handler.on_offset_year(); - break; - case 'C': - handler.on_century(numeric_system::alternative); - break; - case 'c': - handler.on_datetime(numeric_system::alternative); - break; - case 'x': - handler.on_loc_date(numeric_system::alternative); - break; - case 'X': - handler.on_loc_time(numeric_system::alternative); - break; - default: - FMT_THROW(format_error("invalid format")); - } - break; - } - case 'O': - if (ptr == end) FMT_THROW(format_error("invalid format")); - c = *ptr++; - switch (c) { - case 'y': - handler.on_short_year(numeric_system::alternative); - break; - case 'm': - handler.on_dec_month(numeric_system::alternative); - break; - case 'U': - handler.on_dec0_week_of_year(numeric_system::alternative); - break; - case 'W': - handler.on_dec1_week_of_year(numeric_system::alternative); - break; - case 'V': - handler.on_iso_week_of_year(numeric_system::alternative); - break; - case 'd': - handler.on_day_of_month(numeric_system::alternative); - break; - case 'e': - handler.on_day_of_month_space(numeric_system::alternative); - break; - case 'w': - handler.on_dec0_weekday(numeric_system::alternative); - break; - case 'u': - handler.on_dec1_weekday(numeric_system::alternative); - break; - case 'H': - handler.on_24_hour(numeric_system::alternative); - break; - case 'I': - handler.on_12_hour(numeric_system::alternative); - break; - case 'M': - handler.on_minute(numeric_system::alternative); - break; - case 'S': - handler.on_second(numeric_system::alternative); - break; - default: - FMT_THROW(format_error("invalid format")); - } - break; - default: - FMT_THROW(format_error("invalid format")); - } - begin = ptr; - } - if (begin != ptr) handler.on_text(begin, ptr); - return ptr; -} - -template <typename Derived> struct null_chrono_spec_handler { - FMT_CONSTEXPR void unsupported() { - static_cast<Derived*>(this)->unsupported(); - } - FMT_CONSTEXPR void on_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_offset_year() { unsupported(); } - FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); } - FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); } - FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); } - FMT_CONSTEXPR void on_full_weekday() { unsupported(); } - FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_abbr_month() { unsupported(); } - FMT_CONSTEXPR void on_full_month() { unsupported(); } - FMT_CONSTEXPR void on_dec_month(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_day_of_year() { unsupported(); } - FMT_CONSTEXPR void on_day_of_month(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_day_of_month_space(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); } - FMT_CONSTEXPR void on_us_date() { unsupported(); } - FMT_CONSTEXPR void on_iso_date() { unsupported(); } - FMT_CONSTEXPR void on_12_hour_time() { unsupported(); } - FMT_CONSTEXPR void on_24_hour_time() { unsupported(); } - FMT_CONSTEXPR void on_iso_time() { unsupported(); } - FMT_CONSTEXPR void on_am_pm() { unsupported(); } - FMT_CONSTEXPR void on_duration_value() { unsupported(); } - FMT_CONSTEXPR void on_duration_unit() { unsupported(); } - FMT_CONSTEXPR void on_utc_offset() { unsupported(); } - FMT_CONSTEXPR void on_tz_name() { unsupported(); } -}; - -struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> { - FMT_NORETURN void unsupported() { FMT_THROW(format_error("no format")); } - - template <typename Char> - FMT_CONSTEXPR void on_text(const Char*, const Char*) {} - FMT_CONSTEXPR void on_year(numeric_system) {} - FMT_CONSTEXPR void on_short_year(numeric_system) {} - FMT_CONSTEXPR void on_offset_year() {} - FMT_CONSTEXPR void on_century(numeric_system) {} - FMT_CONSTEXPR void on_iso_week_based_year() {} - FMT_CONSTEXPR void on_iso_week_based_short_year() {} - FMT_CONSTEXPR void on_abbr_weekday() {} - FMT_CONSTEXPR void on_full_weekday() {} - FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {} - FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {} - FMT_CONSTEXPR void on_abbr_month() {} - FMT_CONSTEXPR void on_full_month() {} - FMT_CONSTEXPR void on_dec_month(numeric_system) {} - FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) {} - FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) {} - FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) {} - FMT_CONSTEXPR void on_day_of_year() {} - FMT_CONSTEXPR void on_day_of_month(numeric_system) {} - FMT_CONSTEXPR void on_day_of_month_space(numeric_system) {} - FMT_CONSTEXPR void on_24_hour(numeric_system) {} - FMT_CONSTEXPR void on_12_hour(numeric_system) {} - FMT_CONSTEXPR void on_minute(numeric_system) {} - FMT_CONSTEXPR void on_second(numeric_system) {} - FMT_CONSTEXPR void on_datetime(numeric_system) {} - FMT_CONSTEXPR void on_loc_date(numeric_system) {} - FMT_CONSTEXPR void on_loc_time(numeric_system) {} - FMT_CONSTEXPR void on_us_date() {} - FMT_CONSTEXPR void on_iso_date() {} - FMT_CONSTEXPR void on_12_hour_time() {} - FMT_CONSTEXPR void on_24_hour_time() {} - FMT_CONSTEXPR void on_iso_time() {} - FMT_CONSTEXPR void on_am_pm() {} - FMT_CONSTEXPR void on_utc_offset() {} - FMT_CONSTEXPR void on_tz_name() {} -}; - -inline const char* tm_wday_full_name(int wday) { - static constexpr const char* full_name_list[] = { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday"}; - return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?"; -} -inline const char* tm_wday_short_name(int wday) { - static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat"}; - return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???"; -} - -inline const char* tm_mon_full_name(int mon) { - static constexpr const char* full_name_list[] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"}; - return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?"; -} -inline const char* tm_mon_short_name(int mon) { - static constexpr const char* short_name_list[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???"; -} - -template <typename T, typename = void> -struct has_member_data_tm_gmtoff : std::false_type {}; -template <typename T> -struct has_member_data_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>> - : std::true_type {}; - -template <typename T, typename = void> -struct has_member_data_tm_zone : std::false_type {}; -template <typename T> -struct has_member_data_tm_zone<T, void_t<decltype(T::tm_zone)>> - : std::true_type {}; - -#if FMT_USE_TZSET -inline void tzset_once() { - static bool init = []() -> bool { - _tzset(); - return true; - }(); - ignore_unused(init); -} -#endif - -template <typename OutputIt, typename Char> class tm_writer { - private: - static constexpr int days_per_week = 7; - - const std::locale& loc_; - const bool is_classic_; - OutputIt out_; - const std::tm& tm_; - - auto tm_sec() const noexcept -> int { - FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, ""); - return tm_.tm_sec; - } - auto tm_min() const noexcept -> int { - FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, ""); - return tm_.tm_min; - } - auto tm_hour() const noexcept -> int { - FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, ""); - return tm_.tm_hour; - } - auto tm_mday() const noexcept -> int { - FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, ""); - return tm_.tm_mday; - } - auto tm_mon() const noexcept -> int { - FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, ""); - return tm_.tm_mon; - } - auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; } - auto tm_wday() const noexcept -> int { - FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, ""); - return tm_.tm_wday; - } - auto tm_yday() const noexcept -> int { - FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, ""); - return tm_.tm_yday; - } - - auto tm_hour12() const noexcept -> int { - const auto h = tm_hour(); - const auto z = h < 12 ? h : h - 12; - return z == 0 ? 12 : z; - } - - // POSIX and the C Standard are unclear or inconsistent about what %C and %y - // do if the year is negative or exceeds 9999. Use the convention that %C - // concatenated with %y yields the same output as %Y, and that %Y contains at - // least 4 characters, with more only if necessary. - auto split_year_lower(long long year) const noexcept -> int { - auto l = year % 100; - if (l < 0) l = -l; // l in [0, 99] - return static_cast<int>(l); - } - - // Algorithm: - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_from_a_month_and_day_of_the_month_or_ordinal_date - auto iso_year_weeks(long long curr_year) const noexcept -> int { - const auto prev_year = curr_year - 1; - const auto curr_p = - (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) % - days_per_week; - const auto prev_p = - (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) % - days_per_week; - return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0); - } - auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int { - return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) / - days_per_week; - } - auto tm_iso_week_year() const noexcept -> long long { - const auto year = tm_year(); - const auto w = iso_week_num(tm_yday(), tm_wday()); - if (w < 1) return year - 1; - if (w > iso_year_weeks(year)) return year + 1; - return year; - } - auto tm_iso_week_of_year() const noexcept -> int { - const auto year = tm_year(); - const auto w = iso_week_num(tm_yday(), tm_wday()); - if (w < 1) return iso_year_weeks(year - 1); - if (w > iso_year_weeks(year)) return 1; - return w; - } - - void write1(int value) { - *out_++ = static_cast<char>('0' + to_unsigned(value) % 10); - } - void write2(int value) { - const char* d = digits2(to_unsigned(value) % 100); - *out_++ = *d++; - *out_++ = *d; - } - - void write_year_extended(long long year) { - // At least 4 characters. - int width = 4; - if (year < 0) { - *out_++ = '-'; - year = 0 - year; - --width; - } - uint32_or_64_or_128_t<long long> n = to_unsigned(year); - const int num_digits = count_digits(n); - if (width > num_digits) out_ = std::fill_n(out_, width - num_digits, '0'); - out_ = format_decimal<Char>(out_, n, num_digits).end; - } - void write_year(long long year) { - if (year >= 0 && year < 10000) { - write2(static_cast<int>(year / 100)); - write2(static_cast<int>(year % 100)); - } else { - write_year_extended(year); - } - } - - void write_utc_offset(long offset) { - if (offset < 0) { - *out_++ = '-'; - offset = -offset; - } else { - *out_++ = '+'; - } - offset /= 60; - write2(static_cast<int>(offset / 60)); - write2(static_cast<int>(offset % 60)); - } - template <typename T, FMT_ENABLE_IF(has_member_data_tm_gmtoff<T>::value)> - void format_utc_offset_impl(const T& tm) { - write_utc_offset(tm.tm_gmtoff); - } - template <typename T, FMT_ENABLE_IF(!has_member_data_tm_gmtoff<T>::value)> - void format_utc_offset_impl(const T& tm) { -#if defined(_WIN32) && defined(_UCRT) -# if FMT_USE_TZSET - tzset_once(); -# endif - long offset = 0; - _get_timezone(&offset); - if (tm.tm_isdst) { - long dstbias = 0; - _get_dstbias(&dstbias); - offset += dstbias; - } - write_utc_offset(-offset); -#else - ignore_unused(tm); - format_localized('z'); -#endif - } - - template <typename T, FMT_ENABLE_IF(has_member_data_tm_zone<T>::value)> - void format_tz_name_impl(const T& tm) { - if (is_classic_) - out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_); - else - format_localized('Z'); - } - template <typename T, FMT_ENABLE_IF(!has_member_data_tm_zone<T>::value)> - void format_tz_name_impl(const T&) { - format_localized('Z'); - } - - void format_localized(char format, char modifier = 0) { - out_ = write<Char>(out_, tm_, loc_, format, modifier); - } - - public: - tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm) - : loc_(loc), - is_classic_(loc_ == get_classic_locale()), - out_(out), - tm_(tm) {} - - OutputIt out() const { return out_; } - - FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) { - out_ = copy_str<Char>(begin, end, out_); - } - - void on_abbr_weekday() { - if (is_classic_) - out_ = write(out_, tm_wday_short_name(tm_wday())); - else - format_localized('a'); - } - void on_full_weekday() { - if (is_classic_) - out_ = write(out_, tm_wday_full_name(tm_wday())); - else - format_localized('A'); - } - void on_dec0_weekday(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday()); - format_localized('w', 'O'); - } - void on_dec1_weekday(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto wday = tm_wday(); - write1(wday == 0 ? days_per_week : wday); - } else { - format_localized('u', 'O'); - } - } - - void on_abbr_month() { - if (is_classic_) - out_ = write(out_, tm_mon_short_name(tm_mon())); - else - format_localized('b'); - } - void on_full_month() { - if (is_classic_) - out_ = write(out_, tm_mon_full_name(tm_mon())); - else - format_localized('B'); - } - - void on_datetime(numeric_system ns) { - if (is_classic_) { - on_abbr_weekday(); - *out_++ = ' '; - on_abbr_month(); - *out_++ = ' '; - on_day_of_month_space(numeric_system::standard); - *out_++ = ' '; - on_iso_time(); - *out_++ = ' '; - on_year(numeric_system::standard); - } else { - format_localized('c', ns == numeric_system::standard ? '\0' : 'E'); - } - } - void on_loc_date(numeric_system ns) { - if (is_classic_) - on_us_date(); - else - format_localized('x', ns == numeric_system::standard ? '\0' : 'E'); - } - void on_loc_time(numeric_system ns) { - if (is_classic_) - on_iso_time(); - else - format_localized('X', ns == numeric_system::standard ? '\0' : 'E'); - } - void on_us_date() { - char buf[8]; - write_digit2_separated(buf, to_unsigned(tm_mon() + 1), - to_unsigned(tm_mday()), - to_unsigned(split_year_lower(tm_year())), '/'); - out_ = copy_str<Char>(std::begin(buf), std::end(buf), out_); - } - void on_iso_date() { - auto year = tm_year(); - char buf[10]; - size_t offset = 0; - if (year >= 0 && year < 10000) { - copy2(buf, digits2(to_unsigned(year / 100))); - } else { - offset = 4; - write_year_extended(year); - year = 0; - } - write_digit2_separated(buf + 2, static_cast<unsigned>(year % 100), - to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()), - '-'); - out_ = copy_str<Char>(std::begin(buf) + offset, std::end(buf), out_); - } - - void on_utc_offset() { format_utc_offset_impl(tm_); } - void on_tz_name() { format_tz_name_impl(tm_); } - - void on_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write_year(tm_year()); - format_localized('Y', 'E'); - } - void on_short_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2(split_year_lower(tm_year())); - format_localized('y', 'O'); - } - void on_offset_year() { - if (is_classic_) return write2(split_year_lower(tm_year())); - format_localized('y', 'E'); - } - - void on_century(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto year = tm_year(); - auto upper = year / 100; - if (year >= -99 && year < 0) { - // Zero upper on negative year. - *out_++ = '-'; - *out_++ = '0'; - } else if (upper >= 0 && upper < 100) { - write2(static_cast<int>(upper)); - } else { - out_ = write<Char>(out_, upper); - } - } else { - format_localized('C', 'E'); - } - } - - void on_dec_month(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_mon() + 1); - format_localized('m', 'O'); - } - - void on_dec0_week_of_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week); - format_localized('U', 'O'); - } - void on_dec1_week_of_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto wday = tm_wday(); - write2((tm_yday() + days_per_week - - (wday == 0 ? (days_per_week - 1) : (wday - 1))) / - days_per_week); - } else { - format_localized('W', 'O'); - } - } - void on_iso_week_of_year(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_iso_week_of_year()); - format_localized('V', 'O'); - } - - void on_iso_week_based_year() { write_year(tm_iso_week_year()); } - void on_iso_week_based_short_year() { - write2(split_year_lower(tm_iso_week_year())); - } - - void on_day_of_year() { - auto yday = tm_yday() + 1; - write1(yday / 100); - write2(yday % 100); - } - void on_day_of_month(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write2(tm_mday()); - format_localized('d', 'O'); - } - void on_day_of_month_space(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) { - auto mday = to_unsigned(tm_mday()) % 100; - const char* d2 = digits2(mday); - *out_++ = mday < 10 ? ' ' : d2[0]; - *out_++ = d2[1]; - } else { - format_localized('e', 'O'); - } - } - - void on_24_hour(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write2(tm_hour()); - format_localized('H', 'O'); - } - void on_12_hour(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) - return write2(tm_hour12()); - format_localized('I', 'O'); - } - void on_minute(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write2(tm_min()); - format_localized('M', 'O'); - } - void on_second(numeric_system ns) { - if (is_classic_ || ns == numeric_system::standard) return write2(tm_sec()); - format_localized('S', 'O'); - } - - void on_12_hour_time() { - if (is_classic_) { - char buf[8]; - write_digit2_separated(buf, to_unsigned(tm_hour12()), - to_unsigned(tm_min()), to_unsigned(tm_sec()), ':'); - out_ = copy_str<Char>(std::begin(buf), std::end(buf), out_); - *out_++ = ' '; - on_am_pm(); - } else { - format_localized('r'); - } - } - void on_24_hour_time() { - write2(tm_hour()); - *out_++ = ':'; - write2(tm_min()); - } - void on_iso_time() { - char buf[8]; - write_digit2_separated(buf, to_unsigned(tm_hour()), to_unsigned(tm_min()), - to_unsigned(tm_sec()), ':'); - out_ = copy_str<Char>(std::begin(buf), std::end(buf), out_); - } - - void on_am_pm() { - if (is_classic_) { - *out_++ = tm_hour() < 12 ? 'A' : 'P'; - *out_++ = 'M'; - } else { - format_localized('p'); - } - } - - // These apply to chrono durations but not tm. - void on_duration_value() {} - void on_duration_unit() {} -}; - -struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> { - FMT_NORETURN void unsupported() { FMT_THROW(format_error("no date")); } - - template <typename Char> - FMT_CONSTEXPR void on_text(const Char*, const Char*) {} - FMT_CONSTEXPR void on_24_hour(numeric_system) {} - FMT_CONSTEXPR void on_12_hour(numeric_system) {} - FMT_CONSTEXPR void on_minute(numeric_system) {} - FMT_CONSTEXPR void on_second(numeric_system) {} - FMT_CONSTEXPR void on_12_hour_time() {} - FMT_CONSTEXPR void on_24_hour_time() {} - FMT_CONSTEXPR void on_iso_time() {} - FMT_CONSTEXPR void on_am_pm() {} - FMT_CONSTEXPR void on_duration_value() {} - FMT_CONSTEXPR void on_duration_unit() {} -}; - -template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> -inline bool isnan(T) { - return false; -} -template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> -inline bool isnan(T value) { - return std::isnan(value); -} - -template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> -inline bool isfinite(T) { - return true; -} - -// Converts value to Int and checks that it's in the range [0, upper). -template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)> -inline Int to_nonnegative_int(T value, Int upper) { - FMT_ASSERT(value >= 0 && to_unsigned(value) <= to_unsigned(upper), - "invalid value"); - (void)upper; - return static_cast<Int>(value); -} -template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)> -inline Int to_nonnegative_int(T value, Int upper) { - if (value < 0 || value > static_cast<T>(upper)) - FMT_THROW(format_error("invalid value")); - return static_cast<Int>(value); -} - -template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> -inline T mod(T x, int y) { - return x % static_cast<T>(y); -} -template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> -inline T mod(T x, int y) { - return std::fmod(x, static_cast<T>(y)); -} - -// If T is an integral type, maps T to its unsigned counterpart, otherwise -// leaves it unchanged (unlike std::make_unsigned). -template <typename T, bool INTEGRAL = std::is_integral<T>::value> -struct make_unsigned_or_unchanged { - using type = T; -}; - -template <typename T> struct make_unsigned_or_unchanged<T, true> { - using type = typename std::make_unsigned<T>::type; -}; - -#if FMT_SAFE_DURATION_CAST -// throwing version of safe_duration_cast -template <typename To, typename FromRep, typename FromPeriod> -To fmt_safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) { - int ec; - To to = safe_duration_cast::safe_duration_cast<To>(from, ec); - if (ec) FMT_THROW(format_error("cannot format duration")); - return to; -} -#endif - -template <typename Rep, typename Period, - FMT_ENABLE_IF(std::is_integral<Rep>::value)> -inline std::chrono::duration<Rep, std::milli> get_milliseconds( - std::chrono::duration<Rep, Period> d) { - // this may overflow and/or the result may not fit in the - // target type. -#if FMT_SAFE_DURATION_CAST - using CommonSecondsType = - typename std::common_type<decltype(d), std::chrono::seconds>::type; - const auto d_as_common = fmt_safe_duration_cast<CommonSecondsType>(d); - const auto d_as_whole_seconds = - fmt_safe_duration_cast<std::chrono::seconds>(d_as_common); - // this conversion should be nonproblematic - const auto diff = d_as_common - d_as_whole_seconds; - const auto ms = - fmt_safe_duration_cast<std::chrono::duration<Rep, std::milli>>(diff); - return ms; -#else - auto s = std::chrono::duration_cast<std::chrono::seconds>(d); - return std::chrono::duration_cast<std::chrono::milliseconds>(d - s); -#endif -} - -// Returns the number of fractional digits in the range [0, 18] according to the -// C++20 spec. If more than 18 fractional digits are required then returns 6 for -// microseconds precision. -constexpr int count_fractional_digits(long long num, long long den, int n = 0) { - return num % den == 0 - ? n - : (n > 18 ? 6 : count_fractional_digits(num * 10, den, n + 1)); -} - -constexpr long long pow10(std::uint32_t n) { - return n == 0 ? 1 : 10 * pow10(n - 1); -} - -template <class Rep, class Period, - FMT_ENABLE_IF(std::numeric_limits<Rep>::is_signed)> -constexpr std::chrono::duration<Rep, Period> abs( - std::chrono::duration<Rep, Period> d) { - // We need to compare the duration using the count() method directly - // due to a compiler bug in clang-11 regarding the spaceship operator, - // when -Wzero-as-null-pointer-constant is enabled. - // In clang-12 the bug has been fixed. See - // https://bugs.llvm.org/show_bug.cgi?id=46235 and the reproducible example: - // https://www.godbolt.org/z/Knbb5joYx. - return d.count() >= d.zero().count() ? d : -d; -} - -template <class Rep, class Period, - FMT_ENABLE_IF(!std::numeric_limits<Rep>::is_signed)> -constexpr std::chrono::duration<Rep, Period> abs( - std::chrono::duration<Rep, Period> d) { - return d; -} - -template <typename Char, typename Rep, typename OutputIt, - FMT_ENABLE_IF(std::is_integral<Rep>::value)> -OutputIt format_duration_value(OutputIt out, Rep val, int) { - return write<Char>(out, val); -} - -template <typename Char, typename Rep, typename OutputIt, - FMT_ENABLE_IF(std::is_floating_point<Rep>::value)> -OutputIt format_duration_value(OutputIt out, Rep val, int precision) { - auto specs = basic_format_specs<Char>(); - specs.precision = precision; - specs.type = precision >= 0 ? presentation_type::fixed_lower - : presentation_type::general_lower; - return write<Char>(out, val, specs); -} - -template <typename Char, typename OutputIt> -OutputIt copy_unit(string_view unit, OutputIt out, Char) { - return std::copy(unit.begin(), unit.end(), out); -} - -template <typename OutputIt> -OutputIt copy_unit(string_view unit, OutputIt out, wchar_t) { - // This works when wchar_t is UTF-32 because units only contain characters - // that have the same representation in UTF-16 and UTF-32. - utf8_to_utf16 u(unit); - return std::copy(u.c_str(), u.c_str() + u.size(), out); -} - -template <typename Char, typename Period, typename OutputIt> -OutputIt format_duration_unit(OutputIt out) { - if (const char* unit = get_units<Period>()) - return copy_unit(string_view(unit), out, Char()); - *out++ = '['; - out = write<Char>(out, Period::num); - if (const_check(Period::den != 1)) { - *out++ = '/'; - out = write<Char>(out, Period::den); - } - *out++ = ']'; - *out++ = 's'; - return out; -} - -class get_locale { - private: - union { - std::locale locale_; - }; - bool has_locale_ = false; - - public: - get_locale(bool localized, locale_ref loc) : has_locale_(localized) { - if (localized) - ::new (&locale_) std::locale(loc.template get<std::locale>()); - } - ~get_locale() { - if (has_locale_) locale_.~locale(); - } - operator const std::locale&() const { - return has_locale_ ? locale_ : get_classic_locale(); - } -}; - -template <typename FormatContext, typename OutputIt, typename Rep, - typename Period> -struct chrono_formatter { - FormatContext& context; - OutputIt out; - int precision; - bool localized = false; - // rep is unsigned to avoid overflow. - using rep = - conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int), - unsigned, typename make_unsigned_or_unchanged<Rep>::type>; - rep val; - using seconds = std::chrono::duration<rep>; - seconds s; - using milliseconds = std::chrono::duration<rep, std::milli>; - bool negative; - - using char_type = typename FormatContext::char_type; - using tm_writer_type = tm_writer<OutputIt, char_type>; - - chrono_formatter(FormatContext& ctx, OutputIt o, - std::chrono::duration<Rep, Period> d) - : context(ctx), - out(o), - val(static_cast<rep>(d.count())), - negative(false) { - if (d.count() < 0) { - val = 0 - val; - negative = true; - } - - // this may overflow and/or the result may not fit in the - // target type. -#if FMT_SAFE_DURATION_CAST - // might need checked conversion (rep!=Rep) - auto tmpval = std::chrono::duration<rep, Period>(val); - s = fmt_safe_duration_cast<seconds>(tmpval); -#else - s = std::chrono::duration_cast<seconds>( - std::chrono::duration<rep, Period>(val)); -#endif - } - - // returns true if nan or inf, writes to out. - bool handle_nan_inf() { - if (isfinite(val)) { - return false; - } - if (isnan(val)) { - write_nan(); - return true; - } - // must be +-inf - if (val > 0) { - write_pinf(); - } else { - write_ninf(); - } - return true; - } - - Rep hour() const { return static_cast<Rep>(mod((s.count() / 3600), 24)); } - - Rep hour12() const { - Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12)); - return hour <= 0 ? 12 : hour; - } - - Rep minute() const { return static_cast<Rep>(mod((s.count() / 60), 60)); } - Rep second() const { return static_cast<Rep>(mod(s.count(), 60)); } - - std::tm time() const { - auto time = std::tm(); - time.tm_hour = to_nonnegative_int(hour(), 24); - time.tm_min = to_nonnegative_int(minute(), 60); - time.tm_sec = to_nonnegative_int(second(), 60); - return time; - } - - void write_sign() { - if (negative) { - *out++ = '-'; - negative = false; - } - } - - void write(Rep value, int width) { - write_sign(); - if (isnan(value)) return write_nan(); - uint32_or_64_or_128_t<int> n = - to_unsigned(to_nonnegative_int(value, max_value<int>())); - int num_digits = detail::count_digits(n); - if (width > num_digits) out = std::fill_n(out, width - num_digits, '0'); - out = format_decimal<char_type>(out, n, num_digits).end; - } - - template <class Duration> void write_fractional_seconds(Duration d) { - constexpr auto num_fractional_digits = - count_fractional_digits(Duration::period::num, Duration::period::den); - - using subsecond_precision = std::chrono::duration< - typename std::common_type<typename Duration::rep, - std::chrono::seconds::rep>::type, - std::ratio<1, detail::pow10(num_fractional_digits)>>; - if (std::ratio_less<typename subsecond_precision::period, - std::chrono::seconds::period>::value) { - *out++ = '.'; - // Don't convert long double to integer seconds to avoid overflow. - using sec = conditional_t< - std::is_same<typename Duration::rep, long double>::value, - std::chrono::duration<long double>, std::chrono::seconds>; - auto fractional = detail::abs(d) - std::chrono::duration_cast<sec>(d); - const auto subseconds = - std::chrono::treat_as_floating_point< - typename subsecond_precision::rep>::value - ? fractional.count() - : std::chrono::duration_cast<subsecond_precision>(fractional) - .count(); - uint32_or_64_or_128_t<long long> n = - to_unsigned(to_nonnegative_int(subseconds, max_value<long long>())); - int num_digits = detail::count_digits(n); - if (num_fractional_digits > num_digits) - out = std::fill_n(out, num_fractional_digits - num_digits, '0'); - out = format_decimal<char_type>(out, n, num_digits).end; - } - } - - void write_nan() { std::copy_n("nan", 3, out); } - void write_pinf() { std::copy_n("inf", 3, out); } - void write_ninf() { std::copy_n("-inf", 4, out); } - - template <typename Callback, typename... Args> - void format_tm(const tm& time, Callback cb, Args... args) { - if (isnan(val)) return write_nan(); - get_locale loc(localized, context.locale()); - auto w = tm_writer_type(loc, out, time); - (w.*cb)(args...); - out = w.out(); - } - - void on_text(const char_type* begin, const char_type* end) { - std::copy(begin, end, out); - } - - // These are not implemented because durations don't have date information. - void on_abbr_weekday() {} - void on_full_weekday() {} - void on_dec0_weekday(numeric_system) {} - void on_dec1_weekday(numeric_system) {} - void on_abbr_month() {} - void on_full_month() {} - void on_datetime(numeric_system) {} - void on_loc_date(numeric_system) {} - void on_loc_time(numeric_system) {} - void on_us_date() {} - void on_iso_date() {} - void on_utc_offset() {} - void on_tz_name() {} - void on_year(numeric_system) {} - void on_short_year(numeric_system) {} - void on_offset_year() {} - void on_century(numeric_system) {} - void on_iso_week_based_year() {} - void on_iso_week_based_short_year() {} - void on_dec_month(numeric_system) {} - void on_dec0_week_of_year(numeric_system) {} - void on_dec1_week_of_year(numeric_system) {} - void on_iso_week_of_year(numeric_system) {} - void on_day_of_year() {} - void on_day_of_month(numeric_system) {} - void on_day_of_month_space(numeric_system) {} - - void on_24_hour(numeric_system ns) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(hour(), 2); - auto time = tm(); - time.tm_hour = to_nonnegative_int(hour(), 24); - format_tm(time, &tm_writer_type::on_24_hour, ns); - } - - void on_12_hour(numeric_system ns) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(hour12(), 2); - auto time = tm(); - time.tm_hour = to_nonnegative_int(hour12(), 12); - format_tm(time, &tm_writer_type::on_12_hour, ns); - } - - void on_minute(numeric_system ns) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) return write(minute(), 2); - auto time = tm(); - time.tm_min = to_nonnegative_int(minute(), 60); - format_tm(time, &tm_writer_type::on_minute, ns); - } - - void on_second(numeric_system ns) { - if (handle_nan_inf()) return; - - if (ns == numeric_system::standard) { - write(second(), 2); - write_fractional_seconds(std::chrono::duration<rep, Period>{val}); - return; - } - auto time = tm(); - time.tm_sec = to_nonnegative_int(second(), 60); - format_tm(time, &tm_writer_type::on_second, ns); - } - - void on_12_hour_time() { - if (handle_nan_inf()) return; - format_tm(time(), &tm_writer_type::on_12_hour_time); - } - - void on_24_hour_time() { - if (handle_nan_inf()) { - *out++ = ':'; - handle_nan_inf(); - return; - } - - write(hour(), 2); - *out++ = ':'; - write(minute(), 2); - } - - void on_iso_time() { - on_24_hour_time(); - *out++ = ':'; - if (handle_nan_inf()) return; - on_second(numeric_system::standard); - } - - void on_am_pm() { - if (handle_nan_inf()) return; - format_tm(time(), &tm_writer_type::on_am_pm); - } - - void on_duration_value() { - if (handle_nan_inf()) return; - write_sign(); - out = format_duration_value<char_type>(out, val, precision); - } - - void on_duration_unit() { - out = format_duration_unit<char_type, Period>(out); - } -}; - -FMT_END_DETAIL_NAMESPACE - -#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907 -using weekday = std::chrono::weekday; -#else -// A fallback version of weekday. -class weekday { - private: - unsigned char value; - - public: - weekday() = default; - explicit constexpr weekday(unsigned wd) noexcept - : value(static_cast<unsigned char>(wd != 7 ? wd : 0)) {} - constexpr unsigned c_encoding() const noexcept { return value; } -}; - -class year_month_day {}; -#endif - -// A rudimentary weekday formatter. -template <typename Char> struct formatter<weekday, Char> { - private: - bool localized = false; - - public: - FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx) - -> decltype(ctx.begin()) { - auto begin = ctx.begin(), end = ctx.end(); - if (begin != end && *begin == 'L') { - ++begin; - localized = true; - } - return begin; - } - - template <typename FormatContext> - auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { - auto time = std::tm(); - time.tm_wday = static_cast<int>(wd.c_encoding()); - detail::get_locale loc(localized, ctx.locale()); - auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time); - w.on_abbr_weekday(); - return w.out(); - } -}; - -template <typename Rep, typename Period, typename Char> -struct formatter<std::chrono::duration<Rep, Period>, Char> { - private: - basic_format_specs<Char> specs; - int precision = -1; - using arg_ref_type = detail::arg_ref<Char>; - arg_ref_type width_ref; - arg_ref_type precision_ref; - bool localized = false; - basic_string_view<Char> format_str; - using duration = std::chrono::duration<Rep, Period>; - - struct spec_handler { - formatter& f; - basic_format_parse_context<Char>& context; - basic_string_view<Char> format_str; - - template <typename Id> FMT_CONSTEXPR arg_ref_type make_arg_ref(Id arg_id) { - context.check_arg_id(arg_id); - return arg_ref_type(arg_id); - } - - FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view<Char> arg_id) { - context.check_arg_id(arg_id); - return arg_ref_type(arg_id); - } - - FMT_CONSTEXPR arg_ref_type make_arg_ref(detail::auto_id) { - return arg_ref_type(context.next_arg_id()); - } - - void on_error(const char* msg) { FMT_THROW(format_error(msg)); } - FMT_CONSTEXPR void on_fill(basic_string_view<Char> fill) { - f.specs.fill = fill; - } - FMT_CONSTEXPR void on_align(align_t align) { f.specs.align = align; } - FMT_CONSTEXPR void on_width(int width) { f.specs.width = width; } - FMT_CONSTEXPR void on_precision(int _precision) { - f.precision = _precision; - } - FMT_CONSTEXPR void end_precision() {} - - template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { - f.width_ref = make_arg_ref(arg_id); - } - - template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { - f.precision_ref = make_arg_ref(arg_id); - } - }; - - using iterator = typename basic_format_parse_context<Char>::iterator; - struct parse_range { - iterator begin; - iterator end; - }; - - FMT_CONSTEXPR parse_range do_parse(basic_format_parse_context<Char>& ctx) { - auto begin = ctx.begin(), end = ctx.end(); - if (begin == end || *begin == '}') return {begin, begin}; - spec_handler handler{*this, ctx, format_str}; - begin = detail::parse_align(begin, end, handler); - if (begin == end) return {begin, begin}; - begin = detail::parse_width(begin, end, handler); - if (begin == end) return {begin, begin}; - if (*begin == '.') { - if (std::is_floating_point<Rep>::value) - begin = detail::parse_precision(begin, end, handler); - else - handler.on_error("precision not allowed for this argument type"); - } - if (begin != end && *begin == 'L') { - ++begin; - localized = true; - } - end = detail::parse_chrono_format(begin, end, - detail::chrono_format_checker()); - return {begin, end}; - } - - public: - FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx) - -> decltype(ctx.begin()) { - auto range = do_parse(ctx); - format_str = basic_string_view<Char>( - &*range.begin, detail::to_unsigned(range.end - range.begin)); - return range.end; - } - - template <typename FormatContext> - auto format(const duration& d, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto specs_copy = specs; - auto precision_copy = precision; - auto begin = format_str.begin(), end = format_str.end(); - // As a possible future optimization, we could avoid extra copying if width - // is not specified. - basic_memory_buffer<Char> buf; - auto out = std::back_inserter(buf); - detail::handle_dynamic_spec<detail::width_checker>(specs_copy.width, - width_ref, ctx); - detail::handle_dynamic_spec<detail::precision_checker>(precision_copy, - precision_ref, ctx); - if (begin == end || *begin == '}') { - out = detail::format_duration_value<Char>(out, d.count(), precision_copy); - detail::format_duration_unit<Char, Period>(out); - } else { - detail::chrono_formatter<FormatContext, decltype(out), Rep, Period> f( - ctx, out, d); - f.precision = precision_copy; - f.localized = localized; - detail::parse_chrono_format(begin, end, f); - } - return detail::write( - ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs_copy); - } -}; - -template <typename Char, typename Duration> -struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>, - Char> : formatter<std::tm, Char> { - FMT_CONSTEXPR formatter() { - this->do_parse(default_specs, - default_specs + sizeof(default_specs) / sizeof(Char)); - } - - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return this->do_parse(ctx.begin(), ctx.end(), true); - } - - template <typename FormatContext> - auto format(std::chrono::time_point<std::chrono::system_clock> val, - FormatContext& ctx) const -> decltype(ctx.out()) { - return formatter<std::tm, Char>::format(localtime(val), ctx); - } - - static constexpr const Char default_specs[] = {'%', 'F', ' ', '%', 'T'}; -}; - -template <typename Char, typename Duration> -constexpr const Char - formatter<std::chrono::time_point<std::chrono::system_clock, Duration>, - Char>::default_specs[]; - -template <typename Char> struct formatter<std::tm, Char> { - private: - enum class spec { - unknown, - year_month_day, - hh_mm_ss, - }; - spec spec_ = spec::unknown; - basic_string_view<Char> specs; - - protected: - template <typename It> - FMT_CONSTEXPR auto do_parse(It begin, It end, bool with_default = false) - -> It { - if (begin != end && *begin == ':') ++begin; - end = detail::parse_chrono_format(begin, end, detail::tm_format_checker()); - if (!with_default || end != begin) - specs = {begin, detail::to_unsigned(end - begin)}; - // basic_string_view<>::compare isn't constexpr before C++17. - if (specs.size() == 2 && specs[0] == Char('%')) { - if (specs[1] == Char('F')) - spec_ = spec::year_month_day; - else if (specs[1] == Char('T')) - spec_ = spec::hh_mm_ss; - } - return end; - } - - public: - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return this->do_parse(ctx.begin(), ctx.end()); - } - - template <typename FormatContext> - auto format(const std::tm& tm, FormatContext& ctx) const - -> decltype(ctx.out()) { - const auto loc_ref = ctx.locale(); - detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref); - auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), tm); - if (spec_ == spec::year_month_day) - w.on_iso_date(); - else if (spec_ == spec::hh_mm_ss) - w.on_iso_time(); - else - detail::parse_chrono_format(specs.begin(), specs.end(), w); - return w.out(); - } -}; - -FMT_MODULE_EXPORT_END -FMT_END_NAMESPACE - -#endif // FMT_CHRONO_H_ diff --git a/contrib/libs/fmt/include/fmt/color.h b/contrib/libs/fmt/include/fmt/color.h deleted file mode 100644 index dfbe482938..0000000000 --- a/contrib/libs/fmt/include/fmt/color.h +++ /dev/null @@ -1,638 +0,0 @@ -// Formatting library for C++ - color support -// -// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_COLOR_H_ -#define FMT_COLOR_H_ - -#include "format.h" - -// __declspec(deprecated) is broken in some MSVC versions. -#if FMT_MSC_VER -# define FMT_DEPRECATED_NONMSVC -#else -# define FMT_DEPRECATED_NONMSVC FMT_DEPRECATED -#endif - -FMT_BEGIN_NAMESPACE -FMT_MODULE_EXPORT_BEGIN - -enum class color : uint32_t { - alice_blue = 0xF0F8FF, // rgb(240,248,255) - antique_white = 0xFAEBD7, // rgb(250,235,215) - aqua = 0x00FFFF, // rgb(0,255,255) - aquamarine = 0x7FFFD4, // rgb(127,255,212) - azure = 0xF0FFFF, // rgb(240,255,255) - beige = 0xF5F5DC, // rgb(245,245,220) - bisque = 0xFFE4C4, // rgb(255,228,196) - black = 0x000000, // rgb(0,0,0) - blanched_almond = 0xFFEBCD, // rgb(255,235,205) - blue = 0x0000FF, // rgb(0,0,255) - blue_violet = 0x8A2BE2, // rgb(138,43,226) - brown = 0xA52A2A, // rgb(165,42,42) - burly_wood = 0xDEB887, // rgb(222,184,135) - cadet_blue = 0x5F9EA0, // rgb(95,158,160) - chartreuse = 0x7FFF00, // rgb(127,255,0) - chocolate = 0xD2691E, // rgb(210,105,30) - coral = 0xFF7F50, // rgb(255,127,80) - cornflower_blue = 0x6495ED, // rgb(100,149,237) - cornsilk = 0xFFF8DC, // rgb(255,248,220) - crimson = 0xDC143C, // rgb(220,20,60) - cyan = 0x00FFFF, // rgb(0,255,255) - dark_blue = 0x00008B, // rgb(0,0,139) - dark_cyan = 0x008B8B, // rgb(0,139,139) - dark_golden_rod = 0xB8860B, // rgb(184,134,11) - dark_gray = 0xA9A9A9, // rgb(169,169,169) - dark_green = 0x006400, // rgb(0,100,0) - dark_khaki = 0xBDB76B, // rgb(189,183,107) - dark_magenta = 0x8B008B, // rgb(139,0,139) - dark_olive_green = 0x556B2F, // rgb(85,107,47) - dark_orange = 0xFF8C00, // rgb(255,140,0) - dark_orchid = 0x9932CC, // rgb(153,50,204) - dark_red = 0x8B0000, // rgb(139,0,0) - dark_salmon = 0xE9967A, // rgb(233,150,122) - dark_sea_green = 0x8FBC8F, // rgb(143,188,143) - dark_slate_blue = 0x483D8B, // rgb(72,61,139) - dark_slate_gray = 0x2F4F4F, // rgb(47,79,79) - dark_turquoise = 0x00CED1, // rgb(0,206,209) - dark_violet = 0x9400D3, // rgb(148,0,211) - deep_pink = 0xFF1493, // rgb(255,20,147) - deep_sky_blue = 0x00BFFF, // rgb(0,191,255) - dim_gray = 0x696969, // rgb(105,105,105) - dodger_blue = 0x1E90FF, // rgb(30,144,255) - fire_brick = 0xB22222, // rgb(178,34,34) - floral_white = 0xFFFAF0, // rgb(255,250,240) - forest_green = 0x228B22, // rgb(34,139,34) - fuchsia = 0xFF00FF, // rgb(255,0,255) - gainsboro = 0xDCDCDC, // rgb(220,220,220) - ghost_white = 0xF8F8FF, // rgb(248,248,255) - gold = 0xFFD700, // rgb(255,215,0) - golden_rod = 0xDAA520, // rgb(218,165,32) - gray = 0x808080, // rgb(128,128,128) - green = 0x008000, // rgb(0,128,0) - green_yellow = 0xADFF2F, // rgb(173,255,47) - honey_dew = 0xF0FFF0, // rgb(240,255,240) - hot_pink = 0xFF69B4, // rgb(255,105,180) - indian_red = 0xCD5C5C, // rgb(205,92,92) - indigo = 0x4B0082, // rgb(75,0,130) - ivory = 0xFFFFF0, // rgb(255,255,240) - khaki = 0xF0E68C, // rgb(240,230,140) - lavender = 0xE6E6FA, // rgb(230,230,250) - lavender_blush = 0xFFF0F5, // rgb(255,240,245) - lawn_green = 0x7CFC00, // rgb(124,252,0) - lemon_chiffon = 0xFFFACD, // rgb(255,250,205) - light_blue = 0xADD8E6, // rgb(173,216,230) - light_coral = 0xF08080, // rgb(240,128,128) - light_cyan = 0xE0FFFF, // rgb(224,255,255) - light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210) - light_gray = 0xD3D3D3, // rgb(211,211,211) - light_green = 0x90EE90, // rgb(144,238,144) - light_pink = 0xFFB6C1, // rgb(255,182,193) - light_salmon = 0xFFA07A, // rgb(255,160,122) - light_sea_green = 0x20B2AA, // rgb(32,178,170) - light_sky_blue = 0x87CEFA, // rgb(135,206,250) - light_slate_gray = 0x778899, // rgb(119,136,153) - light_steel_blue = 0xB0C4DE, // rgb(176,196,222) - light_yellow = 0xFFFFE0, // rgb(255,255,224) - lime = 0x00FF00, // rgb(0,255,0) - lime_green = 0x32CD32, // rgb(50,205,50) - linen = 0xFAF0E6, // rgb(250,240,230) - magenta = 0xFF00FF, // rgb(255,0,255) - maroon = 0x800000, // rgb(128,0,0) - medium_aquamarine = 0x66CDAA, // rgb(102,205,170) - medium_blue = 0x0000CD, // rgb(0,0,205) - medium_orchid = 0xBA55D3, // rgb(186,85,211) - medium_purple = 0x9370DB, // rgb(147,112,219) - medium_sea_green = 0x3CB371, // rgb(60,179,113) - medium_slate_blue = 0x7B68EE, // rgb(123,104,238) - medium_spring_green = 0x00FA9A, // rgb(0,250,154) - medium_turquoise = 0x48D1CC, // rgb(72,209,204) - medium_violet_red = 0xC71585, // rgb(199,21,133) - midnight_blue = 0x191970, // rgb(25,25,112) - mint_cream = 0xF5FFFA, // rgb(245,255,250) - misty_rose = 0xFFE4E1, // rgb(255,228,225) - moccasin = 0xFFE4B5, // rgb(255,228,181) - navajo_white = 0xFFDEAD, // rgb(255,222,173) - navy = 0x000080, // rgb(0,0,128) - old_lace = 0xFDF5E6, // rgb(253,245,230) - olive = 0x808000, // rgb(128,128,0) - olive_drab = 0x6B8E23, // rgb(107,142,35) - orange = 0xFFA500, // rgb(255,165,0) - orange_red = 0xFF4500, // rgb(255,69,0) - orchid = 0xDA70D6, // rgb(218,112,214) - pale_golden_rod = 0xEEE8AA, // rgb(238,232,170) - pale_green = 0x98FB98, // rgb(152,251,152) - pale_turquoise = 0xAFEEEE, // rgb(175,238,238) - pale_violet_red = 0xDB7093, // rgb(219,112,147) - papaya_whip = 0xFFEFD5, // rgb(255,239,213) - peach_puff = 0xFFDAB9, // rgb(255,218,185) - peru = 0xCD853F, // rgb(205,133,63) - pink = 0xFFC0CB, // rgb(255,192,203) - plum = 0xDDA0DD, // rgb(221,160,221) - powder_blue = 0xB0E0E6, // rgb(176,224,230) - purple = 0x800080, // rgb(128,0,128) - rebecca_purple = 0x663399, // rgb(102,51,153) - red = 0xFF0000, // rgb(255,0,0) - rosy_brown = 0xBC8F8F, // rgb(188,143,143) - royal_blue = 0x4169E1, // rgb(65,105,225) - saddle_brown = 0x8B4513, // rgb(139,69,19) - salmon = 0xFA8072, // rgb(250,128,114) - sandy_brown = 0xF4A460, // rgb(244,164,96) - sea_green = 0x2E8B57, // rgb(46,139,87) - sea_shell = 0xFFF5EE, // rgb(255,245,238) - sienna = 0xA0522D, // rgb(160,82,45) - silver = 0xC0C0C0, // rgb(192,192,192) - sky_blue = 0x87CEEB, // rgb(135,206,235) - slate_blue = 0x6A5ACD, // rgb(106,90,205) - slate_gray = 0x708090, // rgb(112,128,144) - snow = 0xFFFAFA, // rgb(255,250,250) - spring_green = 0x00FF7F, // rgb(0,255,127) - steel_blue = 0x4682B4, // rgb(70,130,180) - tan = 0xD2B48C, // rgb(210,180,140) - teal = 0x008080, // rgb(0,128,128) - thistle = 0xD8BFD8, // rgb(216,191,216) - tomato = 0xFF6347, // rgb(255,99,71) - turquoise = 0x40E0D0, // rgb(64,224,208) - violet = 0xEE82EE, // rgb(238,130,238) - wheat = 0xF5DEB3, // rgb(245,222,179) - white = 0xFFFFFF, // rgb(255,255,255) - white_smoke = 0xF5F5F5, // rgb(245,245,245) - yellow = 0xFFFF00, // rgb(255,255,0) - yellow_green = 0x9ACD32 // rgb(154,205,50) -}; // enum class color - -enum class terminal_color : uint8_t { - black = 30, - red, - green, - yellow, - blue, - magenta, - cyan, - white, - bright_black = 90, - bright_red, - bright_green, - bright_yellow, - bright_blue, - bright_magenta, - bright_cyan, - bright_white -}; - -enum class emphasis : uint8_t { - bold = 1, - faint = 1 << 1, - italic = 1 << 2, - underline = 1 << 3, - blink = 1 << 4, - reverse = 1 << 5, - conceal = 1 << 6, - strikethrough = 1 << 7, -}; - -// rgb is a struct for red, green and blue colors. -// Using the name "rgb" makes some editors show the color in a tooltip. -struct rgb { - FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {} - FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} - FMT_CONSTEXPR rgb(uint32_t hex) - : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {} - FMT_CONSTEXPR rgb(color hex) - : r((uint32_t(hex) >> 16) & 0xFF), - g((uint32_t(hex) >> 8) & 0xFF), - b(uint32_t(hex) & 0xFF) {} - uint8_t r; - uint8_t g; - uint8_t b; -}; - -FMT_BEGIN_DETAIL_NAMESPACE - -// color is a struct of either a rgb color or a terminal color. -struct color_type { - FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {} - FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true), - value{} { - value.rgb_color = static_cast<uint32_t>(rgb_color); - } - FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} { - value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) | - (static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b; - } - FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(), - value{} { - value.term_color = static_cast<uint8_t>(term_color); - } - bool is_rgb; - union color_union { - uint8_t term_color; - uint32_t rgb_color; - } value; -}; - -FMT_END_DETAIL_NAMESPACE - -/** A text style consisting of foreground and background colors and emphasis. */ -class text_style { - public: - FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT - : set_foreground_color(), - set_background_color(), - ems(em) {} - - FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) { - if (!set_foreground_color) { - set_foreground_color = rhs.set_foreground_color; - foreground_color = rhs.foreground_color; - } else if (rhs.set_foreground_color) { - if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb) - FMT_THROW(format_error("can't OR a terminal color")); - foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color; - } - - if (!set_background_color) { - set_background_color = rhs.set_background_color; - background_color = rhs.background_color; - } else if (rhs.set_background_color) { - if (!background_color.is_rgb || !rhs.background_color.is_rgb) - FMT_THROW(format_error("can't OR a terminal color")); - background_color.value.rgb_color |= rhs.background_color.value.rgb_color; - } - - ems = static_cast<emphasis>(static_cast<uint8_t>(ems) | - static_cast<uint8_t>(rhs.ems)); - return *this; - } - - friend FMT_CONSTEXPR text_style operator|(text_style lhs, - const text_style& rhs) { - return lhs |= rhs; - } - - FMT_DEPRECATED_NONMSVC FMT_CONSTEXPR text_style& operator&=( - const text_style& rhs) { - return and_assign(rhs); - } - - FMT_DEPRECATED_NONMSVC friend FMT_CONSTEXPR text_style - operator&(text_style lhs, const text_style& rhs) { - return lhs.and_assign(rhs); - } - - FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT { - return set_foreground_color; - } - FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT { - return set_background_color; - } - FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT { - return static_cast<uint8_t>(ems) != 0; - } - FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT { - FMT_ASSERT(has_foreground(), "no foreground specified for this style"); - return foreground_color; - } - FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT { - FMT_ASSERT(has_background(), "no background specified for this style"); - return background_color; - } - FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT { - FMT_ASSERT(has_emphasis(), "no emphasis specified for this style"); - return ems; - } - - private: - FMT_CONSTEXPR text_style(bool is_foreground, - detail::color_type text_color) FMT_NOEXCEPT - : set_foreground_color(), - set_background_color(), - ems() { - if (is_foreground) { - foreground_color = text_color; - set_foreground_color = true; - } else { - background_color = text_color; - set_background_color = true; - } - } - - // DEPRECATED! - FMT_CONSTEXPR text_style& and_assign(const text_style& rhs) { - if (!set_foreground_color) { - set_foreground_color = rhs.set_foreground_color; - foreground_color = rhs.foreground_color; - } else if (rhs.set_foreground_color) { - if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb) - FMT_THROW(format_error("can't AND a terminal color")); - foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color; - } - - if (!set_background_color) { - set_background_color = rhs.set_background_color; - background_color = rhs.background_color; - } else if (rhs.set_background_color) { - if (!background_color.is_rgb || !rhs.background_color.is_rgb) - FMT_THROW(format_error("can't AND a terminal color")); - background_color.value.rgb_color &= rhs.background_color.value.rgb_color; - } - - ems = static_cast<emphasis>(static_cast<uint8_t>(ems) & - static_cast<uint8_t>(rhs.ems)); - return *this; - } - - friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground) - FMT_NOEXCEPT; - - friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background) - FMT_NOEXCEPT; - - detail::color_type foreground_color; - detail::color_type background_color; - bool set_foreground_color; - bool set_background_color; - emphasis ems; -}; - -/** Creates a text style from the foreground (text) color. */ -FMT_CONSTEXPR inline text_style fg(detail::color_type foreground) FMT_NOEXCEPT { - return text_style(true, foreground); -} - -/** Creates a text style from the background color. */ -FMT_CONSTEXPR inline text_style bg(detail::color_type background) FMT_NOEXCEPT { - return text_style(false, background); -} - -FMT_CONSTEXPR inline text_style operator|(emphasis lhs, - emphasis rhs) FMT_NOEXCEPT { - return text_style(lhs) | rhs; -} - -FMT_BEGIN_DETAIL_NAMESPACE - -template <typename Char> struct ansi_color_escape { - FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color, - const char* esc) FMT_NOEXCEPT { - // If we have a terminal color, we need to output another escape code - // sequence. - if (!text_color.is_rgb) { - bool is_background = esc == string_view("\x1b[48;2;"); - uint32_t value = text_color.value.term_color; - // Background ASCII codes are the same as the foreground ones but with - // 10 more. - if (is_background) value += 10u; - - size_t index = 0; - buffer[index++] = static_cast<Char>('\x1b'); - buffer[index++] = static_cast<Char>('['); - - if (value >= 100u) { - buffer[index++] = static_cast<Char>('1'); - value %= 100u; - } - buffer[index++] = static_cast<Char>('0' + value / 10u); - buffer[index++] = static_cast<Char>('0' + value % 10u); - - buffer[index++] = static_cast<Char>('m'); - buffer[index++] = static_cast<Char>('\0'); - return; - } - - for (int i = 0; i < 7; i++) { - buffer[i] = static_cast<Char>(esc[i]); - } - rgb color(text_color.value.rgb_color); - to_esc(color.r, buffer + 7, ';'); - to_esc(color.g, buffer + 11, ';'); - to_esc(color.b, buffer + 15, 'm'); - buffer[19] = static_cast<Char>(0); - } - FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT { - uint8_t em_codes[num_emphases] = {}; - if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1; - if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2; - if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3; - if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4; - if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5; - if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7; - if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8; - if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9; - - size_t index = 0; - for (size_t i = 0; i < num_emphases; ++i) { - if (!em_codes[i]) continue; - buffer[index++] = static_cast<Char>('\x1b'); - buffer[index++] = static_cast<Char>('['); - buffer[index++] = static_cast<Char>('0' + em_codes[i]); - buffer[index++] = static_cast<Char>('m'); - } - buffer[index++] = static_cast<Char>(0); - } - FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; } - - FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; } - FMT_CONSTEXPR_CHAR_TRAITS const Char* end() const FMT_NOEXCEPT { - return buffer + std::char_traits<Char>::length(buffer); - } - - private: - static constexpr size_t num_emphases = 8; - Char buffer[7u + 3u * num_emphases + 1u]; - - static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, - char delimiter) FMT_NOEXCEPT { - out[0] = static_cast<Char>('0' + c / 100); - out[1] = static_cast<Char>('0' + c / 10 % 10); - out[2] = static_cast<Char>('0' + c % 10); - out[3] = static_cast<Char>(delimiter); - } - static FMT_CONSTEXPR bool has_emphasis(emphasis em, - emphasis mask) FMT_NOEXCEPT { - return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask); - } -}; - -template <typename Char> -FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color( - detail::color_type foreground) FMT_NOEXCEPT { - return ansi_color_escape<Char>(foreground, "\x1b[38;2;"); -} - -template <typename Char> -FMT_CONSTEXPR ansi_color_escape<Char> make_background_color( - detail::color_type background) FMT_NOEXCEPT { - return ansi_color_escape<Char>(background, "\x1b[48;2;"); -} - -template <typename Char> -FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT { - return ansi_color_escape<Char>(em); -} - -template <typename Char> -inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT { - std::fputs(chars, stream); -} - -template <> -inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT { - std::fputws(chars, stream); -} - -template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT { - fputs("\x1b[0m", stream); -} - -template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT { - fputs(L"\x1b[0m", stream); -} - -template <typename Char> -inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT { - auto reset_color = string_view("\x1b[0m"); - buffer.append(reset_color.begin(), reset_color.end()); -} - -template <typename Char> -void vformat_to(buffer<Char>& buf, const text_style& ts, - basic_string_view<Char> format_str, - basic_format_args<buffer_context<type_identity_t<Char>>> args) { - bool has_style = false; - if (ts.has_emphasis()) { - has_style = true; - auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis()); - buf.append(emphasis.begin(), emphasis.end()); - } - if (ts.has_foreground()) { - has_style = true; - auto foreground = detail::make_foreground_color<Char>(ts.get_foreground()); - buf.append(foreground.begin(), foreground.end()); - } - if (ts.has_background()) { - has_style = true; - auto background = detail::make_background_color<Char>(ts.get_background()); - buf.append(background.begin(), background.end()); - } - detail::vformat_to(buf, format_str, args, {}); - if (has_style) detail::reset_color<Char>(buf); -} - -FMT_END_DETAIL_NAMESPACE - -template <typename S, typename Char = char_t<S>> -void vprint(std::FILE* f, const text_style& ts, const S& format, - basic_format_args<buffer_context<type_identity_t<Char>>> args) { - basic_memory_buffer<Char> buf; - detail::vformat_to(buf, ts, to_string_view(format), args); - buf.push_back(Char(0)); - detail::fputs(buf.data(), f); -} - -/** - \rst - Formats a string and prints it to the specified file stream using ANSI - escape sequences to specify text formatting. - - **Example**:: - - fmt::print(fmt::emphasis::bold | fg(fmt::color::red), - "Elapsed time: {0:.2f} seconds", 1.23); - \endrst - */ -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_string<S>::value)> -void print(std::FILE* f, const text_style& ts, const S& format_str, - const Args&... args) { - vprint(f, ts, format_str, - fmt::make_args_checked<Args...>(format_str, args...)); -} - -/** - \rst - Formats a string and prints it to stdout using ANSI escape sequences to - specify text formatting. - - **Example**:: - - fmt::print(fmt::emphasis::bold | fg(fmt::color::red), - "Elapsed time: {0:.2f} seconds", 1.23); - \endrst - */ -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_string<S>::value)> -void print(const text_style& ts, const S& format_str, const Args&... args) { - return print(stdout, ts, format_str, args...); -} - -template <typename S, typename Char = char_t<S>> -inline std::basic_string<Char> vformat( - const text_style& ts, const S& format_str, - basic_format_args<buffer_context<type_identity_t<Char>>> args) { - basic_memory_buffer<Char> buf; - detail::vformat_to(buf, ts, to_string_view(format_str), args); - return fmt::to_string(buf); -} - -/** - \rst - Formats arguments and returns the result as a string using ANSI - escape sequences to specify text formatting. - - **Example**:: - - #include <fmt/color.h> - std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), - "The answer is {}", 42); - \endrst -*/ -template <typename S, typename... Args, typename Char = char_t<S>> -inline std::basic_string<Char> format(const text_style& ts, const S& format_str, - const Args&... args) { - return fmt::vformat(ts, to_string_view(format_str), - fmt::make_args_checked<Args...>(format_str, args...)); -} - -/** - Formats a string with the given text_style and writes the output to ``out``. - */ -template <typename OutputIt, typename Char, - FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)> -OutputIt vformat_to( - OutputIt out, const text_style& ts, basic_string_view<Char> format_str, - basic_format_args<buffer_context<type_identity_t<Char>>> args) { - auto&& buf = detail::get_buffer<Char>(out); - detail::vformat_to(buf, ts, format_str, args); - return detail::get_iterator(buf); -} - -/** - \rst - Formats arguments with the given text_style, writes the result to the output - iterator ``out`` and returns the iterator past the end of the output range. - - **Example**:: - - std::vector<char> out; - fmt::format_to(std::back_inserter(out), - fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); - \endrst -*/ -template <typename OutputIt, typename S, typename... Args, - bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&& - detail::is_string<S>::value> -inline auto format_to(OutputIt out, const text_style& ts, const S& format_str, - Args&&... args) -> - typename std::enable_if<enable, OutputIt>::type { - return vformat_to(out, ts, to_string_view(format_str), - fmt::make_args_checked<Args...>(format_str, args...)); -} - -FMT_MODULE_EXPORT_END -FMT_END_NAMESPACE - -#endif // FMT_COLOR_H_ diff --git a/contrib/libs/fmt/include/fmt/compile.h b/contrib/libs/fmt/include/fmt/compile.h deleted file mode 100644 index 1dba3ddb52..0000000000 --- a/contrib/libs/fmt/include/fmt/compile.h +++ /dev/null @@ -1,642 +0,0 @@ -// Formatting library for C++ - experimental format string compilation -// -// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_COMPILE_H_ -#define FMT_COMPILE_H_ - -#include "format.h" - -FMT_BEGIN_NAMESPACE -namespace detail { - -// An output iterator that counts the number of objects written to it and -// discards them. -class counting_iterator { - private: - size_t count_; - - public: - using iterator_category = std::output_iterator_tag; - using difference_type = std::ptrdiff_t; - using pointer = void; - using reference = void; - using _Unchecked_type = counting_iterator; // Mark iterator as checked. - - struct value_type { - template <typename T> void operator=(const T&) {} - }; - - counting_iterator() : count_(0) {} - - size_t count() const { return count_; } - - counting_iterator& operator++() { - ++count_; - return *this; - } - counting_iterator operator++(int) { - auto it = *this; - ++*this; - return it; - } - - friend counting_iterator operator+(counting_iterator it, difference_type n) { - it.count_ += static_cast<size_t>(n); - return it; - } - - value_type operator*() const { return {}; } -}; - -template <typename Char, typename InputIt> -inline counting_iterator copy_str(InputIt begin, InputIt end, - counting_iterator it) { - return it + (end - begin); -} - -template <typename OutputIt> class truncating_iterator_base { - protected: - OutputIt out_; - size_t limit_; - size_t count_ = 0; - - truncating_iterator_base() : out_(), limit_(0) {} - - truncating_iterator_base(OutputIt out, size_t limit) - : out_(out), limit_(limit) {} - - public: - using iterator_category = std::output_iterator_tag; - using value_type = typename std::iterator_traits<OutputIt>::value_type; - using difference_type = std::ptrdiff_t; - using pointer = void; - using reference = void; - using _Unchecked_type = - truncating_iterator_base; // Mark iterator as checked. - - OutputIt base() const { return out_; } - size_t count() const { return count_; } -}; - -// An output iterator that truncates the output and counts the number of objects -// written to it. -template <typename OutputIt, - typename Enable = typename std::is_void< - typename std::iterator_traits<OutputIt>::value_type>::type> -class truncating_iterator; - -template <typename OutputIt> -class truncating_iterator<OutputIt, std::false_type> - : public truncating_iterator_base<OutputIt> { - mutable typename truncating_iterator_base<OutputIt>::value_type blackhole_; - - public: - using value_type = typename truncating_iterator_base<OutputIt>::value_type; - - truncating_iterator() = default; - - truncating_iterator(OutputIt out, size_t limit) - : truncating_iterator_base<OutputIt>(out, limit) {} - - truncating_iterator& operator++() { - if (this->count_++ < this->limit_) ++this->out_; - return *this; - } - - truncating_iterator operator++(int) { - auto it = *this; - ++*this; - return it; - } - - value_type& operator*() const { - return this->count_ < this->limit_ ? *this->out_ : blackhole_; - } -}; - -template <typename OutputIt> -class truncating_iterator<OutputIt, std::true_type> - : public truncating_iterator_base<OutputIt> { - public: - truncating_iterator() = default; - - truncating_iterator(OutputIt out, size_t limit) - : truncating_iterator_base<OutputIt>(out, limit) {} - - template <typename T> truncating_iterator& operator=(T val) { - if (this->count_++ < this->limit_) *this->out_++ = val; - return *this; - } - - truncating_iterator& operator++() { return *this; } - truncating_iterator& operator++(int) { return *this; } - truncating_iterator& operator*() { return *this; } -}; - -// A compile-time string which is compiled into fast formatting code. -class compiled_string {}; - -template <typename S> -struct is_compiled_string : std::is_base_of<compiled_string, S> {}; - -/** - \rst - Converts a string literal *s* into a format string that will be parsed at - compile time and converted into efficient formatting code. Requires C++17 - ``constexpr if`` compiler support. - - **Example**:: - - // Converts 42 into std::string using the most efficient method and no - // runtime format string processing. - std::string s = fmt::format(FMT_COMPILE("{}"), 42); - \endrst - */ -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -# define FMT_COMPILE(s) \ - FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit) -#else -# define FMT_COMPILE(s) FMT_STRING(s) -#endif - -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -template <typename Char, size_t N, - fmt::detail_exported::fixed_string<Char, N> Str> -struct udl_compiled_string : compiled_string { - using char_type = Char; - constexpr operator basic_string_view<char_type>() const { - return {Str.data, N - 1}; - } -}; -#endif - -template <typename T, typename... Tail> -const T& first(const T& value, const Tail&...) { - return value; -} - -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -template <typename... Args> struct type_list {}; - -// Returns a reference to the argument at index N from [first, rest...]. -template <int N, typename T, typename... Args> -constexpr const auto& get([[maybe_unused]] const T& first, - [[maybe_unused]] const Args&... rest) { - static_assert(N < 1 + sizeof...(Args), "index is out of bounds"); - if constexpr (N == 0) - return first; - else - return detail::get<N - 1>(rest...); -} - -template <typename Char, typename... Args> -constexpr int get_arg_index_by_name(basic_string_view<Char> name, - type_list<Args...>) { - return get_arg_index_by_name<Args...>(name); -} - -template <int N, typename> struct get_type_impl; - -template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> { - using type = - remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>; -}; - -template <int N, typename T> -using get_type = typename get_type_impl<N, T>::type; - -template <typename T> struct is_compiled_format : std::false_type {}; - -template <typename Char> struct text { - basic_string_view<Char> data; - using char_type = Char; - - template <typename OutputIt, typename... Args> - constexpr OutputIt format(OutputIt out, const Args&...) const { - return write<Char>(out, data); - } -}; - -template <typename Char> -struct is_compiled_format<text<Char>> : std::true_type {}; - -template <typename Char> -constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos, - size_t size) { - return {{&s[pos], size}}; -} - -template <typename Char> struct code_unit { - Char value; - using char_type = Char; - - template <typename OutputIt, typename... Args> - constexpr OutputIt format(OutputIt out, const Args&...) const { - return write<Char>(out, value); - } -}; - -// This ensures that the argument type is convertible to `const T&`. -template <typename T, int N, typename... Args> -constexpr const T& get_arg_checked(const Args&... args) { - const auto& arg = detail::get<N>(args...); - if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) { - return arg.value; - } else { - return arg; - } -} - -template <typename Char> -struct is_compiled_format<code_unit<Char>> : std::true_type {}; - -// A replacement field that refers to argument N. -template <typename Char, typename T, int N> struct field { - using char_type = Char; - - template <typename OutputIt, typename... Args> - constexpr OutputIt format(OutputIt out, const Args&... args) const { - return write<Char>(out, get_arg_checked<T, N>(args...)); - } -}; - -template <typename Char, typename T, int N> -struct is_compiled_format<field<Char, T, N>> : std::true_type {}; - -// A replacement field that refers to argument with name. -template <typename Char> struct runtime_named_field { - using char_type = Char; - basic_string_view<Char> name; - - template <typename OutputIt, typename T> - constexpr static bool try_format_argument( - OutputIt& out, - // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9 - [[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) { - if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) { - if (arg_name == arg.name) { - out = write<Char>(out, arg.value); - return true; - } - } - return false; - } - - template <typename OutputIt, typename... Args> - constexpr OutputIt format(OutputIt out, const Args&... args) const { - bool found = (try_format_argument(out, name, args) || ...); - if (!found) { - FMT_THROW(format_error("argument with specified name is not found")); - } - return out; - } -}; - -template <typename Char> -struct is_compiled_format<runtime_named_field<Char>> : std::true_type {}; - -// A replacement field that refers to argument N and has format specifiers. -template <typename Char, typename T, int N> struct spec_field { - using char_type = Char; - formatter<T, Char> fmt; - - template <typename OutputIt, typename... Args> - constexpr FMT_INLINE OutputIt format(OutputIt out, - const Args&... args) const { - const auto& vargs = - fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...); - basic_format_context<OutputIt, Char> ctx(out, vargs); - return fmt.format(get_arg_checked<T, N>(args...), ctx); - } -}; - -template <typename Char, typename T, int N> -struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {}; - -template <typename L, typename R> struct concat { - L lhs; - R rhs; - using char_type = typename L::char_type; - - template <typename OutputIt, typename... Args> - constexpr OutputIt format(OutputIt out, const Args&... args) const { - out = lhs.format(out, args...); - return rhs.format(out, args...); - } -}; - -template <typename L, typename R> -struct is_compiled_format<concat<L, R>> : std::true_type {}; - -template <typename L, typename R> -constexpr concat<L, R> make_concat(L lhs, R rhs) { - return {lhs, rhs}; -} - -struct unknown_format {}; - -template <typename Char> -constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) { - for (size_t size = str.size(); pos != size; ++pos) { - if (str[pos] == '{' || str[pos] == '}') break; - } - return pos; -} - -template <typename Args, size_t POS, int ID, typename S> -constexpr auto compile_format_string(S format_str); - -template <typename Args, size_t POS, int ID, typename T, typename S> -constexpr auto parse_tail(T head, S format_str) { - if constexpr (POS != - basic_string_view<typename S::char_type>(format_str).size()) { - constexpr auto tail = compile_format_string<Args, POS, ID>(format_str); - if constexpr (std::is_same<remove_cvref_t<decltype(tail)>, - unknown_format>()) - return tail; - else - return make_concat(head, tail); - } else { - return head; - } -} - -template <typename T, typename Char> struct parse_specs_result { - formatter<T, Char> fmt; - size_t end; - int next_arg_id; -}; - -constexpr int manual_indexing_id = -1; - -template <typename T, typename Char> -constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str, - size_t pos, int next_arg_id) { - str.remove_prefix(pos); - auto ctx = basic_format_parse_context<Char>(str, {}, next_arg_id); - auto f = formatter<T, Char>(); - auto end = f.parse(ctx); - return {f, pos + fmt::detail::to_unsigned(end - str.data()) + 1, - next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()}; -} - -template <typename Char> struct arg_id_handler { - arg_ref<Char> arg_id; - - constexpr int operator()() { - FMT_ASSERT(false, "handler cannot be used with automatic indexing"); - return 0; - } - constexpr int operator()(int id) { - arg_id = arg_ref<Char>(id); - return 0; - } - constexpr int operator()(basic_string_view<Char> id) { - arg_id = arg_ref<Char>(id); - return 0; - } - - constexpr void on_error(const char* message) { - FMT_THROW(format_error(message)); - } -}; - -template <typename Char> struct parse_arg_id_result { - arg_ref<Char> arg_id; - const Char* arg_id_end; -}; - -template <int ID, typename Char> -constexpr auto parse_arg_id(const Char* begin, const Char* end) { - auto handler = arg_id_handler<Char>{arg_ref<Char>{}}; - auto arg_id_end = parse_arg_id(begin, end, handler); - return parse_arg_id_result<Char>{handler.arg_id, arg_id_end}; -} - -template <typename T, typename Enable = void> struct field_type { - using type = remove_cvref_t<T>; -}; - -template <typename T> -struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> { - using type = remove_cvref_t<decltype(T::value)>; -}; - -template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID, - typename S> -constexpr auto parse_replacement_field_then_tail(S format_str) { - using char_type = typename S::char_type; - constexpr auto str = basic_string_view<char_type>(format_str); - constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type(); - if constexpr (c == '}') { - return parse_tail<Args, END_POS + 1, NEXT_ID>( - field<char_type, typename field_type<T>::type, ARG_INDEX>(), - format_str); - } else if constexpr (c == ':') { - constexpr auto result = parse_specs<typename field_type<T>::type>( - str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID); - return parse_tail<Args, result.end, result.next_arg_id>( - spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{ - result.fmt}, - format_str); - } -} - -// Compiles a non-empty format string and returns the compiled representation -// or unknown_format() on unrecognized input. -template <typename Args, size_t POS, int ID, typename S> -constexpr auto compile_format_string(S format_str) { - using char_type = typename S::char_type; - constexpr auto str = basic_string_view<char_type>(format_str); - if constexpr (str[POS] == '{') { - if constexpr (POS + 1 == str.size()) - FMT_THROW(format_error("unmatched '{' in format string")); - if constexpr (str[POS + 1] == '{') { - return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str); - } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') { - static_assert(ID != manual_indexing_id, - "cannot switch from manual to automatic argument indexing"); - constexpr auto next_id = - ID != manual_indexing_id ? ID + 1 : manual_indexing_id; - return parse_replacement_field_then_tail<get_type<ID, Args>, Args, - POS + 1, ID, next_id>( - format_str); - } else { - constexpr auto arg_id_result = - parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size()); - constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data(); - constexpr char_type c = - arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type(); - static_assert(c == '}' || c == ':', "missing '}' in format string"); - if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) { - static_assert( - ID == manual_indexing_id || ID == 0, - "cannot switch from automatic to manual argument indexing"); - constexpr auto arg_index = arg_id_result.arg_id.val.index; - return parse_replacement_field_then_tail<get_type<arg_index, Args>, - Args, arg_id_end_pos, - arg_index, manual_indexing_id>( - format_str); - } else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) { - constexpr auto arg_index = - get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{}); - if constexpr (arg_index != invalid_arg_index) { - constexpr auto next_id = - ID != manual_indexing_id ? ID + 1 : manual_indexing_id; - return parse_replacement_field_then_tail< - decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos, - arg_index, next_id>(format_str); - } else { - if constexpr (c == '}') { - return parse_tail<Args, arg_id_end_pos + 1, ID>( - runtime_named_field<char_type>{arg_id_result.arg_id.val.name}, - format_str); - } else if constexpr (c == ':') { - return unknown_format(); // no type info for specs parsing - } - } - } - } - } else if constexpr (str[POS] == '}') { - if constexpr (POS + 1 == str.size()) - FMT_THROW(format_error("unmatched '}' in format string")); - return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str); - } else { - constexpr auto end = parse_text(str, POS + 1); - if constexpr (end - POS > 1) { - return parse_tail<Args, end, ID>(make_text(str, POS, end - POS), - format_str); - } else { - return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]}, - format_str); - } - } -} - -template <typename... Args, typename S, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -constexpr auto compile(S format_str) { - constexpr auto str = basic_string_view<typename S::char_type>(format_str); - if constexpr (str.size() == 0) { - return detail::make_text(str, 0, 0); - } else { - constexpr auto result = - detail::compile_format_string<detail::type_list<Args...>, 0, 0>( - format_str); - return result; - } -} -#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -} // namespace detail - -FMT_MODULE_EXPORT_BEGIN - -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) - -template <typename CompiledFormat, typename... Args, - typename Char = typename CompiledFormat::char_type, - FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)> -FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf, - const Args&... args) { - auto s = std::basic_string<Char>(); - cf.format(std::back_inserter(s), args...); - return s; -} - -template <typename OutputIt, typename CompiledFormat, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)> -constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf, - const Args&... args) { - return cf.format(out, args...); -} - -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -FMT_INLINE std::basic_string<typename S::char_type> format(const S&, - Args&&... args) { - if constexpr (std::is_same<typename S::char_type, char>::value) { - constexpr auto str = basic_string_view<typename S::char_type>(S()); - if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') { - const auto& first = detail::first(args...); - if constexpr (detail::is_named_arg< - remove_cvref_t<decltype(first)>>::value) { - return fmt::to_string(first.value); - } else { - return fmt::to_string(first); - } - } - } - constexpr auto compiled = detail::compile<Args...>(S()); - if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>, - detail::unknown_format>()) { - return format(static_cast<basic_string_view<typename S::char_type>>(S()), - std::forward<Args>(args)...); - } else { - return format(compiled, std::forward<Args>(args)...); - } -} - -template <typename OutputIt, typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) { - constexpr auto compiled = detail::compile<Args...>(S()); - if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>, - detail::unknown_format>()) { - return format_to(out, - static_cast<basic_string_view<typename S::char_type>>(S()), - std::forward<Args>(args)...); - } else { - return format_to(out, compiled, std::forward<Args>(args)...); - } -} -#endif - -template <typename OutputIt, typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n, - const S& format_str, Args&&... args) { - auto it = format_to(detail::truncating_iterator<OutputIt>(out, n), format_str, - std::forward<Args>(args)...); - return {it.base(), it.count()}; -} - -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -size_t formatted_size(const S& format_str, const Args&... args) { - return format_to(detail::counting_iterator(), format_str, args...).count(); -} - -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -void print(std::FILE* f, const S& format_str, const Args&... args) { - memory_buffer buffer; - format_to(std::back_inserter(buffer), format_str, args...); - detail::print(f, {buffer.data(), buffer.size()}); -} - -template <typename S, typename... Args, - FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> -void print(const S& format_str, const Args&... args) { - print(stdout, format_str, args...); -} - -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -inline namespace literals { -template <detail_exported::fixed_string Str> -constexpr detail::udl_compiled_string< - remove_cvref_t<decltype(Str.data[0])>, - sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> -operator""_cf() { - return {}; -} -} // namespace literals -#endif - -FMT_MODULE_EXPORT_END -FMT_END_NAMESPACE - -#endif // FMT_COMPILE_H_ diff --git a/contrib/libs/fmt/include/fmt/ostream.h b/contrib/libs/fmt/include/fmt/ostream.h deleted file mode 100644 index 3d716ece84..0000000000 --- a/contrib/libs/fmt/include/fmt/ostream.h +++ /dev/null @@ -1,135 +0,0 @@ -// Formatting library for C++ - std::ostream support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_OSTREAM_H_ -#define FMT_OSTREAM_H_ - -#include <ostream> - -#include "format.h" - -FMT_BEGIN_NAMESPACE - -template <typename OutputIt, typename Char> class basic_printf_context; - -namespace detail { - -// Checks if T has a user-defined operator<<. -template <typename T, typename Char, typename Enable = void> -class is_streamable { - private: - template <typename U> - static auto test(int) - -> bool_constant<sizeof(std::declval<std::basic_ostream<Char>&>() - << std::declval<U>()) != 0>; - - template <typename> static auto test(...) -> std::false_type; - - using result = decltype(test<T>(0)); - - public: - is_streamable() = default; - - static const bool value = result::value; -}; - -// Formatting of built-in types and arrays is intentionally disabled because -// it's handled by standard (non-ostream) formatters. -template <typename T, typename Char> -struct is_streamable< - T, Char, - enable_if_t< - std::is_arithmetic<T>::value || std::is_array<T>::value || - std::is_pointer<T>::value || std::is_same<T, char8_type>::value || - std::is_same<T, std::basic_string<Char>>::value || - std::is_same<T, std_string_view<Char>>::value || - (std::is_convertible<T, int>::value && !std::is_enum<T>::value)>> - : std::false_type {}; - -// Write the content of buf to os. -// It is a separate function rather than a part of vprint to simplify testing. -template <typename Char> -void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) { - const Char* buf_data = buf.data(); - using unsigned_streamsize = std::make_unsigned<std::streamsize>::type; - unsigned_streamsize size = buf.size(); - unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>()); - do { - unsigned_streamsize n = size <= max_size ? size : max_size; - os.write(buf_data, static_cast<std::streamsize>(n)); - buf_data += n; - size -= n; - } while (size != 0); -} - -template <typename Char, typename T> -void format_value(buffer<Char>& buf, const T& value, - locale_ref loc = locale_ref()) { - auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf); - auto&& output = std::basic_ostream<Char>(&format_buf); -#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) - if (loc) output.imbue(loc.get<std::locale>()); -#endif - output << value; - output.exceptions(std::ios_base::failbit | std::ios_base::badbit); - buf.try_resize(buf.size()); -} - -// Formats an object of type T that has an overloaded ostream operator<<. -template <typename T, typename Char> -struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>> - : private formatter<basic_string_view<Char>, Char> { - using formatter<basic_string_view<Char>, Char>::parse; - - template <typename OutputIt> - auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) - -> OutputIt { - auto buffer = basic_memory_buffer<Char>(); - format_value(buffer, value, ctx.locale()); - return formatter<basic_string_view<Char>, Char>::format( - {buffer.data(), buffer.size()}, ctx); - } - - // DEPRECATED! - template <typename OutputIt> - auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx) - -> OutputIt { - auto buffer = basic_memory_buffer<Char>(); - format_value(buffer, value, ctx.locale()); - return std::copy(buffer.begin(), buffer.end(), ctx.out()); - } -}; -} // namespace detail - -FMT_MODULE_EXPORT -template <typename Char> -void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str, - basic_format_args<buffer_context<type_identity_t<Char>>> args) { - auto buffer = basic_memory_buffer<Char>(); - detail::vformat_to(buffer, format_str, args); - detail::write_buffer(os, buffer); -} - -/** - \rst - Prints formatted data to the stream *os*. - - **Example**:: - - fmt::print(cerr, "Don't {}!", "panic"); - \endrst - */ -FMT_MODULE_EXPORT -template <typename S, typename... Args, - typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>> -void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) { - vprint(os, to_string_view(format_str), - fmt::make_args_checked<Args...>(format_str, args...)); -} -FMT_END_NAMESPACE - -#endif // FMT_OSTREAM_H_ diff --git a/contrib/libs/fmt/include/fmt/printf.h b/contrib/libs/fmt/include/fmt/printf.h deleted file mode 100644 index 19d550f6cf..0000000000 --- a/contrib/libs/fmt/include/fmt/printf.h +++ /dev/null @@ -1,657 +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_ - -#include <algorithm> // std::max -#include <limits> // std::numeric_limits -#include <ostream> - -#include "format.h" - -FMT_BEGIN_NAMESPACE -FMT_MODULE_EXPORT_BEGIN - -template <typename T> struct printf_formatter { printf_formatter() = delete; }; - -template <typename Char> -class basic_printf_parse_context : public basic_format_parse_context<Char> { - using basic_format_parse_context<Char>::basic_format_parse_context; -}; - -template <typename OutputIt, typename Char> class basic_printf_context { - private: - OutputIt out_; - basic_format_args<basic_printf_context> args_; - - public: - using char_type = Char; - using format_arg = basic_format_arg<basic_printf_context>; - using parse_context_type = basic_printf_parse_context<Char>; - template <typename T> using formatter_type = printf_formatter<T>; - - /** - \rst - Constructs a ``printf_context`` object. References to the arguments are - stored in the context object so make sure they have appropriate lifetimes. - \endrst - */ - basic_printf_context(OutputIt out, - basic_format_args<basic_printf_context> args) - : out_(out), args_(args) {} - - OutputIt out() { return out_; } - void advance_to(OutputIt it) { out_ = it; } - - detail::locale_ref locale() { return {}; } - - format_arg arg(int id) const { return args_.get(id); } - - FMT_CONSTEXPR void on_error(const char* message) { - detail::error_handler().on_error(message); - } -}; - -FMT_BEGIN_DETAIL_NAMESPACE - -// Checks if a value fits in int - used to avoid warnings about comparing -// signed and unsigned integers. -template <bool IsSigned> struct int_checker { - template <typename T> static bool fits_in_int(T value) { - unsigned max = max_value<int>(); - return value <= max; - } - static bool fits_in_int(bool) { return true; } -}; - -template <> struct int_checker<true> { - template <typename T> static bool fits_in_int(T value) { - return value >= (std::numeric_limits<int>::min)() && - value <= max_value<int>(); - } - static bool fits_in_int(int) { return true; } -}; - -class printf_precision_handler { - public: - template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> - int operator()(T value) { - if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) - FMT_THROW(format_error("number is too big")); - return (std::max)(static_cast<int>(value), 0); - } - - template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)> - int operator()(T) { - FMT_THROW(format_error("precision is not integer")); - return 0; - } -}; - -// An argument visitor that returns true iff arg is a zero integer. -class is_zero_int { - public: - template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> - bool operator()(T value) { - return value == 0; - } - - template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)> - bool operator()(T) { - return false; - } -}; - -template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {}; - -template <> struct make_unsigned_or_bool<bool> { using type = bool; }; - -template <typename T, typename Context> class arg_converter { - private: - using char_type = typename Context::char_type; - - basic_format_arg<Context>& arg_; - char_type type_; - - public: - arg_converter(basic_format_arg<Context>& arg, char_type type) - : arg_(arg), type_(type) {} - - void operator()(bool value) { - if (type_ != 's') operator()<bool>(value); - } - - template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)> - void operator()(U value) { - bool is_signed = type_ == 'd' || type_ == 'i'; - using target_type = conditional_t<std::is_same<T, void>::value, U, T>; - if (const_check(sizeof(target_type) <= sizeof(int))) { - // Extra casts are used to silence warnings. - if (is_signed) { - arg_ = detail::make_arg<Context>( - static_cast<int>(static_cast<target_type>(value))); - } else { - using unsigned_type = typename make_unsigned_or_bool<target_type>::type; - arg_ = detail::make_arg<Context>( - static_cast<unsigned>(static_cast<unsigned_type>(value))); - } - } 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. - arg_ = detail::make_arg<Context>(static_cast<long long>(value)); - } else { - arg_ = detail::make_arg<Context>( - static_cast<typename make_unsigned_or_bool<U>::type>(value)); - } - } - } - - template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::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 <typename T, typename Context, typename Char> -void convert_arg(basic_format_arg<Context>& arg, Char type) { - visit_format_arg(arg_converter<T, Context>(arg, type), arg); -} - -// Converts an integer argument to char for printf. -template <typename Context> class char_converter { - private: - basic_format_arg<Context>& arg_; - - public: - explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {} - - template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> - void operator()(T value) { - arg_ = detail::make_arg<Context>( - static_cast<typename Context::char_type>(value)); - } - - template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::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 <typename Char> struct get_cstring { - template <typename T> const Char* operator()(T) { return nullptr; } - const Char* operator()(const Char* s) { return s; } -}; - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -template <typename Char> class printf_width_handler { - private: - using format_specs = basic_format_specs<Char>; - - format_specs& specs_; - - public: - explicit printf_width_handler(format_specs& specs) : specs_(specs) {} - - template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> - unsigned operator()(T value) { - auto width = static_cast<uint32_or_64_or_128_t<T>>(value); - if (detail::is_negative(value)) { - specs_.align = align::left; - width = 0 - width; - } - unsigned int_max = max_value<int>(); - if (width > int_max) FMT_THROW(format_error("number is too big")); - return static_cast<unsigned>(width); - } - - template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)> - unsigned operator()(T) { - FMT_THROW(format_error("width is not integer")); - return 0; - } -}; - -// The ``printf`` argument formatter. -template <typename OutputIt, typename Char> -class printf_arg_formatter : public arg_formatter<Char> { - private: - using base = arg_formatter<Char>; - using context_type = basic_printf_context<OutputIt, Char>; - using format_specs = basic_format_specs<Char>; - - context_type& context_; - - OutputIt write_null_pointer(bool is_string = false) { - auto s = this->specs; - s.type = presentation_type::none; - return write_bytes(this->out, is_string ? "(null)" : "(nil)", s); - } - - public: - printf_arg_formatter(OutputIt iter, format_specs& s, context_type& ctx) - : base{iter, s, locale_ref()}, context_(ctx) {} - - OutputIt operator()(monostate value) { return base::operator()(value); } - - template <typename T, FMT_ENABLE_IF(detail::is_integral<T>::value)> - OutputIt operator()(T value) { - // MSVC2013 fails to compile separate overloads for bool and Char so use - // std::is_same instead. - if (std::is_same<T, Char>::value) { - format_specs fmt_specs = this->specs; - if (fmt_specs.type != presentation_type::none && - fmt_specs.type != presentation_type::chr) { - return (*this)(static_cast<int>(value)); - } - fmt_specs.sign = sign::none; - fmt_specs.alt = false; - fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types. - // align::numeric needs to be overwritten here since the '0' flag is - // ignored for non-numeric types - if (fmt_specs.align == align::none || fmt_specs.align == align::numeric) - fmt_specs.align = align::right; - return write<Char>(this->out, static_cast<Char>(value), fmt_specs); - } - return base::operator()(value); - } - - template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> - OutputIt operator()(T value) { - return base::operator()(value); - } - - /** Formats a null-terminated C string. */ - OutputIt operator()(const char* value) { - if (value) return base::operator()(value); - return write_null_pointer(this->specs.type != presentation_type::pointer); - } - - /** Formats a null-terminated wide C string. */ - OutputIt operator()(const wchar_t* value) { - if (value) return base::operator()(value); - return write_null_pointer(this->specs.type != presentation_type::pointer); - } - - OutputIt operator()(basic_string_view<Char> value) { - return base::operator()(value); - } - - /** Formats a pointer. */ - OutputIt operator()(const void* value) { - return value ? base::operator()(value) : write_null_pointer(); - } - - /** Formats an argument of a custom (user-defined) type. */ - OutputIt operator()(typename basic_format_arg<context_type>::handle handle) { - auto parse_ctx = - basic_printf_parse_context<Char>(basic_string_view<Char>()); - handle.format(parse_ctx, context_); - return this->out; - } -}; - -template <typename Char> -void parse_flags(basic_format_specs<Char>& 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] = '0'; - break; - case ' ': - if (specs.sign != sign::plus) { - specs.sign = sign::space; - } - break; - case '#': - specs.alt = true; - break; - default: - return; - } - } -} - -template <typename Char, typename GetArg> -int parse_header(const Char*& it, const Char* end, - basic_format_specs<Char>& specs, GetArg get_arg) { - 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<int>(); - } else { - if (c == '0') specs.fill[0] = '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) FMT_THROW(format_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) FMT_THROW(format_error("number is too big")); - } else if (*it == '*') { - ++it; - specs.width = static_cast<int>(visit_format_arg( - detail::printf_width_handler<Char>(specs), get_arg(-1))); - } - } - return arg_index; -} - -template <typename Char, typename Context> -void vprintf(buffer<Char>& buf, basic_string_view<Char> format, - basic_format_args<Context> args) { - using OutputIt = buffer_appender<Char>; - auto out = OutputIt(buf); - auto context = basic_printf_context<OutputIt, Char>(out, args); - auto parse_ctx = basic_printf_parse_context<Char>(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 (!detail::find<false, Char>(it, end, '%', it)) { - it = end; // detail::find leaves it == nullptr if it doesn't find '%' - break; - } - Char c = *it++; - if (it != end && *it == c) { - out = detail::write( - out, basic_string_view<Char>(start, detail::to_unsigned(it - start))); - start = ++it; - continue; - } - out = detail::write(out, basic_string_view<Char>( - start, detail::to_unsigned(it - 1 - start))); - - basic_format_specs<Char> 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) parse_ctx.on_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<int>( - visit_format_arg(detail::printf_precision_handler(), get_arg(-1))); - } 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()) - specs.fill[0] = - ' '; // Ignore '0' flag for non-numeric types or if '-' present. - if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) { - auto str = visit_format_arg(detail::get_cstring<Char>(), arg); - auto str_end = str + specs.precision; - auto nul = std::find(str, str_end, Char()); - arg = detail::make_arg<basic_printf_context<OutputIt, Char>>( - basic_string_view<Char>( - str, detail::to_unsigned(nul != str_end ? nul - str - : specs.precision))); - } - if (specs.alt && visit_format_arg(detail::is_zero_int(), arg)) - specs.alt = false; - if (specs.fill[0] == '0') { - if (arg.is_arithmetic() && specs.align != align::left) - specs.align = align::numeric; - else - specs.fill[0] = ' '; // 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; - using detail::convert_arg; - switch (c) { - case 'h': - if (t == 'h') { - ++it; - t = it != end ? *it : 0; - convert_arg<signed char>(arg, t); - } else { - convert_arg<short>(arg, t); - } - break; - case 'l': - if (t == 'l') { - ++it; - t = it != end ? *it : 0; - convert_arg<long long>(arg, t); - } else { - convert_arg<long>(arg, t); - } - break; - case 'j': - convert_arg<intmax_t>(arg, t); - break; - case 'z': - convert_arg<size_t>(arg, t); - break; - case 't': - convert_arg<std::ptrdiff_t>(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<void>(arg, c); - } - - // Parse type. - if (it == end) FMT_THROW(format_error("invalid format string")); - char type = static_cast<char>(*it++); - if (arg.is_integral()) { - // Normalize type. - switch (type) { - case 'i': - case 'u': - type = 'd'; - break; - case 'c': - visit_format_arg( - detail::char_converter<basic_printf_context<OutputIt, Char>>(arg), - arg); - break; - } - } - specs.type = parse_presentation_type(type); - if (specs.type == presentation_type::none) - parse_ctx.on_error("invalid type specifier"); - - start = it; - - // Format argument. - out = visit_format_arg( - detail::printf_arg_formatter<OutputIt, Char>(out, specs, context), arg); - } - detail::write(out, basic_string_view<Char>(start, to_unsigned(it - start))); -} -FMT_END_DETAIL_NAMESPACE - -template <typename Char> -using basic_printf_context_t = - basic_printf_context<detail::buffer_appender<Char>, Char>; - -using printf_context = basic_printf_context_t<char>; -using wprintf_context = basic_printf_context_t<wchar_t>; - -using printf_args = basic_format_args<printf_context>; -using wprintf_args = basic_format_args<wprintf_context>; - -/** - \rst - Constructs an `~fmt::format_arg_store` object that contains references to - arguments and can be implicitly converted to `~fmt::printf_args`. - \endrst - */ -template <typename... T> -inline auto make_printf_args(const T&... args) - -> format_arg_store<printf_context, T...> { - return {args...}; -} - -/** - \rst - Constructs an `~fmt::format_arg_store` object that contains references to - arguments and can be implicitly converted to `~fmt::wprintf_args`. - \endrst - */ -template <typename... T> -inline auto make_wprintf_args(const T&... args) - -> format_arg_store<wprintf_context, T...> { - return {args...}; -} - -template <typename S, typename Char = char_t<S>> -inline auto vsprintf( - const S& fmt, - basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) - -> std::basic_string<Char> { - basic_memory_buffer<Char> buffer; - vprintf(buffer, to_string_view(fmt), args); - return to_string(buffer); -} - -/** - \rst - Formats arguments and returns the result as a string. - - **Example**:: - - std::string message = fmt::sprintf("The answer is %d", 42); - \endrst -*/ -template <typename S, typename... T, - typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>> -inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> { - using context = basic_printf_context_t<Char>; - return vsprintf(to_string_view(fmt), fmt::make_format_args<context>(args...)); -} - -template <typename S, typename Char = char_t<S>> -inline auto vfprintf( - std::FILE* f, const S& fmt, - basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) - -> int { - basic_memory_buffer<Char> buffer; - vprintf(buffer, to_string_view(fmt), args); - size_t size = buffer.size(); - return std::fwrite(buffer.data(), sizeof(Char), size, f) < size - ? -1 - : static_cast<int>(size); -} - -/** - \rst - Prints formatted data to the file *f*. - - **Example**:: - - fmt::fprintf(stderr, "Don't %s!", "panic"); - \endrst - */ -template <typename S, typename... T, typename Char = char_t<S>> -inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int { - using context = basic_printf_context_t<Char>; - return vfprintf(f, to_string_view(fmt), - fmt::make_format_args<context>(args...)); -} - -template <typename S, typename Char = char_t<S>> -inline auto vprintf( - const S& fmt, - basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) - -> int { - return vfprintf(stdout, to_string_view(fmt), args); -} - -/** - \rst - Prints formatted data to ``stdout``. - - **Example**:: - - fmt::printf("Elapsed time: %.2f seconds", 1.23); - \endrst - */ -template <typename S, typename... T, FMT_ENABLE_IF(detail::is_string<S>::value)> -inline auto printf(const S& fmt, const T&... args) -> int { - return vprintf( - to_string_view(fmt), - fmt::make_format_args<basic_printf_context_t<char_t<S>>>(args...)); -} - -template <typename S, typename Char = char_t<S>> -FMT_DEPRECATED auto vfprintf( - std::basic_ostream<Char>& os, const S& fmt, - basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) - -> int { - basic_memory_buffer<Char> buffer; - vprintf(buffer, to_string_view(fmt), args); - os.write(buffer.data(), static_cast<std::streamsize>(buffer.size())); - return static_cast<int>(buffer.size()); -} -template <typename S, typename... T, typename Char = char_t<S>> -FMT_DEPRECATED auto fprintf(std::basic_ostream<Char>& os, const S& fmt, - const T&... args) -> int { - return vfprintf(os, to_string_view(fmt), - fmt::make_format_args<basic_printf_context_t<Char>>(args...)); -} - -FMT_MODULE_EXPORT_END -FMT_END_NAMESPACE - -#endif // FMT_PRINTF_H_ diff --git a/contrib/libs/fmt/include/fmt/ranges.h b/contrib/libs/fmt/include/fmt/ranges.h deleted file mode 100644 index fd87b4f4f8..0000000000 --- a/contrib/libs/fmt/include/fmt/ranges.h +++ /dev/null @@ -1,793 +0,0 @@ -// Formatting library for C++ - experimental range support -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. -// -// Copyright (c) 2018 - present, Remotion (Igor Schulz) -// All Rights Reserved -// {fmt} support for ranges, containers and types tuple interface. - -#ifndef FMT_RANGES_H_ -#define FMT_RANGES_H_ - -#include <initializer_list> -#include <tuple> -#include <type_traits> - -#include "format.h" - -FMT_BEGIN_NAMESPACE - -namespace detail { - -template <typename RangeT, typename OutputIterator> -OutputIterator copy(const RangeT& range, OutputIterator out) { - for (auto it = range.begin(), end = range.end(); it != end; ++it) - *out++ = *it; - return out; -} - -template <typename OutputIterator> -OutputIterator copy(const char* str, OutputIterator out) { - while (*str) *out++ = *str++; - return out; -} - -template <typename OutputIterator> -OutputIterator copy(char ch, OutputIterator out) { - *out++ = ch; - return out; -} - -template <typename OutputIterator> -OutputIterator copy(wchar_t ch, OutputIterator out) { - *out++ = ch; - return out; -} - -// Returns true if T has a std::string-like interface, like std::string_view. -template <typename T> class is_std_string_like { - template <typename U> - static auto check(U* p) - -> decltype((void)p->find('a'), p->length(), (void)p->data(), int()); - template <typename> static void check(...); - - public: - static FMT_CONSTEXPR_DECL const bool value = - is_string<T>::value || - std::is_convertible<T, std_string_view<char>>::value || - !std::is_void<decltype(check<T>(nullptr))>::value; -}; - -template <typename Char> -struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {}; - -template <typename T> class is_map { - template <typename U> static auto check(U*) -> typename U::mapped_type; - template <typename> static void check(...); - - public: -#ifdef FMT_FORMAT_MAP_AS_LIST - static FMT_CONSTEXPR_DECL const bool value = false; -#else - static FMT_CONSTEXPR_DECL const bool value = - !std::is_void<decltype(check<T>(nullptr))>::value; -#endif -}; - -template <typename T> class is_set { - template <typename U> static auto check(U*) -> typename U::key_type; - template <typename> static void check(...); - - public: -#ifdef FMT_FORMAT_SET_AS_LIST - static FMT_CONSTEXPR_DECL const bool value = false; -#else - static FMT_CONSTEXPR_DECL const bool value = - !std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value; -#endif -}; - -template <typename... Ts> struct conditional_helper {}; - -template <typename T, typename _ = void> struct is_range_ : std::false_type {}; - -#if !FMT_MSC_VER || FMT_MSC_VER > 1800 - -# define FMT_DECLTYPE_RETURN(val) \ - ->decltype(val) { return val; } \ - static_assert( \ - true, "") // This makes it so that a semicolon is required after the - // macro, which helps clang-format handle the formatting. - -// C array overload -template <typename T, std::size_t N> -auto range_begin(const T (&arr)[N]) -> const T* { - return arr; -} -template <typename T, std::size_t N> -auto range_end(const T (&arr)[N]) -> const T* { - return arr + N; -} - -template <typename T, typename Enable = void> -struct has_member_fn_begin_end_t : std::false_type {}; - -template <typename T> -struct has_member_fn_begin_end_t<T, void_t<decltype(std::declval<T>().begin()), - decltype(std::declval<T>().end())>> - : std::true_type {}; - -// Member function overload -template <typename T> -auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin()); -template <typename T> -auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end()); - -// ADL overload. Only participates in overload resolution if member functions -// are not found. -template <typename T> -auto range_begin(T&& rng) - -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value, - decltype(begin(static_cast<T&&>(rng)))> { - return begin(static_cast<T&&>(rng)); -} -template <typename T> -auto range_end(T&& rng) -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value, - decltype(end(static_cast<T&&>(rng)))> { - return end(static_cast<T&&>(rng)); -} - -template <typename T, typename Enable = void> -struct has_const_begin_end : std::false_type {}; -template <typename T, typename Enable = void> -struct has_mutable_begin_end : std::false_type {}; - -template <typename T> -struct has_const_begin_end< - T, - void_t< - decltype(detail::range_begin(std::declval<const remove_cvref_t<T>&>())), - decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>> - : std::true_type {}; - -template <typename T> -struct has_mutable_begin_end< - T, void_t<decltype(detail::range_begin(std::declval<T>())), - decltype(detail::range_end(std::declval<T>())), - enable_if_t<std::is_copy_constructible<T>::value>>> - : std::true_type {}; - -template <typename T> -struct is_range_<T, void> - : std::integral_constant<bool, (has_const_begin_end<T>::value || - has_mutable_begin_end<T>::value)> {}; -# undef FMT_DECLTYPE_RETURN -#endif - -// tuple_size and tuple_element check. -template <typename T> class is_tuple_like_ { - template <typename U> - static auto check(U* p) -> decltype(std::tuple_size<U>::value, int()); - template <typename> static void check(...); - - public: - static FMT_CONSTEXPR_DECL const bool value = - !std::is_void<decltype(check<T>(nullptr))>::value; -}; - -// Check for integer_sequence -#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 -template <typename T, T... N> -using integer_sequence = std::integer_sequence<T, N...>; -template <size_t... N> using index_sequence = std::index_sequence<N...>; -template <size_t N> using make_index_sequence = std::make_index_sequence<N>; -#else -template <typename T, T... N> struct integer_sequence { - using value_type = T; - - static FMT_CONSTEXPR size_t size() { return sizeof...(N); } -}; - -template <size_t... N> using index_sequence = integer_sequence<size_t, N...>; - -template <typename T, size_t N, T... Ns> -struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {}; -template <typename T, T... Ns> -struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {}; - -template <size_t N> -using make_index_sequence = make_integer_sequence<size_t, N>; -#endif - -template <class Tuple, class F, size_t... Is> -void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT { - using std::get; - // using free function get<I>(T) now. - const int _[] = {0, ((void)f(get<Is>(tup)), 0)...}; - (void)_; // blocks warnings -} - -template <class T> -FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes( - T const&) { - return {}; -} - -template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) { - const auto indexes = get_indexes(tup); - for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f)); -} - -template <typename Range> -using value_type = - remove_cvref_t<decltype(*detail::range_begin(std::declval<Range>()))>; - -template <typename OutputIt> OutputIt write_delimiter(OutputIt out) { - *out++ = ','; - *out++ = ' '; - return out; -} - -struct singleton { - unsigned char upper; - unsigned char lower_count; -}; - -inline auto is_printable(uint16_t x, const singleton* singletons, - size_t singletons_size, - const unsigned char* singleton_lowers, - const unsigned char* normal, size_t normal_size) - -> bool { - auto upper = x >> 8; - auto lower_start = 0; - for (size_t i = 0; i < singletons_size; ++i) { - auto s = singletons[i]; - auto lower_end = lower_start + s.lower_count; - if (upper < s.upper) break; - if (upper == s.upper) { - for (auto j = lower_start; j < lower_end; ++j) { - if (singleton_lowers[j] == (x & 0xff)) return false; - } - } - lower_start = lower_end; - } - - auto xsigned = static_cast<int>(x); - auto current = true; - for (size_t i = 0; i < normal_size; ++i) { - auto v = static_cast<int>(normal[i]); - auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v; - xsigned -= len; - if (xsigned < 0) break; - current = !current; - } - return current; -} - -// Returns true iff the code point cp is printable. -// This code is generated by support/printable.py. -inline auto is_printable(uint32_t cp) -> bool { - static constexpr singleton singletons0[] = { - {0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8}, - {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13}, - {0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5}, - {0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22}, - {0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3}, - {0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8}, - {0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9}, - }; - static constexpr unsigned char singletons0_lower[] = { - 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90, - 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, - 0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1, - 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, - 0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d, - 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, - 0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, - 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, - 0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d, - 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d, - 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, - 0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7, - 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, - 0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7, - 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, - 0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e, - 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, - 0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e, - 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, - 0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, - 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, - 0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, - 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, - 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, - 0xfe, 0xff, - }; - static constexpr singleton singletons1[] = { - {0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2}, - {0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5}, - {0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5}, - {0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2}, - {0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5}, - {0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2}, - {0xfa, 2}, {0xfb, 1}, - }; - static constexpr unsigned char singletons1_lower[] = { - 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07, - 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36, - 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87, - 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, - 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b, - 0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9, - 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, - 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, - 0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, - 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, - 0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6, - 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, - 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, - 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, - 0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93, - }; - static constexpr unsigned char normal0[] = { - 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04, - 0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0, - 0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01, - 0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03, - 0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03, - 0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a, - 0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15, - 0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f, - 0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80, - 0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07, - 0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06, - 0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04, - 0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac, - 0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c, - 0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11, - 0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c, - 0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b, - 0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6, - 0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03, - 0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80, - 0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06, - 0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c, - 0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17, - 0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80, - 0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80, - 0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d, - }; - static constexpr unsigned char normal1[] = { - 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f, - 0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e, - 0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04, - 0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09, - 0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16, - 0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f, - 0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36, - 0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33, - 0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08, - 0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e, - 0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41, - 0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03, - 0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22, - 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04, - 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45, - 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03, - 0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81, - 0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75, - 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1, - 0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a, - 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11, - 0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09, - 0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89, - 0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6, - 0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09, - 0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50, - 0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05, - 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83, - 0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05, - 0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80, - 0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80, - 0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07, - 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e, - 0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07, - 0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06, - }; - auto lower = static_cast<uint16_t>(cp); - if (cp < 0x10000) { - return is_printable(lower, singletons0, - sizeof(singletons0) / sizeof(*singletons0), - singletons0_lower, normal0, sizeof(normal0)); - } - if (cp < 0x20000) { - return is_printable(lower, singletons1, - sizeof(singletons1) / sizeof(*singletons1), - singletons1_lower, normal1, sizeof(normal1)); - } - if (0x2a6de <= cp && cp < 0x2a700) return false; - if (0x2b735 <= cp && cp < 0x2b740) return false; - if (0x2b81e <= cp && cp < 0x2b820) return false; - if (0x2cea2 <= cp && cp < 0x2ceb0) return false; - if (0x2ebe1 <= cp && cp < 0x2f800) return false; - if (0x2fa1e <= cp && cp < 0x30000) return false; - if (0x3134b <= cp && cp < 0xe0100) return false; - if (0xe01f0 <= cp && cp < 0x110000) return false; - return cp < 0x110000; -} - -inline auto needs_escape(uint32_t cp) -> bool { - return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' || - !is_printable(cp); -} - -template <typename Char> struct find_escape_result { - const Char* begin; - const Char* end; - uint32_t cp; -}; - -template <typename Char> -auto find_escape(const Char* begin, const Char* end) - -> find_escape_result<Char> { - for (; begin != end; ++begin) { - auto cp = static_cast<typename std::make_unsigned<Char>::type>(*begin); - if (sizeof(Char) == 1 && cp >= 0x80) continue; - if (needs_escape(cp)) return {begin, begin + 1, cp}; - } - return {begin, nullptr, 0}; -} - -inline auto find_escape(const char* begin, const char* end) - -> find_escape_result<char> { - if (!is_utf8()) return find_escape<char>(begin, end); - auto result = find_escape_result<char>{end, nullptr, 0}; - for_each_codepoint(string_view(begin, to_unsigned(end - begin)), - [&](uint32_t cp, string_view sv) { - if (needs_escape(cp)) { - result = {sv.begin(), sv.end(), cp}; - return false; - } - return true; - }); - return result; -} - -template <typename Char, typename OutputIt> -auto write_range_entry(OutputIt out, basic_string_view<Char> str) -> OutputIt { - *out++ = '"'; - auto begin = str.begin(), end = str.end(); - do { - auto escape = find_escape(begin, end); - out = copy_str<Char>(begin, escape.begin, out); - begin = escape.end; - if (!begin) break; - auto c = static_cast<Char>(escape.cp); - switch (escape.cp) { - case '\n': - *out++ = '\\'; - c = 'n'; - break; - case '\r': - *out++ = '\\'; - c = 'r'; - break; - case '\t': - *out++ = '\\'; - c = 't'; - break; - case '"': - FMT_FALLTHROUGH; - case '\\': - *out++ = '\\'; - break; - default: - if (is_utf8()) { - if (escape.cp < 0x100) { - out = fmt::format_to(out, "\\x{:02x}", escape.cp); - continue; - } - if (escape.cp < 0x10000) { - out = fmt::format_to(out, "\\u{:04x}", escape.cp); - continue; - } - if (escape.cp < 0x110000) { - out = fmt::format_to(out, "\\U{:08x}", escape.cp); - continue; - } - } - for (Char escape_char : basic_string_view<Char>( - escape.begin, to_unsigned(escape.end - escape.begin))) { - out = fmt::format_to( - out, "\\x{:02x}", - static_cast<typename std::make_unsigned<Char>::type>(escape_char)); - } - continue; - } - *out++ = c; - } while (begin != end); - *out++ = '"'; - return out; -} - -template <typename Char, typename OutputIt, typename T, - FMT_ENABLE_IF(std::is_convertible<T, std_string_view<char>>::value)> -inline auto write_range_entry(OutputIt out, const T& str) -> OutputIt { - auto sv = std_string_view<Char>(str); - return write_range_entry<Char>(out, basic_string_view<Char>(sv)); -} - -template <typename Char, typename OutputIt, typename Arg, - FMT_ENABLE_IF(std::is_same<Arg, Char>::value)> -OutputIt write_range_entry(OutputIt out, const Arg v) { - *out++ = '\''; - *out++ = v; - *out++ = '\''; - return out; -} - -template < - typename Char, typename OutputIt, typename Arg, - FMT_ENABLE_IF(!is_std_string_like<typename std::decay<Arg>::type>::value && - !std::is_same<Arg, Char>::value)> -OutputIt write_range_entry(OutputIt out, const Arg& v) { - return write<Char>(out, v); -} - -} // namespace detail - -template <typename T> struct is_tuple_like { - static FMT_CONSTEXPR_DECL const bool value = - detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value; -}; - -template <typename TupleT, typename Char> -struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> { - private: - // C++11 generic lambda for format(). - template <typename FormatContext> struct format_each { - template <typename T> void operator()(const T& v) { - if (i > 0) out = detail::write_delimiter(out); - out = detail::write_range_entry<Char>(out, v); - ++i; - } - int i; - typename FormatContext::iterator& out; - }; - - public: - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename FormatContext = format_context> - auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) { - auto out = ctx.out(); - *out++ = '('; - detail::for_each(values, format_each<FormatContext>{0, out}); - *out++ = ')'; - return out; - } -}; - -template <typename T, typename Char> struct is_range { - static FMT_CONSTEXPR_DECL const bool value = - detail::is_range_<T>::value && !detail::is_std_string_like<T>::value && - !detail::is_map<T>::value && - !std::is_convertible<T, std::basic_string<Char>>::value && - !std::is_constructible<detail::std_string_view<Char>, T>::value; -}; - -template <typename T, typename Char> -struct formatter< - T, Char, - enable_if_t< - fmt::is_range<T, Char>::value -// Workaround a bug in MSVC 2019 and earlier. -#if !FMT_MSC_VER - && (is_formattable<detail::value_type<T>, Char>::value || - detail::has_fallback_formatter<detail::value_type<T>, Char>::value) -#endif - >> { - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template < - typename FormatContext, typename U, - FMT_ENABLE_IF( - std::is_same<U, conditional_t<detail::has_const_begin_end<T>::value, - const T, T>>::value)> - auto format(U& range, FormatContext& ctx) -> decltype(ctx.out()) { -#ifdef FMT_DEPRECATED_BRACED_RANGES - Char prefix = '{'; - Char postfix = '}'; -#else - Char prefix = detail::is_set<T>::value ? '{' : '['; - Char postfix = detail::is_set<T>::value ? '}' : ']'; -#endif - auto out = ctx.out(); - *out++ = prefix; - int i = 0; - auto it = std::begin(range); - auto end = std::end(range); - for (; it != end; ++it) { - if (i > 0) out = detail::write_delimiter(out); - out = detail::write_range_entry<Char>(out, *it); - ++i; - } - *out++ = postfix; - return out; - } -}; - -template <typename T, typename Char> -struct formatter< - T, Char, - enable_if_t< - detail::is_map<T>::value -// Workaround a bug in MSVC 2019 and earlier. -#if !FMT_MSC_VER - && (is_formattable<detail::value_type<T>, Char>::value || - detail::has_fallback_formatter<detail::value_type<T>, Char>::value) -#endif - >> { - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template < - typename FormatContext, typename U, - FMT_ENABLE_IF( - std::is_same<U, conditional_t<detail::has_const_begin_end<T>::value, - const T, T>>::value)> - auto format(U& map, FormatContext& ctx) -> decltype(ctx.out()) { - auto out = ctx.out(); - *out++ = '{'; - int i = 0; - for (const auto& item : map) { - if (i > 0) out = detail::write_delimiter(out); - out = detail::write_range_entry<Char>(out, item.first); - *out++ = ':'; - *out++ = ' '; - out = detail::write_range_entry<Char>(out, item.second); - ++i; - } - *out++ = '}'; - return out; - } -}; - -template <typename Char, typename... T> struct tuple_join_view : detail::view { - const std::tuple<T...>& tuple; - basic_string_view<Char> sep; - - tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s) - : tuple(t), sep{s} {} -}; - -template <typename Char, typename... T> -using tuple_arg_join = tuple_join_view<Char, T...>; - -// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers -// support in tuple_join. It is disabled by default because of issues with -// the dynamic width and precision. -#ifndef FMT_TUPLE_JOIN_SPECIFIERS -# define FMT_TUPLE_JOIN_SPECIFIERS 0 -#endif - -template <typename Char, typename... T> -struct formatter<tuple_join_view<Char, T...>, Char> { - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>()); - } - - template <typename FormatContext> - auto format(const tuple_join_view<Char, T...>& value, - FormatContext& ctx) const -> typename FormatContext::iterator { - return do_format(value, ctx, - std::integral_constant<size_t, sizeof...(T)>()); - } - - private: - std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_; - - template <typename ParseContext> - FMT_CONSTEXPR auto do_parse(ParseContext& ctx, - std::integral_constant<size_t, 0>) - -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename ParseContext, size_t N> - FMT_CONSTEXPR auto do_parse(ParseContext& ctx, - std::integral_constant<size_t, N>) - -> decltype(ctx.begin()) { - auto end = ctx.begin(); -#if FMT_TUPLE_JOIN_SPECIFIERS - end = std::get<sizeof...(T) - N>(formatters_).parse(ctx); - if (N > 1) { - auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>()); - if (end != end1) - FMT_THROW(format_error("incompatible format specs for tuple elements")); - } -#endif - return end; - } - - template <typename FormatContext> - auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx, - std::integral_constant<size_t, 0>) const -> - typename FormatContext::iterator { - return ctx.out(); - } - - template <typename FormatContext, size_t N> - auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx, - std::integral_constant<size_t, N>) const -> - typename FormatContext::iterator { - auto out = std::get<sizeof...(T) - N>(formatters_) - .format(std::get<sizeof...(T) - N>(value.tuple), ctx); - if (N > 1) { - out = std::copy(value.sep.begin(), value.sep.end(), out); - ctx.advance_to(out); - return do_format(value, ctx, std::integral_constant<size_t, N - 1>()); - } - return out; - } -}; - -FMT_MODULE_EXPORT_BEGIN - -/** - \rst - Returns an object that formats `tuple` with elements separated by `sep`. - - **Example**:: - - std::tuple<int, char> t = {1, 'a'}; - fmt::print("{}", fmt::join(t, ", ")); - // Output: "1, a" - \endrst - */ -template <typename... T> -FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep) - -> tuple_join_view<char, T...> { - return {tuple, sep}; -} - -template <typename... T> -FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, - basic_string_view<wchar_t> sep) - -> tuple_join_view<wchar_t, T...> { - return {tuple, sep}; -} - -/** - \rst - Returns an object that formats `initializer_list` with elements separated by - `sep`. - - **Example**:: - - fmt::print("{}", fmt::join({1, 2, 3}, ", ")); - // Output: "1, 2, 3" - \endrst - */ -template <typename T> -auto join(std::initializer_list<T> list, string_view sep) - -> join_view<const T*, const T*> { - return join(std::begin(list), std::end(list), sep); -} - -FMT_MODULE_EXPORT_END -FMT_END_NAMESPACE - -#endif // FMT_RANGES_H_ diff --git a/contrib/libs/fmt/test/args-test.cc b/contrib/libs/fmt/test/args-test.cc deleted file mode 100644 index aa01fa4e08..0000000000 --- a/contrib/libs/fmt/test/args-test.cc +++ /dev/null @@ -1,186 +0,0 @@ -// Formatting library for C++ - dynamic argument store tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/args.h" - -#include <memory> - -#include "gtest/gtest.h" - -TEST(args_test, basic) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(42); - store.push_back("abc1"); - store.push_back(1.5f); - EXPECT_EQ("42 and abc1 and 1.5", fmt::vformat("{} and {} and {}", store)); -} - -TEST(args_test, strings_and_refs) { - // Unfortunately the tests are compiled with old ABI so strings use COW. - fmt::dynamic_format_arg_store<fmt::format_context> store; - char str[] = "1234567890"; - store.push_back(str); - store.push_back(std::cref(str)); - store.push_back(fmt::string_view{str}); - str[0] = 'X'; - - auto result = fmt::vformat("{} and {} and {}", store); - EXPECT_EQ("1234567890 and X234567890 and X234567890", result); -} - -struct custom_type { - int i = 0; -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<custom_type> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename FormatContext> - auto format(const custom_type& p, FormatContext& ctx) -> decltype(ctx.out()) { - return format_to(ctx.out(), "cust={}", p.i); - } -}; -FMT_END_NAMESPACE - -TEST(args_test, custom_format) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - auto c = custom_type(); - store.push_back(c); - ++c.i; - store.push_back(c); - ++c.i; - store.push_back(std::cref(c)); - ++c.i; - auto result = fmt::vformat("{} and {} and {}", store); - EXPECT_EQ("cust=0 and cust=1 and cust=3", result); -} - -struct to_stringable { - friend fmt::string_view to_string_view(to_stringable) { return {}; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<to_stringable> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - - auto format(to_stringable, format_context& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(args_test, to_string_and_formatter) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - auto s = to_stringable(); - store.push_back(s); - store.push_back(std::cref(s)); - fmt::vformat("", store); -} - -TEST(args_test, named_int) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(fmt::arg("a1", 42)); - EXPECT_EQ("42", fmt::vformat("{a1}", store)); -} - -TEST(args_test, named_strings) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - char str[] = "1234567890"; - store.push_back(fmt::arg("a1", str)); - store.push_back(fmt::arg("a2", std::cref(str))); - str[0] = 'X'; - EXPECT_EQ("1234567890 and X234567890", fmt::vformat("{a1} and {a2}", store)); -} - -TEST(args_test, named_arg_by_ref) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - char band[] = "Rolling Stones"; - store.push_back(fmt::arg("band", std::cref(band))); - band[9] = 'c'; // Changing band affects the output. - EXPECT_EQ(fmt::vformat("{band}", store), "Rolling Scones"); -} - -TEST(args_test, named_custom_format) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - auto c = custom_type(); - store.push_back(fmt::arg("c1", c)); - ++c.i; - store.push_back(fmt::arg("c2", c)); - ++c.i; - store.push_back(fmt::arg("c_ref", std::cref(c))); - ++c.i; - auto result = fmt::vformat("{c1} and {c2} and {c_ref}", store); - EXPECT_EQ("cust=0 and cust=1 and cust=3", result); -} - -TEST(args_test, clear) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(42); - - auto result = fmt::vformat("{}", store); - EXPECT_EQ("42", result); - - store.push_back(43); - result = fmt::vformat("{} and {}", store); - EXPECT_EQ("42 and 43", result); - - store.clear(); - store.push_back(44); - result = fmt::vformat("{}", store); - EXPECT_EQ("44", result); -} - -TEST(args_test, reserve) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.reserve(2, 1); - store.push_back(1.5f); - store.push_back(fmt::arg("a1", 42)); - auto result = fmt::vformat("{a1} and {}", store); - EXPECT_EQ("42 and 1.5", result); -} - -struct copy_throwable { - copy_throwable() {} - copy_throwable(const copy_throwable&) { throw "deal with it"; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<copy_throwable> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(copy_throwable, format_context& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(args_test, throw_on_copy) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(std::string("foo")); - try { - store.push_back(copy_throwable()); - } catch (...) { - } - EXPECT_EQ(fmt::vformat("{}", store), "foo"); -} - -TEST(args_test, move_constructor) { - using store_type = fmt::dynamic_format_arg_store<fmt::format_context>; - auto store = std::unique_ptr<store_type>(new store_type()); - store->push_back(42); - store->push_back(std::string("foo")); - store->push_back(fmt::arg("a1", "foo")); - auto moved_store = std::move(*store); - store.reset(); - EXPECT_EQ(fmt::vformat("{} {} {a1}", moved_store), "42 foo foo"); -} diff --git a/contrib/libs/fmt/test/args-test/ya.make b/contrib/libs/fmt/test/args-test/ya.make deleted file mode 100644 index 430ed1293a..0000000000 --- a/contrib/libs/fmt/test/args-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - args-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/assert-test.cc b/contrib/libs/fmt/test/assert-test.cc deleted file mode 100644 index c74e617e68..0000000000 --- a/contrib/libs/fmt/test/assert-test.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Formatting library for C++ - FMT_ASSERT test -// -// It is a separate test to minimize the number of EXPECT_DEBUG_DEATH checks -// which are slow on some platforms. In other tests FMT_ASSERT is made to throw -// an exception which is much faster and easier to check. -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/core.h" -#include "gtest/gtest.h" - -TEST(assert_test, fail) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEBUG_DEATH(FMT_ASSERT(false, "don't panic!"), "don't panic!"); -#else - fmt::print("warning: death tests are not supported\n"); -#endif -} - -TEST(assert_test, dangling_else) { - bool test_condition = false; - bool executed_else = false; - if (test_condition) - FMT_ASSERT(true, ""); - else - executed_else = true; - EXPECT_TRUE(executed_else); -} diff --git a/contrib/libs/fmt/test/assert-test/ya.make b/contrib/libs/fmt/test/assert-test/ya.make deleted file mode 100644 index 7b8997a7e6..0000000000 --- a/contrib/libs/fmt/test/assert-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - assert-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/chrono-test.cc b/contrib/libs/fmt/test/chrono-test.cc deleted file mode 100644 index 42360e5f12..0000000000 --- a/contrib/libs/fmt/test/chrono-test.cc +++ /dev/null @@ -1,625 +0,0 @@ -// Formatting library for C++ - time formatting tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/chrono.h" - -#include <ctime> -#include <vector> - -#include "gtest-extra.h" // EXPECT_THROW_MSG -#include "util.h" // get_locale - -using fmt::runtime; - -using testing::Contains; - -auto make_tm() -> std::tm { - auto time = std::tm(); - time.tm_mday = 1; - return time; -} - -auto make_hour(int h) -> std::tm { - auto time = make_tm(); - time.tm_hour = h; - return time; -} - -auto make_minute(int m) -> std::tm { - auto time = make_tm(); - time.tm_min = m; - return time; -} - -auto make_second(int s) -> std::tm { - auto time = make_tm(); - time.tm_sec = s; - return time; -} - -std::string system_strftime(const std::string& format, const std::tm* timeptr, - std::locale* locptr = nullptr) { - auto loc = locptr ? *locptr : std::locale::classic(); - auto& facet = std::use_facet<std::time_put<char>>(loc); - std::ostringstream os; - os.imbue(loc); - facet.put(os, os, ' ', timeptr, format.c_str(), - format.c_str() + format.size()); -#ifdef _WIN32 - // Workaround a bug in older versions of Universal CRT. - auto str = os.str(); - if (str == "-0000") str = "+0000"; - return str; -#else - return os.str(); -#endif -} - -FMT_CONSTEXPR std::tm make_tm(int year, int mon, int mday, int hour, int min, - int sec) { - auto tm = std::tm(); - tm.tm_sec = sec; - tm.tm_min = min; - tm.tm_hour = hour; - tm.tm_mday = mday; - tm.tm_mon = mon - 1; - tm.tm_year = year - 1900; - return tm; -} - -TEST(chrono_test, format_tm) { - auto tm = std::tm(); - tm.tm_year = 116; - tm.tm_mon = 3; - tm.tm_mday = 25; - tm.tm_hour = 11; - tm.tm_min = 22; - tm.tm_sec = 33; - EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm), - "The date is 2016-04-25 11:22:33."); - EXPECT_EQ(fmt::format("{:%Y}", tm), "2016"); - EXPECT_EQ(fmt::format("{:%C}", tm), "20"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), fmt::format("{:%Y}", tm)); - EXPECT_EQ(fmt::format("{:%e}", tm), "25"); - EXPECT_EQ(fmt::format("{:%D}", tm), "04/25/16"); - EXPECT_EQ(fmt::format("{:%F}", tm), "2016-04-25"); - EXPECT_EQ(fmt::format("{:%T}", tm), "11:22:33"); - - // Short year - tm.tm_year = 999 - 1900; - tm.tm_mon = 0; // for %G - tm.tm_mday = 2; // for %G - tm.tm_wday = 3; // for %G - tm.tm_yday = 1; // for %G - EXPECT_EQ(fmt::format("{:%Y}", tm), "0999"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), "0999"); - EXPECT_EQ(fmt::format("{:%G}", tm), "0999"); - - tm.tm_year = 27 - 1900; - EXPECT_EQ(fmt::format("{:%Y}", tm), "0027"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), "0027"); - - // Overflow year - tm.tm_year = 2147483647; - EXPECT_EQ(fmt::format("{:%Y}", tm), "2147485547"); - - tm.tm_year = -2147483648; - EXPECT_EQ(fmt::format("{:%Y}", tm), "-2147481748"); - - // for week on the year - // https://www.cl.cam.ac.uk/~mgk25/iso-time.html - std::vector<std::tm> tm_list = { - make_tm(1975, 12, 29, 12, 14, 16), // W01 - make_tm(1977, 1, 2, 12, 14, 16), // W53 - make_tm(1999, 12, 27, 12, 14, 16), // W52 - make_tm(1999, 12, 31, 12, 14, 16), // W52 - make_tm(2000, 1, 1, 12, 14, 16), // W52 - make_tm(2000, 1, 2, 12, 14, 16), // W52 - make_tm(2000, 1, 3, 12, 14, 16) // W1 - }; - const std::string iso_week_spec = "%Y-%m-%d: %G %g %V"; - for (auto ctm : tm_list) { - // Calculate tm_yday, tm_wday, etc. - std::time_t t = std::mktime(&ctm); - tm = *std::localtime(&t); - - auto fmt_spec = fmt::format("{{:{}}}", iso_week_spec); - EXPECT_EQ(system_strftime(iso_week_spec, &tm), - fmt::format(fmt::runtime(fmt_spec), tm)); - } - - // Every day from 1970-01-01 - std::time_t time_now = std::time(nullptr); - for (std::time_t t = 6 * 3600; t < time_now; t += 86400) { - tm = *std::localtime(&t); - - auto fmt_spec = fmt::format("{{:{}}}", iso_week_spec); - EXPECT_EQ(system_strftime(iso_week_spec, &tm), - fmt::format(fmt::runtime(fmt_spec), tm)); - } -} - -// MSVC: -// minkernel\crts\ucrt\src\appcrt\time\wcsftime.cpp(971) : Assertion failed: -// timeptr->tm_year >= -1900 && timeptr->tm_year <= 8099 -#ifndef _WIN32 -TEST(chrono_test, format_tm_future) { - auto tm = std::tm(); - tm.tm_year = 10445; // 10000+ years - tm.tm_mon = 3; - tm.tm_mday = 25; - tm.tm_hour = 11; - tm.tm_min = 22; - tm.tm_sec = 33; - EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm), - "The date is 12345-04-25 11:22:33."); - EXPECT_EQ(fmt::format("{:%Y}", tm), "12345"); - EXPECT_EQ(fmt::format("{:%C}", tm), "123"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), fmt::format("{:%Y}", tm)); - EXPECT_EQ(fmt::format("{:%D}", tm), "04/25/45"); - EXPECT_EQ(fmt::format("{:%F}", tm), "12345-04-25"); - EXPECT_EQ(fmt::format("{:%T}", tm), "11:22:33"); -} - -TEST(chrono_test, format_tm_past) { - auto tm = std::tm(); - tm.tm_year = -2001; - tm.tm_mon = 3; - tm.tm_mday = 25; - tm.tm_hour = 11; - tm.tm_min = 22; - tm.tm_sec = 33; - EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm), - "The date is -101-04-25 11:22:33."); - EXPECT_EQ(fmt::format("{:%Y}", tm), "-101"); - - // macOS %C - "-1" - // Linux %C - "-2" - // fmt %C - "-1" - EXPECT_EQ(fmt::format("{:%C}", tm), "-1"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), fmt::format("{:%Y}", tm)); - - // macOS %D - "04/25/01" (%y) - // Linux %D - "04/25/99" (%y) - // fmt %D - "04/25/01" (%y) - EXPECT_EQ(fmt::format("{:%D}", tm), "04/25/01"); - - EXPECT_EQ(fmt::format("{:%F}", tm), "-101-04-25"); - EXPECT_EQ(fmt::format("{:%T}", tm), "11:22:33"); - - tm.tm_year = -1901; // -1 - EXPECT_EQ(fmt::format("{:%Y}", tm), "-001"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), fmt::format("{:%Y}", tm)); - - tm.tm_year = -1911; // -11 - EXPECT_EQ(fmt::format("{:%Y}", tm), "-011"); - EXPECT_EQ(fmt::format("{:%C%y}", tm), fmt::format("{:%Y}", tm)); -} -#endif - -TEST(chrono_test, grow_buffer) { - auto s = std::string("{:"); - for (int i = 0; i < 30; ++i) s += "%c"; - s += "}\n"; - auto t = std::time(nullptr); - (void)fmt::format(fmt::runtime(s), *std::localtime(&t)); -} - -TEST(chrono_test, format_to_empty_container) { - auto time = std::tm(); - time.tm_sec = 42; - auto s = std::string(); - fmt::format_to(std::back_inserter(s), "{:%S}", time); - EXPECT_EQ(s, "42"); -} - -TEST(chrono_test, empty_result) { EXPECT_EQ(fmt::format("{}", std::tm()), ""); } - -auto equal(const std::tm& lhs, const std::tm& rhs) -> bool { - return lhs.tm_sec == rhs.tm_sec && lhs.tm_min == rhs.tm_min && - lhs.tm_hour == rhs.tm_hour && lhs.tm_mday == rhs.tm_mday && - lhs.tm_mon == rhs.tm_mon && lhs.tm_year == rhs.tm_year && - lhs.tm_wday == rhs.tm_wday && lhs.tm_yday == rhs.tm_yday && - lhs.tm_isdst == rhs.tm_isdst; -} - -TEST(chrono_test, localtime) { - auto t = std::time(nullptr); - auto tm = *std::localtime(&t); - EXPECT_TRUE(equal(tm, fmt::localtime(t))); -} - -TEST(chrono_test, gmtime) { - auto t = std::time(nullptr); - auto tm = *std::gmtime(&t); - EXPECT_TRUE(equal(tm, fmt::gmtime(t))); -} - -template <typename TimePoint> auto strftime_full(TimePoint tp) -> std::string { - auto t = std::chrono::system_clock::to_time_t(tp); - auto tm = *std::localtime(&t); - return system_strftime("%Y-%m-%d %H:%M:%S", &tm); -} - -TEST(chrono_test, time_point) { - auto t1 = std::chrono::system_clock::now(); - EXPECT_EQ(strftime_full(t1), fmt::format("{:%Y-%m-%d %H:%M:%S}", t1)); - EXPECT_EQ(strftime_full(t1), fmt::format("{}", t1)); - using time_point = - std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>; - auto t2 = time_point(std::chrono::seconds(42)); - EXPECT_EQ(strftime_full(t2), fmt::format("{:%Y-%m-%d %H:%M:%S}", t2)); - - std::vector<std::string> spec_list = { - "%%", "%n", "%t", "%Y", "%EY", "%y", "%Oy", "%Ey", "%C", - "%EC", "%G", "%g", "%b", "%h", "%B", "%m", "%Om", "%U", - "%OU", "%W", "%OW", "%V", "%OV", "%j", "%d", "%Od", "%e", - "%Oe", "%a", "%A", "%w", "%Ow", "%u", "%Ou", "%H", "%OH", - "%I", "%OI", "%M", "%OM", "%S", "%OS", "%x", "%Ex", "%X", - "%EX", "%D", "%F", "%R", "%T", "%p", "%z", "%Z"}; - spec_list.push_back("%Y-%m-%d %H:%M:%S"); -#ifndef _WIN32 - // Disabled on Windows because these formats are not consistent among - // platforms. - spec_list.insert(spec_list.end(), {"%c", "%Ec", "%r"}); -#endif - - for (const auto& spec : spec_list) { - auto t = std::chrono::system_clock::to_time_t(t1); - auto tm = *std::localtime(&t); - - auto sys_output = system_strftime(spec, &tm); - - auto fmt_spec = fmt::format("{{:{}}}", spec); - EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), t1)); - EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), tm)); - } -} - -#ifndef FMT_STATIC_THOUSANDS_SEPARATOR - -TEST(chrono_test, format_default) { - EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); - EXPECT_EQ("42as", - fmt::format("{}", std::chrono::duration<int, std::atto>(42))); - EXPECT_EQ("42fs", - fmt::format("{}", std::chrono::duration<int, std::femto>(42))); - EXPECT_EQ("42ps", - fmt::format("{}", std::chrono::duration<int, std::pico>(42))); - EXPECT_EQ("42ns", fmt::format("{}", std::chrono::nanoseconds(42))); - EXPECT_EQ("42µs", fmt::format("{}", std::chrono::microseconds(42))); - EXPECT_EQ("42ms", fmt::format("{}", std::chrono::milliseconds(42))); - EXPECT_EQ("42cs", - fmt::format("{}", std::chrono::duration<int, std::centi>(42))); - EXPECT_EQ("42ds", - fmt::format("{}", std::chrono::duration<int, std::deci>(42))); - EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); - EXPECT_EQ("42das", - fmt::format("{}", std::chrono::duration<int, std::deca>(42))); - EXPECT_EQ("42hs", - fmt::format("{}", std::chrono::duration<int, std::hecto>(42))); - EXPECT_EQ("42ks", - fmt::format("{}", std::chrono::duration<int, std::kilo>(42))); - EXPECT_EQ("42Ms", - fmt::format("{}", std::chrono::duration<int, std::mega>(42))); - EXPECT_EQ("42Gs", - fmt::format("{}", std::chrono::duration<int, std::giga>(42))); - EXPECT_EQ("42Ts", - fmt::format("{}", std::chrono::duration<int, std::tera>(42))); - EXPECT_EQ("42Ps", - fmt::format("{}", std::chrono::duration<int, std::peta>(42))); - EXPECT_EQ("42Es", - fmt::format("{}", std::chrono::duration<int, std::exa>(42))); - EXPECT_EQ("42m", fmt::format("{}", std::chrono::minutes(42))); - EXPECT_EQ("42h", fmt::format("{}", std::chrono::hours(42))); - EXPECT_EQ( - "42[15]s", - fmt::format("{}", std::chrono::duration<int, std::ratio<15, 1>>(42))); - EXPECT_EQ( - "42[15/4]s", - fmt::format("{}", std::chrono::duration<int, std::ratio<15, 4>>(42))); -} - -TEST(chrono_test, align) { - auto s = std::chrono::seconds(42); - EXPECT_EQ("42s ", fmt::format("{:5}", s)); - EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5)); - EXPECT_EQ(" 42s", fmt::format("{:>5}", s)); - EXPECT_EQ("**42s**", fmt::format("{:*^7}", s)); - EXPECT_EQ("03:25:45 ", - fmt::format("{:12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ(" 03:25:45", - fmt::format("{:>12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("~~03:25:45~~", - fmt::format("{:~^12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25:45 ", - fmt::format("{:{}%H:%M:%S}", std::chrono::seconds(12345), 12)); -} - -TEST(chrono_test, format_specs) { - EXPECT_EQ("%", fmt::format("{:%%}", std::chrono::seconds(0))); - EXPECT_EQ("\n", fmt::format("{:%n}", std::chrono::seconds(0))); - EXPECT_EQ("\t", fmt::format("{:%t}", std::chrono::seconds(0))); - EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(0))); - EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(60))); - EXPECT_EQ("42", fmt::format("{:%S}", std::chrono::seconds(42))); - EXPECT_EQ("01.234", fmt::format("{:%S}", std::chrono::milliseconds(1234))); - EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(0))); - EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(60))); - EXPECT_EQ("42", fmt::format("{:%M}", std::chrono::minutes(42))); - EXPECT_EQ("01", fmt::format("{:%M}", std::chrono::seconds(61))); - EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(0))); - EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(24))); - EXPECT_EQ("14", fmt::format("{:%H}", std::chrono::hours(14))); - EXPECT_EQ("01", fmt::format("{:%H}", std::chrono::minutes(61))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(0))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(12))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(24))); - EXPECT_EQ("04", fmt::format("{:%I}", std::chrono::hours(4))); - EXPECT_EQ("02", fmt::format("{:%I}", std::chrono::hours(14))); - EXPECT_EQ("03:25:45", - fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25", fmt::format("{:%R}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25:45", fmt::format("{:%T}", std::chrono::seconds(12345))); - EXPECT_EQ("12345", fmt::format("{:%Q}", std::chrono::seconds(12345))); - EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(12345))); -} - -TEST(chrono_test, invalid_specs) { - auto sec = std::chrono::seconds(0); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%a}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%A}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%c}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%x}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%Ex}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%X}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%EX}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%D}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%F}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%Ec}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%w}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%u}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%b}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%B}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%z}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%Z}"), sec), fmt::format_error, - "no date"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%Eq}"), sec), fmt::format_error, - "invalid format"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:%Oq}"), sec), fmt::format_error, - "invalid format"); -} - -auto format_tm(const std::tm& time, fmt::string_view spec, - const std::locale& loc) -> std::string { - auto& facet = std::use_facet<std::time_put<char>>(loc); - std::ostringstream os; - os.imbue(loc); - facet.put(os, os, ' ', &time, spec.begin(), spec.end()); - return os.str(); -} - -TEST(chrono_test, locale) { - auto loc = get_locale("ja_JP.utf8"); - if (loc == std::locale::classic()) return; -# define EXPECT_TIME(spec, time, duration) \ - { \ - auto jp_loc = std::locale("ja_JP.utf8"); \ - EXPECT_EQ(format_tm(time, spec, jp_loc), \ - fmt::format(jp_loc, "{:L" spec "}", duration)); \ - } - EXPECT_TIME("%OH", make_hour(14), std::chrono::hours(14)); - EXPECT_TIME("%OI", make_hour(14), std::chrono::hours(14)); - EXPECT_TIME("%OM", make_minute(42), std::chrono::minutes(42)); - EXPECT_TIME("%OS", make_second(42), std::chrono::seconds(42)); - auto time = make_tm(); - time.tm_hour = 3; - time.tm_min = 25; - time.tm_sec = 45; - auto sec = std::chrono::seconds(12345); - EXPECT_TIME("%r", time, sec); - EXPECT_TIME("%p", time, sec); -} - -using dms = std::chrono::duration<double, std::milli>; - -TEST(chrono_test, format_default_fp) { - typedef std::chrono::duration<float> fs; - EXPECT_EQ("1.234s", fmt::format("{}", fs(1.234))); - typedef std::chrono::duration<float, std::milli> fms; - EXPECT_EQ("1.234ms", fmt::format("{}", fms(1.234))); - typedef std::chrono::duration<double> ds; - EXPECT_EQ("1.234s", fmt::format("{}", ds(1.234))); - EXPECT_EQ("1.234ms", fmt::format("{}", dms(1.234))); -} - -TEST(chrono_test, format_precision) { - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{:.2}"), std::chrono::seconds(42)), - fmt::format_error, "precision not allowed for this argument type"); - EXPECT_EQ("1ms", fmt::format("{:.0}", dms(1.234))); - EXPECT_EQ("1.2ms", fmt::format("{:.1}", dms(1.234))); - EXPECT_EQ("1.23ms", fmt::format("{:.{}}", dms(1.234), 2)); - - EXPECT_EQ("13ms", fmt::format("{:.0}", dms(12.56))); - EXPECT_EQ("12.6ms", fmt::format("{:.1}", dms(12.56))); - EXPECT_EQ("12.56ms", fmt::format("{:.2}", dms(12.56))); -} - -TEST(chrono_test, format_full_specs) { - EXPECT_EQ("1ms ", fmt::format("{:6.0}", dms(1.234))); - EXPECT_EQ("1.2ms ", fmt::format("{:6.1}", dms(1.234))); - EXPECT_EQ(" 1.23ms", fmt::format("{:>8.{}}", dms(1.234), 2)); - EXPECT_EQ(" 1.2ms ", fmt::format("{:^{}.{}}", dms(1.234), 7, 1)); - EXPECT_EQ(" 1.23ms ", fmt::format("{0:^{2}.{1}}", dms(1.234), 2, 8)); - EXPECT_EQ("=1.234ms=", fmt::format("{:=^{}.{}}", dms(1.234), 9, 3)); - EXPECT_EQ("*1.2340ms*", fmt::format("{:*^10.4}", dms(1.234))); - - EXPECT_EQ("13ms ", fmt::format("{:6.0}", dms(12.56))); - EXPECT_EQ(" 13ms", fmt::format("{:>8.{}}", dms(12.56), 0)); - EXPECT_EQ(" 13ms ", fmt::format("{:^{}.{}}", dms(12.56), 6, 0)); - EXPECT_EQ(" 13ms ", fmt::format("{0:^{2}.{1}}", dms(12.56), 0, 8)); - EXPECT_EQ("==13ms===", fmt::format("{:=^{}.{}}", dms(12.56), 9, 0)); - EXPECT_EQ("***13ms***", fmt::format("{:*^10.0}", dms(12.56))); -} - -TEST(chrono_test, format_simple_q) { - typedef std::chrono::duration<float> fs; - EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", fs(1.234))); - typedef std::chrono::duration<float, std::milli> fms; - EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", fms(1.234))); - typedef std::chrono::duration<double> ds; - EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", ds(1.234))); - EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", dms(1.234))); -} - -TEST(chrono_test, format_precision_q) { - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{:.2%Q %q}"), std::chrono::seconds(42)), - fmt::format_error, "precision not allowed for this argument type"); - EXPECT_EQ("1.2 ms", fmt::format("{:.1%Q %q}", dms(1.234))); - EXPECT_EQ("1.23 ms", fmt::format("{:.{}%Q %q}", dms(1.234), 2)); -} - -TEST(chrono_test, format_full_specs_q) { - EXPECT_EQ("1 ms ", fmt::format("{:7.0%Q %q}", dms(1.234))); - EXPECT_EQ("1.2 ms ", fmt::format("{:7.1%Q %q}", dms(1.234))); - EXPECT_EQ(" 1.23 ms", fmt::format("{:>8.{}%Q %q}", dms(1.234), 2)); - EXPECT_EQ(" 1.2 ms ", fmt::format("{:^{}.{}%Q %q}", dms(1.234), 8, 1)); - EXPECT_EQ(" 1.23 ms ", fmt::format("{0:^{2}.{1}%Q %q}", dms(1.234), 2, 9)); - EXPECT_EQ("=1.234 ms=", fmt::format("{:=^{}.{}%Q %q}", dms(1.234), 10, 3)); - EXPECT_EQ("*1.2340 ms*", fmt::format("{:*^11.4%Q %q}", dms(1.234))); - - EXPECT_EQ("13 ms ", fmt::format("{:7.0%Q %q}", dms(12.56))); - EXPECT_EQ(" 13 ms", fmt::format("{:>8.{}%Q %q}", dms(12.56), 0)); - EXPECT_EQ(" 13 ms ", fmt::format("{:^{}.{}%Q %q}", dms(12.56), 8, 0)); - EXPECT_EQ(" 13 ms ", fmt::format("{0:^{2}.{1}%Q %q}", dms(12.56), 0, 9)); - EXPECT_EQ("==13 ms==", fmt::format("{:=^{}.{}%Q %q}", dms(12.56), 9, 0)); - EXPECT_EQ("***13 ms***", fmt::format("{:*^11.0%Q %q}", dms(12.56))); -} - -TEST(chrono_test, invalid_width_id) { - EXPECT_THROW((void)fmt::format(runtime("{:{o}"), std::chrono::seconds(0)), - fmt::format_error); -} - -TEST(chrono_test, invalid_colons) { - EXPECT_THROW((void)fmt::format(runtime("{0}=:{0::"), std::chrono::seconds(0)), - fmt::format_error); -} - -TEST(chrono_test, negative_durations) { - EXPECT_EQ("-12345", fmt::format("{:%Q}", std::chrono::seconds(-12345))); - EXPECT_EQ("-03:25:45", - fmt::format("{:%H:%M:%S}", std::chrono::seconds(-12345))); - EXPECT_EQ("-00:01", - fmt::format("{:%M:%S}", std::chrono::duration<double>(-1))); - EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(-12345))); - EXPECT_EQ("-00.127", - fmt::format("{:%S}", - std::chrono::duration<signed char, std::milli>{-127})); - auto min = std::numeric_limits<int>::min(); - EXPECT_EQ(fmt::format("{}", min), - fmt::format("{:%Q}", std::chrono::duration<int>(min))); -} - -TEST(chrono_test, special_durations) { - auto value = fmt::format("{:%S}", std::chrono::duration<double>(1e20)); - EXPECT_EQ(value, "40"); - auto nan = std::numeric_limits<double>::quiet_NaN(); - EXPECT_EQ( - "nan nan nan nan nan:nan nan", - fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration<double>(nan))); - EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::exa>(1)), - "1Es"); - EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::atto>(1)), - "1as"); - EXPECT_EQ(fmt::format("{:%R}", std::chrono::duration<char, std::mega>{2}), - "03:33"); - EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}), - "03:33:20"); -} - -TEST(chrono_test, unsigned_duration) { - EXPECT_EQ("42s", fmt::format("{}", std::chrono::duration<unsigned>(42))); -} - -TEST(chrono_test, weekday) { - auto loc = get_locale("ru_RU.UTF-8"); - std::locale::global(loc); - auto mon = fmt::weekday(1); - - auto tm = std::tm(); - tm.tm_wday = static_cast<int>(mon.c_encoding()); - - EXPECT_EQ(fmt::format("{}", mon), "Mon"); - EXPECT_EQ(fmt::format("{:%a}", tm), "Mon"); - - if (loc != std::locale::classic()) { - EXPECT_THAT((std::vector<std::string>{"пн", "Пн", "пнд", "Пнд"}), - Contains(fmt::format(loc, "{:L}", mon))); - EXPECT_THAT((std::vector<std::string>{"пн", "Пн", "пнд", "Пнд"}), - Contains(fmt::format(loc, "{:%a}", tm))); - } -} - -TEST(chrono_test, cpp20_duration_subsecond_support) { - using attoseconds = std::chrono::duration<long long, std::atto>; - // Check that 18 digits of subsecond precision are supported. - EXPECT_EQ(fmt::format("{:%S}", attoseconds{999999999999999999}), - "00.999999999999999999"); - EXPECT_EQ(fmt::format("{:%S}", attoseconds{673231113420148734}), - "00.673231113420148734"); - EXPECT_EQ(fmt::format("{:%S}", attoseconds{-673231113420148734}), - "-00.673231113420148734"); - EXPECT_EQ(fmt::format("{:%S}", std::chrono::nanoseconds{13420148734}), - "13.420148734"); - EXPECT_EQ(fmt::format("{:%S}", std::chrono::nanoseconds{-13420148734}), - "-13.420148734"); - EXPECT_EQ(fmt::format("{:%S}", std::chrono::milliseconds{1234}), "01.234"); - { - // Check that {:%H:%M:%S} is equivalent to {:%T}. - auto dur = std::chrono::milliseconds{3601234}; - auto formatted_dur = fmt::format("{:%T}", dur); - EXPECT_EQ(formatted_dur, "01:00:01.234"); - EXPECT_EQ(fmt::format("{:%H:%M:%S}", dur), formatted_dur); - } - using nanoseconds_dbl = std::chrono::duration<double, std::nano>; - EXPECT_EQ(fmt::format("{:%S}", nanoseconds_dbl{-123456789}), "-00.123456789"); - EXPECT_EQ(fmt::format("{:%S}", nanoseconds_dbl{9123456789}), "09.123456789"); - // Verify that only the seconds part is extracted and printed. - EXPECT_EQ(fmt::format("{:%S}", nanoseconds_dbl{99123456789}), "39.123456789"); - EXPECT_EQ(fmt::format("{:%S}", nanoseconds_dbl{99123000000}), "39.123000000"); - { - // Now the hour is printed, and we also test if negative doubles work. - auto dur = nanoseconds_dbl{-99123456789}; - auto formatted_dur = fmt::format("{:%T}", dur); - EXPECT_EQ(formatted_dur, "-00:01:39.123456789"); - EXPECT_EQ(fmt::format("{:%H:%M:%S}", dur), formatted_dur); - } - // Check that durations with precision greater than std::chrono::seconds have - // fixed precision, and print zeros even if there is no fractional part. - EXPECT_EQ(fmt::format("{:%S}", std::chrono::microseconds{7000000}), - "07.000000"); -} - -#endif // FMT_STATIC_THOUSANDS_SEPARATOR diff --git a/contrib/libs/fmt/test/chrono-test/ya.make b/contrib/libs/fmt/test/chrono-test/ya.make deleted file mode 100644 index c3f3bbd49e..0000000000 --- a/contrib/libs/fmt/test/chrono-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - chrono-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/color-test.cc b/contrib/libs/fmt/test/color-test.cc deleted file mode 100644 index af8f149426..0000000000 --- a/contrib/libs/fmt/test/color-test.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Formatting library for C++ - color tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/color.h" - -#include <iterator> // std::back_inserter - -#include "gtest-extra.h" // EXPECT_WRITE - -TEST(color_test, format) { - EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), - "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue"), - "\x1b[38;2;000;000;255mblue\x1b[0m"); - EXPECT_EQ( - fmt::format(fg(fmt::color::blue) | bg(fmt::color::red), "two color"), - "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold"), "\x1b[1mbold\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::faint, "faint"), "\x1b[2mfaint\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::italic, "italic"), - "\x1b[3mitalic\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::underline, "underline"), - "\x1b[4munderline\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::blink, "blink"), "\x1b[5mblink\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::reverse, "reverse"), - "\x1b[7mreverse\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::conceal, "conceal"), - "\x1b[8mconceal\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::strikethrough, "strikethrough"), - "\x1b[9mstrikethrough\x1b[0m"); - EXPECT_EQ( - fmt::format(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"), - "\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"), - "\x1b[1mbold error\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue log"), - "\x1b[38;2;000;000;255mblue log\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::text_style(), "hi"), "hi"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "tred"), - "\x1b[31mtred\x1b[0m"); - EXPECT_EQ(fmt::format(bg(fmt::terminal_color::cyan), "tcyan"), - "\x1b[46mtcyan\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::bright_green), "tbgreen"), - "\x1b[92mtbgreen\x1b[0m"); - EXPECT_EQ(fmt::format(bg(fmt::terminal_color::bright_magenta), "tbmagenta"), - "\x1b[105mtbmagenta\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "{}", "foo"), - "\x1b[31mfoo\x1b[0m"); -} - -TEST(color_test, format_to) { - auto out = std::string(); - fmt::format_to(std::back_inserter(out), fg(fmt::rgb(255, 20, 30)), - "rgb(255,20,30){}{}{}", 1, 2, 3); - EXPECT_EQ(fmt::to_string(out), - "\x1b[38;2;255;020;030mrgb(255,20,30)123\x1b[0m"); -} - -TEST(color_test, print) { - EXPECT_WRITE(stdout, fmt::print(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), - "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); -} diff --git a/contrib/libs/fmt/test/color-test/ya.make b/contrib/libs/fmt/test/color-test/ya.make deleted file mode 100644 index d526cd77cb..0000000000 --- a/contrib/libs/fmt/test/color-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - color-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/compile-fp-test.cc b/contrib/libs/fmt/test/compile-fp-test.cc deleted file mode 100644 index afedc26d06..0000000000 --- a/contrib/libs/fmt/test/compile-fp-test.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/compile.h" -#include "gmock/gmock.h" - -#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806 && \ - defined(__cpp_constexpr) && __cpp_constexpr >= 201907 && \ - defined(__cpp_constexpr_dynamic_alloc) && \ - __cpp_constexpr_dynamic_alloc >= 201907 && __cplusplus >= 202002L -template <size_t max_string_length, typename Char = char> struct test_string { - template <typename T> constexpr bool operator==(const T& rhs) const noexcept { - return fmt::basic_string_view<Char>(rhs).compare(buffer) == 0; - } - Char buffer[max_string_length]{}; -}; - -template <size_t max_string_length, typename Char = char, typename... Args> -consteval auto test_format(auto format, const Args&... args) { - test_string<max_string_length, Char> string{}; - fmt::format_to(string.buffer, format, args...); - return string; -} - -TEST(compile_time_formatting_test, floating_point) { - EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{}"), 0.0f)); - EXPECT_EQ("392.500000", test_format<11>(FMT_COMPILE("{0:f}"), 392.5f)); - - EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{:}"), 0.0)); - EXPECT_EQ("0.000000", test_format<9>(FMT_COMPILE("{:f}"), 0.0)); - EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{:g}"), 0.0)); - EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:}"), 392.65)); - EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:g}"), 392.65)); - EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:G}"), 392.65)); - EXPECT_EQ("4.9014e+06", test_format<11>(FMT_COMPILE("{:g}"), 4.9014e6)); - EXPECT_EQ("-392.650000", test_format<12>(FMT_COMPILE("{:f}"), -392.65)); - EXPECT_EQ("-392.650000", test_format<12>(FMT_COMPILE("{:F}"), -392.65)); - - EXPECT_EQ("3.926500e+02", test_format<13>(FMT_COMPILE("{0:e}"), 392.65)); - EXPECT_EQ("3.926500E+02", test_format<13>(FMT_COMPILE("{0:E}"), 392.65)); - EXPECT_EQ("+0000392.6", test_format<11>(FMT_COMPILE("{0:+010.4g}"), 392.65)); - EXPECT_EQ("9223372036854775808.000000", - test_format<27>(FMT_COMPILE("{:f}"), 9223372036854775807.0)); - - constexpr double nan = std::numeric_limits<double>::quiet_NaN(); - EXPECT_EQ("nan", test_format<4>(FMT_COMPILE("{}"), nan)); - EXPECT_EQ("+nan", test_format<5>(FMT_COMPILE("{:+}"), nan)); - if (std::signbit(-nan)) - EXPECT_EQ("-nan", test_format<5>(FMT_COMPILE("{}"), -nan)); - else - fmt::print("Warning: compiler doesn't handle negative NaN correctly"); - - constexpr double inf = std::numeric_limits<double>::infinity(); - EXPECT_EQ("inf", test_format<4>(FMT_COMPILE("{}"), inf)); - EXPECT_EQ("+inf", test_format<5>(FMT_COMPILE("{:+}"), inf)); - EXPECT_EQ("-inf", test_format<5>(FMT_COMPILE("{}"), -inf)); -} -#endif diff --git a/contrib/libs/fmt/test/compile-fp-test/ya.make b/contrib/libs/fmt/test/compile-fp-test/ya.make deleted file mode 100644 index 35f77d31a5..0000000000 --- a/contrib/libs/fmt/test/compile-fp-test/ya.make +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -ADDINCL( - contrib/libs/fmt/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_HEADER_ONLY=1 - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt) - -SRCS( - src/os.cc - test/compile-fp-test.cc - test/gtest-extra.cc - test/util.cc -) - -END() diff --git a/contrib/libs/fmt/test/compile-test.cc b/contrib/libs/fmt/test/compile-test.cc deleted file mode 100644 index 1765961b89..0000000000 --- a/contrib/libs/fmt/test/compile-test.cc +++ /dev/null @@ -1,376 +0,0 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/compile.h" - -#include <type_traits> - -#include "fmt/chrono.h" -#include "gmock/gmock.h" -#include "gtest-extra.h" - -TEST(iterator_test, counting_iterator) { - auto it = fmt::detail::counting_iterator(); - auto prev = it++; - EXPECT_EQ(prev.count(), 0); - EXPECT_EQ(it.count(), 1); - EXPECT_EQ((it + 41).count(), 42); -} - -TEST(iterator_test, truncating_iterator) { - char* p = nullptr; - auto it = fmt::detail::truncating_iterator<char*>(p, 3); - auto prev = it++; - EXPECT_EQ(prev.base(), p); - EXPECT_EQ(it.base(), p + 1); -} - -TEST(iterator_test, truncating_iterator_default_construct) { - auto it = fmt::detail::truncating_iterator<char*>(); - EXPECT_EQ(nullptr, it.base()); - EXPECT_EQ(std::size_t{0}, it.count()); -} - -#ifdef __cpp_lib_ranges -TEST(iterator_test, truncating_iterator_is_output_iterator) { - static_assert( - std::output_iterator<fmt::detail::truncating_iterator<char*>, char>); -} -#endif - -TEST(iterator_test, truncating_back_inserter) { - auto buffer = std::string(); - auto bi = std::back_inserter(buffer); - auto it = fmt::detail::truncating_iterator<decltype(bi)>(bi, 2); - *it++ = '4'; - *it++ = '2'; - *it++ = '1'; - EXPECT_EQ(buffer.size(), 2); - EXPECT_EQ(buffer, "42"); -} - -TEST(compile_test, compile_fallback) { - // FMT_COMPILE should fallback on runtime formatting when `if constexpr` is - // not available. - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42)); -} - -struct type_with_get { - template <int> friend void get(type_with_get); -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<type_with_get> : formatter<int> { - template <typename FormatContext> - auto format(type_with_get, FormatContext& ctx) -> decltype(ctx.out()) { - return formatter<int>::format(42, ctx); - } -}; -FMT_END_NAMESPACE - -TEST(compile_test, compile_type_with_get) { - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), type_with_get())); -} - -#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) -struct test_formattable {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<test_formattable> : formatter<const char*> { - char word_spec = 'f'; - constexpr auto parse(format_parse_context& ctx) { - auto it = ctx.begin(), end = ctx.end(); - if (it == end || *it == '}') return it; - if (it != end && (*it == 'f' || *it == 'b')) word_spec = *it++; - if (it != end && *it != '}') throw format_error("invalid format"); - return it; - } - template <typename FormatContext> - constexpr auto format(test_formattable, FormatContext& ctx) const - -> decltype(ctx.out()) { - return formatter<const char*>::format(word_spec == 'f' ? "foo" : "bar", - ctx); - } -}; -FMT_END_NAMESPACE - -TEST(compile_test, format_default) { - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42)); - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42u)); - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42ll)); - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42ull)); - EXPECT_EQ("true", fmt::format(FMT_COMPILE("{}"), true)); - EXPECT_EQ("x", fmt::format(FMT_COMPILE("{}"), 'x')); - EXPECT_EQ("4.2", fmt::format(FMT_COMPILE("{}"), 4.2)); - EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), "foo")); - EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), std::string("foo"))); - EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), test_formattable())); - auto t = std::chrono::system_clock::now(); - EXPECT_EQ(fmt::format("{}", t), fmt::format(FMT_COMPILE("{}"), t)); -# ifdef __cpp_lib_byte - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), std::byte{42})); -# endif -} - -TEST(compile_test, format_wide_string) { - EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{}"), 42)); -} - -TEST(compile_test, format_specs) { - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42)); - EXPECT_EQ("1.2 ms ", - fmt::format(FMT_COMPILE("{:7.1%Q %q}"), - std::chrono::duration<double, std::milli>(1.234))); -} - -TEST(compile_test, dynamic_format_specs) { - EXPECT_EQ("foo ", fmt::format(FMT_COMPILE("{:{}}"), "foo", 5)); - EXPECT_EQ(" 3.14", fmt::format(FMT_COMPILE("{:{}.{}f}"), 3.141592, 6, 2)); - EXPECT_EQ( - "=1.234ms=", - fmt::format(FMT_COMPILE("{:=^{}.{}}"), - std::chrono::duration<double, std::milli>(1.234), 9, 3)); -} - -TEST(compile_test, manual_ordering) { - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{0}"), 42)); - EXPECT_EQ(" -42", fmt::format(FMT_COMPILE("{0:4}"), -42)); - EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{0} {1}"), 41, 43)); - EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{1} {0}"), 43, 41)); - EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{0} {2}"), 41, 42, 43)); - EXPECT_EQ(" 41 43", fmt::format(FMT_COMPILE("{1:{2}} {0:4}"), 43, 41, 4)); - EXPECT_EQ("42 1.2 ms ", - fmt::format(FMT_COMPILE("{0} {1:7.1%Q %q}"), 42, - std::chrono::duration<double, std::milli>(1.234))); - EXPECT_EQ( - "true 42 42 foo 0x1234 foo", - fmt::format(FMT_COMPILE("{0} {1} {2} {3} {4} {5}"), true, 42, 42.0f, - "foo", reinterpret_cast<void*>(0x1234), test_formattable())); - EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{0}"), 42)); -} - -TEST(compile_test, named) { - auto runtime_named_field_compiled = - fmt::detail::compile<decltype(fmt::arg("arg", 42))>(FMT_COMPILE("{arg}")); - static_assert(std::is_same_v<decltype(runtime_named_field_compiled), - fmt::detail::runtime_named_field<char>>); - - EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), fmt::arg("arg", 42))); - EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{} {}"), fmt::arg("arg", 41), - fmt::arg("arg", 43))); - - EXPECT_EQ("foobar", - fmt::format(FMT_COMPILE("{a0}{a1}"), fmt::arg("a0", "foo"), - fmt::arg("a1", "bar"))); - EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{}{a1}"), fmt::arg("a0", "foo"), - fmt::arg("a1", "bar"))); - EXPECT_EQ("foofoo", fmt::format(FMT_COMPILE("{a0}{}"), fmt::arg("a0", "foo"), - fmt::arg("a1", "bar"))); - EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{0}{a1}"), fmt::arg("a0", "foo"), - fmt::arg("a1", "bar"))); - EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{a0}{1}"), fmt::arg("a0", "foo"), - fmt::arg("a1", "bar"))); - - EXPECT_EQ("foobar", - fmt::format(FMT_COMPILE("{}{a1}"), "foo", fmt::arg("a1", "bar"))); - EXPECT_EQ("foobar", - fmt::format(FMT_COMPILE("{a0}{a1}"), fmt::arg("a1", "bar"), - fmt::arg("a2", "baz"), fmt::arg("a0", "foo"))); - EXPECT_EQ(" bar foo ", - fmt::format(FMT_COMPILE(" {foo} {bar} "), fmt::arg("foo", "bar"), - fmt::arg("bar", "foo"))); - - EXPECT_THROW(fmt::format(FMT_COMPILE("{invalid}"), fmt::arg("valid", 42)), - fmt::format_error); - -# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS - using namespace fmt::literals; - auto statically_named_field_compiled = - fmt::detail::compile<decltype("arg"_a = 42)>(FMT_COMPILE("{arg}")); - static_assert(std::is_same_v<decltype(statically_named_field_compiled), - fmt::detail::field<char, int, 0>>); - - EXPECT_EQ("41 43", - fmt::format(FMT_COMPILE("{a0} {a1}"), "a0"_a = 41, "a1"_a = 43)); - EXPECT_EQ("41 43", - fmt::format(FMT_COMPILE("{a1} {a0}"), "a0"_a = 43, "a1"_a = 41)); -# endif -} - -TEST(compile_test, format_to) { - char buf[8]; - auto end = fmt::format_to(buf, FMT_COMPILE("{}"), 42); - *end = '\0'; - EXPECT_STREQ("42", buf); - end = fmt::format_to(buf, FMT_COMPILE("{:x}"), 42); - *end = '\0'; - EXPECT_STREQ("2a", buf); -} - -TEST(compile_test, format_to_n) { - constexpr auto buffer_size = 8; - char buffer[buffer_size]; - auto res = fmt::format_to_n(buffer, buffer_size, FMT_COMPILE("{}"), 42); - *res.out = '\0'; - EXPECT_STREQ("42", buffer); - res = fmt::format_to_n(buffer, buffer_size, FMT_COMPILE("{:x}"), 42); - *res.out = '\0'; - EXPECT_STREQ("2a", buffer); -} - -TEST(compile_test, formatted_size) { - EXPECT_EQ(2, fmt::formatted_size(FMT_COMPILE("{0}"), 42)); - EXPECT_EQ(5, fmt::formatted_size(FMT_COMPILE("{0:<4.2f}"), 42.0)); -} - -TEST(compile_test, text_and_arg) { - EXPECT_EQ(">>>42<<<", fmt::format(FMT_COMPILE(">>>{}<<<"), 42)); - EXPECT_EQ("42!", fmt::format(FMT_COMPILE("{}!"), 42)); -} - -TEST(compile_test, unknown_format_fallback) { - EXPECT_EQ(" 42 ", - fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42))); - - std::vector<char> v; - fmt::format_to(std::back_inserter(v), FMT_COMPILE("{name:^4}"), - fmt::arg("name", 42)); - EXPECT_EQ(" 42 ", fmt::string_view(v.data(), v.size())); - - char buffer[4]; - auto result = fmt::format_to_n(buffer, 4, FMT_COMPILE("{name:^5}"), - fmt::arg("name", 42)); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 4, result.out); - EXPECT_EQ(" 42 ", fmt::string_view(buffer, 4)); -} - -TEST(compile_test, empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); } - -struct to_stringable { - friend fmt::string_view to_string_view(to_stringable) { return {}; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<to_stringable> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename FormatContext> - auto format(const to_stringable&, FormatContext& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(compile_test, to_string_and_formatter) { - fmt::format(FMT_COMPILE("{}"), to_stringable()); -} - -TEST(compile_test, print) { - EXPECT_WRITE(stdout, fmt::print(FMT_COMPILE("Don't {}!"), "panic"), - "Don't panic!"); - EXPECT_WRITE(stderr, fmt::print(stderr, FMT_COMPILE("Don't {}!"), "panic"), - "Don't panic!"); -} -#endif - -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -TEST(compile_test, compile_format_string_literal) { - using namespace fmt::literals; - EXPECT_EQ("", fmt::format(""_cf)); - EXPECT_EQ("42", fmt::format("{}"_cf, 42)); - EXPECT_EQ(L"42", fmt::format(L"{}"_cf, 42)); -} -#endif - -#if __cplusplus >= 202002L || \ - (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002) -template <size_t max_string_length, typename Char = char> struct test_string { - template <typename T> constexpr bool operator==(const T& rhs) const noexcept { - return fmt::basic_string_view<Char>(rhs).compare(buffer) == 0; - } - Char buffer[max_string_length]{}; -}; - -template <size_t max_string_length, typename Char = char, typename... Args> -consteval auto test_format(auto format, const Args&... args) { - test_string<max_string_length, Char> string{}; - fmt::format_to(string.buffer, format, args...); - return string; -} - -TEST(compile_time_formatting_test, bool) { - EXPECT_EQ("true", test_format<5>(FMT_COMPILE("{}"), true)); - EXPECT_EQ("false", test_format<6>(FMT_COMPILE("{}"), false)); - EXPECT_EQ("true ", test_format<6>(FMT_COMPILE("{:5}"), true)); - EXPECT_EQ("1", test_format<2>(FMT_COMPILE("{:d}"), true)); -} - -TEST(compile_time_formatting_test, integer) { - EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), 42)); - EXPECT_EQ("420", test_format<4>(FMT_COMPILE("{}"), 420)); - EXPECT_EQ("42 42", test_format<6>(FMT_COMPILE("{} {}"), 42, 42)); - EXPECT_EQ("42 42", - test_format<6>(FMT_COMPILE("{} {}"), uint32_t{42}, uint64_t{42})); - - EXPECT_EQ("+42", test_format<4>(FMT_COMPILE("{:+}"), 42)); - EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{:-}"), 42)); - EXPECT_EQ(" 42", test_format<4>(FMT_COMPILE("{: }"), 42)); - - EXPECT_EQ("-0042", test_format<6>(FMT_COMPILE("{:05}"), -42)); - - EXPECT_EQ("101010", test_format<7>(FMT_COMPILE("{:b}"), 42)); - EXPECT_EQ("0b101010", test_format<9>(FMT_COMPILE("{:#b}"), 42)); - EXPECT_EQ("0B101010", test_format<9>(FMT_COMPILE("{:#B}"), 42)); - EXPECT_EQ("042", test_format<4>(FMT_COMPILE("{:#o}"), 042)); - EXPECT_EQ("0x4a", test_format<5>(FMT_COMPILE("{:#x}"), 0x4a)); - EXPECT_EQ("0X4A", test_format<5>(FMT_COMPILE("{:#X}"), 0x4a)); - - EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42)); - EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42ll)); - EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42ull)); - - EXPECT_EQ("42 ", test_format<5>(FMT_COMPILE("{:<4}"), 42)); - EXPECT_EQ(" 42", test_format<5>(FMT_COMPILE("{:>4}"), 42)); - EXPECT_EQ(" 42 ", test_format<5>(FMT_COMPILE("{:^4}"), 42)); - EXPECT_EQ("**-42", test_format<6>(FMT_COMPILE("{:*>5}"), -42)); -} - -TEST(compile_time_formatting_test, char) { - EXPECT_EQ("c", test_format<2>(FMT_COMPILE("{}"), 'c')); - - EXPECT_EQ("c ", test_format<4>(FMT_COMPILE("{:3}"), 'c')); - EXPECT_EQ("99", test_format<3>(FMT_COMPILE("{:d}"), 'c')); -} - -TEST(compile_time_formatting_test, string) { - EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), "42")); - EXPECT_EQ("The answer is 42", - test_format<17>(FMT_COMPILE("{} is {}"), "The answer", "42")); - - EXPECT_EQ("abc**", test_format<6>(FMT_COMPILE("{:*<5}"), "abc")); - EXPECT_EQ("**🤡**", test_format<9>(FMT_COMPILE("{:*^6}"), "🤡")); -} - -TEST(compile_time_formatting_test, combination) { - EXPECT_EQ("420, true, answer", - test_format<18>(FMT_COMPILE("{}, {}, {}"), 420, true, "answer")); - - EXPECT_EQ(" -42", test_format<5>(FMT_COMPILE("{:{}}"), -42, 4)); -} - -TEST(compile_time_formatting_test, custom_type) { - EXPECT_EQ("foo", test_format<4>(FMT_COMPILE("{}"), test_formattable())); - EXPECT_EQ("bar", test_format<4>(FMT_COMPILE("{:b}"), test_formattable())); -} - -TEST(compile_time_formatting_test, multibyte_fill) { - EXPECT_EQ("жж42", test_format<8>(FMT_COMPILE("{:ж>4}"), 42)); -} -#endif diff --git a/contrib/libs/fmt/test/compile-test/ya.make b/contrib/libs/fmt/test/compile-test/ya.make deleted file mode 100644 index d75f41a908..0000000000 --- a/contrib/libs/fmt/test/compile-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - compile-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/core-test.cc b/contrib/libs/fmt/test/core-test.cc deleted file mode 100644 index b2f2097ea1..0000000000 --- a/contrib/libs/fmt/test/core-test.cc +++ /dev/null @@ -1,923 +0,0 @@ -// Formatting library for C++ - core tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -// clang-format off -#include "test-assert.h" -// clang-format on - -#include "fmt/core.h" - -#include <algorithm> // std::copy_n -#include <climits> // INT_MAX -#include <cstring> // std::strlen -#include <functional> // std::equal_to -#include <iterator> // std::back_insert_iterator -#include <limits> // std::numeric_limits -#include <string> // std::string -#include <type_traits> // std::is_same - -#include "gmock/gmock.h" - -using fmt::string_view; -using fmt::detail::buffer; - -using testing::_; -using testing::Invoke; -using testing::Return; - -#ifdef FMT_FORMAT_H_ -# error core-test includes format.h -#endif - -TEST(string_view_test, value_type) { - static_assert(std::is_same<string_view::value_type, char>::value, ""); -} - -TEST(string_view_test, ctor) { - EXPECT_STREQ("abc", fmt::string_view("abc").data()); - EXPECT_EQ(3u, fmt::string_view("abc").size()); - - EXPECT_STREQ("defg", fmt::string_view(std::string("defg")).data()); - EXPECT_EQ(4u, fmt::string_view(std::string("defg")).size()); -} - -TEST(string_view_test, length) { - // Test that string_view::size() returns string length, not buffer size. - char str[100] = "some string"; - EXPECT_EQ(std::strlen(str), string_view(str).size()); - EXPECT_LT(std::strlen(str), sizeof(str)); -} - -// Check string_view's comparison operator. -template <template <typename> class Op> void check_op() { - const char* inputs[] = {"foo", "fop", "fo"}; - size_t num_inputs = sizeof(inputs) / sizeof(*inputs); - for (size_t i = 0; i < num_inputs; ++i) { - for (size_t j = 0; j < num_inputs; ++j) { - string_view lhs(inputs[i]), rhs(inputs[j]); - EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs)); - } - } -} - -TEST(string_view_test, compare) { - EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0); - EXPECT_GT(string_view("fop").compare(string_view("foo")), 0); - EXPECT_LT(string_view("foo").compare(string_view("fop")), 0); - EXPECT_GT(string_view("foo").compare(string_view("fo")), 0); - EXPECT_LT(string_view("fo").compare(string_view("foo")), 0); - check_op<std::equal_to>(); - check_op<std::not_equal_to>(); - check_op<std::less>(); - check_op<std::less_equal>(); - check_op<std::greater>(); - check_op<std::greater_equal>(); -} - -namespace test_ns { -template <typename Char> class test_string { - private: - std::basic_string<Char> s_; - - public: - test_string(const Char* s) : s_(s) {} - const Char* data() const { return s_.data(); } - size_t length() const { return s_.size(); } - operator const Char*() const { return s_.c_str(); } -}; - -template <typename Char> -fmt::basic_string_view<Char> to_string_view(const test_string<Char>& s) { - return {s.data(), s.length()}; -} -} // namespace test_ns - -TEST(core_test, is_output_iterator) { - EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value)); - EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value)); - EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value)); - EXPECT_TRUE( - (fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>, - char>::value)); - EXPECT_TRUE( - (fmt::detail::is_output_iterator<std::string::iterator, char>::value)); - EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator, - char>::value)); -} - -TEST(core_test, buffer_appender) { - // back_insert_iterator is not default-constructible before C++20, so - // buffer_appender can only be default-constructible when back_insert_iterator - // is. - static_assert( - std::is_default_constructible< - std::back_insert_iterator<fmt::detail::buffer<char>>>::value == - std::is_default_constructible< - fmt::detail::buffer_appender<char>>::value, - ""); - -#ifdef __cpp_lib_ranges - static_assert(std::output_iterator<fmt::detail::buffer_appender<char>, char>); -#endif -} - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470 -TEST(buffer_test, noncopyable) { - EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value); -# if !FMT_MSC_VER - // std::is_copy_assignable is broken in MSVC2013. - EXPECT_FALSE(std::is_copy_assignable<buffer<char>>::value); -# endif -} - -TEST(buffer_test, nonmoveable) { - EXPECT_FALSE(std::is_move_constructible<buffer<char>>::value); -# if !FMT_MSC_VER - // std::is_move_assignable is broken in MSVC2013. - EXPECT_FALSE(std::is_move_assignable<buffer<char>>::value); -# endif -} -#endif - -TEST(buffer_test, indestructible) { - static_assert(!std::is_destructible<fmt::detail::buffer<int>>(), - "buffer's destructor is protected"); -} - -template <typename T> struct mock_buffer final : buffer<T> { - MOCK_METHOD1(do_grow, size_t(size_t capacity)); - - void grow(size_t capacity) override { - this->set(this->data(), do_grow(capacity)); - } - - mock_buffer(T* data = nullptr, size_t buf_capacity = 0) { - this->set(data, buf_capacity); - ON_CALL(*this, do_grow(_)).WillByDefault(Invoke([](size_t capacity) { - return capacity; - })); - } -}; - -TEST(buffer_test, ctor) { - { - mock_buffer<int> buffer; - EXPECT_EQ(nullptr, buffer.data()); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); - } - { - int dummy; - mock_buffer<int> buffer(&dummy); - EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); - } - { - int dummy; - size_t capacity = std::numeric_limits<size_t>::max(); - mock_buffer<int> buffer(&dummy, capacity); - EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(capacity, buffer.capacity()); - } -} - -TEST(buffer_test, access) { - char data[10]; - mock_buffer<char> buffer(data, sizeof(data)); - buffer[0] = 11; - EXPECT_EQ(11, buffer[0]); - buffer[3] = 42; - EXPECT_EQ(42, *(&buffer[0] + 3)); - const fmt::detail::buffer<char>& const_buffer = buffer; - EXPECT_EQ(42, const_buffer[3]); -} - -TEST(buffer_test, try_resize) { - char data[123]; - mock_buffer<char> buffer(data, sizeof(data)); - buffer[10] = 42; - EXPECT_EQ(42, buffer[10]); - buffer.try_resize(20); - EXPECT_EQ(20u, buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); - EXPECT_EQ(42, buffer[10]); - buffer.try_resize(5); - EXPECT_EQ(5u, buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); - EXPECT_EQ(42, buffer[10]); - // Check if try_resize calls grow. - EXPECT_CALL(buffer, do_grow(124)); - buffer.try_resize(124); - EXPECT_CALL(buffer, do_grow(200)); - buffer.try_resize(200); -} - -TEST(buffer_test, try_resize_partial) { - char data[10]; - mock_buffer<char> buffer(data, sizeof(data)); - EXPECT_CALL(buffer, do_grow(20)).WillOnce(Return(15)); - buffer.try_resize(20); - EXPECT_EQ(buffer.capacity(), 15); - EXPECT_EQ(buffer.size(), 15); -} - -TEST(buffer_test, clear) { - mock_buffer<char> buffer; - EXPECT_CALL(buffer, do_grow(20)); - buffer.try_resize(20); - buffer.try_resize(0); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(20u, buffer.capacity()); -} - -TEST(buffer_test, append) { - char data[15]; - mock_buffer<char> buffer(data, 10); - auto test = "test"; - buffer.append(test, test + 5); - EXPECT_STREQ(test, &buffer[0]); - EXPECT_EQ(5u, buffer.size()); - buffer.try_resize(10); - EXPECT_CALL(buffer, do_grow(12)); - buffer.append(test, test + 2); - EXPECT_EQ('t', buffer[10]); - EXPECT_EQ('e', buffer[11]); - EXPECT_EQ(12u, buffer.size()); -} - -TEST(buffer_test, append_partial) { - char data[10]; - mock_buffer<char> buffer(data, sizeof(data)); - testing::InSequence seq; - EXPECT_CALL(buffer, do_grow(15)).WillOnce(Return(10)); - EXPECT_CALL(buffer, do_grow(15)).WillOnce(Invoke([&buffer](size_t) { - EXPECT_EQ(fmt::string_view(buffer.data(), buffer.size()), "0123456789"); - buffer.clear(); - return 10; - })); - auto test = "0123456789abcde"; - buffer.append(test, test + 15); -} - -TEST(buffer_test, append_allocates_enough_storage) { - char data[19]; - mock_buffer<char> buffer(data, 10); - auto test = "abcdefgh"; - buffer.try_resize(10); - EXPECT_CALL(buffer, do_grow(19)); - buffer.append(test, test + 9); -} - -struct custom_context { - using char_type = char; - using parse_context_type = fmt::format_parse_context; - - bool called = false; - - template <typename T> struct formatter_type { - auto parse(fmt::format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - const char* format(const T&, custom_context& ctx) { - ctx.called = true; - return nullptr; - } - }; - - void advance_to(const char*) {} -}; - -struct test_struct {}; - -FMT_BEGIN_NAMESPACE -template <typename Char> struct formatter<test_struct, Char> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - auto format(test_struct, format_context& ctx) -> decltype(ctx.out()) { - auto test = string_view("test"); - return std::copy_n(test.data(), test.size(), ctx.out()); - } -}; -FMT_END_NAMESPACE - -TEST(arg_test, format_args) { - auto args = fmt::format_args(); - EXPECT_FALSE(args.get(1)); -} - -TEST(arg_test, make_value_with_custom_context) { - auto t = test_struct(); - fmt::detail::value<custom_context> arg( - fmt::detail::arg_mapper<custom_context>().map(t)); - auto ctx = custom_context(); - auto parse_ctx = fmt::format_parse_context(""); - arg.custom.format(&t, parse_ctx, ctx); - EXPECT_TRUE(ctx.called); -} - -// Use a unique result type to make sure that there are no undesirable -// conversions. -struct test_result {}; - -template <typename T> struct mock_visitor { - template <typename U> struct result { using type = test_result; }; - - mock_visitor() { - ON_CALL(*this, visit(_)).WillByDefault(Return(test_result())); - } - - MOCK_METHOD1_T(visit, test_result(T value)); - MOCK_METHOD0_T(unexpected, void()); - - test_result operator()(T value) { return visit(value); } - - template <typename U> test_result operator()(U) { - unexpected(); - return test_result(); - } -}; - -template <typename T> struct visit_type { using type = T; }; - -#define VISIT_TYPE(type_, visit_type_) \ - template <> struct visit_type<type_> { using type = visit_type_; } - -VISIT_TYPE(signed char, int); -VISIT_TYPE(unsigned char, unsigned); -VISIT_TYPE(short, int); -VISIT_TYPE(unsigned short, unsigned); - -#if LONG_MAX == INT_MAX -VISIT_TYPE(long, int); -VISIT_TYPE(unsigned long, unsigned); -#else -VISIT_TYPE(long, long long); -VISIT_TYPE(unsigned long, unsigned long long); -#endif - -#define CHECK_ARG(Char, expected, value) \ - { \ - testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \ - EXPECT_CALL(visitor, visit(expected)); \ - using iterator = std::back_insert_iterator<buffer<Char>>; \ - fmt::visit_format_arg( \ - visitor, \ - fmt::detail::make_arg<fmt::basic_format_context<iterator, Char>>( \ - value)); \ - } - -#define CHECK_ARG_SIMPLE(value) \ - { \ - using value_type = decltype(value); \ - typename visit_type<value_type>::type expected = value; \ - CHECK_ARG(char, expected, value) \ - CHECK_ARG(wchar_t, expected, value) \ - } - -template <typename T> class numeric_arg_test : public testing::Test {}; - -using types = - testing::Types<bool, signed char, unsigned char, short, unsigned short, int, - unsigned, long, unsigned long, long long, unsigned long long, - float, double, long double>; -TYPED_TEST_SUITE(numeric_arg_test, types); - -template <typename T, fmt::enable_if_t<std::is_integral<T>::value, int> = 0> -T test_value() { - return static_cast<T>(42); -} - -template <typename T, - fmt::enable_if_t<std::is_floating_point<T>::value, int> = 0> -T test_value() { - return static_cast<T>(4.2); -} - -TYPED_TEST(numeric_arg_test, make_and_visit) { - CHECK_ARG_SIMPLE(test_value<TypeParam>()); - CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::min()); - CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::max()); -} - -TEST(arg_test, char_arg) { CHECK_ARG(char, 'a', 'a'); } - -TEST(arg_test, string_arg) { - char str_data[] = "test"; - char* str = str_data; - const char* cstr = str; - CHECK_ARG(char, cstr, str); - - auto sv = fmt::string_view(str); - CHECK_ARG(char, sv, std::string(str)); -} - -TEST(arg_test, wstring_arg) { - wchar_t str_data[] = L"test"; - wchar_t* str = str_data; - const wchar_t* cstr = str; - - auto sv = fmt::basic_string_view<wchar_t>(str); - CHECK_ARG(wchar_t, cstr, str); - CHECK_ARG(wchar_t, cstr, cstr); - CHECK_ARG(wchar_t, sv, std::wstring(str)); - CHECK_ARG(wchar_t, sv, fmt::basic_string_view<wchar_t>(str)); -} - -TEST(arg_test, pointer_arg) { - void* p = nullptr; - const void* cp = nullptr; - CHECK_ARG(char, cp, p); - CHECK_ARG(wchar_t, cp, p); - CHECK_ARG_SIMPLE(cp); -} - -struct check_custom { - test_result operator()( - fmt::basic_format_arg<fmt::format_context>::handle h) const { - struct test_buffer final : fmt::detail::buffer<char> { - char data[10]; - test_buffer() : fmt::detail::buffer<char>(data, 0, 10) {} - void grow(size_t) override {} - } buffer; - auto parse_ctx = fmt::format_parse_context(""); - auto ctx = fmt::format_context(fmt::detail::buffer_appender<char>(buffer), - fmt::format_args()); - h.format(parse_ctx, ctx); - EXPECT_EQ("test", std::string(buffer.data, buffer.size())); - return test_result(); - } -}; - -TEST(arg_test, custom_arg) { - auto test = test_struct(); - using visitor = - mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>; - testing::StrictMock<visitor> v; - EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom())); - fmt::visit_format_arg(v, fmt::detail::make_arg<fmt::format_context>(test)); -} - -TEST(arg_test, visit_invalid_arg) { - testing::StrictMock<mock_visitor<fmt::monostate>> visitor; - EXPECT_CALL(visitor, visit(_)); - auto arg = fmt::basic_format_arg<fmt::format_context>(); - fmt::visit_format_arg(visitor, arg); -} - -#if FMT_USE_CONSTEXPR - -enum class arg_id_result { none, empty, index, name, error }; -struct test_arg_id_handler { - arg_id_result res = arg_id_result::none; - int index = 0; - string_view name; - - constexpr void operator()() { res = arg_id_result::empty; } - - constexpr void operator()(int i) { - res = arg_id_result::index; - index = i; - } - - constexpr void operator()(string_view n) { - res = arg_id_result::name; - name = n; - } - - constexpr void on_error(const char*) { res = arg_id_result::error; } -}; - -template <size_t N> -constexpr test_arg_id_handler parse_arg_id(const char (&s)[N]) { - test_arg_id_handler h; - fmt::detail::parse_arg_id(s, s + N, h); - return h; -} - -TEST(format_test, constexpr_parse_arg_id) { - static_assert(parse_arg_id(":").res == arg_id_result::empty, ""); - static_assert(parse_arg_id("}").res == arg_id_result::empty, ""); - static_assert(parse_arg_id("42:").res == arg_id_result::index, ""); - static_assert(parse_arg_id("42:").index == 42, ""); - static_assert(parse_arg_id("foo:").res == arg_id_result::name, ""); - static_assert(parse_arg_id("foo:").name.size() == 3, ""); - static_assert(parse_arg_id("!").res == arg_id_result::error, ""); -} - -struct test_format_specs_handler { - enum result { none, hash, zero, loc, error }; - result res = none; - - fmt::align_t alignment = fmt::align::none; - fmt::sign_t sign = fmt::sign::none; - char fill = 0; - int width = 0; - fmt::detail::arg_ref<char> width_ref; - int precision = 0; - fmt::detail::arg_ref<char> precision_ref; - fmt::presentation_type type = fmt::presentation_type::none; - - // Workaround for MSVC2017 bug that results in "expression did not evaluate - // to a constant" with compiler-generated copy ctor. - constexpr test_format_specs_handler() {} - constexpr test_format_specs_handler(const test_format_specs_handler& other) = - default; - - constexpr void on_align(fmt::align_t a) { alignment = a; } - constexpr void on_fill(fmt::string_view f) { fill = f[0]; } - constexpr void on_sign(fmt::sign_t s) { sign = s; } - constexpr void on_hash() { res = hash; } - constexpr void on_zero() { res = zero; } - constexpr void on_localized() { res = loc; } - - constexpr void on_width(int w) { width = w; } - constexpr void on_dynamic_width(fmt::detail::auto_id) {} - constexpr void on_dynamic_width(int index) { width_ref = index; } - constexpr void on_dynamic_width(string_view) {} - - constexpr void on_precision(int p) { precision = p; } - constexpr void on_dynamic_precision(fmt::detail::auto_id) {} - constexpr void on_dynamic_precision(int index) { precision_ref = index; } - constexpr void on_dynamic_precision(string_view) {} - - constexpr void end_precision() {} - constexpr void on_type(fmt::presentation_type t) { type = t; } - constexpr void on_error(const char*) { res = error; } -}; - -template <size_t N> -constexpr test_format_specs_handler parse_test_specs(const char (&s)[N]) { - auto h = test_format_specs_handler(); - fmt::detail::parse_format_specs(s, s + N - 1, h); - return h; -} - -TEST(core_test, constexpr_parse_format_specs) { - using handler = test_format_specs_handler; - static_assert(parse_test_specs("<").alignment == fmt::align::left, ""); - static_assert(parse_test_specs("*^").fill == '*', ""); - static_assert(parse_test_specs("+").sign == fmt::sign::plus, ""); - static_assert(parse_test_specs("-").sign == fmt::sign::minus, ""); - static_assert(parse_test_specs(" ").sign == fmt::sign::space, ""); - static_assert(parse_test_specs("#").res == handler::hash, ""); - static_assert(parse_test_specs("0").res == handler::zero, ""); - static_assert(parse_test_specs("L").res == handler::loc, ""); - static_assert(parse_test_specs("42").width == 42, ""); - static_assert(parse_test_specs("{42}").width_ref.val.index == 42, ""); - static_assert(parse_test_specs(".42").precision == 42, ""); - static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(parse_test_specs("d").type == fmt::presentation_type::dec, ""); - static_assert(parse_test_specs("{<").res == handler::error, ""); -} - -struct test_parse_context { - using char_type = char; - - constexpr int next_arg_id() { return 11; } - template <typename Id> FMT_CONSTEXPR void check_arg_id(Id) {} - - constexpr const char* begin() { return nullptr; } - constexpr const char* end() { return nullptr; } - - void on_error(const char*) {} -}; - -template <size_t N> -constexpr fmt::detail::dynamic_format_specs<char> parse_dynamic_specs( - const char (&s)[N]) { - auto specs = fmt::detail::dynamic_format_specs<char>(); - auto ctx = test_parse_context(); - auto h = fmt::detail::dynamic_specs_handler<test_parse_context>(specs, ctx); - parse_format_specs(s, s + N - 1, h); - return specs; -} - -TEST(format_test, constexpr_dynamic_specs_handler) { - static_assert(parse_dynamic_specs("<").align == fmt::align::left, ""); - static_assert(parse_dynamic_specs("*^").fill[0] == '*', ""); - static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, ""); - static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, ""); - static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, ""); - static_assert(parse_dynamic_specs("#").alt, ""); - static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, ""); - static_assert(parse_dynamic_specs("42").width == 42, ""); - static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, ""); - static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, ""); - static_assert(parse_dynamic_specs(".42").precision == 42, ""); - static_assert(parse_dynamic_specs(".{}").precision_ref.val.index == 11, ""); - static_assert(parse_dynamic_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(parse_dynamic_specs("d").type == fmt::presentation_type::dec, - ""); -} - -template <size_t N> -constexpr test_format_specs_handler check_specs(const char (&s)[N]) { - fmt::detail::specs_checker<test_format_specs_handler> checker( - test_format_specs_handler(), fmt::detail::type::double_type); - parse_format_specs(s, s + N - 1, checker); - return checker; -} - -TEST(format_test, constexpr_specs_checker) { - using handler = test_format_specs_handler; - static_assert(check_specs("<").alignment == fmt::align::left, ""); - static_assert(check_specs("*^").fill == '*', ""); - static_assert(check_specs("+").sign == fmt::sign::plus, ""); - static_assert(check_specs("-").sign == fmt::sign::minus, ""); - static_assert(check_specs(" ").sign == fmt::sign::space, ""); - static_assert(check_specs("#").res == handler::hash, ""); - static_assert(check_specs("0").res == handler::zero, ""); - static_assert(check_specs("42").width == 42, ""); - static_assert(check_specs("{42}").width_ref.val.index == 42, ""); - static_assert(check_specs(".42").precision == 42, ""); - static_assert(check_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(check_specs("d").type == fmt::presentation_type::dec, ""); - static_assert(check_specs("{<").res == handler::error, ""); -} - -struct test_format_string_handler { - constexpr void on_text(const char*, const char*) {} - - constexpr int on_arg_id() { return 0; } - - template <typename T> constexpr int on_arg_id(T) { return 0; } - - constexpr void on_replacement_field(int, const char*) {} - - constexpr const char* on_format_specs(int, const char* begin, const char*) { - return begin; - } - - constexpr void on_error(const char*) { error = true; } - - bool error = false; -}; - -template <size_t N> constexpr bool parse_string(const char (&s)[N]) { - auto h = test_format_string_handler(); - fmt::detail::parse_format_string<true>(fmt::string_view(s, N - 1), h); - return !h.error; -} - -TEST(format_test, constexpr_parse_format_string) { - static_assert(parse_string("foo"), ""); - static_assert(!parse_string("}"), ""); - static_assert(parse_string("{}"), ""); - static_assert(parse_string("{42}"), ""); - static_assert(parse_string("{foo}"), ""); - static_assert(parse_string("{:}"), ""); -} -#endif // FMT_USE_CONSTEXPR - -struct enabled_formatter {}; -struct disabled_formatter {}; -struct disabled_formatter_convertible { - operator int() const { return 42; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<enabled_formatter> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(enabled_formatter, format_context& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(core_test, has_formatter) { - using fmt::has_formatter; - using context = fmt::format_context; - static_assert(has_formatter<enabled_formatter, context>::value, ""); - static_assert(!has_formatter<disabled_formatter, context>::value, ""); - static_assert(!has_formatter<disabled_formatter_convertible, context>::value, - ""); -} - -struct const_formattable {}; -struct nonconst_formattable {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<const_formattable> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - auto format(const const_formattable&, format_context& ctx) - -> decltype(ctx.out()) { - auto test = string_view("test"); - return std::copy_n(test.data(), test.size(), ctx.out()); - } -}; - -template <> struct formatter<nonconst_formattable> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - auto format(nonconst_formattable&, format_context& ctx) - -> decltype(ctx.out()) { - auto test = string_view("test"); - return std::copy_n(test.data(), test.size(), ctx.out()); - } -}; -FMT_END_NAMESPACE - -struct convertible_to_pointer { - operator const int*() const { return nullptr; } -}; - -enum class test_scoped_enum {}; - -TEST(core_test, is_formattable) { -#if 0 - // This should be enabled once corresponding map overloads are gone. - static_assert(fmt::is_formattable<signed char*>::value, ""); - static_assert(fmt::is_formattable<unsigned char*>::value, ""); - static_assert(fmt::is_formattable<const signed char*>::value, ""); - static_assert(fmt::is_formattable<const unsigned char*>::value, ""); -#endif - static_assert(!fmt::is_formattable<wchar_t>::value, ""); -#ifdef __cpp_char8_t - static_assert(!fmt::is_formattable<char8_t>::value, ""); -#endif - static_assert(!fmt::is_formattable<char16_t>::value, ""); - static_assert(!fmt::is_formattable<char32_t>::value, ""); - static_assert(!fmt::is_formattable<const wchar_t*>::value, ""); - static_assert(!fmt::is_formattable<const wchar_t[3]>::value, ""); - static_assert(!fmt::is_formattable<fmt::basic_string_view<wchar_t>>::value, - ""); - static_assert(fmt::is_formattable<enabled_formatter>::value, ""); - static_assert(!fmt::is_formattable<disabled_formatter>::value, ""); - static_assert(fmt::is_formattable<disabled_formatter_convertible>::value, ""); - - static_assert(fmt::is_formattable<const_formattable&>::value, ""); - static_assert(fmt::is_formattable<const const_formattable&>::value, ""); - - static_assert(fmt::is_formattable<nonconst_formattable&>::value, ""); -#if !FMT_MSC_VER || FMT_MSC_VER >= 1910 - static_assert(!fmt::is_formattable<const nonconst_formattable&>::value, ""); -#endif - - static_assert(!fmt::is_formattable<convertible_to_pointer>::value, ""); - - static_assert(!fmt::is_formattable<void (*)()>::value, ""); - - struct s; - - static_assert(!fmt::is_formattable<int(s::*)>::value, ""); - static_assert(!fmt::is_formattable<int (s::*)()>::value, ""); - static_assert(!fmt::is_formattable<test_scoped_enum>::value, ""); -} - -TEST(core_test, format) { EXPECT_EQ(fmt::format("{}", 42), "42"); } - -TEST(core_test, format_to) { - std::string s; - fmt::format_to(std::back_inserter(s), "{}", 42); - EXPECT_EQ(s, "42"); -} - -struct convertible_to_int { - operator int() const { return 42; } -}; - -struct convertible_to_c_string { - operator const char*() const { return "foo"; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<convertible_to_int> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(convertible_to_int, format_context& ctx) -> decltype(ctx.out()) { - return std::copy_n("foo", 3, ctx.out()); - } -}; - -template <> struct formatter<convertible_to_c_string> { - FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(convertible_to_c_string, format_context& ctx) - -> decltype(ctx.out()) { - return std::copy_n("bar", 3, ctx.out()); - } -}; -FMT_END_NAMESPACE - -TEST(core_test, formatter_overrides_implicit_conversion) { - EXPECT_EQ(fmt::format("{}", convertible_to_int()), "foo"); - EXPECT_EQ(fmt::format("{}", convertible_to_c_string()), "bar"); -} - -// Test that check is not found by ADL. -template <typename T> void check(T); -TEST(core_test, adl_check) { - EXPECT_EQ(fmt::format("{}", test_struct()), "test"); -} - -TEST(core_test, to_string_view_foreign_strings) { - using namespace test_ns; - EXPECT_EQ(to_string_view(test_string<char>("42")), "42"); - fmt::detail::type type = - fmt::detail::mapped_type_constant<test_string<char>, - fmt::format_context>::value; - EXPECT_EQ(type, fmt::detail::type::string_type); -} - -struct implicitly_convertible_to_string { - operator std::string() const { return "foo"; } -}; - -struct implicitly_convertible_to_string_view { - operator fmt::string_view() const { return "foo"; } -}; - -TEST(core_test, format_implicitly_convertible_to_string_view) { - EXPECT_EQ("foo", fmt::format("{}", implicitly_convertible_to_string_view())); -} - -// std::is_constructible is broken in MSVC until version 2015. -#if !FMT_MSC_VER || FMT_MSC_VER >= 1900 -struct explicitly_convertible_to_string_view { - explicit operator fmt::string_view() const { return "foo"; } -}; - -TEST(core_test, format_explicitly_convertible_to_string_view) { - EXPECT_EQ("foo", fmt::format("{}", explicitly_convertible_to_string_view())); -} - -# ifdef FMT_USE_STRING_VIEW -struct explicitly_convertible_to_std_string_view { - explicit operator std::string_view() const { return "foo"; } -}; - -TEST(core_test, format_explicitly_convertible_to_std_string_view) { - EXPECT_EQ("foo", - fmt::format("{}", explicitly_convertible_to_std_string_view())); -} -# endif -#endif - -struct convertible_to_long_long { - operator long long() const { return 1LL << 32; } -}; - -TEST(format_test, format_convertible_to_long_long) { - EXPECT_EQ("100000000", fmt::format("{:x}", convertible_to_long_long())); -} - -struct disabled_rvalue_conversion { - operator const char*() const& { return "foo"; } - operator const char*() & { return "foo"; } - operator const char*() const&& = delete; - operator const char*() && = delete; -}; - -TEST(core_test, disabled_rvalue_conversion) { - EXPECT_EQ("foo", fmt::format("{}", disabled_rvalue_conversion())); -} - -namespace adl_test { -template <typename... T> void make_format_args(const T&...) = delete; - -struct string : std::string {}; -} // namespace adl_test - -// Test that formatting functions compile when make_format_args is found by ADL. -TEST(core_test, adl) { - // Only check compilation and don't run the code to avoid polluting the output - // and since the output is tested elsewhere. - if (fmt::detail::const_check(true)) return; - auto s = adl_test::string(); - char buf[10]; - (void)fmt::format("{}", s); - fmt::format_to(buf, "{}", s); - fmt::format_to_n(buf, 10, "{}", s); - (void)fmt::formatted_size("{}", s); - fmt::print("{}", s); - fmt::print(stdout, "{}", s); -} - -TEST(core_test, has_const_formatter) { - EXPECT_TRUE((fmt::detail::has_const_formatter<const_formattable, - fmt::format_context>())); - EXPECT_FALSE((fmt::detail::has_const_formatter<nonconst_formattable, - fmt::format_context>())); -} - -TEST(core_test, format_nonconst) { - EXPECT_EQ(fmt::format("{}", nonconst_formattable()), "test"); -} diff --git a/contrib/libs/fmt/test/core-test/ya.make b/contrib/libs/fmt/test/core-test/ya.make deleted file mode 100644 index af342ff101..0000000000 --- a/contrib/libs/fmt/test/core-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - core-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/enforce-checks-test.cc b/contrib/libs/fmt/test/enforce-checks-test.cc deleted file mode 100644 index c77cb142f6..0000000000 --- a/contrib/libs/fmt/test/enforce-checks-test.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <iterator> -#include <vector> - -#include "fmt/chrono.h" -#include "fmt/color.h" -#include "fmt/format.h" -#include "fmt/ostream.h" -#include "fmt/ranges.h" -#include "fmt/xchar.h" - -// Exercise the API to verify that everything we expect to can compile. -void test_format_api() { - (void)fmt::format(FMT_STRING("{}"), 42); - (void)fmt::format(FMT_STRING(L"{}"), 42); - (void)fmt::format(FMT_STRING("noop")); - - (void)fmt::to_string(42); - (void)fmt::to_wstring(42); - - std::vector<char> out; - fmt::format_to(std::back_inserter(out), FMT_STRING("{}"), 42); - - char buffer[4]; - fmt::format_to_n(buffer, 3, FMT_STRING("{}"), 12345); - - wchar_t wbuffer[4]; - fmt::format_to_n(wbuffer, 3, FMT_STRING(L"{}"), 12345); -} - -void test_chrono() { - (void)fmt::format(FMT_STRING("{}"), std::chrono::seconds(42)); - (void)fmt::format(FMT_STRING(L"{}"), std::chrono::seconds(42)); -} - -void test_text_style() { - fmt::print(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), "rgb(255,20,30)"); - (void)fmt::format(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), - "rgb(255,20,30)"); - - fmt::text_style ts = fg(fmt::rgb(255, 20, 30)); - std::string out; - fmt::format_to(std::back_inserter(out), ts, - FMT_STRING("rgb(255,20,30){}{}{}"), 1, 2, 3); -} - -void test_range() { - std::vector<char> hello = {'h', 'e', 'l', 'l', 'o'}; - (void)fmt::format(FMT_STRING("{}"), hello); -} - -int main() { - test_format_api(); - test_chrono(); - test_text_style(); - test_range(); -} diff --git a/contrib/libs/fmt/test/enforce-checks-test/ya.make b/contrib/libs/fmt/test/enforce-checks-test/ya.make deleted file mode 100644 index 0d67fef412..0000000000 --- a/contrib/libs/fmt/test/enforce-checks-test/ya.make +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_ENFORCE_COMPILE_STRING - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - enforce-checks-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/format-impl-test.cc b/contrib/libs/fmt/test/format-impl-test.cc deleted file mode 100644 index a012306f5b..0000000000 --- a/contrib/libs/fmt/test/format-impl-test.cc +++ /dev/null @@ -1,377 +0,0 @@ -// Formatting library for C++ - formatting library implementation tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <algorithm> -#include <cstring> - -// clang-format off -#include "test-assert.h" -// clang-format on - -#include "fmt/format.h" -#include "gmock/gmock.h" -#include "util.h" - -using fmt::detail::bigint; -using fmt::detail::fp; -using fmt::detail::max_value; - -static_assert(!std::is_copy_constructible<bigint>::value, ""); -static_assert(!std::is_copy_assignable<bigint>::value, ""); - -TEST(bigint_test, construct) { - EXPECT_EQ("", fmt::format("{}", bigint())); - EXPECT_EQ("42", fmt::format("{}", bigint(0x42))); - EXPECT_EQ("123456789abcedf0", fmt::format("{}", bigint(0x123456789abcedf0))); -} - -TEST(bigint_test, compare) { - bigint n1(42); - bigint n2(42); - EXPECT_EQ(compare(n1, n2), 0); - n2 <<= 32; - EXPECT_LT(compare(n1, n2), 0); - bigint n3(43); - EXPECT_LT(compare(n1, n3), 0); - EXPECT_GT(compare(n3, n1), 0); - bigint n4(42 * 0x100000001); - EXPECT_LT(compare(n2, n4), 0); - EXPECT_GT(compare(n4, n2), 0); -} - -TEST(bigint_test, add_compare) { - EXPECT_LT( - add_compare(bigint(0xffffffff), bigint(0xffffffff), bigint(1) <<= 64), 0); - EXPECT_LT(add_compare(bigint(1) <<= 32, bigint(1), bigint(1) <<= 96), 0); - EXPECT_GT(add_compare(bigint(1) <<= 32, bigint(0), bigint(0xffffffff)), 0); - EXPECT_GT(add_compare(bigint(0), bigint(1) <<= 32, bigint(0xffffffff)), 0); - EXPECT_GT(add_compare(bigint(42), bigint(1), bigint(42)), 0); - EXPECT_GT(add_compare(bigint(0xffffffff), bigint(1), bigint(0xffffffff)), 0); - EXPECT_LT(add_compare(bigint(10), bigint(10), bigint(22)), 0); - EXPECT_LT(add_compare(bigint(0x100000010), bigint(0x100000010), - bigint(0x300000010)), - 0); - EXPECT_GT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000000)), - 0); - EXPECT_EQ(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000001)), - 0); - EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000002)), - 0); - EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000003)), - 0); -} - -TEST(bigint_test, shift_left) { - bigint n(0x42); - n <<= 0; - EXPECT_EQ("42", fmt::format("{}", n)); - n <<= 1; - EXPECT_EQ("84", fmt::format("{}", n)); - n <<= 25; - EXPECT_EQ("108000000", fmt::format("{}", n)); -} - -TEST(bigint_test, multiply) { - bigint n(0x42); - EXPECT_THROW(n *= 0, assertion_failure); - n *= 1; - EXPECT_EQ("42", fmt::format("{}", n)); - n *= 2; - EXPECT_EQ("84", fmt::format("{}", n)); - n *= 0x12345678; - EXPECT_EQ("962fc95e0", fmt::format("{}", n)); - bigint bigmax(max_value<uint32_t>()); - bigmax *= max_value<uint32_t>(); - EXPECT_EQ("fffffffe00000001", fmt::format("{}", bigmax)); - bigmax.assign(max_value<uint64_t>()); - bigmax *= max_value<uint64_t>(); - EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", bigmax)); -} - -TEST(bigint_test, accumulator) { - fmt::detail::accumulator acc; - EXPECT_EQ(acc.lower, 0); - EXPECT_EQ(acc.upper, 0); - acc.upper = 12; - acc.lower = 34; - EXPECT_EQ(static_cast<uint32_t>(acc), 34); - acc += 56; - EXPECT_EQ(acc.lower, 90); - acc += max_value<uint64_t>(); - EXPECT_EQ(acc.upper, 13); - EXPECT_EQ(acc.lower, 89); - acc >>= 32; - EXPECT_EQ(acc.upper, 0); - EXPECT_EQ(acc.lower, 13 * 0x100000000); -} - -TEST(bigint_test, square) { - bigint n0(0); - n0.square(); - EXPECT_EQ("0", fmt::format("{}", n0)); - bigint n1(0x100); - n1.square(); - EXPECT_EQ("10000", fmt::format("{}", n1)); - bigint n2(0xfffffffff); - n2.square(); - EXPECT_EQ("ffffffffe000000001", fmt::format("{}", n2)); - bigint n3(max_value<uint64_t>()); - n3.square(); - EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", n3)); - bigint n4; - n4.assign_pow10(10); - EXPECT_EQ("2540be400", fmt::format("{}", n4)); -} - -TEST(bigint_test, divmod_assign_zero_divisor) { - bigint zero(0); - EXPECT_THROW(bigint(0).divmod_assign(zero), assertion_failure); - EXPECT_THROW(bigint(42).divmod_assign(zero), assertion_failure); -} - -TEST(bigint_test, divmod_assign_self) { - bigint n(100); - EXPECT_THROW(n.divmod_assign(n), assertion_failure); -} - -TEST(bigint_test, divmod_assign_unaligned) { - // (42 << 340) / pow(10, 100): - bigint n1(42); - n1 <<= 340; - bigint n2; - n2.assign_pow10(100); - int result = n1.divmod_assign(n2); - EXPECT_EQ(result, 9406); - EXPECT_EQ("10f8353019583bfc29ffc8f564e1b9f9d819dbb4cf783e4507eca1539220p96", - fmt::format("{}", n1)); -} - -TEST(bigint_test, divmod_assign) { - // 100 / 10: - bigint n1(100); - int result = n1.divmod_assign(bigint(10)); - EXPECT_EQ(result, 10); - EXPECT_EQ("0", fmt::format("{}", n1)); - // pow(10, 100) / (42 << 320): - n1.assign_pow10(100); - result = n1.divmod_assign(bigint(42) <<= 320); - EXPECT_EQ(result, 111); - EXPECT_EQ("13ad2594c37ceb0b2784c4ce0bf38ace408e211a7caab24308a82e8f10p96", - fmt::format("{}", n1)); - // 42 / 100: - bigint n2(42); - n1.assign_pow10(2); - result = n2.divmod_assign(n1); - EXPECT_EQ(result, 0); - EXPECT_EQ("2a", fmt::format("{}", n2)); -} - -template <bool is_iec559> void run_double_tests() { - fmt::print("warning: double is not IEC559, skipping FP tests\n"); -} - -template <> void run_double_tests<true>() { - // Construct from double. - EXPECT_EQ(fp(1.23), fp(0x13ae147ae147aeu, -52)); -} - -TEST(fp_test, double_tests) { - run_double_tests<std::numeric_limits<double>::is_iec559>(); -} - -TEST(fp_test, normalize) { - const auto v = fp(0xbeef, 42); - auto normalized = normalize(v); - EXPECT_EQ(0xbeef000000000000, normalized.f); - EXPECT_EQ(-6, normalized.e); -} - -TEST(fp_test, multiply) { - auto v = fp(123ULL << 32, 4) * fp(56ULL << 32, 7); - EXPECT_EQ(v.f, 123u * 56u); - EXPECT_EQ(v.e, 4 + 7 + 64); - v = fp(123ULL << 32, 4) * fp(567ULL << 31, 8); - EXPECT_EQ(v.f, (123 * 567 + 1u) / 2); - EXPECT_EQ(v.e, 4 + 8 + 64); -} - -TEST(fp_test, get_cached_power) { - using limits = std::numeric_limits<double>; - for (auto exp = limits::min_exponent; exp <= limits::max_exponent; ++exp) { - int dec_exp = 0; - auto fp = fmt::detail::get_cached_power(exp, dec_exp); - bigint exact, cache(fp.f); - if (dec_exp >= 0) { - exact.assign_pow10(dec_exp); - if (fp.e <= 0) - exact <<= -fp.e; - else - cache <<= fp.e; - exact.align(cache); - cache.align(exact); - auto exact_str = fmt::format("{}", exact); - auto cache_str = fmt::format("{}", cache); - EXPECT_EQ(exact_str.size(), cache_str.size()); - EXPECT_EQ(exact_str.substr(0, 15), cache_str.substr(0, 15)); - int diff = cache_str[15] - exact_str[15]; - if (diff == 1) - EXPECT_GT(exact_str[16], '8'); - else - EXPECT_EQ(diff, 0); - } else { - cache.assign_pow10(-dec_exp); - cache *= fp.f + 1; // Inexact check. - exact.assign(1); - exact <<= -fp.e; - exact.align(cache); - auto exact_str = fmt::format("{}", exact); - auto cache_str = fmt::format("{}", cache); - EXPECT_EQ(exact_str.size(), cache_str.size()); - EXPECT_EQ(exact_str.substr(0, 16), cache_str.substr(0, 16)); - } - } -} - -TEST(fp_test, dragonbox_max_k) { - using fmt::detail::dragonbox::floor_log10_pow2; - using float_info = fmt::detail::dragonbox::float_info<float>; - EXPECT_EQ(fmt::detail::const_check(float_info::max_k), - float_info::kappa - floor_log10_pow2(float_info::min_exponent - - float_info::significand_bits)); - using double_info = fmt::detail::dragonbox::float_info<double>; - EXPECT_EQ( - fmt::detail::const_check(double_info::max_k), - double_info::kappa - floor_log10_pow2(double_info::min_exponent - - double_info::significand_bits)); -} - -TEST(fp_test, get_round_direction) { - using fmt::detail::get_round_direction; - using fmt::detail::round_direction; - EXPECT_EQ(round_direction::down, get_round_direction(100, 50, 0)); - EXPECT_EQ(round_direction::up, get_round_direction(100, 51, 0)); - EXPECT_EQ(round_direction::down, get_round_direction(100, 40, 10)); - EXPECT_EQ(round_direction::up, get_round_direction(100, 60, 10)); - for (size_t i = 41; i < 60; ++i) - EXPECT_EQ(round_direction::unknown, get_round_direction(100, i, 10)); - uint64_t max = max_value<uint64_t>(); - EXPECT_THROW(get_round_direction(100, 100, 0), assertion_failure); - EXPECT_THROW(get_round_direction(100, 0, 100), assertion_failure); - EXPECT_THROW(get_round_direction(100, 0, 50), assertion_failure); - // Check that remainder + error doesn't overflow. - EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 2)); - // Check that 2 * (remainder + error) doesn't overflow. - EXPECT_EQ(round_direction::unknown, - get_round_direction(max, max / 2 + 1, max / 2)); - // Check that remainder - error doesn't overflow. - EXPECT_EQ(round_direction::unknown, get_round_direction(100, 40, 41)); - // Check that 2 * (remainder - error) doesn't overflow. - EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 1)); -} - -TEST(fp_test, fixed_handler) { - struct handler : fmt::detail::gen_digits_handler { - char buffer[10]; - handler(int prec = 0) : fmt::detail::gen_digits_handler() { - buf = buffer; - precision = prec; - } - }; - handler().on_digit('0', 100, 99, 0, false); - EXPECT_THROW(handler().on_digit('0', 100, 100, 0, false), assertion_failure); - namespace digits = fmt::detail::digits; - EXPECT_EQ(handler(1).on_digit('0', 100, 10, 10, false), digits::error); - // Check that divisor - error doesn't overflow. - EXPECT_EQ(handler(1).on_digit('0', 100, 10, 101, false), digits::error); - // Check that 2 * error doesn't overflow. - uint64_t max = max_value<uint64_t>(); - EXPECT_EQ(handler(1).on_digit('0', max, 10, max - 1, false), digits::error); -} - -TEST(fp_test, grisu_format_compiles_with_on_ieee_double) { - fmt::memory_buffer buf; - format_float(0.42, -1, fmt::detail::float_specs(), buf); -} - -TEST(format_impl_test, format_error_code) { - std::string msg = "error 42", sep = ": "; - { - fmt::memory_buffer buffer; - format_to(fmt::appender(buffer), "garbage"); - fmt::detail::format_error_code(buffer, 42, "test"); - EXPECT_EQ("test: " + msg, to_string(buffer)); - } - { - fmt::memory_buffer buffer; - auto prefix = - std::string(fmt::inline_buffer_size - msg.size() - sep.size() + 1, 'x'); - fmt::detail::format_error_code(buffer, 42, prefix); - EXPECT_EQ(msg, to_string(buffer)); - } - int codes[] = {42, -1}; - for (size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) { - // Test maximum buffer size. - msg = fmt::format("error {}", codes[i]); - fmt::memory_buffer buffer; - auto prefix = - std::string(fmt::inline_buffer_size - msg.size() - sep.size(), 'x'); - fmt::detail::format_error_code(buffer, codes[i], prefix); - EXPECT_EQ(prefix + sep + msg, to_string(buffer)); - size_t size = fmt::inline_buffer_size; - EXPECT_EQ(size, buffer.size()); - buffer.resize(0); - // Test with a message that doesn't fit into the buffer. - prefix += 'x'; - fmt::detail::format_error_code(buffer, codes[i], prefix); - EXPECT_EQ(msg, to_string(buffer)); - } -} - -TEST(format_impl_test, compute_width) { - EXPECT_EQ(4, - fmt::detail::compute_width( - fmt::basic_string_view<fmt::detail::char8_type>( - reinterpret_cast<const fmt::detail::char8_type*>("ёжик")))); -} - -// Tests fmt::detail::count_digits for integer type Int. -template <typename Int> void test_count_digits() { - for (Int i = 0; i < 10; ++i) EXPECT_EQ(1u, fmt::detail::count_digits(i)); - for (Int i = 1, n = 1, end = max_value<Int>() / 10; n <= end; ++i) { - n *= 10; - EXPECT_EQ(i, fmt::detail::count_digits(n - 1)); - EXPECT_EQ(i + 1, fmt::detail::count_digits(n)); - } -} - -TEST(format_impl_test, count_digits) { - test_count_digits<uint32_t>(); - test_count_digits<uint64_t>(); -} - -TEST(format_impl_test, write_fallback_uintptr) { - std::string s; - fmt::detail::write_ptr<char>( - std::back_inserter(s), - fmt::detail::fallback_uintptr(reinterpret_cast<void*>(0xface)), nullptr); - EXPECT_EQ(s, "0xface"); -} - -#ifdef _WIN32 -# include <windows.h> -#endif - -#ifdef _WIN32 -TEST(format_impl_test, write_console_signature) { - decltype(WriteConsoleW)* p = fmt::detail::WriteConsoleW; - (void)p; -} -#endif diff --git a/contrib/libs/fmt/test/format-impl-test/ya.make b/contrib/libs/fmt/test/format-impl-test/ya.make deleted file mode 100644 index fe49868ec1..0000000000 --- a/contrib/libs/fmt/test/format-impl-test/ya.make +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -ADDINCL( - contrib/libs/fmt/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_HEADER_ONLY=1 - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt) - -SRCS( - test/format-impl-test.cc - test/header-only-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/format-test.cc b/contrib/libs/fmt/test/format-test.cc deleted file mode 100644 index a8592ef07e..0000000000 --- a/contrib/libs/fmt/test/format-test.cc +++ /dev/null @@ -1,2190 +0,0 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -// Check if fmt/format.h compiles with windows.h included before it. -#ifdef _WIN32 -# include <windows.h> -#endif -// clang-format off -#include "fmt/format.h" -// clang-format on - -#include <stdint.h> // uint32_t - -#include <climits> // INT_MAX -#include <cmath> // std::signbit -#include <cstring> // std::strlen -#include <iterator> // std::back_inserter -#include <list> // std::list -#include <memory> // std::unique_ptr -#include <type_traits> // std::is_default_constructible - -#include "gtest-extra.h" -#include "mock-allocator.h" -#include "util.h" - -using fmt::basic_memory_buffer; -using fmt::format_error; -using fmt::memory_buffer; -using fmt::runtime; -using fmt::string_view; -using fmt::detail::max_value; - -using testing::Return; -using testing::StrictMock; - -enum { buffer_size = 256 }; - -struct uint32_pair { - uint32_t u[2]; -}; - -TEST(util_test, bit_cast) { - auto s = fmt::detail::bit_cast<uint32_pair>(uint64_t{42}); - EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), 42ull); - s = fmt::detail::bit_cast<uint32_pair>(~uint64_t{0}); - EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), ~0ull); -} - -// Increment a number in a string. -void increment(char* s) { - for (int i = static_cast<int>(std::strlen(s)) - 1; i >= 0; --i) { - if (s[i] != '9') { - ++s[i]; - break; - } - s[i] = '0'; - } -} - -TEST(util_test, increment) { - char s[10] = "123"; - increment(s); - EXPECT_STREQ("124", s); - s[2] = '8'; - increment(s); - EXPECT_STREQ("129", s); - increment(s); - EXPECT_STREQ("130", s); - s[1] = s[2] = '9'; - increment(s); - EXPECT_STREQ("200", s); -} - -TEST(util_test, parse_nonnegative_int) { - auto s = fmt::string_view("10000000000"); - auto begin = s.begin(), end = s.end(); - EXPECT_EQ(fmt::detail::parse_nonnegative_int(begin, end, -1), -1); - s = "2147483649"; - begin = s.begin(); - end = s.end(); - EXPECT_EQ(fmt::detail::parse_nonnegative_int(begin, end, -1), -1); -} - -TEST(util_test, utf8_to_utf16) { - auto u = fmt::detail::utf8_to_utf16("лошадка"); - EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str()); - EXPECT_EQ(7, u.size()); - // U+10437 { DESERET SMALL LETTER YEE } - EXPECT_EQ(L"\xD801\xDC37", fmt::detail::utf8_to_utf16("𐐷").str()); - EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16("\xc3\x28"), std::runtime_error, - "invalid utf8"); - EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16(fmt::string_view("л", 1)), - std::runtime_error, "invalid utf8"); - EXPECT_EQ(L"123456", fmt::detail::utf8_to_utf16("123456").str()); -} - -TEST(util_test, utf8_to_utf16_empty_string) { - auto s = std::string(); - auto u = fmt::detail::utf8_to_utf16(s.c_str()); - EXPECT_EQ(L"", u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -TEST(util_test, allocator_ref) { - using test_allocator_ref = allocator_ref<mock_allocator<int>>; - auto check_forwarding = [](mock_allocator<int>& alloc, - test_allocator_ref& ref) { - int mem; - // Check if value_type is properly defined. - allocator_ref<mock_allocator<int>>::value_type* ptr = &mem; - // Check forwarding. - EXPECT_CALL(alloc, allocate(42)).WillOnce(Return(ptr)); - ref.allocate(42); - EXPECT_CALL(alloc, deallocate(ptr, 42)); - ref.deallocate(ptr, 42); - }; - - StrictMock<mock_allocator<int>> alloc; - auto ref = test_allocator_ref(&alloc); - // Check if allocator_ref forwards to the underlying allocator. - check_forwarding(alloc, ref); - test_allocator_ref ref2(ref); - check_forwarding(alloc, ref2); - test_allocator_ref ref3; - EXPECT_EQ(nullptr, ref3.get()); - ref3 = ref; - check_forwarding(alloc, ref3); -} - -TEST(util_test, format_system_error) { - fmt::memory_buffer message; - fmt::format_system_error(message, EDOM, "test"); - auto ec = std::error_code(EDOM, std::generic_category()); - EXPECT_EQ(to_string(message), std::system_error(ec, "test").what()); - message = fmt::memory_buffer(); - - // Check if std::allocator throws on allocating max size_t / 2 chars. - size_t max_size = max_value<size_t>() / 2; - bool throws_on_alloc = false; - try { - auto alloc = std::allocator<char>(); - alloc.deallocate(alloc.allocate(max_size), max_size); - } catch (const std::bad_alloc&) { - throws_on_alloc = true; - } - if (!throws_on_alloc) { - fmt::print("warning: std::allocator allocates {} chars", max_size); - return; - } -} - -TEST(util_test, system_error) { - auto test_error = fmt::system_error(EDOM, "test"); - auto ec = std::error_code(EDOM, std::generic_category()); - EXPECT_STREQ(test_error.what(), std::system_error(ec, "test").what()); - EXPECT_EQ(test_error.code(), ec); - - auto error = std::system_error(std::error_code()); - try { - throw fmt::system_error(EDOM, "test {}", "error"); - } catch (const std::system_error& e) { - error = e; - } - fmt::memory_buffer message; - fmt::format_system_error(message, EDOM, "test error"); - EXPECT_EQ(error.what(), to_string(message)); - EXPECT_EQ(error.code(), std::error_code(EDOM, std::generic_category())); -} - -TEST(util_test, report_system_error) { - fmt::memory_buffer out; - fmt::format_system_error(out, EDOM, "test error"); - out.push_back('\n'); - EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), - to_string(out)); -} - -TEST(memory_buffer_test, ctor) { - basic_memory_buffer<char, 123> buffer; - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); -} - -using std_allocator = allocator_ref<std::allocator<char>>; - -TEST(memory_buffer_test, move_ctor_inline_buffer) { - auto check_move_buffer = - [](const char* str, basic_memory_buffer<char, 5, std_allocator>& buffer) { - std::allocator<char>* alloc = buffer.get_allocator().get(); - basic_memory_buffer<char, 5, std_allocator> buffer2(std::move(buffer)); - // Move shouldn't destroy the inline content of the first buffer. - EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); - EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); - EXPECT_EQ(5u, buffer2.capacity()); - // Move should transfer allocator. - EXPECT_EQ(nullptr, buffer.get_allocator().get()); - EXPECT_EQ(alloc, buffer2.get_allocator().get()); - }; - - auto alloc = std::allocator<char>(); - basic_memory_buffer<char, 5, std_allocator> buffer((std_allocator(&alloc))); - const char test[] = "test"; - buffer.append(string_view(test, 4)); - check_move_buffer("test", buffer); - // Adding one more character fills the inline buffer, but doesn't cause - // dynamic allocation. - buffer.push_back('a'); - check_move_buffer("testa", buffer); -} - -TEST(memory_buffer_test, move_ctor_dynamic_buffer) { - auto alloc = std::allocator<char>(); - basic_memory_buffer<char, 4, std_allocator> buffer((std_allocator(&alloc))); - const char test[] = "test"; - buffer.append(test, test + 4); - const char* inline_buffer_ptr = &buffer[0]; - // Adding one more character causes the content to move from the inline to - // a dynamically allocated buffer. - buffer.push_back('a'); - basic_memory_buffer<char, 4, std_allocator> buffer2(std::move(buffer)); - // Move should rip the guts of the first buffer. - EXPECT_EQ(inline_buffer_ptr, &buffer[0]); - EXPECT_EQ("testa", std::string(&buffer2[0], buffer2.size())); - EXPECT_GT(buffer2.capacity(), 4u); -} - -void check_move_assign_buffer(const char* str, - basic_memory_buffer<char, 5>& buffer) { - basic_memory_buffer<char, 5> buffer2; - buffer2 = std::move(buffer); - // Move shouldn't destroy the inline content of the first buffer. - EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); - EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); - EXPECT_EQ(5u, buffer2.capacity()); -} - -TEST(memory_buffer_test, move_assignment) { - basic_memory_buffer<char, 5> buffer; - const char test[] = "test"; - buffer.append(test, test + 4); - check_move_assign_buffer("test", buffer); - // Adding one more character fills the inline buffer, but doesn't cause - // dynamic allocation. - buffer.push_back('a'); - check_move_assign_buffer("testa", buffer); - const char* inline_buffer_ptr = &buffer[0]; - // Adding one more character causes the content to move from the inline to - // a dynamically allocated buffer. - buffer.push_back('b'); - basic_memory_buffer<char, 5> buffer2; - buffer2 = std::move(buffer); - // Move should rip the guts of the first buffer. - EXPECT_EQ(inline_buffer_ptr, &buffer[0]); - EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size())); - EXPECT_GT(buffer2.capacity(), 5u); -} - -TEST(memory_buffer_test, grow) { - typedef allocator_ref<mock_allocator<int>> Allocator; - mock_allocator<int> alloc; - basic_memory_buffer<int, 10, Allocator> buffer((Allocator(&alloc))); - buffer.resize(7); - using fmt::detail::to_unsigned; - for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i; - EXPECT_EQ(10u, buffer.capacity()); - int mem[20]; - mem[7] = 0xdead; - EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem)); - buffer.try_reserve(20); - EXPECT_EQ(20u, buffer.capacity()); - // Check if size elements have been copied - for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]); - // and no more than that. - EXPECT_EQ(0xdead, buffer[7]); - EXPECT_CALL(alloc, deallocate(mem, 20)); -} - -TEST(memory_buffer_test, allocator) { - using test_allocator = allocator_ref<mock_allocator<char>>; - basic_memory_buffer<char, 10, test_allocator> buffer; - EXPECT_EQ(nullptr, buffer.get_allocator().get()); - StrictMock<mock_allocator<char>> alloc; - char mem; - { - basic_memory_buffer<char, 10, test_allocator> buffer2( - (test_allocator(&alloc))); - EXPECT_EQ(&alloc, buffer2.get_allocator().get()); - size_t size = 2 * fmt::inline_buffer_size; - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem)); - buffer2.reserve(size); - EXPECT_CALL(alloc, deallocate(&mem, size)); - } -} - -TEST(memory_buffer_test, exception_in_deallocate) { - using test_allocator = allocator_ref<mock_allocator<char>>; - StrictMock<mock_allocator<char>> alloc; - basic_memory_buffer<char, 10, test_allocator> buffer( - (test_allocator(&alloc))); - size_t size = 2 * fmt::inline_buffer_size; - auto mem = std::vector<char>(size); - { - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0])); - buffer.resize(size); - std::fill(&buffer[0], &buffer[0] + size, 'x'); - } - auto mem2 = std::vector<char>(2 * size); - { - EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0])); - auto e = std::exception(); - EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e)); - EXPECT_THROW(buffer.reserve(2 * size), std::exception); - EXPECT_EQ(&mem2[0], &buffer[0]); - // Check that the data has been copied. - for (size_t i = 0; i < size; ++i) EXPECT_EQ('x', buffer[i]); - } - EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size)); -} - -template <typename Allocator, size_t MaxSize> -class max_size_allocator : public Allocator { - public: - using typename Allocator::value_type; - size_t max_size() const FMT_NOEXCEPT { return MaxSize; } - value_type* allocate(size_t n) { - if (n > max_size()) { - throw std::length_error("size > max_size"); - } - return std::allocator_traits<Allocator>::allocate( - *static_cast<Allocator*>(this), n); - } - void deallocate(value_type* p, size_t n) { - std::allocator_traits<Allocator>::deallocate(*static_cast<Allocator*>(this), - p, n); - } -}; - -TEST(memory_buffer_test, max_size_allocator) { - // 160 = 128 + 32 - using test_allocator = max_size_allocator<std::allocator<char>, 160>; - basic_memory_buffer<char, 10, test_allocator> buffer; - buffer.resize(128); - // new_capacity = 128 + 128/2 = 192 > 160 - buffer.resize(160); // Shouldn't throw. -} - -TEST(memory_buffer_test, max_size_allocator_overflow) { - using test_allocator = max_size_allocator<std::allocator<char>, 160>; - basic_memory_buffer<char, 10, test_allocator> buffer; - EXPECT_THROW(buffer.resize(161), std::exception); -} - -TEST(format_test, escape) { - EXPECT_EQ("{", fmt::format("{{")); - EXPECT_EQ("before {", fmt::format("before {{")); - EXPECT_EQ("{ after", fmt::format("{{ after")); - EXPECT_EQ("before { after", fmt::format("before {{ after")); - - EXPECT_EQ("}", fmt::format("}}")); - EXPECT_EQ("before }", fmt::format("before }}")); - EXPECT_EQ("} after", fmt::format("}} after")); - EXPECT_EQ("before } after", fmt::format("before }} after")); - - EXPECT_EQ("{}", fmt::format("{{}}")); - EXPECT_EQ("{42}", fmt::format("{{{0}}}", 42)); -} - -TEST(format_test, unmatched_braces) { - EXPECT_THROW_MSG((void)fmt::format(runtime("{")), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("}")), format_error, - "unmatched '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0{}")), format_error, - "invalid format string"); -} - -TEST(format_test, no_args) { EXPECT_EQ("test", fmt::format("test")); } - -TEST(format_test, args_in_different_positions) { - EXPECT_EQ("42", fmt::format("{0}", 42)); - EXPECT_EQ("before 42", fmt::format("before {0}", 42)); - EXPECT_EQ("42 after", fmt::format("{0} after", 42)); - EXPECT_EQ("before 42 after", fmt::format("before {0} after", 42)); - EXPECT_EQ("answer = 42", fmt::format("{0} = {1}", "answer", 42)); - EXPECT_EQ("42 is the answer", fmt::format("{1} is the {0}", "answer", 42)); - EXPECT_EQ("abracadabra", fmt::format("{0}{1}{0}", "abra", "cad")); -} - -TEST(format_test, arg_errors) { - EXPECT_THROW_MSG((void)fmt::format(runtime("{")), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{?}")), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0")), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0}")), format_error, - "argument not found"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{00}"), 42), format_error, - "invalid format string"); - - char format_str[buffer_size]; - safe_sprintf(format_str, "{%u", INT_MAX); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str)), format_error, - "invalid format string"); - safe_sprintf(format_str, "{%u}", INT_MAX); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str)), format_error, - "argument not found"); - - safe_sprintf(format_str, "{%u", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str)), format_error, - "invalid format string"); - safe_sprintf(format_str, "{%u}", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str)), format_error, - "argument not found"); -} - -template <int N> struct test_format { - template <typename... T> - static std::string format(fmt::string_view fmt, const T&... args) { - return test_format<N - 1>::format(fmt, N - 1, args...); - } -}; - -template <> struct test_format<0> { - template <typename... T> - static std::string format(fmt::string_view fmt, const T&... args) { - return fmt::format(runtime(fmt), args...); - } -}; - -TEST(format_test, many_args) { - EXPECT_EQ("19", test_format<20>::format("{19}")); - EXPECT_THROW_MSG(test_format<20>::format("{20}"), format_error, - "argument not found"); - EXPECT_THROW_MSG(test_format<21>::format("{21}"), format_error, - "argument not found"); - using fmt::detail::max_packed_args; - std::string format_str = fmt::format("{{{}}}", max_packed_args + 1); - EXPECT_THROW_MSG(test_format<max_packed_args>::format(format_str), - format_error, "argument not found"); -} - -TEST(format_test, named_arg) { - EXPECT_EQ("1/a/A", fmt::format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'), - fmt::arg("A_", "A"), fmt::arg("_1", 1))); - EXPECT_EQ(" -42", fmt::format("{0:{width}}", -42, fmt::arg("width", 4))); - EXPECT_EQ("st", - fmt::format("{0:.{precision}}", "str", fmt::arg("precision", 2))); - EXPECT_EQ("1 2", fmt::format("{} {two}", 1, fmt::arg("two", 2))); - EXPECT_EQ("42", - fmt::format("{c}", fmt::arg("a", 0), fmt::arg("b", 0), - fmt::arg("c", 42), fmt::arg("d", 0), fmt::arg("e", 0), - fmt::arg("f", 0), fmt::arg("g", 0), fmt::arg("h", 0), - fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0), - fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0), - fmt::arg("o", 0), fmt::arg("p", 0))); - EXPECT_THROW_MSG((void)fmt::format(runtime("{a}")), format_error, - "argument not found"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{a}"), 42), format_error, - "argument not found"); -} - -TEST(format_test, auto_arg_index) { - EXPECT_EQ("abc", fmt::format("{}{}{}", 'a', 'b', 'c')); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0}{}"), 'a', 'b'), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{}{0}"), 'a', 'b'), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_EQ("1.2", fmt::format("{:.{}}", 1.2345, 2)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0}:.{}"), 1.2345, 2), - format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{0}}"), 1.2345, 2), - format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{}")), format_error, - "argument not found"); -} - -TEST(format_test, empty_specs) { EXPECT_EQ("42", fmt::format("{0:}", 42)); } - -TEST(format_test, left_align) { - EXPECT_EQ("42 ", fmt::format("{0:<4}", 42)); - EXPECT_EQ("42 ", fmt::format("{0:<4o}", 042)); - EXPECT_EQ("42 ", fmt::format("{0:<4x}", 0x42)); - EXPECT_EQ("-42 ", fmt::format("{0:<5}", -42)); - EXPECT_EQ("42 ", fmt::format("{0:<5}", 42u)); - EXPECT_EQ("-42 ", fmt::format("{0:<5}", -42l)); - EXPECT_EQ("42 ", fmt::format("{0:<5}", 42ul)); - EXPECT_EQ("-42 ", fmt::format("{0:<5}", -42ll)); - EXPECT_EQ("42 ", fmt::format("{0:<5}", 42ull)); - EXPECT_EQ("-42 ", fmt::format("{0:<5}", -42.0)); - EXPECT_EQ("-42 ", fmt::format("{0:<5}", -42.0l)); - EXPECT_EQ("c ", fmt::format("{0:<5}", 'c')); - EXPECT_EQ("abc ", fmt::format("{0:<5}", "abc")); - EXPECT_EQ("0xface ", fmt::format("{0:<8}", reinterpret_cast<void*>(0xface))); -} - -TEST(format_test, right_align) { - EXPECT_EQ(" 42", fmt::format("{0:>4}", 42)); - EXPECT_EQ(" 42", fmt::format("{0:>4o}", 042)); - EXPECT_EQ(" 42", fmt::format("{0:>4x}", 0x42)); - EXPECT_EQ(" -42", fmt::format("{0:>5}", -42)); - EXPECT_EQ(" 42", fmt::format("{0:>5}", 42u)); - EXPECT_EQ(" -42", fmt::format("{0:>5}", -42l)); - EXPECT_EQ(" 42", fmt::format("{0:>5}", 42ul)); - EXPECT_EQ(" -42", fmt::format("{0:>5}", -42ll)); - EXPECT_EQ(" 42", fmt::format("{0:>5}", 42ull)); - EXPECT_EQ(" -42", fmt::format("{0:>5}", -42.0)); - EXPECT_EQ(" -42", fmt::format("{0:>5}", -42.0l)); - EXPECT_EQ(" c", fmt::format("{0:>5}", 'c')); - EXPECT_EQ(" abc", fmt::format("{0:>5}", "abc")); - EXPECT_EQ(" 0xface", fmt::format("{0:>8}", reinterpret_cast<void*>(0xface))); -} - -TEST(format_test, center_align) { - EXPECT_EQ(" 42 ", fmt::format("{0:^5}", 42)); - EXPECT_EQ(" 42 ", fmt::format("{0:^5o}", 042)); - EXPECT_EQ(" 42 ", fmt::format("{0:^5x}", 0x42)); - EXPECT_EQ(" -42 ", fmt::format("{0:^5}", -42)); - EXPECT_EQ(" 42 ", fmt::format("{0:^5}", 42u)); - EXPECT_EQ(" -42 ", fmt::format("{0:^5}", -42l)); - EXPECT_EQ(" 42 ", fmt::format("{0:^5}", 42ul)); - EXPECT_EQ(" -42 ", fmt::format("{0:^5}", -42ll)); - EXPECT_EQ(" 42 ", fmt::format("{0:^5}", 42ull)); - EXPECT_EQ(" -42 ", fmt::format("{0:^5}", -42.0)); - EXPECT_EQ(" -42 ", fmt::format("{0:^5}", -42.0l)); - EXPECT_EQ(" c ", fmt::format("{0:^5}", 'c')); - EXPECT_EQ(" abc ", fmt::format("{0:^6}", "abc")); - EXPECT_EQ(" 0xface ", fmt::format("{0:^8}", reinterpret_cast<void*>(0xface))); -} - -TEST(format_test, fill) { - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{<5}"), 'c'), format_error, - "invalid fill character '{'"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{<5}}"), 'c'), format_error, - "invalid fill character '{'"); - EXPECT_EQ("**42", fmt::format("{0:*>4}", 42)); - EXPECT_EQ("**-42", fmt::format("{0:*>5}", -42)); - EXPECT_EQ("***42", fmt::format("{0:*>5}", 42u)); - EXPECT_EQ("**-42", fmt::format("{0:*>5}", -42l)); - EXPECT_EQ("***42", fmt::format("{0:*>5}", 42ul)); - EXPECT_EQ("**-42", fmt::format("{0:*>5}", -42ll)); - EXPECT_EQ("***42", fmt::format("{0:*>5}", 42ull)); - EXPECT_EQ("**-42", fmt::format("{0:*>5}", -42.0)); - EXPECT_EQ("**-42", fmt::format("{0:*>5}", -42.0l)); - EXPECT_EQ("c****", fmt::format("{0:*<5}", 'c')); - EXPECT_EQ("abc**", fmt::format("{0:*<5}", "abc")); - EXPECT_EQ("**0xface", - fmt::format("{0:*>8}", reinterpret_cast<void*>(0xface))); - EXPECT_EQ("foo=", fmt::format("{:}=", "foo")); - EXPECT_EQ(std::string("\0\0\0*", 4), - fmt::format(string_view("{:\0>4}", 6), '*')); - EXPECT_EQ("жж42", fmt::format("{0:ж>4}", 42)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:\x80\x80\x80\x80\x80>}"), 0), - format_error, "invalid type specifier"); -} - -TEST(format_test, plus_sign) { - EXPECT_EQ("+42", fmt::format("{0:+}", 42)); - EXPECT_EQ("-42", fmt::format("{0:+}", -42)); - EXPECT_EQ("+42", fmt::format("{0:+}", 42)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("+42", fmt::format("{0:+}", 42l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("+42", fmt::format("{0:+}", 42ll)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42ull), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("+42", fmt::format("{0:+}", 42.0)); - EXPECT_EQ("+42", fmt::format("{0:+}", 42.0l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+"), 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:+}"), reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(format_test, minus_sign) { - EXPECT_EQ("42", fmt::format("{0:-}", 42)); - EXPECT_EQ("-42", fmt::format("{0:-}", -42)); - EXPECT_EQ("42", fmt::format("{0:-}", 42)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("42", fmt::format("{0:-}", 42l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("42", fmt::format("{0:-}", 42ll)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42ull), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("42", fmt::format("{0:-}", 42.0)); - EXPECT_EQ("42", fmt::format("{0:-}", 42.0l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-"), 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:-}"), reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(format_test, space_sign) { - EXPECT_EQ(" 42", fmt::format("{0: }", 42)); - EXPECT_EQ("-42", fmt::format("{0: }", -42)); - EXPECT_EQ(" 42", fmt::format("{0: }", 42)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ(" 42", fmt::format("{0: }", 42l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ(" 42", fmt::format("{0: }", 42ll)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42ull), format_error, - "format specifier requires signed argument"); - EXPECT_EQ(" 42", fmt::format("{0: }", 42.0)); - EXPECT_EQ(" 42", fmt::format("{0: }", 42.0l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: "), 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0: }"), reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(format_test, hash_flag) { - EXPECT_EQ("42", fmt::format("{0:#}", 42)); - EXPECT_EQ("-42", fmt::format("{0:#}", -42)); - EXPECT_EQ("0b101010", fmt::format("{0:#b}", 42)); - EXPECT_EQ("0B101010", fmt::format("{0:#B}", 42)); - EXPECT_EQ("-0b101010", fmt::format("{0:#b}", -42)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42)); - EXPECT_EQ("0X42", fmt::format("{0:#X}", 0x42)); - EXPECT_EQ("-0x42", fmt::format("{0:#x}", -0x42)); - EXPECT_EQ("0", fmt::format("{0:#o}", 0)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042)); - EXPECT_EQ("-042", fmt::format("{0:#o}", -042)); - EXPECT_EQ("42", fmt::format("{0:#}", 42u)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42u)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042u)); - - EXPECT_EQ("-42", fmt::format("{0:#}", -42l)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42l)); - EXPECT_EQ("-0x42", fmt::format("{0:#x}", -0x42l)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042l)); - EXPECT_EQ("-042", fmt::format("{0:#o}", -042l)); - EXPECT_EQ("42", fmt::format("{0:#}", 42ul)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42ul)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042ul)); - - EXPECT_EQ("-42", fmt::format("{0:#}", -42ll)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42ll)); - EXPECT_EQ("-0x42", fmt::format("{0:#x}", -0x42ll)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042ll)); - EXPECT_EQ("-042", fmt::format("{0:#o}", -042ll)); - EXPECT_EQ("42", fmt::format("{0:#}", 42ull)); - EXPECT_EQ("0x42", fmt::format("{0:#x}", 0x42ull)); - EXPECT_EQ("042", fmt::format("{0:#o}", 042ull)); - - EXPECT_EQ("-42.0", fmt::format("{0:#}", -42.0)); - EXPECT_EQ("-42.0", fmt::format("{0:#}", -42.0l)); - EXPECT_EQ("4.e+01", fmt::format("{:#.0e}", 42.0)); - EXPECT_EQ("0.", fmt::format("{:#.0f}", 0.01)); - EXPECT_EQ("0.50", fmt::format("{:#.2g}", 0.5)); - EXPECT_EQ("0.", fmt::format("{:#.0f}", 0.5)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#"), 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:#}"), reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(format_test, zero_flag) { - EXPECT_EQ("42", fmt::format("{0:0}", 42)); - EXPECT_EQ("-0042", fmt::format("{0:05}", -42)); - EXPECT_EQ("00042", fmt::format("{0:05}", 42u)); - EXPECT_EQ("-0042", fmt::format("{0:05}", -42l)); - EXPECT_EQ("00042", fmt::format("{0:05}", 42ul)); - EXPECT_EQ("-0042", fmt::format("{0:05}", -42ll)); - EXPECT_EQ("00042", fmt::format("{0:05}", 42ull)); - EXPECT_EQ("-000042", fmt::format("{0:07}", -42.0)); - EXPECT_EQ("-000042", fmt::format("{0:07}", -42.0l)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:0"), 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:05}"), reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(format_test, width) { - char format_str[buffer_size]; - safe_sprintf(format_str, "{0:%u", UINT_MAX); - increment(format_str + 3); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - - safe_sprintf(format_str, "{0:%u", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - EXPECT_EQ(" -42", fmt::format("{0:4}", -42)); - EXPECT_EQ(" 42", fmt::format("{0:5}", 42u)); - EXPECT_EQ(" -42", fmt::format("{0:6}", -42l)); - EXPECT_EQ(" 42", fmt::format("{0:7}", 42ul)); - EXPECT_EQ(" -42", fmt::format("{0:6}", -42ll)); - EXPECT_EQ(" 42", fmt::format("{0:7}", 42ull)); - EXPECT_EQ(" -1.23", fmt::format("{0:8}", -1.23)); - EXPECT_EQ(" -1.23", fmt::format("{0:9}", -1.23l)); - EXPECT_EQ(" 0xcafe", - fmt::format("{0:10}", reinterpret_cast<void*>(0xcafe))); - EXPECT_EQ("x ", fmt::format("{0:11}", 'x')); - EXPECT_EQ("str ", fmt::format("{0:12}", "str")); - EXPECT_EQ(fmt::format("{:*^6}", "🤡"), "**🤡**"); - EXPECT_EQ(fmt::format("{:*^8}", "你好"), "**你好**"); - EXPECT_EQ(fmt::format("{:#6}", 42.0), " 42.0"); - EXPECT_EQ(fmt::format("{:6c}", static_cast<int>('x')), "x "); - EXPECT_EQ(fmt::format("{:>06.0f}", 0.00884311), "000000"); -} - -TEST(format_test, runtime_width) { - char format_str[buffer_size]; - safe_sprintf(format_str, "{0:{%u", UINT_MAX); - increment(format_str + 4); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "invalid format string"); - size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "argument not found"); - format_str[size + 1] = '}'; - format_str[size + 2] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "argument not found"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{"), 0), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{}"), 0), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{?}}"), 0), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0), format_error, - "argument not found"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{0:}}"), 0), format_error, - "invalid format string"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, -1), format_error, - "negative width"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (INT_MAX + 1u)), - format_error, "number is too big"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, -1l), format_error, - "negative width"); - if (fmt::detail::const_check(sizeof(long) > sizeof(int))) { - long value = INT_MAX; - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (value + 1)), - format_error, "number is too big"); - } - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (INT_MAX + 1ul)), - format_error, "number is too big"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, '0'), format_error, - "width is not integer"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, 0.0), format_error, - "width is not integer"); - - EXPECT_EQ(" -42", fmt::format("{0:{1}}", -42, 4)); - EXPECT_EQ(" 42", fmt::format("{0:{1}}", 42u, 5)); - EXPECT_EQ(" -42", fmt::format("{0:{1}}", -42l, 6)); - EXPECT_EQ(" 42", fmt::format("{0:{1}}", 42ul, 7)); - EXPECT_EQ(" -42", fmt::format("{0:{1}}", -42ll, 6)); - EXPECT_EQ(" 42", fmt::format("{0:{1}}", 42ull, 7)); - EXPECT_EQ(" -1.23", fmt::format("{0:{1}}", -1.23, 8)); - EXPECT_EQ(" -1.23", fmt::format("{0:{1}}", -1.23l, 9)); - EXPECT_EQ(" 0xcafe", - fmt::format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10)); - EXPECT_EQ("x ", fmt::format("{0:{1}}", 'x', 11)); - EXPECT_EQ("str ", fmt::format("{0:{1}}", "str", 12)); -} - -TEST(format_test, precision) { - char format_str[buffer_size]; - safe_sprintf(format_str, "{0:.%u", UINT_MAX); - increment(format_str + 4); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - - safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "number is too big"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0), format_error, - "missing precision specifier"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0), format_error, - "missing precision specifier"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2"), 0), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42u), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42u), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42l), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42l), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ul), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ul), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ll), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ll), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ull), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ull), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.0}"), 'x'), format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2", fmt::format("{0:.2}", 1.2345)); - EXPECT_EQ("1.2", fmt::format("{0:.2}", 1.2345l)); - EXPECT_EQ("1.2e+56", fmt::format("{:.2}", 1.234e56)); - EXPECT_EQ("1.1", fmt::format("{0:.3}", 1.1)); - EXPECT_EQ("1e+00", fmt::format("{:.0e}", 1.0L)); - EXPECT_EQ(" 0.0e+00", fmt::format("{:9.1e}", 0.0)); - EXPECT_EQ( - fmt::format("{:.494}", 4.9406564584124654E-324), - "4.9406564584124654417656879286822137236505980261432476442558568250067550" - "727020875186529983636163599237979656469544571773092665671035593979639877" - "479601078187812630071319031140452784581716784898210368871863605699873072" - "305000638740915356498438731247339727316961514003171538539807412623856559" - "117102665855668676818703956031062493194527159149245532930545654440112748" - "012970999954193198940908041656332452475714786901472678015935523861155013" - "480352649347201937902681071074917033322268447533357208324319361e-324"); - EXPECT_EQ( - fmt::format("{:.1074f}", 1.1125369292536e-308), - "0.0000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000111253692925360019747947051741965785554081512200979" - "355021686109411883779182127659725163430929750364498219730822952552570601" - "152163505899912777129583674906301179059298598412303893909188340988729019" - "014361467448914817838555156840459458527907308695109202499990850735085304" - "478476991912072201449236975063640913461919914396877093174125167509869762" - "482369631100360266123742648159508919592746619553246586039571522788247697" - "156360766271842991667238355464496455107749716934387136380536472531224398" - "559833794807213172371254492216255558078524900147957309382830827524104234" - "530961756787819847850302379672357738807808384667004752163416921762619527" - "462847642037420991432005657440259928195996762610375541867198059294212446" - "81962777939941034720757232455434770912461317493580281734466552734375"); - - std::string outputs[] = { - "-0X1.41FE3FFE71C9E000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000P+127", - "-0XA.0FF1FFF38E4F0000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000P+124"}; - EXPECT_THAT(outputs, - testing::Contains(fmt::format("{:.838A}", -2.14001164E+38))); - - EXPECT_EQ("123.", fmt::format("{:#.0f}", 123.0)); - EXPECT_EQ("1.23", fmt::format("{:.02f}", 1.234)); - EXPECT_EQ("0.001", fmt::format("{:.1g}", 0.001)); - EXPECT_EQ("1019666400", fmt::format("{}", 1019666432.0f)); - EXPECT_EQ("1e+01", fmt::format("{:.0e}", 9.5)); - EXPECT_EQ("1.0e-34", fmt::format("{:.1e}", 1e-34)); - - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:.2}"), reinterpret_cast<void*>(0xcafe)), - format_error, "precision not allowed for this argument type"); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0:.2f}"), reinterpret_cast<void*>(0xcafe)), - format_error, "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{}e}"), 42.0, - fmt::detail::max_value<int>()), - format_error, "number is too big"); - EXPECT_THROW_MSG( - (void)fmt::format("{:.2147483646f}", -2.2121295195081227E+304), - format_error, "number is too big"); - - EXPECT_EQ("st", fmt::format("{0:.2}", "str")); -} - -TEST(format_test, runtime_precision) { - char format_str[buffer_size]; - safe_sprintf(format_str, "{0:.{%u", UINT_MAX); - increment(format_str + 5); - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "invalid format string"); - size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "argument not found"); - format_str[size + 1] = '}'; - format_str[size + 2] = 0; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error, - "argument not found"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{"), 0), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{}"), 0), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{?}}"), 0), format_error, - "invalid format string"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}"), 0, 0), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0), format_error, - "argument not found"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{0:}}"), 0), format_error, - "invalid format string"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, -1), format_error, - "negative precision"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, (INT_MAX + 1u)), - format_error, "number is too big"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, -1l), format_error, - "negative precision"); - if (fmt::detail::const_check(sizeof(long) > sizeof(int))) { - long value = INT_MAX; - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, (value + 1)), - format_error, "number is too big"); - } - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, (INT_MAX + 1ul)), - format_error, "number is too big"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, '0'), format_error, - "precision is not integer"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0, 0.0), format_error, - "precision is not integer"); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42u, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42u, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42l, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42l, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ul, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ul, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ll, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ll, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ull, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ull, 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.{1}}"), 'x', 0), - format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2", fmt::format("{0:.{1}}", 1.2345, 2)); - EXPECT_EQ("1.2", fmt::format("{1:.{0}}", 2, 1.2345l)); - - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), - reinterpret_cast<void*>(0xcafe), 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), - reinterpret_cast<void*>(0xcafe), 2), - format_error, - "precision not allowed for this argument type"); - - EXPECT_EQ("st", fmt::format("{0:.{1}}", "str", 2)); -} - -TEST(format_test, format_bool) { - EXPECT_EQ("true", fmt::format("{}", true)); - EXPECT_EQ("false", fmt::format("{}", false)); - EXPECT_EQ("1", fmt::format("{:d}", true)); - EXPECT_EQ("true ", fmt::format("{:5}", true)); - EXPECT_EQ("true", fmt::format("{:s}", true)); - EXPECT_EQ("false", fmt::format("{:s}", false)); - EXPECT_EQ("false ", fmt::format("{:6s}", false)); -} - -TEST(format_test, format_short) { - short s = 42; - EXPECT_EQ("42", fmt::format("{0:d}", s)); - unsigned short us = 42; - EXPECT_EQ("42", fmt::format("{0:d}", us)); -} - -template <typename T> -void check_unknown_types(const T& value, const char* types, const char*) { - char format_str[buffer_size]; - const char* special = ".0123456789L}"; - for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) { - char c = static_cast<char>(i); - if (std::strchr(types, c) || std::strchr(special, c) || !c) continue; - safe_sprintf(format_str, "{0:10%c}", c); - const char* message = "invalid type specifier"; - EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), value), - format_error, message) - << format_str << " " << message; - } -} - -TEST(format_test, format_int) { - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:v"), 42), format_error, - "invalid type specifier"); - check_unknown_types(42, "bBdoxXnLc", "integer"); - EXPECT_EQ("x", fmt::format("{:c}", static_cast<int>('x'))); -} - -TEST(format_test, format_bin) { - EXPECT_EQ("0", fmt::format("{0:b}", 0)); - EXPECT_EQ("101010", fmt::format("{0:b}", 42)); - EXPECT_EQ("101010", fmt::format("{0:b}", 42u)); - EXPECT_EQ("-101010", fmt::format("{0:b}", -42)); - EXPECT_EQ("11000000111001", fmt::format("{0:b}", 12345)); - EXPECT_EQ("10010001101000101011001111000", fmt::format("{0:b}", 0x12345678)); - EXPECT_EQ("10010000101010111100110111101111", - fmt::format("{0:b}", 0x90ABCDEF)); - EXPECT_EQ("11111111111111111111111111111111", - fmt::format("{0:b}", max_value<uint32_t>())); -} - -#if FMT_USE_INT128 -constexpr auto int128_max = static_cast<__int128_t>( - (static_cast<__uint128_t>(1) << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1); -constexpr auto int128_min = -int128_max - 1; - -constexpr auto uint128_max = ~static_cast<__uint128_t>(0); -#endif - -TEST(format_test, format_dec) { - EXPECT_EQ("0", fmt::format("{0}", 0)); - EXPECT_EQ("42", fmt::format("{0}", 42)); - EXPECT_EQ("42", fmt::format("{0:d}", 42)); - EXPECT_EQ("42", fmt::format("{0}", 42u)); - EXPECT_EQ("-42", fmt::format("{0}", -42)); - EXPECT_EQ("12345", fmt::format("{0}", 12345)); - EXPECT_EQ("67890", fmt::format("{0}", 67890)); -#if FMT_USE_INT128 - EXPECT_EQ("0", fmt::format("{0}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", fmt::format("{0}", static_cast<__uint128_t>(0))); - EXPECT_EQ("9223372036854775808", - fmt::format("{0}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-9223372036854775809", - fmt::format("{0}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("18446744073709551616", - fmt::format("{0}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("170141183460469231731687303715884105727", - fmt::format("{0}", int128_max)); - EXPECT_EQ("-170141183460469231731687303715884105728", - fmt::format("{0}", int128_min)); - EXPECT_EQ("340282366920938463463374607431768211455", - fmt::format("{0}", uint128_max)); -#endif - - char buffer[buffer_size]; - safe_sprintf(buffer, "%d", INT_MIN); - EXPECT_EQ(buffer, fmt::format("{0}", INT_MIN)); - safe_sprintf(buffer, "%d", INT_MAX); - EXPECT_EQ(buffer, fmt::format("{0}", INT_MAX)); - safe_sprintf(buffer, "%u", UINT_MAX); - EXPECT_EQ(buffer, fmt::format("{0}", UINT_MAX)); - safe_sprintf(buffer, "%ld", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, fmt::format("{0}", LONG_MIN)); - safe_sprintf(buffer, "%ld", LONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0}", LONG_MAX)); - safe_sprintf(buffer, "%lu", ULONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0}", ULONG_MAX)); -} - -TEST(format_test, format_hex) { - EXPECT_EQ("0", fmt::format("{0:x}", 0)); - EXPECT_EQ("42", fmt::format("{0:x}", 0x42)); - EXPECT_EQ("42", fmt::format("{0:x}", 0x42u)); - EXPECT_EQ("-42", fmt::format("{0:x}", -0x42)); - EXPECT_EQ("12345678", fmt::format("{0:x}", 0x12345678)); - EXPECT_EQ("90abcdef", fmt::format("{0:x}", 0x90abcdef)); - EXPECT_EQ("12345678", fmt::format("{0:X}", 0x12345678)); - EXPECT_EQ("90ABCDEF", fmt::format("{0:X}", 0x90ABCDEF)); -#if FMT_USE_INT128 - EXPECT_EQ("0", fmt::format("{0:x}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", fmt::format("{0:x}", static_cast<__uint128_t>(0))); - EXPECT_EQ("8000000000000000", - fmt::format("{0:x}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-8000000000000001", - fmt::format("{0:x}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("10000000000000000", - fmt::format("{0:x}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("7fffffffffffffffffffffffffffffff", - fmt::format("{0:x}", int128_max)); - EXPECT_EQ("-80000000000000000000000000000000", - fmt::format("{0:x}", int128_min)); - EXPECT_EQ("ffffffffffffffffffffffffffffffff", - fmt::format("{0:x}", uint128_max)); -#endif - - char buffer[buffer_size]; - safe_sprintf(buffer, "-%x", 0 - static_cast<unsigned>(INT_MIN)); - EXPECT_EQ(buffer, fmt::format("{0:x}", INT_MIN)); - safe_sprintf(buffer, "%x", INT_MAX); - EXPECT_EQ(buffer, fmt::format("{0:x}", INT_MAX)); - safe_sprintf(buffer, "%x", UINT_MAX); - EXPECT_EQ(buffer, fmt::format("{0:x}", UINT_MAX)); - safe_sprintf(buffer, "-%lx", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, fmt::format("{0:x}", LONG_MIN)); - safe_sprintf(buffer, "%lx", LONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0:x}", LONG_MAX)); - safe_sprintf(buffer, "%lx", ULONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0:x}", ULONG_MAX)); -} - -TEST(format_test, format_oct) { - EXPECT_EQ("0", fmt::format("{0:o}", 0)); - EXPECT_EQ("42", fmt::format("{0:o}", 042)); - EXPECT_EQ("42", fmt::format("{0:o}", 042u)); - EXPECT_EQ("-42", fmt::format("{0:o}", -042)); - EXPECT_EQ("12345670", fmt::format("{0:o}", 012345670)); -#if FMT_USE_INT128 - EXPECT_EQ("0", fmt::format("{0:o}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", fmt::format("{0:o}", static_cast<__uint128_t>(0))); - EXPECT_EQ("1000000000000000000000", - fmt::format("{0:o}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-1000000000000000000001", - fmt::format("{0:o}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("2000000000000000000000", - fmt::format("{0:o}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("1777777777777777777777777777777777777777777", - fmt::format("{0:o}", int128_max)); - EXPECT_EQ("-2000000000000000000000000000000000000000000", - fmt::format("{0:o}", int128_min)); - EXPECT_EQ("3777777777777777777777777777777777777777777", - fmt::format("{0:o}", uint128_max)); -#endif - - char buffer[buffer_size]; - safe_sprintf(buffer, "-%o", 0 - static_cast<unsigned>(INT_MIN)); - EXPECT_EQ(buffer, fmt::format("{0:o}", INT_MIN)); - safe_sprintf(buffer, "%o", INT_MAX); - EXPECT_EQ(buffer, fmt::format("{0:o}", INT_MAX)); - safe_sprintf(buffer, "%o", UINT_MAX); - EXPECT_EQ(buffer, fmt::format("{0:o}", UINT_MAX)); - safe_sprintf(buffer, "-%lo", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, fmt::format("{0:o}", LONG_MIN)); - safe_sprintf(buffer, "%lo", LONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0:o}", LONG_MAX)); - safe_sprintf(buffer, "%lo", ULONG_MAX); - EXPECT_EQ(buffer, fmt::format("{0:o}", ULONG_MAX)); -} - -TEST(format_test, format_int_locale) { - EXPECT_EQ("1234", fmt::format("{:L}", 1234)); -} - -TEST(format_test, format_float) { - EXPECT_EQ("0", fmt::format("{}", 0.0f)); - EXPECT_EQ("392.500000", fmt::format("{0:f}", 392.5f)); -} - -TEST(format_test, format_double) { - EXPECT_EQ("0", fmt::format("{}", 0.0)); - check_unknown_types(1.2, "eEfFgGaAnL%", "double"); - EXPECT_EQ("0", fmt::format("{:}", 0.0)); - EXPECT_EQ("0.000000", fmt::format("{:f}", 0.0)); - EXPECT_EQ("0", fmt::format("{:g}", 0.0)); - EXPECT_EQ("392.65", fmt::format("{:}", 392.65)); - EXPECT_EQ("392.65", fmt::format("{:g}", 392.65)); - EXPECT_EQ("392.65", fmt::format("{:G}", 392.65)); - EXPECT_EQ("4.9014e+06", fmt::format("{:g}", 4.9014e6)); - EXPECT_EQ("392.650000", fmt::format("{:f}", 392.65)); - EXPECT_EQ("392.650000", fmt::format("{:F}", 392.65)); - EXPECT_EQ("42", fmt::format("{:L}", 42.0)); - EXPECT_EQ(" 0x1.0cccccccccccdp+2", fmt::format("{:24a}", 4.2)); - EXPECT_EQ("0x1.0cccccccccccdp+2 ", fmt::format("{:<24a}", 4.2)); - char buffer[buffer_size]; - safe_sprintf(buffer, "%e", 392.65); - EXPECT_EQ(buffer, fmt::format("{0:e}", 392.65)); - safe_sprintf(buffer, "%E", 392.65); - EXPECT_EQ(buffer, fmt::format("{0:E}", 392.65)); - EXPECT_EQ("+0000392.6", fmt::format("{0:+010.4g}", 392.65)); - safe_sprintf(buffer, "%a", -42.0); - EXPECT_EQ(buffer, fmt::format("{:a}", -42.0)); - safe_sprintf(buffer, "%A", -42.0); - EXPECT_EQ(buffer, fmt::format("{:A}", -42.0)); - EXPECT_EQ("9223372036854775808.000000", - fmt::format("{:f}", 9223372036854775807.0)); -} - -TEST(format_test, precision_rounding) { - EXPECT_EQ("0", fmt::format("{:.0f}", 0.0)); - EXPECT_EQ("0", fmt::format("{:.0f}", 0.01)); - EXPECT_EQ("0", fmt::format("{:.0f}", 0.1)); - EXPECT_EQ("0.000", fmt::format("{:.3f}", 0.00049)); - EXPECT_EQ("0.001", fmt::format("{:.3f}", 0.0005)); - EXPECT_EQ("0.001", fmt::format("{:.3f}", 0.00149)); - EXPECT_EQ("0.002", fmt::format("{:.3f}", 0.0015)); - EXPECT_EQ("1.000", fmt::format("{:.3f}", 0.9999)); - EXPECT_EQ("0.00123", fmt::format("{:.3}", 0.00123)); - EXPECT_EQ("0.1", fmt::format("{:.16g}", 0.1)); - EXPECT_EQ("1", fmt::format("{:.0}", 1.0)); - EXPECT_EQ("225.51575035152063720", - fmt::format("{:.17f}", 225.51575035152064)); - EXPECT_EQ("-761519619559038.2", fmt::format("{:.1f}", -761519619559038.2)); - EXPECT_EQ("1.9156918820264798e-56", - fmt::format("{}", 1.9156918820264798e-56)); - EXPECT_EQ("0.0000", fmt::format("{:.4f}", 7.2809479766055470e-15)); - - // Trigger a rounding error in Grisu by a specially chosen number. - EXPECT_EQ("3788512123356.985352", fmt::format("{:f}", 3788512123356.985352)); -} - -TEST(format_test, prettify_float) { - EXPECT_EQ("0.0001", fmt::format("{}", 1e-4)); - EXPECT_EQ("1e-05", fmt::format("{}", 1e-5)); - EXPECT_EQ("1000000000000000", fmt::format("{}", 1e15)); - EXPECT_EQ("1e+16", fmt::format("{}", 1e16)); - EXPECT_EQ("9.999e-05", fmt::format("{}", 9.999e-5)); - EXPECT_EQ("10000000000", fmt::format("{}", 1e10)); - EXPECT_EQ("100000000000", fmt::format("{}", 1e11)); - EXPECT_EQ("12340000000", fmt::format("{}", 1234e7)); - EXPECT_EQ("12.34", fmt::format("{}", 1234e-2)); - EXPECT_EQ("0.001234", fmt::format("{}", 1234e-6)); - EXPECT_EQ("0.1", fmt::format("{}", 0.1f)); - EXPECT_EQ("0.10000000149011612", fmt::format("{}", double(0.1f))); - EXPECT_EQ("1.3563156e-19", fmt::format("{}", 1.35631564e-19f)); -} - -TEST(format_test, format_nan) { - double nan = std::numeric_limits<double>::quiet_NaN(); - EXPECT_EQ("nan", fmt::format("{}", nan)); - EXPECT_EQ("+nan", fmt::format("{:+}", nan)); - EXPECT_EQ(" +nan", fmt::format("{:+06}", nan)); - EXPECT_EQ("+nan ", fmt::format("{:<+06}", nan)); - EXPECT_EQ(" +nan ", fmt::format("{:^+06}", nan)); - EXPECT_EQ(" +nan", fmt::format("{:>+06}", nan)); - if (std::signbit(-nan)) { - EXPECT_EQ("-nan", fmt::format("{}", -nan)); - EXPECT_EQ(" -nan", fmt::format("{:+06}", -nan)); - } else { - fmt::print("Warning: compiler doesn't handle negative NaN correctly"); - } - EXPECT_EQ(" nan", fmt::format("{: }", nan)); - EXPECT_EQ("NAN", fmt::format("{:F}", nan)); - EXPECT_EQ("nan ", fmt::format("{:<7}", nan)); - EXPECT_EQ(" nan ", fmt::format("{:^7}", nan)); - EXPECT_EQ(" nan", fmt::format("{:>7}", nan)); -} - -TEST(format_test, format_infinity) { - double inf = std::numeric_limits<double>::infinity(); - EXPECT_EQ("inf", fmt::format("{}", inf)); - EXPECT_EQ("+inf", fmt::format("{:+}", inf)); - EXPECT_EQ("-inf", fmt::format("{}", -inf)); - EXPECT_EQ(" +inf", fmt::format("{:+06}", inf)); - EXPECT_EQ(" -inf", fmt::format("{:+06}", -inf)); - EXPECT_EQ("+inf ", fmt::format("{:<+06}", inf)); - EXPECT_EQ(" +inf ", fmt::format("{:^+06}", inf)); - EXPECT_EQ(" +inf", fmt::format("{:>+06}", inf)); - EXPECT_EQ(" inf", fmt::format("{: }", inf)); - EXPECT_EQ("INF", fmt::format("{:F}", inf)); - EXPECT_EQ("inf ", fmt::format("{:<7}", inf)); - EXPECT_EQ(" inf ", fmt::format("{:^7}", inf)); - EXPECT_EQ(" inf", fmt::format("{:>7}", inf)); -} - -TEST(format_test, format_long_double) { - EXPECT_EQ("0", fmt::format("{0:}", 0.0l)); - EXPECT_EQ("0.000000", fmt::format("{0:f}", 0.0l)); - EXPECT_EQ("392.65", fmt::format("{0:}", 392.65l)); - EXPECT_EQ("392.65", fmt::format("{0:g}", 392.65l)); - EXPECT_EQ("392.65", fmt::format("{0:G}", 392.65l)); - EXPECT_EQ("392.650000", fmt::format("{0:f}", 392.65l)); - EXPECT_EQ("392.650000", fmt::format("{0:F}", 392.65l)); - char buffer[buffer_size]; - safe_sprintf(buffer, "%Le", 392.65l); - EXPECT_EQ(buffer, fmt::format("{0:e}", 392.65l)); - EXPECT_EQ("+0000392.6", fmt::format("{0:+010.4g}", 392.64l)); - safe_sprintf(buffer, "%La", 3.31l); - EXPECT_EQ(buffer, fmt::format("{:a}", 3.31l)); -} - -TEST(format_test, format_char) { - const char types[] = "cbBdoxX"; - check_unknown_types('a', types, "char"); - EXPECT_EQ("a", fmt::format("{0}", 'a')); - EXPECT_EQ("z", fmt::format("{0:c}", 'z')); - int n = 'x'; - for (const char* type = types + 1; *type; ++type) { - std::string format_str = fmt::format("{{:{}}}", *type); - EXPECT_EQ(fmt::format(runtime(format_str), n), - fmt::format(runtime(format_str), 'x')) - << format_str; - } - EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x')); -} - -TEST(format_test, format_volatile_char) { - volatile char c = 'x'; - EXPECT_EQ("x", fmt::format("{}", c)); -} - -TEST(format_test, format_unsigned_char) { - EXPECT_EQ("42", fmt::format("{}", static_cast<unsigned char>(42))); - EXPECT_EQ("42", fmt::format("{}", static_cast<uint8_t>(42))); -} - -TEST(format_test, format_cstring) { - check_unknown_types("test", "sp", "string"); - EXPECT_EQ("test", fmt::format("{0}", "test")); - EXPECT_EQ("test", fmt::format("{0:s}", "test")); - char nonconst[] = "nonconst"; - EXPECT_EQ("nonconst", fmt::format("{0}", nonconst)); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("{0}"), static_cast<const char*>(nullptr)), - format_error, "string pointer is null"); -} - -void function_pointer_test(int, double, std::string) {} - -TEST(format_test, format_pointer) { - check_unknown_types(reinterpret_cast<void*>(0x1234), "p", "pointer"); - EXPECT_EQ("0x0", fmt::format("{0}", static_cast<void*>(nullptr))); - EXPECT_EQ("0x1234", fmt::format("{0}", reinterpret_cast<void*>(0x1234))); - EXPECT_EQ("0x1234", fmt::format("{0:p}", reinterpret_cast<void*>(0x1234))); - EXPECT_EQ("0x" + std::string(sizeof(void*) * CHAR_BIT / 4, 'f'), - fmt::format("{0}", reinterpret_cast<void*>(~uintptr_t()))); - EXPECT_EQ("0x1234", - fmt::format("{}", fmt::ptr(reinterpret_cast<int*>(0x1234)))); - std::unique_ptr<int> up(new int(1)); - EXPECT_EQ(fmt::format("{}", fmt::ptr(up.get())), - fmt::format("{}", fmt::ptr(up))); - std::shared_ptr<int> sp(new int(1)); - EXPECT_EQ(fmt::format("{}", fmt::ptr(sp.get())), - fmt::format("{}", fmt::ptr(sp))); - EXPECT_EQ(fmt::format("{}", fmt::detail::bit_cast<const void*>( - &function_pointer_test)), - fmt::format("{}", fmt::ptr(function_pointer_test))); - EXPECT_EQ("0x0", fmt::format("{}", nullptr)); -} - -TEST(format_test, format_string) { - EXPECT_EQ("test", fmt::format("{0}", std::string("test"))); - EXPECT_THROW((void)fmt::format(fmt::runtime("{:x}"), std::string("test")), - fmt::format_error); -} - -TEST(format_test, format_string_view) { - EXPECT_EQ("test", fmt::format("{}", string_view("test"))); - EXPECT_EQ("", fmt::format("{}", string_view())); -} - -#ifdef FMT_USE_STRING_VIEW -struct string_viewable {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<string_viewable> : formatter<std::string_view> { - auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) { - return formatter<std::string_view>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -TEST(format_test, format_std_string_view) { - EXPECT_EQ("test", fmt::format("{}", std::string_view("test"))); - EXPECT_EQ("foo", fmt::format("{}", string_viewable())); -} - -struct explicitly_convertible_to_std_string_view { - explicit operator std::string_view() const { return "foo"; } -}; - -template <> -struct fmt::formatter<explicitly_convertible_to_std_string_view> - : formatter<std::string_view> { - auto format(explicitly_convertible_to_std_string_view v, format_context& ctx) - -> decltype(ctx.out()) { - return format_to(ctx.out(), "'{}'", std::string_view(v)); - } -}; - -TEST(format_test, format_explicitly_convertible_to_std_string_view) { - EXPECT_EQ("'foo'", - fmt::format("{}", explicitly_convertible_to_std_string_view())); -} -#endif - -struct converible_to_anything { - template <typename T> operator T() const { return T(); } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<converible_to_anything> { - FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - auto format(converible_to_anything, format_context& ctx) - -> decltype(ctx.out()) { - return format_to(ctx.out(), "foo"); - } -}; -FMT_END_NAMESPACE - -TEST(format_test, format_convertible_to_anything) { - EXPECT_EQ("foo", fmt::format("{}", converible_to_anything())); -} - -class Answer {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<date> { - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(); - if (it != ctx.end() && *it == 'd') ++it; - return it; - } - - auto format(const date& d, format_context& ctx) -> decltype(ctx.out()) { - format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day()); - return ctx.out(); - } -}; - -template <> struct formatter<Answer> : formatter<int> { - template <typename FormatContext> - auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) { - return formatter<int>::format(42, ctx); - } -}; -FMT_END_NAMESPACE - -TEST(format_test, format_custom) { - EXPECT_THROW_MSG((void)fmt::format(runtime("{:s}"), date(2012, 12, 9)), - format_error, "unknown format specifier"); - EXPECT_EQ("42", fmt::format("{0}", Answer())); - EXPECT_EQ("0042", fmt::format("{:04}", Answer())); -} - -TEST(format_test, format_to_custom) { - char buf[10] = {}; - auto end = - &*fmt::format_to(fmt::detail::make_checked(buf, 10), "{}", Answer()); - EXPECT_EQ(end, buf + 2); - EXPECT_STREQ(buf, "42"); -} - -TEST(format_test, format_string_from_speed_test) { - EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%", - fmt::format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42, - 3.13, "str", reinterpret_cast<void*>(1000), 'X')); -} - -TEST(format_test, format_examples) { - std::string message = fmt::format("The answer is {}", 42); - EXPECT_EQ("The answer is 42", message); - - EXPECT_EQ("42", fmt::format("{}", 42)); - - memory_buffer out; - format_to(std::back_inserter(out), "The answer is {}.", 42); - EXPECT_EQ("The answer is 42.", to_string(out)); - - const char* filename = "nonexistent"; - FILE* ftest = safe_fopen(filename, "r"); - if (ftest) fclose(ftest); - int error_code = errno; - EXPECT_TRUE(ftest == nullptr); - EXPECT_SYSTEM_ERROR( - { - FILE* f = safe_fopen(filename, "r"); - if (!f) - throw fmt::system_error(errno, "Cannot open file '{}'", filename); - fclose(f); - }, - error_code, "Cannot open file 'nonexistent'"); - - EXPECT_EQ("First, thou shalt count to three", - fmt::format("First, thou shalt count to {0}", "three")); - EXPECT_EQ("Bring me a shrubbery", fmt::format("Bring me a {}", "shrubbery")); - EXPECT_EQ("From 1 to 3", fmt::format("From {} to {}", 1, 3)); - - char buffer[buffer_size]; - safe_sprintf(buffer, "%03.2f", -1.2); - EXPECT_EQ(buffer, fmt::format("{:03.2f}", -1.2)); - - EXPECT_EQ("a, b, c", fmt::format("{0}, {1}, {2}", 'a', 'b', 'c')); - EXPECT_EQ("a, b, c", fmt::format("{}, {}, {}", 'a', 'b', 'c')); - EXPECT_EQ("c, b, a", fmt::format("{2}, {1}, {0}", 'a', 'b', 'c')); - EXPECT_EQ("abracadabra", fmt::format("{0}{1}{0}", "abra", "cad")); - - EXPECT_EQ("left aligned ", - fmt::format("{:<30}", "left aligned")); - EXPECT_EQ(" right aligned", - fmt::format("{:>30}", "right aligned")); - EXPECT_EQ(" centered ", - fmt::format("{:^30}", "centered")); - EXPECT_EQ("***********centered***********", - fmt::format("{:*^30}", "centered")); - - EXPECT_EQ("+3.140000; -3.140000", fmt::format("{:+f}; {:+f}", 3.14, -3.14)); - EXPECT_EQ(" 3.140000; -3.140000", fmt::format("{: f}; {: f}", 3.14, -3.14)); - EXPECT_EQ("3.140000; -3.140000", fmt::format("{:-f}; {:-f}", 3.14, -3.14)); - - EXPECT_EQ("int: 42; hex: 2a; oct: 52", - fmt::format("int: {0:d}; hex: {0:x}; oct: {0:o}", 42)); - EXPECT_EQ("int: 42; hex: 0x2a; oct: 052", - fmt::format("int: {0:d}; hex: {0:#x}; oct: {0:#o}", 42)); - - EXPECT_EQ("The answer is 42", fmt::format("The answer is {}", 42)); - EXPECT_THROW_MSG( - (void)fmt::format(runtime("The answer is {:d}"), "forty-two"), - format_error, "invalid type specifier"); - - EXPECT_WRITE( - stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf"); -} - -TEST(format_test, print) { - EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!"); - EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"), - "Don't panic!"); -} - -TEST(format_test, variadic) { - EXPECT_EQ("abc1", fmt::format("{}c{}", "ab", 1)); -} - -TEST(format_test, dynamic) { - using ctx = fmt::format_context; - auto args = std::vector<fmt::basic_format_arg<ctx>>(); - args.emplace_back(fmt::detail::make_arg<ctx>(42)); - args.emplace_back(fmt::detail::make_arg<ctx>("abc1")); - args.emplace_back(fmt::detail::make_arg<ctx>(1.5f)); - - std::string result = fmt::vformat( - "{} and {} and {}", - fmt::format_args(args.data(), static_cast<int>(args.size()))); - - EXPECT_EQ("42 and abc1 and 1.5", result); -} - -TEST(format_test, bytes) { - auto s = fmt::format("{:10}", fmt::bytes("ёжик")); - EXPECT_EQ("ёжик ", s); - EXPECT_EQ(10, s.size()); -} - -TEST(format_test, group_digits_view) { - EXPECT_EQ(fmt::format("{}", fmt::group_digits(10000000)), "10,000,000"); - EXPECT_EQ(fmt::format("{:8}", fmt::group_digits(1000)), " 1,000"); -} - -enum test_enum { foo, bar }; - -TEST(format_test, join) { - using fmt::join; - int v1[3] = {1, 2, 3}; - auto v2 = std::vector<float>(); - v2.push_back(1.2f); - v2.push_back(3.4f); - void* v3[2] = {&v1[0], &v1[1]}; - - EXPECT_EQ("(1, 2, 3)", fmt::format("({})", join(v1, v1 + 3, ", "))); - EXPECT_EQ("(1)", fmt::format("({})", join(v1, v1 + 1, ", "))); - EXPECT_EQ("()", fmt::format("({})", join(v1, v1, ", "))); - EXPECT_EQ("(001, 002, 003)", fmt::format("({:03})", join(v1, v1 + 3, ", "))); - EXPECT_EQ("(+01.20, +03.40)", - fmt::format("({:+06.2f})", join(v2.begin(), v2.end(), ", "))); - - EXPECT_EQ("1, 2, 3", fmt::format("{0:{1}}", join(v1, v1 + 3, ", "), 1)); - - EXPECT_EQ(fmt::format("{}, {}", v3[0], v3[1]), - fmt::format("{}", join(v3, v3 + 2, ", "))); - - EXPECT_EQ("(1, 2, 3)", fmt::format("({})", join(v1, ", "))); - EXPECT_EQ("(+01.20, +03.40)", fmt::format("({:+06.2f})", join(v2, ", "))); - - auto v4 = std::vector<test_enum>{foo, bar, foo}; - EXPECT_EQ("0 1 0", fmt::format("{}", join(v4, " "))); -} - -#ifdef __cpp_lib_byte -TEST(format_test, join_bytes) { - auto v = std::vector<std::byte>{std::byte(1), std::byte(2), std::byte(3)}; - EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, ", "))); -} -#endif - -std::string vformat_message(int id, const char* format, fmt::format_args args) { - auto buffer = fmt::memory_buffer(); - format_to(fmt::appender(buffer), "[{}] ", id); - vformat_to(fmt::appender(buffer), format, args); - return to_string(buffer); -} - -template <typename... Args> -std::string format_message(int id, const char* format, const Args&... args) { - auto va = fmt::make_format_args(args...); - return vformat_message(id, format, va); -} - -TEST(format_test, format_message_example) { - EXPECT_EQ("[42] something happened", - format_message(42, "{} happened", "something")); -} - -template <typename... Args> -void print_error(const char* file, int line, const char* format, - const Args&... args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args...); -} - -TEST(format_test, unpacked_args) { - EXPECT_EQ("0123456789abcdefg", - fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g')); -} - -struct string_like {}; -fmt::string_view to_string_view(string_like) { return "foo"; } - -constexpr char with_null[3] = {'{', '}', '\0'}; -constexpr char no_null[2] = {'{', '}'}; -static FMT_CONSTEXPR_DECL const char static_with_null[3] = {'{', '}', '\0'}; -static FMT_CONSTEXPR_DECL const char static_no_null[2] = {'{', '}'}; - -TEST(format_test, compile_time_string) { - EXPECT_EQ("foo", fmt::format(FMT_STRING("foo"))); - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); - EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like())); - -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS - using namespace fmt::literals; - EXPECT_EQ("foobar", fmt::format(FMT_STRING("{foo}{bar}"), "bar"_a = "bar", - "foo"_a = "foo")); - EXPECT_EQ("", fmt::format(FMT_STRING(""))); - EXPECT_EQ("", fmt::format(FMT_STRING(""), "arg"_a = 42)); -#endif - - (void)static_with_null; - (void)static_no_null; -#ifndef _MSC_VER - EXPECT_EQ("42", fmt::format(FMT_STRING(static_with_null), 42)); - EXPECT_EQ("42", fmt::format(FMT_STRING(static_no_null), 42)); -#endif - - (void)with_null; - (void)no_null; -#if __cplusplus >= 201703L - EXPECT_EQ("42", fmt::format(FMT_STRING(with_null), 42)); - EXPECT_EQ("42", fmt::format(FMT_STRING(no_null), 42)); -#endif -#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L - EXPECT_EQ("42", fmt::format(FMT_STRING(std::string_view("{}")), 42)); -#endif -} - -TEST(format_test, custom_format_compile_time_string) { - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), Answer())); - auto answer = Answer(); - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), answer)); - char buf[10] = {}; - fmt::format_to(buf, FMT_STRING("{}"), answer); - const Answer const_answer = Answer(); - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), const_answer)); -} - -#if FMT_USE_USER_DEFINED_LITERALS -// Passing user-defined literals directly to EXPECT_EQ causes problems -// with macro argument stringification (#) on some versions of GCC. -// Workaround: Assing the UDL result to a variable before the macro. - -using namespace fmt::literals; - -# if FMT_GCC_VERSION -# define FMT_CHECK_DEPRECATED_UDL_FORMAT 1 -# elif FMT_CLANG_VERSION && defined(__has_warning) -# if __has_warning("-Wdeprecated-declarations") -# define FMT_CHECK_DEPRECATED_UDL_FORMAT 1 -# endif -# endif -# ifndef FMT_CHECK_DEPRECATED_UDL_FORMAT -# define FMT_CHECK_DEPRECATED_UDL_FORMAT 0 -# endif - -# if FMT_CHECK_DEPRECATED_UDL_FORMAT -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -TEST(format_test, format_udl) { - EXPECT_EQ("{}c{}"_format("ab", 1), fmt::format("{}c{}", "ab", 1)); - EXPECT_EQ("foo"_format(), "foo"); - EXPECT_EQ("{0:10}"_format(42), " 42"); - EXPECT_EQ("{}"_format(date(2015, 10, 21)), "2015-10-21"); -} - -# pragma GCC diagnostic pop -# endif - -TEST(format_test, named_arg_udl) { - auto udl_a = fmt::format("{first}{second}{first}{third}", "first"_a = "abra", - "second"_a = "cad", "third"_a = 99); - EXPECT_EQ( - fmt::format("{first}{second}{first}{third}", fmt::arg("first", "abra"), - fmt::arg("second", "cad"), fmt::arg("third", 99)), - udl_a); -} -#endif // FMT_USE_USER_DEFINED_LITERALS - -TEST(format_test, enum) { EXPECT_EQ("0", fmt::format("{}", foo)); } - -TEST(format_test, formatter_not_specialized) { - static_assert(!fmt::has_formatter<fmt::formatter<test_enum>, - fmt::format_context>::value, - ""); -} - -#if FMT_HAS_FEATURE(cxx_strong_enums) -enum big_enum : unsigned long long { big_enum_value = 5000000000ULL }; - -TEST(format_test, strong_enum) { - EXPECT_EQ("5000000000", fmt::format("{}", big_enum_value)); -} -#endif - -TEST(format_test, non_null_terminated_format_string) { - EXPECT_EQ("42", fmt::format(string_view("{}foo", 2), 42)); -} - -struct variant { - enum { int_type, string_type } type; - explicit variant(int) : type(int_type) {} - explicit variant(const char*) : type(string_type) {} -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<variant> : dynamic_formatter<> { - auto format(variant value, format_context& ctx) -> decltype(ctx.out()) { - if (value.type == variant::int_type) - return dynamic_formatter<>::format(42, ctx); - return dynamic_formatter<>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -TEST(format_test, dynamic_formatter) { - auto num = variant(42); - auto str = variant("foo"); - EXPECT_EQ("42", fmt::format("{:d}", num)); - EXPECT_EQ("foo", fmt::format("{:s}", str)); - EXPECT_EQ(" 42 foo ", fmt::format("{:{}} {:{}}", num, 3, str, 4)); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{}}"), num), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:{0}}"), num), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:+}"), str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:-}"), str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{: }"), str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:#}"), str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:0}"), str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{:.2}"), num), format_error, - "precision not allowed for this argument type"); -} - -namespace adl_test { -namespace fmt { -namespace detail { -struct foo {}; -template <typename, typename OutputIt> void write(OutputIt, foo) = delete; -} // namespace detail -} // namespace fmt -} // namespace adl_test - -FMT_BEGIN_NAMESPACE -template <> -struct formatter<adl_test::fmt::detail::foo> : formatter<std::string> { - template <typename FormatContext> - auto format(adl_test::fmt::detail::foo, FormatContext& ctx) - -> decltype(ctx.out()) { - return formatter<std::string>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -struct convertible_to_int { - operator int() const { return value; } - - int value = 42; -}; - -TEST(format_test, to_string) { - EXPECT_EQ(fmt::to_string(42), "42"); - EXPECT_EQ(fmt::to_string(reinterpret_cast<void*>(0x1234)), "0x1234"); - EXPECT_EQ(fmt::to_string(adl_test::fmt::detail::foo()), "foo"); - EXPECT_EQ(fmt::to_string(convertible_to_int()), "42"); - - enum foo : unsigned char { zero }; - EXPECT_EQ(fmt::to_string(zero), "0"); -} - -TEST(format_test, output_iterators) { - std::list<char> out; - fmt::format_to(std::back_inserter(out), "{}", 42); - EXPECT_EQ("42", std::string(out.begin(), out.end())); - std::stringstream s; - fmt::format_to(std::ostream_iterator<char>(s), "{}", 42); - EXPECT_EQ("42", s.str()); -} - -TEST(format_test, formatted_size) { - EXPECT_EQ(2u, fmt::formatted_size("{}", 42)); -} - -TEST(format_test, format_to_no_args) { - std::string s; - fmt::format_to(std::back_inserter(s), "test"); - EXPECT_EQ("test", s); -} - -TEST(format_test, format_to) { - std::string s; - fmt::format_to(std::back_inserter(s), "part{0}", 1); - EXPECT_EQ("part1", s); - fmt::format_to(std::back_inserter(s), "part{0}", 2); - EXPECT_EQ("part1part2", s); -} - -TEST(format_test, format_to_memory_buffer) { - auto buf = fmt::basic_memory_buffer<char, 100>(); - fmt::format_to(fmt::appender(buf), "{}", "foo"); - EXPECT_EQ("foo", to_string(buf)); -} - -TEST(format_test, format_to_vector) { - std::vector<char> v; - fmt::format_to(std::back_inserter(v), "{}", "foo"); - EXPECT_EQ(string_view(v.data(), v.size()), "foo"); -} - -struct nongrowing_container { - using value_type = char; - void push_back(char) { throw std::runtime_error("can't take it any more"); } -}; - -TEST(format_test, format_to_propagates_exceptions) { - auto c = nongrowing_container(); - EXPECT_THROW(fmt::format_to(std::back_inserter(c), "{}", 42), - std::runtime_error); -} - -TEST(format_test, format_to_n) { - char buffer[4]; - buffer[3] = 'x'; - auto result = fmt::format_to_n(buffer, 3, "{}", 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("123x", fmt::string_view(buffer, 4)); - - result = fmt::format_to_n(buffer, 3, "{:s}", "foobar"); - EXPECT_EQ(6u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("foox", fmt::string_view(buffer, 4)); - - buffer[0] = 'x'; - buffer[1] = 'x'; - buffer[2] = 'x'; - result = fmt::format_to_n(buffer, 3, "{}", 'A'); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ("Axxx", fmt::string_view(buffer, 4)); - - result = fmt::format_to_n(buffer, 3, "{}{} ", 'B', 'C'); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("BC x", fmt::string_view(buffer, 4)); - - result = fmt::format_to_n(buffer, 4, "{}", "ABCDE"); - EXPECT_EQ(5u, result.size); - EXPECT_EQ("ABCD", fmt::string_view(buffer, 4)); - - buffer[3] = 'x'; - result = fmt::format_to_n(buffer, 3, "{}", std::string(1000, '*')); - EXPECT_EQ(1000u, result.size); - EXPECT_EQ("***x", fmt::string_view(buffer, 4)); -} - -struct test_output_iterator { - char* data; - - using iterator_category = std::output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - - test_output_iterator& operator++() { - ++data; - return *this; - } - test_output_iterator operator++(int) { - auto tmp = *this; - ++data; - return tmp; - } - char& operator*() { return *data; } -}; - -TEST(format_test, format_to_n_output_iterator) { - char buf[10] = {}; - fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42); - EXPECT_STREQ(buf, "42"); -} - -#if FMT_USE_CONSTEXPR -struct test_error_handler { - const char*& error; - - FMT_CONSTEXPR test_error_handler(const char*& err) : error(err) {} - - FMT_CONSTEXPR test_error_handler(const test_error_handler& other) - : error(other.error) {} - - FMT_CONSTEXPR void on_error(const char* message) { - if (!error) error = message; - } -}; - -FMT_CONSTEXPR size_t len(const char* s) { - size_t len = 0; - while (*s++) ++len; - return len; -} - -FMT_CONSTEXPR bool equal(const char* s1, const char* s2) { - if (!s1 || !s2) return s1 == s2; - while (*s1 && *s1 == *s2) { - ++s1; - ++s2; - } - return *s1 == *s2; -} - -template <typename... Args> -FMT_CONSTEXPR bool test_error(const char* fmt, const char* expected_error) { - const char* actual_error = nullptr; - auto s = string_view(fmt, len(fmt)); - auto checker = - fmt::detail::format_string_checker<char, test_error_handler, Args...>( - s, test_error_handler(actual_error)); - fmt::detail::parse_format_string<true>(s, checker); - return equal(actual_error, expected_error); -} - -# define EXPECT_ERROR_NOARGS(fmt, error) \ - static_assert(test_error(fmt, error), "") -# define EXPECT_ERROR(fmt, error, ...) \ - static_assert(test_error<__VA_ARGS__>(fmt, error), "") - -TEST(format_test, format_string_errors) { - EXPECT_ERROR_NOARGS("foo", nullptr); - EXPECT_ERROR_NOARGS("}", "unmatched '}' in format string"); - EXPECT_ERROR("{0:s", "unknown format specifier", date); -# if !FMT_MSC_VER || FMT_MSC_VER >= 1916 - // This causes an detail compiler error in MSVC2017. - EXPECT_ERROR("{:{<}", "invalid fill character '{'", int); - EXPECT_ERROR("{:10000000000}", "number is too big", int); - EXPECT_ERROR("{:.10000000000}", "number is too big", int); - EXPECT_ERROR_NOARGS("{:x}", "argument not found"); - EXPECT_ERROR("{:+}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:-}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:#}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{: }", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:0}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:+}", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{:-}", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{: }", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{:{}}", "argument not found", int); - EXPECT_ERROR("{:.{}}", "argument not found", double); - EXPECT_ERROR("{:.2}", "precision not allowed for this argument type", int); - EXPECT_ERROR("{:s}", "invalid type specifier", int); - EXPECT_ERROR("{:s}", "invalid type specifier", char); - EXPECT_ERROR("{:+}", "invalid format specifier for char", char); - EXPECT_ERROR("{:s}", "invalid type specifier", double); - EXPECT_ERROR("{:d}", "invalid type specifier", const char*); - EXPECT_ERROR("{:d}", "invalid type specifier", std::string); - EXPECT_ERROR("{:s}", "invalid type specifier", void*); -# else - fmt::print("warning: constexpr is broken in this version of MSVC\n"); -# endif -# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS - EXPECT_ERROR("{foo}", "named argument is not found", decltype("bar"_a = 42)); - EXPECT_ERROR("{foo}", "named argument is not found", - decltype(fmt::arg("foo", 42))); -# else - EXPECT_ERROR("{foo}", - "compile-time checks for named arguments require C++20 support", - int); -# endif - EXPECT_ERROR_NOARGS("{10000000000}", "argument not found"); - EXPECT_ERROR_NOARGS("{0x}", "invalid format string"); - EXPECT_ERROR_NOARGS("{-}", "invalid format string"); - EXPECT_ERROR("{:{0x}}", "invalid format string", int); - EXPECT_ERROR("{:{-}}", "invalid format string", int); - EXPECT_ERROR("{:.{0x}}", "invalid format string", int); - EXPECT_ERROR("{:.{-}}", "invalid format string", int); - EXPECT_ERROR("{:.x}", "missing precision specifier", int); - EXPECT_ERROR_NOARGS("{}", "argument not found"); - EXPECT_ERROR("{1}", "argument not found", int); - EXPECT_ERROR("{1}{}", - "cannot switch from manual to automatic argument indexing", int, - int); - EXPECT_ERROR("{}{1}", - "cannot switch from automatic to manual argument indexing", int, - int); -} - -TEST(format_test, vformat_to) { - using context = fmt::format_context; - fmt::basic_format_arg<context> arg = fmt::detail::make_arg<context>(42); - auto args = fmt::basic_format_args<context>(&arg, 1); - auto s = std::string(); - fmt::vformat_to(std::back_inserter(s), "{}", args); - EXPECT_EQ("42", s); - s.clear(); - fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args); - EXPECT_EQ("42", s); -} - -#endif // FMT_USE_CONSTEXPR - -TEST(format_test, char_traits_is_not_ambiguous) { - // Test that we don't inject detail names into the std namespace. - using namespace std; - auto c = char_traits<char>::char_type(); - (void)c; -#if __cplusplus >= 201103L - auto s = std::string(); - auto lval = begin(s); - (void)lval; -#endif -} - -struct check_back_appender {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<check_back_appender> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename Context> - auto format(check_back_appender, Context& ctx) -> decltype(ctx.out()) { - auto out = ctx.out(); - static_assert(std::is_same<decltype(++out), decltype(out)&>::value, - "needs to satisfy weakly_incrementable"); - *out = 'y'; - return ++out; - } -}; -FMT_END_NAMESPACE - -TEST(format_test, back_insert_slicing) { - EXPECT_EQ(fmt::format("{}", check_back_appender{}), "y"); -} - -template <typename Char, typename T> bool check_enabled_formatter() { - static_assert(std::is_default_constructible<fmt::formatter<T, Char>>::value, - ""); - return true; -} - -template <typename Char, typename... T> void check_enabled_formatters() { - auto dummy = {check_enabled_formatter<Char, T>()...}; - (void)dummy; -} - -TEST(format_test, test_formatters_enabled) { - check_enabled_formatters<char, bool, char, signed char, unsigned char, short, - unsigned short, int, unsigned, long, unsigned long, - long long, unsigned long long, float, double, - long double, void*, const void*, char*, const char*, - std::string, std::nullptr_t>(); - check_enabled_formatters<wchar_t, bool, wchar_t, signed char, unsigned char, - short, unsigned short, int, unsigned, long, - unsigned long, long long, unsigned long long, float, - double, long double, void*, const void*, wchar_t*, - const wchar_t*, std::wstring, std::nullptr_t>(); -} - -TEST(format_int_test, data) { - fmt::format_int format_int(42); - EXPECT_EQ("42", std::string(format_int.data(), format_int.size())); -} - -TEST(format_int_test, format_int) { - EXPECT_EQ("42", fmt::format_int(42).str()); - EXPECT_EQ(2u, fmt::format_int(42).size()); - EXPECT_EQ("-42", fmt::format_int(-42).str()); - EXPECT_EQ(3u, fmt::format_int(-42).size()); - EXPECT_EQ("42", fmt::format_int(42ul).str()); - EXPECT_EQ("-42", fmt::format_int(-42l).str()); - EXPECT_EQ("42", fmt::format_int(42ull).str()); - EXPECT_EQ("-42", fmt::format_int(-42ll).str()); - std::ostringstream os; - os << max_value<int64_t>(); - EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str()); -} diff --git a/contrib/libs/fmt/test/format-test/ya.make b/contrib/libs/fmt/test/format-test/ya.make deleted file mode 100644 index 672765d32b..0000000000 --- a/contrib/libs/fmt/test/format-test/ya.make +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -ALLOCATOR(J) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - format-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/gtest-extra-test.cc b/contrib/libs/fmt/test/gtest-extra-test.cc deleted file mode 100644 index 0d86206c93..0000000000 --- a/contrib/libs/fmt/test/gtest-extra-test.cc +++ /dev/null @@ -1,413 +0,0 @@ -// Formatting library for C++ - tests of custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "gtest-extra.h" - -#include <gtest/gtest-spi.h> - -#include <cstring> -#include <memory> -#include <stdexcept> - -#include "fmt/os.h" -#include "util.h" - -// Tests that assertion macros evaluate their arguments exactly once. -namespace { -class single_evaluation_test : public ::testing::Test { - protected: - single_evaluation_test() { - p_ = s_; - a_ = 0; - b_ = 0; - } - - static const char* const s_; - static const char* p_; - - static int a_; - static int b_; -}; -} // namespace - -const char* const single_evaluation_test::s_ = "01234"; -const char* single_evaluation_test::p_; -int single_evaluation_test::a_; -int single_evaluation_test::b_; - -void do_nothing() {} - -FMT_NORETURN void throw_exception() { throw std::runtime_error("test"); } - -FMT_NORETURN void throw_system_error() { - throw fmt::system_error(EDOM, "test"); -} - -// Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument -// exactly once. -TEST_F(single_evaluation_test, failed_expect_throw_msg) { - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, p_++), "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that when EXPECT_SYSTEM_ERROR fails, it evaluates its message argument -// exactly once. -TEST_F(single_evaluation_test, failed_expect_system_error) { - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++), - "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that assertion arguments are evaluated exactly once. -TEST_F(single_evaluation_test, exception_tests) { - // successful EXPECT_THROW_MSG - EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::exception, (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_THROW_MSG, throws different type - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::logic_error, (b_++, "test")), - "throws a different type"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); - - // failed EXPECT_THROW_MSG, throws an exception with different message - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::exception, (b_++, "other")), - "throws an exception with a different message"); - EXPECT_EQ(3, a_); - EXPECT_EQ(3, b_); - - // failed EXPECT_THROW_MSG, throws nothing - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing"); - EXPECT_EQ(4, a_); - EXPECT_EQ(4, b_); -} - -TEST_F(single_evaluation_test, system_error_tests) { - // successful EXPECT_SYSTEM_ERROR - EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_system_error(); - }, - EDOM, (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_SYSTEM_ERROR, throws different type - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_exception(); - }, - EDOM, (b_++, "test")), - "throws a different type"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); - - // failed EXPECT_SYSTEM_ERROR, throws an exception with different message - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_system_error(); - }, - EDOM, (b_++, "other")), - "throws an exception with a different message"); - EXPECT_EQ(3, a_); - EXPECT_EQ(3, b_); - - // failed EXPECT_SYSTEM_ERROR, throws nothing - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")), - "throws nothing"); - EXPECT_EQ(4, a_); - EXPECT_EQ(4, b_); -} - -#if FMT_USE_FCNTL -// Tests that when EXPECT_WRITE fails, it evaluates its message argument -// exactly once. -TEST_F(single_evaluation_test, failed_expect_write) { - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), p_++), - "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that assertion arguments are evaluated exactly once. -TEST_F(single_evaluation_test, write_tests) { - // successful EXPECT_WRITE - EXPECT_WRITE( - stdout, - { // NOLINT - a_++; - std::printf("test"); - }, - (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_WRITE - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE( - stdout, - { // NOLINT - a_++; - std::printf("test"); - }, - (b_++, "other")), - "Actual: test"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); -} - -// Tests EXPECT_WRITE. -TEST(gtest_extra_test, expect_write) { - EXPECT_WRITE(stdout, do_nothing(), ""); - EXPECT_WRITE(stdout, std::printf("test"), "test"); - EXPECT_WRITE(stderr, std::fprintf(stderr, "test"), "test"); - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("that"), "this"), - "Expected: this\n" - " Actual: that"); -} - -TEST(gtest_extra_test, expect_write_streaming) { - EXPECT_WRITE(stdout, std::printf("test"), "test") << "unexpected failure"; - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), "other") - << "expected failure", - "expected failure"); -} -#endif // FMT_USE_FCNTL - -// Tests that the compiler will not complain about unreachable code in the -// EXPECT_THROW_MSG macro. -TEST(gtest_extra_test, expect_throw_no_unreachable_code_warning) { - int n = 0; - using std::runtime_error; - EXPECT_THROW_MSG(throw runtime_error(""), runtime_error, ""); - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(n++, runtime_error, ""), ""); - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(throw 1, runtime_error, ""), ""); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw runtime_error("a"), runtime_error, "b"), ""); -} - -// Tests that the compiler will not complain about unreachable code in the -// EXPECT_SYSTEM_ERROR macro. -TEST(gtest_extra_test, expect_system_error_no_unreachable_code_warning) { - int n = 0; - EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "test"), EDOM, "test"); - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(n++, EDOM, ""), ""); - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw 1, EDOM, ""), ""); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "aaa"), EDOM, "bbb"), - ""); -} - -TEST(gtest_extra_test, expect_throw_behaves_like_single_statement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_THROW_MSG(do_nothing(), std::exception, ""); - - if (::testing::internal::AlwaysTrue()) - EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - else - do_nothing(); -} - -TEST(gtest_extra_test, expect_system_error_behaves_like_single_statement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, ""); - - if (::testing::internal::AlwaysTrue()) - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - else - do_nothing(); -} - -TEST(gtest_extra_test, expect_write_behaves_like_single_statement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_WRITE(stdout, std::printf("x"), "x"); - - if (::testing::internal::AlwaysTrue()) - EXPECT_WRITE(stdout, std::printf("x"), "x"); - else - do_nothing(); -} - -// Tests EXPECT_THROW_MSG. -TEST(gtest_extra_test, expect_throw_msg) { - EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::logic_error, "test"), - "Expected: throw_exception() throws an exception of " - "type std::logic_error.\n Actual: it throws a different type."); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(do_nothing(), std::exception, "test"), - "Expected: do_nothing() throws an exception of type std::exception.\n" - " Actual: it throws nothing."); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, "other"), - "throw_exception() throws an exception with a different message.\n" - "Expected: other\n" - " Actual: test"); -} - -// Tests EXPECT_SYSTEM_ERROR. -TEST(gtest_extra_test, expect_system_error) { - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_exception(), EDOM, "test"), - "Expected: throw_exception() throws an exception of " - "type std::system_error.\n Actual: it throws a different type."); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "test"), - "Expected: do_nothing() throws an exception of type std::system_error.\n" - " Actual: it throws nothing."); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other"), - fmt::format( - "throw_system_error() throws an exception with a different message.\n" - "Expected: {}\n" - " Actual: {}", - system_error_message(EDOM, "other"), - system_error_message(EDOM, "test"))); -} - -TEST(gtest_extra_test, expect_throw_msg_streaming) { - EXPECT_THROW_MSG(throw_exception(), std::exception, "test") - << "unexpected failure"; - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, "other") - << "expected failure", - "expected failure"); -} - -TEST(gtest_extra_test, expect_system_error_streaming) { - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test") - << "unexpected failure"; - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other") - << "expected failure", - "expected failure"); -} - -#if FMT_USE_FCNTL - -using fmt::buffered_file; -using fmt::file; - -TEST(output_redirect_test, scoped_redirect) { - file read_end, write_end; - file::pipe(read_end, write_end); - { - buffered_file file(write_end.fdopen("w")); - std::fprintf(file.get(), "[[["); - { - output_redirect redir(file.get()); - std::fprintf(file.get(), "censored"); - } - std::fprintf(file.get(), "]]]"); - } - EXPECT_READ(read_end, "[[[]]]"); -} - -// Test that output_redirect handles errors in flush correctly. -TEST(output_redirect_test, flush_error_in_ctor) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); - FMT_POSIX(close(write_fd)); - std::unique_ptr<output_redirect> redir{nullptr}; - EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new output_redirect(f.get())), EBADF, - "cannot flush stream"); - redir.reset(nullptr); - write_copy.dup2(write_fd); // "undo" close or dtor will fail -} - -TEST(output_redirect_test, dup_error_in_ctor) { - buffered_file f = open_buffered_file(); - int fd = (f.fileno)(); - file copy = file::dup(fd); - FMT_POSIX(close(fd)); - std::unique_ptr<output_redirect> redir{nullptr}; - EXPECT_SYSTEM_ERROR_NOASSERT( - redir.reset(new output_redirect(f.get())), EBADF, - fmt::format("cannot duplicate file descriptor {}", fd)); - copy.dup2(fd); // "undo" close or dtor will fail -} - -TEST(output_redirect_test, restore_and_read) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file file(write_end.fdopen("w")); - std::fprintf(file.get(), "[[["); - output_redirect redir(file.get()); - std::fprintf(file.get(), "censored"); - EXPECT_EQ("censored", redir.restore_and_read()); - EXPECT_EQ("", redir.restore_and_read()); - std::fprintf(file.get(), "]]]"); - file = buffered_file(); - EXPECT_READ(read_end, "[[[]]]"); -} - -// Test that OutputRedirect handles errors in flush correctly. -TEST(output_redirect_test, flush_error_in_restore_and_read) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - output_redirect redir(f.get()); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); - FMT_POSIX(close(write_fd)); - EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(), EBADF, - "cannot flush stream"); - write_copy.dup2(write_fd); // "undo" close or dtor will fail -} - -TEST(output_redirect_test, error_in_dtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - std::unique_ptr<output_redirect> redir(new output_redirect(f.get())); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); - EXPECT_WRITE( - stderr, - { - // The close function must be called inside EXPECT_WRITE, - // otherwise the system may recycle closed file descriptor when - // redirecting the output in EXPECT_STDERR and the second close - // will break output redirection. - FMT_POSIX(close(write_fd)); - SUPPRESS_ASSERT(redir.reset(nullptr)); - }, - system_error_message(EBADF, "cannot flush stream")); - write_copy.dup2(write_fd); // "undo" close or dtor of buffered_file will fail -} - -#endif // FMT_USE_FCNTL diff --git a/contrib/libs/fmt/test/gtest-extra-test/ya.make b/contrib/libs/fmt/test/gtest-extra-test/ya.make deleted file mode 100644 index 407c5e33d8..0000000000 --- a/contrib/libs/fmt/test/gtest-extra-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - gtest-extra-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/gtest-extra.cc b/contrib/libs/fmt/test/gtest-extra.cc deleted file mode 100644 index 1d48a1736d..0000000000 --- a/contrib/libs/fmt/test/gtest-extra.cc +++ /dev/null @@ -1,80 +0,0 @@ -// Formatting library for C++ - custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "gtest-extra.h" - -#if FMT_USE_FCNTL - -using fmt::file; - -output_redirect::output_redirect(FILE* f) : file_(f) { - flush(); - int fd = FMT_POSIX(fileno(f)); - // Create a file object referring to the original file. - original_ = file::dup(fd); - // Create a pipe. - file write_end; - file::pipe(read_end_, write_end); - // Connect the passed FILE object to the write end of the pipe. - write_end.dup2(fd); -} - -output_redirect::~output_redirect() FMT_NOEXCEPT { - try { - restore(); - } catch (const std::exception& e) { - std::fputs(e.what(), stderr); - } -} - -void output_redirect::flush() { - int result = 0; - do { - result = fflush(file_); - } while (result == EOF && errno == EINTR); - if (result != 0) throw fmt::system_error(errno, "cannot flush stream"); -} - -void output_redirect::restore() { - if (original_.descriptor() == -1) return; // Already restored. - flush(); - // Restore the original file. - original_.dup2(FMT_POSIX(fileno(file_))); - original_.close(); -} - -std::string output_redirect::restore_and_read() { - // Restore output. - restore(); - - // Read everything from the pipe. - std::string content; - if (read_end_.descriptor() == -1) return content; // Already read. - enum { BUFFER_SIZE = 4096 }; - char buffer[BUFFER_SIZE]; - size_t count = 0; - do { - count = read_end_.read(buffer, BUFFER_SIZE); - content.append(buffer, count); - } while (count != 0); - read_end_.close(); - return content; -} - -std::string read(file& f, size_t count) { - std::string buffer(count, '\0'); - size_t n = 0, offset = 0; - do { - n = f.read(&buffer[offset], count - offset); - // We can't read more than size_t bytes since count has type size_t. - offset += n; - } while (offset < count && n != 0); - buffer.resize(offset); - return buffer; -} - -#endif // FMT_USE_FCNTL diff --git a/contrib/libs/fmt/test/gtest-extra.h b/contrib/libs/fmt/test/gtest-extra.h deleted file mode 100644 index f779731748..0000000000 --- a/contrib/libs/fmt/test/gtest-extra.h +++ /dev/null @@ -1,171 +0,0 @@ -// Formatting library for C++ - custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_GTEST_EXTRA_H_ -#define FMT_GTEST_EXTRA_H_ - -#include <stdlib.h> // _invalid_parameter_handler - -#include <string> - -#ifdef FMT_MODULE_TEST -import fmt; -#else -# include "fmt/os.h" -#endif // FMG_MODULE_TEST - -#include "gmock/gmock.h" - -#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ - std::string gtest_expected_message = expected_message; \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (expected_exception const& e) { \ - if (gtest_expected_message != e.what()) { \ - gtest_ar << #statement \ - " throws an exception with a different message.\n" \ - << "Expected: " << gtest_expected_message << "\n" \ - << " Actual: " << e.what(); \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - gtest_caught_expected = true; \ - } catch (...) { \ - gtest_ar << "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_ar << "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_ar.failure_message()) - -// Tests that the statement throws the expected exception and the exception's -// what() method returns expected message. -#define EXPECT_THROW_MSG(statement, expected_exception, expected_message) \ - FMT_TEST_THROW_(statement, expected_exception, expected_message, \ - GTEST_NONFATAL_FAILURE_) - -inline std::string system_error_message(int error_code, - const std::string& message) { - auto ec = std::error_code(error_code, std::generic_category()); - return std::system_error(ec, message).what(); -} - -#define EXPECT_SYSTEM_ERROR(statement, error_code, message) \ - EXPECT_THROW_MSG(statement, std::system_error, \ - system_error_message(error_code, message)) - -#if FMT_USE_FCNTL - -// Captures file output by redirecting it to a pipe. -// The output it can handle is limited by the pipe capacity. -class output_redirect { - private: - FILE* file_; - fmt::file original_; // Original file passed to redirector. - fmt::file read_end_; // Read end of the pipe where the output is redirected. - - void flush(); - void restore(); - - public: - explicit output_redirect(FILE* file); - ~output_redirect() FMT_NOEXCEPT; - - output_redirect(const output_redirect&) = delete; - void operator=(const output_redirect&) = delete; - - // Restores the original file, reads output from the pipe into a string - // and returns it. - std::string restore_and_read(); -}; - -# define FMT_TEST_WRITE_(statement, expected_output, file, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ - std::string gtest_expected_output = expected_output; \ - output_redirect gtest_redir(file); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - std::string gtest_output = gtest_redir.restore_and_read(); \ - if (gtest_output != gtest_expected_output) { \ - gtest_ar << #statement " produces different output.\n" \ - << "Expected: " << gtest_expected_output << "\n" \ - << " Actual: " << gtest_output; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_ar.failure_message()) - -// Tests that the statement writes the expected output to file. -# define EXPECT_WRITE(file, statement, expected_output) \ - FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_) - -# ifdef _MSC_VER -#include <crtdbg.h> - -// Suppresses Windows assertions on invalid file descriptors, making -// POSIX functions return proper error codes instead of crashing on Windows. -class suppress_assert { - private: - _invalid_parameter_handler original_handler_; - int original_report_mode_; - - static void handle_invalid_parameter(const wchar_t*, const wchar_t*, - const wchar_t*, unsigned, uintptr_t) {} - - public: - suppress_assert() - : original_handler_( - _set_invalid_parameter_handler(handle_invalid_parameter)), - original_report_mode_(_CrtSetReportMode(_CRT_ASSERT, 0)) {} - ~suppress_assert() { - _set_invalid_parameter_handler(original_handler_); - _CrtSetReportMode(_CRT_ASSERT, original_report_mode_); - (void)original_report_mode_; - } -}; - -# define SUPPRESS_ASSERT(statement) \ - { \ - suppress_assert sa; \ - statement; \ - } -# else -# define SUPPRESS_ASSERT(statement) statement -# endif // _MSC_VER - -# define EXPECT_SYSTEM_ERROR_NOASSERT(statement, error_code, message) \ - EXPECT_SYSTEM_ERROR(SUPPRESS_ASSERT(statement), error_code, message) - -// Attempts to read count characters from a file. -std::string read(fmt::file& f, size_t count); - -# define EXPECT_READ(file, expected_content) \ - EXPECT_EQ(expected_content, \ - read(file, fmt::string_view(expected_content).size())) - -#else -# define EXPECT_WRITE(file, statement, expected_output) \ - do { \ - (void)(file); \ - (void)(statement); \ - (void)(expected_output); \ - SUCCEED(); \ - } while (false) -#endif // FMT_USE_FCNTL - -#endif // FMT_GTEST_EXTRA_H_ diff --git a/contrib/libs/fmt/test/header-only-test.cc b/contrib/libs/fmt/test/header-only-test.cc deleted file mode 100644 index 570f09a563..0000000000 --- a/contrib/libs/fmt/test/header-only-test.cc +++ /dev/null @@ -1,11 +0,0 @@ -// Header-only configuration test - -#include "fmt/core.h" -#include "fmt/ostream.h" -#include "gtest/gtest.h" - -#ifndef FMT_HEADER_ONLY -# error "Not in the header-only mode." -#endif - -TEST(header_only_test, format) { EXPECT_EQ(fmt::format("foo"), "foo"); } diff --git a/contrib/libs/fmt/test/mock-allocator.h b/contrib/libs/fmt/test/mock-allocator.h deleted file mode 100644 index 6a67e08f4f..0000000000 --- a/contrib/libs/fmt/test/mock-allocator.h +++ /dev/null @@ -1,64 +0,0 @@ -// Formatting library for C++ - mock allocator -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_MOCK_ALLOCATOR_H_ -#define FMT_MOCK_ALLOCATOR_H_ - -#include <assert.h> // assert -#include <stddef.h> // size_t - -#include <memory> // std::allocator_traits - -#include "gmock/gmock.h" - -template <typename T> class mock_allocator { - public: - mock_allocator() {} - mock_allocator(const mock_allocator&) {} - using value_type = T; - MOCK_METHOD1_T(allocate, T*(size_t n)); - MOCK_METHOD2_T(deallocate, void(T* p, size_t n)); -}; - -template <typename Allocator> class allocator_ref { - private: - Allocator* alloc_; - - void move(allocator_ref& other) { - alloc_ = other.alloc_; - other.alloc_ = nullptr; - } - - public: - using value_type = typename Allocator::value_type; - - explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {} - - allocator_ref(const allocator_ref& other) : alloc_(other.alloc_) {} - allocator_ref(allocator_ref&& other) { move(other); } - - allocator_ref& operator=(allocator_ref&& other) { - assert(this != &other); - move(other); - return *this; - } - - allocator_ref& operator=(const allocator_ref& other) { - alloc_ = other.alloc_; - return *this; - } - - public: - Allocator* get() const { return alloc_; } - - value_type* allocate(size_t n) { - return std::allocator_traits<Allocator>::allocate(*alloc_, n); - } - void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); } -}; - -#endif // FMT_MOCK_ALLOCATOR_H_ diff --git a/contrib/libs/fmt/test/os-test.cc b/contrib/libs/fmt/test/os-test.cc deleted file mode 100644 index 5b5ef76ed6..0000000000 --- a/contrib/libs/fmt/test/os-test.cc +++ /dev/null @@ -1,551 +0,0 @@ -// Formatting library for C++ - tests of the OS-specific functionality -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/os.h" - -#include <cstdlib> // std::exit -#include <cstring> -#include <memory> - -#include "gtest-extra.h" -#include "util.h" - -#ifdef fileno -# undef fileno -#endif - -using fmt::buffered_file; -using testing::HasSubstr; -using wstring_view = fmt::basic_string_view<wchar_t>; - -#ifdef _WIN32 - -# include <windows.h> - -TEST(util_test, utf16_to_utf8) { - auto s = std::string("ёжик"); - fmt::detail::utf16_to_utf8 u(L"\x0451\x0436\x0438\x043A"); - EXPECT_EQ(s, u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -TEST(util_test, utf16_to_utf8_empty_string) { - std::string s = ""; - fmt::detail::utf16_to_utf8 u(L""); - EXPECT_EQ(s, u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -template <typename Converter, typename Char> -void check_utf_conversion_error(const char* message, - fmt::basic_string_view<Char> str = - fmt::basic_string_view<Char>(nullptr, 1)) { - fmt::memory_buffer out; - fmt::detail::format_windows_error(out, ERROR_INVALID_PARAMETER, message); - auto error = std::system_error(std::error_code()); - try { - (Converter)(str); - } catch (const std::system_error& e) { - error = e; - } - EXPECT_EQ(ERROR_INVALID_PARAMETER, error.code().value()); - EXPECT_THAT(error.what(), HasSubstr(fmt::to_string(out))); -} - -TEST(util_test, utf16_to_utf8_error) { - check_utf_conversion_error<fmt::detail::utf16_to_utf8, wchar_t>( - "cannot convert string from UTF-16 to UTF-8"); -} - -TEST(util_test, utf16_to_utf8_convert) { - fmt::detail::utf16_to_utf8 u; - EXPECT_EQ(ERROR_INVALID_PARAMETER, u.convert(wstring_view(nullptr, 1))); - EXPECT_EQ(ERROR_INVALID_PARAMETER, - u.convert(wstring_view(L"foo", INT_MAX + 1u))); -} - -TEST(os_test, format_std_error_code) { - EXPECT_EQ("generic:42", - fmt::format(FMT_STRING("{0}"), - std::error_code(42, std::generic_category()))); - EXPECT_EQ("system:42", - fmt::format(FMT_STRING("{0}"), - std::error_code(42, fmt::system_category()))); - EXPECT_EQ("system:-42", - fmt::format(FMT_STRING("{0}"), - std::error_code(-42, fmt::system_category()))); -} - -TEST(os_test, format_windows_error) { - LPWSTR message = nullptr; - auto result = FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, ERROR_FILE_EXISTS, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast<LPWSTR>(&message), 0, nullptr); - fmt::detail::utf16_to_utf8 utf8_message(wstring_view(message, result - 2)); - LocalFree(message); - fmt::memory_buffer actual_message; - fmt::detail::format_windows_error(actual_message, ERROR_FILE_EXISTS, "test"); - EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), - fmt::to_string(actual_message)); - actual_message.resize(0); -} - -TEST(os_test, format_long_windows_error) { - LPWSTR message = nullptr; - // this error code is not available on all Windows platforms and - // Windows SDKs, so do not fail the test if the error string cannot - // be retrieved. - int provisioning_not_allowed = 0x80284013L; // TBS_E_PROVISIONING_NOT_ALLOWED - auto result = FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, static_cast<DWORD>(provisioning_not_allowed), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast<LPWSTR>(&message), 0, nullptr); - if (result == 0) { - LocalFree(message); - return; - } - fmt::detail::utf16_to_utf8 utf8_message(wstring_view(message, result - 2)); - LocalFree(message); - fmt::memory_buffer actual_message; - fmt::detail::format_windows_error(actual_message, provisioning_not_allowed, - "test"); - EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), - fmt::to_string(actual_message)); -} - -TEST(os_test, windows_error) { - auto error = std::system_error(std::error_code()); - try { - throw fmt::windows_error(ERROR_FILE_EXISTS, "test {}", "error"); - } catch (const std::system_error& e) { - error = e; - } - fmt::memory_buffer message; - fmt::detail::format_windows_error(message, ERROR_FILE_EXISTS, "test error"); - EXPECT_THAT(error.what(), HasSubstr(to_string(message))); - EXPECT_EQ(ERROR_FILE_EXISTS, error.code().value()); -} - -TEST(os_test, report_windows_error) { - fmt::memory_buffer out; - fmt::detail::format_windows_error(out, ERROR_FILE_EXISTS, "test error"); - out.push_back('\n'); - EXPECT_WRITE(stderr, - fmt::report_windows_error(ERROR_FILE_EXISTS, "test error"), - fmt::to_string(out)); -} - -#endif // _WIN32 - -#if FMT_USE_FCNTL - -using fmt::file; - -bool isclosed(int fd) { - char buffer; - auto result = std::streamsize(); - SUPPRESS_ASSERT(result = FMT_POSIX(read(fd, &buffer, 1))); - return result == -1 && errno == EBADF; -} - -// Opens a file for reading. -file open_file() { - file read_end, write_end; - file::pipe(read_end, write_end); - write_end.write(file_content, std::strlen(file_content)); - write_end.close(); - return read_end; -} - -// Attempts to write a string to a file. -void write(file& f, fmt::string_view s) { - size_t num_chars_left = s.size(); - const char* ptr = s.data(); - do { - size_t count = f.write(ptr, num_chars_left); - ptr += count; - // We can't write more than size_t bytes since num_chars_left - // has type size_t. - num_chars_left -= count; - } while (num_chars_left != 0); -} - -TEST(buffered_file_test, default_ctor) { - auto f = buffered_file(); - EXPECT_TRUE(f.get() == nullptr); -} - -TEST(buffered_file_test, move_ctor) { - buffered_file bf = open_buffered_file(); - FILE* fp = bf.get(); - EXPECT_TRUE(fp != nullptr); - buffered_file bf2(std::move(bf)); - EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == nullptr); -} - -TEST(buffered_file_test, move_assignment) { - buffered_file bf = open_buffered_file(); - FILE* fp = bf.get(); - EXPECT_TRUE(fp != nullptr); - buffered_file bf2; - bf2 = std::move(bf); - EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == nullptr); -} - -TEST(buffered_file_test, move_assignment_closes_file) { - buffered_file bf = open_buffered_file(); - buffered_file bf2 = open_buffered_file(); - int old_fd = bf2.fileno(); - bf2 = std::move(bf); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(buffered_file_test, move_from_temporary_in_ctor) { - FILE* fp = nullptr; - buffered_file f = open_buffered_file(&fp); - EXPECT_EQ(fp, f.get()); -} - -TEST(buffered_file_test, move_from_temporary_in_assignment) { - FILE* fp = nullptr; - auto f = buffered_file(); - f = open_buffered_file(&fp); - EXPECT_EQ(fp, f.get()); -} - -TEST(buffered_file_test, move_from_temporary_in_assignment_closes_file) { - buffered_file f = open_buffered_file(); - int old_fd = f.fileno(); - f = open_buffered_file(); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(buffered_file_test, close_file_in_dtor) { - int fd = 0; - { - buffered_file f = open_buffered_file(); - fd = f.fileno(); - } - EXPECT_TRUE(isclosed(fd)); -} - -TEST(buffered_file_test, close_error_in_dtor) { - auto f = - std::unique_ptr<buffered_file>(new buffered_file(open_buffered_file())); - EXPECT_WRITE( - stderr, - { - // The close function must be called inside EXPECT_WRITE, - // otherwise the system may recycle closed file descriptor when - // redirecting the output in EXPECT_STDERR and the second close - // will break output redirection. - FMT_POSIX(close(f->fileno())); - SUPPRESS_ASSERT(f.reset(nullptr)); - }, - system_error_message(EBADF, "cannot close file") + "\n"); -} - -TEST(buffered_file_test, close) { - buffered_file f = open_buffered_file(); - int fd = f.fileno(); - f.close(); - EXPECT_TRUE(f.get() == nullptr); - EXPECT_TRUE(isclosed(fd)); -} - -TEST(buffered_file_test, close_error) { - buffered_file f = open_buffered_file(); - FMT_POSIX(close(f.fileno())); - EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); - EXPECT_TRUE(f.get() == nullptr); -} - -TEST(buffered_file_test, fileno) { - auto f = open_buffered_file(); - EXPECT_TRUE(f.fileno() != -1); - file copy = file::dup(f.fileno()); - EXPECT_READ(copy, file_content); -} - -TEST(ostream_test, move) { - fmt::ostream out = fmt::output_file("test-file"); - fmt::ostream moved(std::move(out)); - moved.print("hello"); -} - -TEST(ostream_test, move_while_holding_data) { - { - fmt::ostream out = fmt::output_file("test-file"); - out.print("Hello, "); - fmt::ostream moved(std::move(out)); - moved.print("world!\n"); - } - { - file in("test-file", file::RDONLY); - EXPECT_READ(in, "Hello, world!\n"); - } -} - -TEST(ostream_test, print) { - fmt::ostream out = fmt::output_file("test-file"); - out.print("The answer is {}.\n", - fmt::join(std::initializer_list<int>{42}, ", ")); - out.close(); - file in("test-file", file::RDONLY); - EXPECT_READ(in, "The answer is 42.\n"); -} - -TEST(ostream_test, buffer_boundary) { - auto str = std::string(4096, 'x'); - fmt::ostream out = fmt::output_file("test-file"); - out.print("{}", str); - out.print("{}", str); - out.close(); - file in("test-file", file::RDONLY); - EXPECT_READ(in, str + str); -} - -TEST(ostream_test, buffer_size) { - fmt::ostream out = fmt::output_file("test-file", fmt::buffer_size = 1); - out.print("{}", "foo"); - out.close(); - file in("test-file", file::RDONLY); - EXPECT_READ(in, "foo"); -} - -TEST(ostream_test, truncate) { - { - fmt::ostream out = fmt::output_file("test-file"); - out.print("0123456789"); - } - { - fmt::ostream out = fmt::output_file("test-file"); - out.print("foo"); - } - file in("test-file", file::RDONLY); - EXPECT_EQ("foo", read(in, 4)); -} - -TEST(ostream_test, flush) { - auto out = fmt::output_file("test-file"); - out.print("x"); - out.flush(); - auto in = fmt::file("test-file", file::RDONLY); - EXPECT_READ(in, "x"); -} - -TEST(file_test, default_ctor) { - file f; - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(file_test, open_buffered_file_in_ctor) { - FILE* fp = safe_fopen("test-file", "w"); - std::fputs(file_content, fp); - std::fclose(fp); - file f("test-file", file::RDONLY); - // Check if the file is open by reading one character from it. - char buffer; - bool isopen = FMT_POSIX(read(f.descriptor(), &buffer, 1)) == 1; - ASSERT_TRUE(isopen); -} - -TEST(file_test, open_buffered_file_error) { - EXPECT_SYSTEM_ERROR(file("nonexistent", file::RDONLY), ENOENT, - "cannot open file nonexistent"); -} - -TEST(file_test, move_ctor) { - file f = open_file(); - int fd = f.descriptor(); - EXPECT_NE(-1, fd); - file f2(std::move(f)); - EXPECT_EQ(fd, f2.descriptor()); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(file_test, move_assignment) { - file f = open_file(); - int fd = f.descriptor(); - EXPECT_NE(-1, fd); - file f2; - f2 = std::move(f); - EXPECT_EQ(fd, f2.descriptor()); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(file_test, move_assignment_closes_file) { - file f = open_file(); - file f2 = open_file(); - int old_fd = f2.descriptor(); - f2 = std::move(f); - EXPECT_TRUE(isclosed(old_fd)); -} - -file open_buffered_file(int& fd) { - file f = open_file(); - fd = f.descriptor(); - return f; -} - -TEST(file_test, move_from_temporary_in_ctor) { - int fd = 0xdead; - file f(open_buffered_file(fd)); - EXPECT_EQ(fd, f.descriptor()); -} - -TEST(file_test, move_from_temporary_in_assignment) { - int fd = 0xdead; - file f; - f = open_buffered_file(fd); - EXPECT_EQ(fd, f.descriptor()); -} - -TEST(file_test, move_from_temporary_in_assignment_closes_file) { - int fd = 0xdead; - file f = open_file(); - int old_fd = f.descriptor(); - f = open_buffered_file(fd); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(file_test, close_file_in_dtor) { - int fd = 0; - { - file f = open_file(); - fd = f.descriptor(); - } - EXPECT_TRUE(isclosed(fd)); -} - -TEST(file_test, close_error_in_dtor) { - std::unique_ptr<file> f(new file(open_file())); - EXPECT_WRITE( - stderr, - { - // The close function must be called inside EXPECT_WRITE, - // otherwise the system may recycle closed file descriptor when - // redirecting the output in EXPECT_STDERR and the second close - // will break output redirection. - FMT_POSIX(close(f->descriptor())); - SUPPRESS_ASSERT(f.reset(nullptr)); - }, - system_error_message(EBADF, "cannot close file") + "\n"); -} - -TEST(file_test, close) { - file f = open_file(); - int fd = f.descriptor(); - f.close(); - EXPECT_EQ(-1, f.descriptor()); - EXPECT_TRUE(isclosed(fd)); -} - -TEST(file_test, close_error) { - file f = open_file(); - FMT_POSIX(close(f.descriptor())); - EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(file_test, read) { - file f = open_file(); - EXPECT_READ(f, file_content); -} - -TEST(file_test, read_error) { - file f("test-file", file::WRONLY); - char buf; - // We intentionally read from a file opened in the write-only mode to - // cause error. - EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file"); -} - -TEST(file_test, write) { - file read_end, write_end; - file::pipe(read_end, write_end); - write(write_end, "test"); - write_end.close(); - EXPECT_READ(read_end, "test"); -} - -TEST(file_test, write_error) { - file f("test-file", file::RDONLY); - // We intentionally write to a file opened in the read-only mode to - // cause error. - EXPECT_SYSTEM_ERROR(f.write(" ", 1), EBADF, "cannot write to file"); -} - -TEST(file_test, dup) { - file f = open_file(); - file copy = file::dup(f.descriptor()); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_EQ(file_content, read(copy, std::strlen(file_content))); -} - -# ifndef __COVERITY__ -TEST(file_test, dup_error) { - int value = -1; - EXPECT_SYSTEM_ERROR_NOASSERT(file::dup(value), EBADF, - "cannot duplicate file descriptor -1"); -} -# endif - -TEST(file_test, dup2) { - file f = open_file(); - file copy = open_file(); - f.dup2(copy.descriptor()); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_READ(copy, file_content); -} - -TEST(file_test, dup2_error) { - file f = open_file(); - EXPECT_SYSTEM_ERROR_NOASSERT( - f.dup2(-1), EBADF, - fmt::format("cannot duplicate file descriptor {} to -1", f.descriptor())); -} - -TEST(file_test, dup2_noexcept) { - file f = open_file(); - file copy = open_file(); - std::error_code ec; - f.dup2(copy.descriptor(), ec); - EXPECT_EQ(ec.value(), 0); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_READ(copy, file_content); -} - -TEST(file_test, dup2_noexcept_error) { - file f = open_file(); - std::error_code ec; - SUPPRESS_ASSERT(f.dup2(-1, ec)); - EXPECT_EQ(EBADF, ec.value()); -} - -TEST(file_test, pipe) { - file read_end, write_end; - file::pipe(read_end, write_end); - EXPECT_NE(-1, read_end.descriptor()); - EXPECT_NE(-1, write_end.descriptor()); - write(write_end, "test"); - EXPECT_READ(read_end, "test"); -} - -TEST(file_test, fdopen) { - file read_end, write_end; - file::pipe(read_end, write_end); - int read_fd = read_end.descriptor(); - EXPECT_EQ(read_fd, FMT_POSIX(fileno(read_end.fdopen("r").get()))); -} -#endif // FMT_USE_FCNTL diff --git a/contrib/libs/fmt/test/os-test/ya.make b/contrib/libs/fmt/test/os-test/ya.make deleted file mode 100644 index ef90d93fea..0000000000 --- a/contrib/libs/fmt/test/os-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - os-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/ostream-test.cc b/contrib/libs/fmt/test/ostream-test.cc deleted file mode 100644 index f81039e5bb..0000000000 --- a/contrib/libs/fmt/test/ostream-test.cc +++ /dev/null @@ -1,301 +0,0 @@ -// Formatting library for C++ - std::ostream support tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/format.h" - -using fmt::runtime; - -struct test {}; - -// Test that there is no issues with specializations when fmt/ostream.h is -// included after fmt/format.h. -namespace fmt { -template <> struct formatter<test> : formatter<int> { - auto format(const test&, format_context& ctx) -> decltype(ctx.out()) { - return formatter<int>::format(42, ctx); - } -}; -} // namespace fmt - -#include <sstream> - -#include "fmt/compile.h" -#include "fmt/ostream.h" -#include "fmt/ranges.h" -#include "gmock/gmock.h" -#include "gtest-extra.h" -#include "util.h" - -std::ostream& operator<<(std::ostream& os, const date& d) { - os << d.year() << '-' << d.month() << '-' << d.day(); - return os; -} - -std::wostream& operator<<(std::wostream& os, const date& d) { - os << d.year() << L'-' << d.month() << L'-' << d.day(); - return os; -} - -// Make sure that overloaded comma operators do no harm to is_streamable. -struct type_with_comma_op {}; -template <typename T> void operator,(type_with_comma_op, const T&); -template <typename T> type_with_comma_op operator<<(T&, const date&); - -enum streamable_enum {}; - -std::ostream& operator<<(std::ostream& os, streamable_enum) { - return os << "streamable_enum"; -} - -enum unstreamable_enum {}; - -TEST(ostream_test, enum) { - EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum())); - EXPECT_EQ("0", fmt::format("{}", unstreamable_enum())); -} - -TEST(ostream_test, format) { - EXPECT_EQ("a string", fmt::format("{0}", test_string("a string"))); - EXPECT_EQ("The date is 2012-12-9", - fmt::format("The date is {0}", date(2012, 12, 9))); -} - -TEST(ostream_test, format_specs) { - using fmt::format_error; - EXPECT_EQ("def ", fmt::format("{0:<5}", test_string("def"))); - EXPECT_EQ(" def", fmt::format("{0:>5}", test_string("def"))); - EXPECT_EQ(" def ", fmt::format("{0:^5}", test_string("def"))); - EXPECT_EQ("def**", fmt::format("{0:*<5}", test_string("def"))); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), test_string()), - format_error, "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), test_string()), - format_error, "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), test_string()), - format_error, "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), test_string()), - format_error, "format specifier requires numeric argument"); - EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), test_string()), - format_error, "format specifier requires numeric argument"); - EXPECT_EQ("test ", fmt::format("{0:13}", test_string("test"))); - EXPECT_EQ("test ", fmt::format("{0:{1}}", test_string("test"), 13)); - EXPECT_EQ("te", fmt::format("{0:.2}", test_string("test"))); - EXPECT_EQ("te", fmt::format("{0:.{1}}", test_string("test"), 2)); -} - -struct empty_test {}; -std::ostream& operator<<(std::ostream& os, empty_test) { return os << ""; } - -TEST(ostream_test, empty_custom_output) { - EXPECT_EQ("", fmt::format("{}", empty_test())); -} - -TEST(ostream_test, print) { - std::ostringstream os; - fmt::print(os, "Don't {}!", "panic"); - EXPECT_EQ("Don't panic!", os.str()); -} - -TEST(ostream_test, write_to_ostream) { - std::ostringstream os; - fmt::memory_buffer buffer; - const char* foo = "foo"; - buffer.append(foo, foo + std::strlen(foo)); - fmt::detail::write_buffer(os, buffer); - EXPECT_EQ("foo", os.str()); -} - -TEST(ostream_test, write_to_ostream_max_size) { - auto max_size = fmt::detail::max_value<size_t>(); - auto max_streamsize = fmt::detail::max_value<std::streamsize>(); - if (max_size <= fmt::detail::to_unsigned(max_streamsize)) return; - - struct test_buffer final : fmt::detail::buffer<char> { - explicit test_buffer(size_t size) - : fmt::detail::buffer<char>(nullptr, size, size) {} - void grow(size_t) override {} - } buffer(max_size); - - struct mock_streambuf : std::streambuf { - MOCK_METHOD2(xsputn, std::streamsize(const void* s, std::streamsize n)); - std::streamsize xsputn(const char* s, std::streamsize n) override { - const void* v = s; - return xsputn(v, n); - } - } streambuf; - - struct test_ostream : std::ostream { - explicit test_ostream(mock_streambuf& output_buffer) - : std::ostream(&output_buffer) {} - } os(streambuf); - - testing::InSequence sequence; - const char* data = nullptr; - using ustreamsize = std::make_unsigned<std::streamsize>::type; - ustreamsize size = max_size; - do { - auto n = std::min(size, fmt::detail::to_unsigned(max_streamsize)); - EXPECT_CALL(streambuf, xsputn(data, static_cast<std::streamsize>(n))) - .WillOnce(testing::Return(max_streamsize)); - data += n; - size -= n; - } while (size != 0); - fmt::detail::write_buffer(os, buffer); -} - -TEST(ostream_test, join) { - int v[3] = {1, 2, 3}; - EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); -} - -TEST(ostream_test, join_fallback_formatter) { - auto strs = std::vector<test_string>{test_string("foo"), test_string("bar")}; - EXPECT_EQ("foo, bar", fmt::format("{}", fmt::join(strs, ", "))); -} - -#if FMT_USE_CONSTEXPR -TEST(ostream_test, constexpr_string) { - EXPECT_EQ("42", format(FMT_STRING("{}"), std::string("42"))); - EXPECT_EQ("a string", format(FMT_STRING("{0}"), test_string("a string"))); -} -#endif - -namespace fmt_test { -struct abc {}; - -template <typename Output> Output& operator<<(Output& out, abc) { - return out << "abc"; -} -} // namespace fmt_test - -template <typename T> struct test_template {}; - -template <typename T> -std::ostream& operator<<(std::ostream& os, test_template<T>) { - return os << 1; -} - -namespace fmt { -template <typename T> struct formatter<test_template<T>> : formatter<int> { - auto format(test_template<T>, format_context& ctx) -> decltype(ctx.out()) { - return formatter<int>::format(2, ctx); - } -}; -} // namespace fmt - -TEST(ostream_test, template) { - EXPECT_EQ("2", fmt::format("{}", test_template<int>())); -} - -TEST(ostream_test, format_to_n) { - char buffer[4]; - buffer[3] = 'x'; - auto result = fmt::format_to_n(buffer, 3, "{}", fmt_test::abc()); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("abcx", fmt::string_view(buffer, 4)); - result = fmt::format_to_n(buffer, 3, "x{}y", fmt_test::abc()); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("xabx", fmt::string_view(buffer, 4)); -} - -template <typename T> struct convertible { - T value; - explicit convertible(const T& val) : value(val) {} - operator T() const { return value; } -}; - -TEST(ostream_test, disable_builtin_ostream_operators) { - EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42))); - EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo"))); -} - -struct explicitly_convertible_to_string_like { - template <typename String, - typename = typename std::enable_if<std::is_constructible< - String, const char*, size_t>::value>::type> - explicit operator String() const { - return String("foo", 3u); - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_string_like) { - return os << "bar"; -} - -TEST(ostream_test, format_explicitly_convertible_to_string_like) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} - -#ifdef FMT_USE_STRING_VIEW -struct explicitly_convertible_to_std_string_view { - explicit operator fmt::detail::std_string_view<char>() const { - return {"foo", 3u}; - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_std_string_view) { - return os << "bar"; -} - -TEST(ostream_test, format_explicitly_convertible_to_std_string_view) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} -#endif // FMT_USE_STRING_VIEW - -struct streamable_and_convertible_to_bool { - operator bool() const { return true; } -}; - -std::ostream& operator<<(std::ostream& os, streamable_and_convertible_to_bool) { - return os << "foo"; -} - -TEST(ostream_test, format_convertible_to_bool) { - // operator<< is intentionally not used because of potential ODR violations. - EXPECT_EQ(fmt::format("{}", streamable_and_convertible_to_bool()), "true"); -} - -struct copyfmt_test {}; - -std::ostream& operator<<(std::ostream& os, copyfmt_test) { - std::ios ios(nullptr); - ios.copyfmt(os); - return os << "foo"; -} - -TEST(ostream_test, copyfmt) { - EXPECT_EQ("foo", fmt::format("{}", copyfmt_test())); -} - -TEST(ostream_test, to_string) { - EXPECT_EQ("abc", fmt::to_string(fmt_test::abc())); -} - -TEST(ostream_test, range) { - auto strs = std::vector<test_string>{test_string("foo"), test_string("bar")}; - EXPECT_EQ("[foo, bar]", fmt::format("{}", strs)); -} - -struct abstract { - virtual ~abstract() = default; - virtual void f() = 0; - friend std::ostream& operator<<(std::ostream& os, const abstract&) { - return os; - } -}; - -void format_abstract_compiles(const abstract& a) { - fmt::format(FMT_COMPILE("{}"), a); -} - -TEST(ostream_test, is_formattable) { - EXPECT_TRUE(fmt::is_formattable<std::string>()); - EXPECT_TRUE(fmt::is_formattable<fmt::detail::std_string_view<char>>()); -} diff --git a/contrib/libs/fmt/test/ostream-test/ya.make b/contrib/libs/fmt/test/ostream-test/ya.make deleted file mode 100644 index 74f45abcf9..0000000000 --- a/contrib/libs/fmt/test/ostream-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - ostream-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/posix-mock-test.cc b/contrib/libs/fmt/test/posix-mock-test.cc deleted file mode 100644 index 3a20b269a4..0000000000 --- a/contrib/libs/fmt/test/posix-mock-test.cc +++ /dev/null @@ -1,540 +0,0 @@ -// Tests of the C++ interface to POSIX functions that require mocks -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -// Disable bogus MSVC warnings. -#ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include "posix-mock.h" - -#include <errno.h> -#include <fcntl.h> - -#include <climits> -#include <memory> - -#include "../src/os.cc" - -#ifdef _WIN32 -# include <io.h> -# undef max -#endif - -#include "gmock/gmock.h" -#include "gtest-extra.h" -#include "util.h" - -using fmt::buffered_file; - -using testing::_; -using testing::Return; -using testing::StrEq; - -template <typename Mock> struct scoped_mock : testing::StrictMock<Mock> { - scoped_mock() { Mock::instance = this; } - ~scoped_mock() { Mock::instance = nullptr; } -}; - -namespace { -int open_count; -int close_count; -int dup_count; -int dup2_count; -int fdopen_count; -int read_count; -int write_count; -int pipe_count; -int fopen_count; -int fclose_count; -int fileno_count; -size_t read_nbyte; -size_t write_nbyte; -bool sysconf_error; - -enum { none, max_size, error } fstat_sim; -} // namespace - -#define EMULATE_EINTR(func, error_result) \ - if (func##_count != 0) { \ - if (func##_count++ != 3) { \ - errno = EINTR; \ - return error_result; \ - } \ - } - -#ifndef _MSC_VER -int test::open(const char* path, int oflag, int mode) { - EMULATE_EINTR(open, -1); - return ::open(path, oflag, mode); -} -#else -errno_t test::sopen_s(int* pfh, const char* filename, int oflag, int shflag, - int pmode) { - EMULATE_EINTR(open, EINTR); - return _sopen_s(pfh, filename, oflag, shflag, pmode); -} -#endif - -#ifndef _WIN32 - -long test::sysconf(int name) { - long result = ::sysconf(name); - if (!sysconf_error) return result; - // Simulate an error. - errno = EINVAL; - return -1; -} - -static off_t max_file_size() { return std::numeric_limits<off_t>::max(); } - -int test::fstat(int fd, struct stat* buf) { - int result = ::fstat(fd, buf); - if (fstat_sim == max_size) buf->st_size = max_file_size(); - return result; -} - -#else - -static LONGLONG max_file_size() { return std::numeric_limits<LONGLONG>::max(); } - -DWORD test::GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { - if (fstat_sim == error) { - SetLastError(ERROR_ACCESS_DENIED); - return INVALID_FILE_SIZE; - } - if (fstat_sim == max_size) { - DWORD max = std::numeric_limits<DWORD>::max(); - *lpFileSizeHigh = max >> 1; - return max; - } - return ::GetFileSize(hFile, lpFileSizeHigh); -} - -#endif - -int test::close(int fildes) { - // Close the file first because close shouldn't be retried. - int result = ::FMT_POSIX(close(fildes)); - EMULATE_EINTR(close, -1); - return result; -} - -int test::dup(int fildes) { - EMULATE_EINTR(dup, -1); - return ::FMT_POSIX(dup(fildes)); -} - -int test::dup2(int fildes, int fildes2) { - EMULATE_EINTR(dup2, -1); - return ::FMT_POSIX(dup2(fildes, fildes2)); -} - -FILE* test::fdopen(int fildes, const char* mode) { - EMULATE_EINTR(fdopen, nullptr); - return ::FMT_POSIX(fdopen(fildes, mode)); -} - -test::ssize_t test::read(int fildes, void* buf, test::size_t nbyte) { - read_nbyte = nbyte; - EMULATE_EINTR(read, -1); - return ::FMT_POSIX(read(fildes, buf, nbyte)); -} - -test::ssize_t test::write(int fildes, const void* buf, test::size_t nbyte) { - write_nbyte = nbyte; - EMULATE_EINTR(write, -1); - return ::FMT_POSIX(write(fildes, buf, nbyte)); -} - -#ifndef _WIN32 -int test::pipe(int fildes[2]) { - EMULATE_EINTR(pipe, -1); - return ::pipe(fildes); -} -#else -int test::pipe(int* pfds, unsigned psize, int textmode) { - EMULATE_EINTR(pipe, -1); - return _pipe(pfds, psize, textmode); -} -#endif - -FILE* test::fopen(const char* filename, const char* mode) { - EMULATE_EINTR(fopen, nullptr); - return ::fopen(filename, mode); -} - -int test::fclose(FILE* stream) { - EMULATE_EINTR(fclose, EOF); - return ::fclose(stream); -} - -int(test::fileno)(FILE* stream) { - EMULATE_EINTR(fileno, -1); -#ifdef fileno - return FMT_POSIX(fileno(stream)); -#else - return ::FMT_POSIX(fileno(stream)); -#endif -} - -#ifndef _WIN32 -# define EXPECT_RETRY(statement, func, message) \ - func##_count = 1; \ - statement; \ - EXPECT_EQ(4, func##_count); \ - func##_count = 0; -# define EXPECT_EQ_POSIX(expected, actual) EXPECT_EQ(expected, actual) -#else -# define EXPECT_RETRY(statement, func, message) \ - func##_count = 1; \ - EXPECT_SYSTEM_ERROR(statement, EINTR, message); \ - func##_count = 0; -# define EXPECT_EQ_POSIX(expected, actual) -#endif - -#if FMT_USE_FCNTL -void write_file(fmt::cstring_view filename, fmt::string_view content) { - fmt::buffered_file f(filename, "w"); - f.print("{}", content); -} - -using fmt::file; - -TEST(os_test, getpagesize) { -# ifdef _WIN32 - SYSTEM_INFO si = {}; - GetSystemInfo(&si); - EXPECT_EQ(si.dwPageSize, fmt::getpagesize()); -# else - EXPECT_EQ(sysconf(_SC_PAGESIZE), fmt::getpagesize()); - sysconf_error = true; - EXPECT_SYSTEM_ERROR(fmt::getpagesize(), EINVAL, - "cannot get memory page size"); - sysconf_error = false; -# endif -} - -TEST(file_test, open_retry) { - write_file("temp", "there must be something here"); - std::unique_ptr<file> f{nullptr}; - EXPECT_RETRY(f.reset(new file("temp", file::RDONLY)), open, - "cannot open file temp"); -# ifndef _WIN32 - char c = 0; - f->read(&c, 1); -# endif -} - -TEST(file_test, close_no_retry_in_dtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - std::unique_ptr<file> f(new file(std::move(read_end))); - int saved_close_count = 0; - EXPECT_WRITE( - stderr, - { - close_count = 1; - f.reset(nullptr); - saved_close_count = close_count; - close_count = 0; - }, - system_error_message(EINTR, "cannot close file") + "\n"); - EXPECT_EQ(2, saved_close_count); -} - -TEST(file_test, close_no_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - close_count = 1; - EXPECT_SYSTEM_ERROR(read_end.close(), EINTR, "cannot close file"); - EXPECT_EQ(2, close_count); - close_count = 0; -} - -TEST(file_test, size) { - std::string content = "top secret, destroy before reading"; - write_file("temp", content); - file f("temp", file::RDONLY); - EXPECT_GE(f.size(), 0); - EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size())); -# ifdef _WIN32 - auto error_code = std::error_code(); - fstat_sim = error; - try { - f.size(); - } catch (const std::system_error& e) { - error_code = e.code(); - } - fstat_sim = none; - EXPECT_EQ(error_code, - std::error_code(ERROR_ACCESS_DENIED, fmt::system_category())); -# else - f.close(); - EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes"); -# endif -} - -TEST(file_test, max_size) { - write_file("temp", ""); - file f("temp", file::RDONLY); - fstat_sim = max_size; - EXPECT_GE(f.size(), 0); - EXPECT_EQ(max_file_size(), f.size()); - fstat_sim = none; -} - -TEST(file_test, read_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - enum { SIZE = 4 }; - write_end.write("test", SIZE); - write_end.close(); - char buffer[SIZE]; - size_t count = 0; - EXPECT_RETRY(count = read_end.read(buffer, SIZE), read, - "cannot read from file"); - EXPECT_EQ_POSIX(static_cast<std::streamsize>(SIZE), count); -} - -TEST(file_test, write_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - enum { SIZE = 4 }; - size_t count = 0; - EXPECT_RETRY(count = write_end.write("test", SIZE), write, - "cannot write to file"); - write_end.close(); -# ifndef _WIN32 - EXPECT_EQ(static_cast<std::streamsize>(SIZE), count); - char buffer[SIZE + 1]; - read_end.read(buffer, SIZE); - buffer[SIZE] = '\0'; - EXPECT_STREQ("test", buffer); -# endif -} - -# ifdef _WIN32 -TEST(file_test, convert_read_count) { - file read_end, write_end; - file::pipe(read_end, write_end); - char c; - size_t size = UINT_MAX; - if (sizeof(unsigned) != sizeof(size_t)) ++size; - read_count = 1; - read_nbyte = 0; - EXPECT_THROW(read_end.read(&c, size), std::system_error); - read_count = 0; - EXPECT_EQ(UINT_MAX, read_nbyte); -} - -TEST(file_test, convert_write_count) { - file read_end, write_end; - file::pipe(read_end, write_end); - char c; - size_t size = UINT_MAX; - if (sizeof(unsigned) != sizeof(size_t)) ++size; - write_count = 1; - write_nbyte = 0; - EXPECT_THROW(write_end.write(&c, size), std::system_error); - write_count = 0; - EXPECT_EQ(UINT_MAX, write_nbyte); -} -# endif - -TEST(file_test, dup_no_retry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - dup_count = 1; - EXPECT_SYSTEM_ERROR( - file::dup(stdout_fd), EINTR, - fmt::format("cannot duplicate file descriptor {}", stdout_fd)); - dup_count = 0; -} - -TEST(file_test, dup2_retry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); - EXPECT_RETRY(f1.dup2(f2.descriptor()), dup2, - fmt::format("cannot duplicate file descriptor {} to {}", - f1.descriptor(), f2.descriptor())); -} - -TEST(file_test, dup2_no_except_retry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); - std::error_code ec; - dup2_count = 1; - f1.dup2(f2.descriptor(), ec); -# ifndef _WIN32 - EXPECT_EQ(4, dup2_count); -# else - EXPECT_EQ(EINTR, ec.value()); -# endif - dup2_count = 0; -} - -TEST(file_test, pipe_no_retry) { - file read_end, write_end; - pipe_count = 1; - EXPECT_SYSTEM_ERROR(file::pipe(read_end, write_end), EINTR, - "cannot create pipe"); - pipe_count = 0; -} - -TEST(file_test, fdopen_no_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - fdopen_count = 1; - EXPECT_SYSTEM_ERROR(read_end.fdopen("r"), EINTR, - "cannot associate stream with file descriptor"); - fdopen_count = 0; -} - -TEST(buffered_file_test, open_retry) { - write_file("temp", "there must be something here"); - std::unique_ptr<buffered_file> f{nullptr}; - EXPECT_RETRY(f.reset(new buffered_file("temp", "r")), fopen, - "cannot open file temp"); -# ifndef _WIN32 - char c = 0; - if (fread(&c, 1, 1, f->get()) < 1) - throw fmt::system_error(errno, "fread failed"); -# endif -} - -TEST(buffered_file_test, close_no_retry_in_dtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - std::unique_ptr<buffered_file> f(new buffered_file(read_end.fdopen("r"))); - int saved_fclose_count = 0; - EXPECT_WRITE( - stderr, - { - fclose_count = 1; - f.reset(nullptr); - saved_fclose_count = fclose_count; - fclose_count = 0; - }, - system_error_message(EINTR, "cannot close file") + "\n"); - EXPECT_EQ(2, saved_fclose_count); -} - -TEST(buffered_file_test, close_no_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file f = read_end.fdopen("r"); - fclose_count = 1; - EXPECT_SYSTEM_ERROR(f.close(), EINTR, "cannot close file"); - EXPECT_EQ(2, fclose_count); - fclose_count = 0; -} - -TEST(buffered_file_test, fileno_no_retry) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file f = read_end.fdopen("r"); - fileno_count = 1; - EXPECT_SYSTEM_ERROR((f.fileno)(), EINTR, "cannot get file descriptor"); - EXPECT_EQ(2, fileno_count); - fileno_count = 0; -} -#endif // FMT_USE_FCNTL - -struct test_mock { - static test_mock* instance; -} * test_mock::instance; - -TEST(scoped_mock, scope) { - { - scoped_mock<test_mock> mock; - EXPECT_EQ(&mock, test_mock::instance); - test_mock& copy = mock; - static_cast<void>(copy); - } - EXPECT_EQ(nullptr, test_mock::instance); -} - -#if defined(FMT_LOCALE) && !defined(_LIBCPP_VERSION) - -using locale_type = fmt::locale::type; - -struct locale_mock { - static locale_mock* instance; - MOCK_METHOD3(newlocale, locale_type(int category_mask, const char* locale, - locale_type base)); - MOCK_METHOD1(freelocale, void(locale_type locale)); -} * locale_mock::instance; - -# ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4273) -# ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Winconsistent-dllimport" -# endif - -_locale_t _create_locale(int category, const char* locale) { - return locale_mock::instance->newlocale(category, locale, 0); -} - -void _free_locale(_locale_t locale) { - locale_mock::instance->freelocale(locale); -} -# ifdef __clang__ -# pragma clang diagnostic pop -# endif -# pragma warning(pop) -# endif - -# if defined(__THROW) && \ - ((FMT_GCC_VERSION > 0 && FMT_GCC_VERSION <= 408) || defined(__e2k__)) -# define FMT_LOCALE_THROW __THROW -# else -# define FMT_LOCALE_THROW -# endif - -# if defined(__APPLE__) || \ - (defined(__FreeBSD__) && __FreeBSD_version < 1200002) -typedef int FreeLocaleResult; -# else -typedef void FreeLocaleResult; -# endif - -FreeLocaleResult freelocale(locale_type locale) FMT_LOCALE_THROW { - locale_mock::instance->freelocale(locale); - return FreeLocaleResult(); -} - -# undef FMT_LOCALE_THROW - -# if !defined(_WIN32) || defined(_LIBCPP_VERSION) -locale_t test::newlocale(int category_mask, const char* locale, locale_t base) { - return locale_mock::instance->newlocale(category_mask, locale, base); -} - -TEST(locale_test, locale_mock) { - scoped_mock<locale_mock> mock; - auto locale = reinterpret_cast<locale_type>(11); - EXPECT_CALL(mock, newlocale(222, StrEq("foo"), locale)); - FMT_SYSTEM(newlocale(222, "foo", locale)); -} -# endif - -TEST(locale_test, locale) { -# ifndef LC_NUMERIC_MASK - enum { LC_NUMERIC_MASK = LC_NUMERIC }; -# endif - scoped_mock<locale_mock> mock; - auto impl = reinterpret_cast<locale_type>(42); - EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), nullptr)) - .WillOnce(Return(impl)); - EXPECT_CALL(mock, freelocale(impl)); - fmt::locale loc; - EXPECT_EQ(impl, loc.get()); -} - -#endif // FMT_LOCALE diff --git a/contrib/libs/fmt/test/posix-mock-test/ya.make b/contrib/libs/fmt/test/posix-mock-test/ya.make deleted file mode 100644 index 411bacbd94..0000000000 --- a/contrib/libs/fmt/test/posix-mock-test/ya.make +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -ADDINCL( - contrib/libs/fmt/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt) - -SRCS( - src/format.cc - test/gtest-extra.cc - test/posix-mock-test.cc - test/util.cc -) - -END() diff --git a/contrib/libs/fmt/test/posix-mock.h b/contrib/libs/fmt/test/posix-mock.h deleted file mode 100644 index 1f204263c6..0000000000 --- a/contrib/libs/fmt/test/posix-mock.h +++ /dev/null @@ -1,78 +0,0 @@ -// Formatting library for C++ - mocks of POSIX functions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_POSIX_TEST_H -#define FMT_POSIX_TEST_H - -#include <errno.h> -#include <locale.h> -#include <stdio.h> -#ifdef __APPLE__ -# include <xlocale.h> -#endif - -#ifdef _WIN32 -# include <windows.h> -# include <locale> // for libc++ locale_win32.h -#else -# include <sys/param.h> // for FreeBSD version -# include <sys/types.h> // for ssize_t -#endif - -#ifndef _MSC_VER -struct stat; -#endif - -namespace test { - -#ifndef _MSC_VER -// Size type for read and write. -typedef size_t size_t; -typedef ssize_t ssize_t; -int open(const char* path, int oflag, int mode); -int fstat(int fd, struct stat* buf); -#else -typedef unsigned size_t; -typedef int ssize_t; -errno_t sopen_s(int* pfh, const char* filename, int oflag, int shflag, - int pmode); -#endif - -#ifndef _WIN32 -long sysconf(int name); -#else -DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); -#endif - -int close(int fildes); - -int dup(int fildes); -int dup2(int fildes, int fildes2); - -FILE* fdopen(int fildes, const char* mode); - -ssize_t read(int fildes, void* buf, size_t nbyte); -ssize_t write(int fildes, const void* buf, size_t nbyte); - -#ifndef _WIN32 -int pipe(int fildes[2]); -#else -int pipe(int* pfds, unsigned psize, int textmode); -#endif - -FILE* fopen(const char* filename, const char* mode); -int fclose(FILE* stream); -int(fileno)(FILE* stream); - -#if defined(FMT_LOCALE) && (!defined(_WIN32) || defined(_LIBCPP_VERSION)) -locale_t newlocale(int category_mask, const char* locale, locale_t base); -#endif -} // namespace test - -#define FMT_SYSTEM(call) test::call - -#endif // FMT_POSIX_TEST_H diff --git a/contrib/libs/fmt/test/printf-test.cc b/contrib/libs/fmt/test/printf-test.cc deleted file mode 100644 index 0bb9ccdaf6..0000000000 --- a/contrib/libs/fmt/test/printf-test.cc +++ /dev/null @@ -1,588 +0,0 @@ -// Formatting library for C++ - printf tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/printf.h" - -#include <cctype> -#include <climits> -#include <cstring> - -#include "fmt/ostream.h" -#include "fmt/xchar.h" -#include "gtest-extra.h" -#include "util.h" - -using fmt::format; -using fmt::format_error; -using fmt::detail::max_value; - -const unsigned big_num = INT_MAX + 1u; - -// Makes format string argument positional. -static std::string make_positional(fmt::string_view format) { - std::string s(format.data(), format.size()); - s.replace(s.find('%'), 1, "%1$"); - return s; -} - -static std::wstring make_positional(fmt::basic_string_view<wchar_t> format) { - std::wstring s(format.data(), format.size()); - s.replace(s.find(L'%'), 1, L"%1$"); - return s; -} - -// A wrapper around fmt::sprintf to workaround bogus warnings about invalid -// format strings in MSVC. -template <typename... Args> -std::string test_sprintf(fmt::string_view format, const Args&... args) { - return fmt::sprintf(format, args...); -} -template <typename... Args> -std::wstring test_sprintf(fmt::basic_string_view<wchar_t> format, - const Args&... args) { - return fmt::sprintf(format, args...); -} - -#define EXPECT_PRINTF(expected_output, format, arg) \ - EXPECT_EQ(expected_output, test_sprintf(format, arg)) \ - << "format: " << format; \ - EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg)) - -TEST(printf_test, no_args) { - EXPECT_EQ("test", test_sprintf("test")); - EXPECT_EQ(L"test", fmt::sprintf(L"test")); -} - -TEST(printf_test, escape) { - EXPECT_EQ("%", test_sprintf("%%")); - EXPECT_EQ("before %", test_sprintf("before %%")); - EXPECT_EQ("% after", test_sprintf("%% after")); - EXPECT_EQ("before % after", test_sprintf("before %% after")); - EXPECT_EQ("%s", test_sprintf("%%s")); - EXPECT_EQ(L"%", fmt::sprintf(L"%%")); - EXPECT_EQ(L"before %", fmt::sprintf(L"before %%")); - EXPECT_EQ(L"% after", fmt::sprintf(L"%% after")); - EXPECT_EQ(L"before % after", fmt::sprintf(L"before %% after")); - EXPECT_EQ(L"%s", fmt::sprintf(L"%%s")); -} - -TEST(printf_test, positional_args) { - EXPECT_EQ("42", test_sprintf("%1$d", 42)); - EXPECT_EQ("before 42", test_sprintf("before %1$d", 42)); - EXPECT_EQ("42 after", test_sprintf("%1$d after", 42)); - EXPECT_EQ("before 42 after", test_sprintf("before %1$d after", 42)); - EXPECT_EQ("answer = 42", test_sprintf("%1$s = %2$d", "answer", 42)); - EXPECT_EQ("42 is the answer", test_sprintf("%2$d is the %1$s", "answer", 42)); - EXPECT_EQ("abracadabra", test_sprintf("%1$s%2$s%1$s", "abra", "cad")); -} - -TEST(printf_test, automatic_arg_indexing) { - EXPECT_EQ("abc", test_sprintf("%c%c%c", 'a', 'b', 'c')); -} - -TEST(printf_test, number_is_too_big_in_arg_index) { - EXPECT_THROW_MSG(test_sprintf(format("%{}$", big_num)), format_error, - "argument not found"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", big_num)), format_error, - "argument not found"); -} - -TEST(printf_test, switch_arg_indexing) { - EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", big_num), 1, 2), - format_error, "number is too big"); - EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2), format_error, - "cannot switch from manual to automatic argument indexing"); - - EXPECT_THROW_MSG(test_sprintf("%d%1$", 1, 2), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_THROW_MSG(test_sprintf(format("%d%{}$d", big_num), 1, 2), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_THROW_MSG(test_sprintf("%d%1$d", 1, 2), format_error, - "cannot switch from automatic to manual argument indexing"); - - // Indexing errors override width errors. - EXPECT_THROW_MSG(test_sprintf(format("%d%1${}d", big_num), 1, 2), - format_error, "number is too big"); - EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", big_num), 1, 2), - format_error, "number is too big"); -} - -TEST(printf_test, invalid_arg_index) { - EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error, - "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error, - "argument not found"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error, - "argument not found"); - - EXPECT_THROW_MSG(test_sprintf("%2$", 42), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", big_num), 42), format_error, - "argument not found"); -} - -TEST(printf_test, default_align_right) { - EXPECT_PRINTF(" 42", "%5d", 42); - EXPECT_PRINTF(" abc", "%5s", "abc"); -} - -TEST(printf_test, zero_flag) { - EXPECT_PRINTF("00042", "%05d", 42); - EXPECT_PRINTF("-0042", "%05d", -42); - - EXPECT_PRINTF("00042", "%05d", 42); - EXPECT_PRINTF("-0042", "%05d", -42); - EXPECT_PRINTF("-004.2", "%06g", -4.2); - - EXPECT_PRINTF("+00042", "%00+6d", 42); - - EXPECT_PRINTF(" 42", "%05.d", 42); - EXPECT_PRINTF(" 0042", "%05.4d", 42); - - // '0' flag is ignored for non-numeric types. - EXPECT_PRINTF(" x", "%05c", 'x'); -} - -TEST(printf_test, plus_flag) { - EXPECT_PRINTF("+42", "%+d", 42); - EXPECT_PRINTF("-42", "%+d", -42); - EXPECT_PRINTF("+0042", "%+05d", 42); - EXPECT_PRINTF("+0042", "%0++5d", 42); - - // '+' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "%+c", 'x'); - - // '+' flag wins over space flag - EXPECT_PRINTF("+42", "%+ d", 42); - EXPECT_PRINTF("-42", "%+ d", -42); - EXPECT_PRINTF("+42", "% +d", 42); - EXPECT_PRINTF("-42", "% +d", -42); - EXPECT_PRINTF("+0042", "% +05d", 42); - EXPECT_PRINTF("+0042", "%0+ 5d", 42); - - // '+' flag and space flag are both ignored for non-numeric types. - EXPECT_PRINTF("x", "%+ c", 'x'); - EXPECT_PRINTF("x", "% +c", 'x'); -} - -TEST(printf_test, minus_flag) { - EXPECT_PRINTF("abc ", "%-5s", "abc"); - EXPECT_PRINTF("abc ", "%0--5s", "abc"); - - EXPECT_PRINTF("7 ", "%-5d", 7); - EXPECT_PRINTF("97 ", "%-5hhi", 'a'); - EXPECT_PRINTF("a ", "%-5c", 'a'); - - // '0' flag is ignored if '-' flag is given - EXPECT_PRINTF("7 ", "%-05d", 7); - EXPECT_PRINTF("7 ", "%0-5d", 7); - EXPECT_PRINTF("a ", "%-05c", 'a'); - EXPECT_PRINTF("a ", "%0-5c", 'a'); - EXPECT_PRINTF("97 ", "%-05hhi", 'a'); - EXPECT_PRINTF("97 ", "%0-5hhi", 'a'); - - // '-' and space flag don't interfere - EXPECT_PRINTF(" 42", "%- d", 42); -} - -TEST(printf_test, space_flag) { - EXPECT_PRINTF(" 42", "% d", 42); - EXPECT_PRINTF("-42", "% d", -42); - EXPECT_PRINTF(" 0042", "% 05d", 42); - EXPECT_PRINTF(" 0042", "%0 5d", 42); - - // ' ' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "% c", 'x'); -} - -TEST(printf_test, hash_flag) { - EXPECT_PRINTF("042", "%#o", 042); - EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042); - EXPECT_PRINTF("0", "%#o", 0); - - EXPECT_PRINTF("0x42", "%#x", 0x42); - EXPECT_PRINTF("0X42", "%#X", 0x42); - EXPECT_PRINTF(fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x", - -0x42); - EXPECT_PRINTF("0", "%#x", 0); - - EXPECT_PRINTF("0x0042", "%#06x", 0x42); - EXPECT_PRINTF("0x0042", "%0##6x", 0x42); - - EXPECT_PRINTF("-42.000000", "%#f", -42.0); - EXPECT_PRINTF("-42.000000", "%#F", -42.0); - - char buffer[256]; - safe_sprintf(buffer, "%#e", -42.0); - EXPECT_PRINTF(buffer, "%#e", -42.0); - safe_sprintf(buffer, "%#E", -42.0); - EXPECT_PRINTF(buffer, "%#E", -42.0); - - EXPECT_PRINTF("-42.0000", "%#g", -42.0); - EXPECT_PRINTF("-42.0000", "%#G", -42.0); - - safe_sprintf(buffer, "%#a", 16.0); - EXPECT_PRINTF(buffer, "%#a", 16.0); - safe_sprintf(buffer, "%#A", 16.0); - EXPECT_PRINTF(buffer, "%#A", 16.0); - - // '#' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "%#c", 'x'); -} - -TEST(printf_test, width) { - EXPECT_PRINTF(" abc", "%5s", "abc"); - - // Width cannot be specified twice. - EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error, - "invalid type specifier"); - - EXPECT_THROW_MSG(test_sprintf(format("%{}d", big_num), 42), format_error, - "number is too big"); - EXPECT_THROW_MSG(test_sprintf(format("%1${}d", big_num), 42), format_error, - "number is too big"); -} - -TEST(printf_test, dynamic_width) { - EXPECT_EQ(" 42", test_sprintf("%*d", 5, 42)); - EXPECT_EQ("42 ", test_sprintf("%*d", -5, 42)); - EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error, - "width is not integer"); - EXPECT_THROW_MSG(test_sprintf("%*d"), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%*d", big_num, 42), format_error, - "number is too big"); -} - -TEST(printf_test, int_precision) { - EXPECT_PRINTF("00042", "%.5d", 42); - EXPECT_PRINTF("-00042", "%.5d", -42); - EXPECT_PRINTF("00042", "%.5x", 0x42); - EXPECT_PRINTF("0x00042", "%#.5x", 0x42); - EXPECT_PRINTF("00042", "%.5o", 042); - EXPECT_PRINTF("00042", "%#.5o", 042); - - EXPECT_PRINTF(" 00042", "%7.5d", 42); - EXPECT_PRINTF(" 00042", "%7.5x", 0x42); - EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42); - EXPECT_PRINTF(" 00042", "%7.5o", 042); - EXPECT_PRINTF(" 00042", "%#10.5o", 042); - - EXPECT_PRINTF("00042 ", "%-7.5d", 42); - EXPECT_PRINTF("00042 ", "%-7.5x", 0x42); - EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42); - EXPECT_PRINTF("00042 ", "%-7.5o", 042); - EXPECT_PRINTF("00042 ", "%-#10.5o", 042); -} - -TEST(printf_test, float_precision) { - char buffer[256]; - safe_sprintf(buffer, "%.3e", 1234.5678); - EXPECT_PRINTF(buffer, "%.3e", 1234.5678); - EXPECT_PRINTF("1234.568", "%.3f", 1234.5678); - EXPECT_PRINTF("1.23e+03", "%.3g", 1234.5678); - safe_sprintf(buffer, "%.3a", 1234.5678); - EXPECT_PRINTF(buffer, "%.3a", 1234.5678); -} - -TEST(printf_test, string_precision) { - char test[] = {'H', 'e', 'l', 'l', 'o'}; - EXPECT_EQ(fmt::sprintf("%.4s", test), "Hell"); -} - -TEST(printf_test, ignore_precision_for_non_numeric_arg) { - EXPECT_PRINTF("abc", "%.5s", "abc"); -} - -TEST(printf_test, dynamic_precision) { - EXPECT_EQ("00042", test_sprintf("%.*d", 5, 42)); - EXPECT_EQ("42", test_sprintf("%.*d", -5, 42)); - EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error, - "precision is not integer"); - EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%.*d", big_num, 42), format_error, - "number is too big"); - if (sizeof(long long) != sizeof(int)) { - long long prec = static_cast<long long>(INT_MIN) - 1; - EXPECT_THROW_MSG(test_sprintf("%.*d", prec, 42), format_error, - "number is too big"); - } -} - -template <typename T> struct make_signed { typedef T type; }; - -#define SPECIALIZE_MAKE_SIGNED(T, S) \ - template <> struct make_signed<T> { typedef S type; } - -SPECIALIZE_MAKE_SIGNED(char, signed char); -SPECIALIZE_MAKE_SIGNED(unsigned char, signed char); -SPECIALIZE_MAKE_SIGNED(unsigned short, short); -SPECIALIZE_MAKE_SIGNED(unsigned, int); -SPECIALIZE_MAKE_SIGNED(unsigned long, long); -SPECIALIZE_MAKE_SIGNED(unsigned long long, long long); - -// Test length format specifier ``length_spec``. -template <typename T, typename U> -void test_length(const char* length_spec, U value) { - long long signed_value = 0; - unsigned long long unsigned_value = 0; - // Apply integer promotion to the argument. - unsigned long long max = max_value<U>(); - using fmt::detail::const_check; - if (const_check(max <= static_cast<unsigned>(max_value<int>()))) { - signed_value = static_cast<int>(value); - unsigned_value = static_cast<unsigned long long>(value); - } else if (const_check(max <= max_value<unsigned>())) { - signed_value = static_cast<unsigned>(value); - unsigned_value = static_cast<unsigned long long>(value); - } - if (sizeof(U) <= sizeof(int) && sizeof(int) < sizeof(T)) { - signed_value = static_cast<long long>(value); - unsigned_value = static_cast<unsigned long long>( - static_cast<typename std::make_unsigned<unsigned>::type>(value)); - } else { - signed_value = static_cast<typename make_signed<T>::type>(value); - unsigned_value = static_cast<typename std::make_unsigned<T>::type>(value); - } - std::ostringstream os; - os << signed_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value); - EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value); - os.str(""); - os << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value); - os.str(""); - os << std::oct << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value); - os.str(""); - os << std::hex << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value); - os.str(""); - os << std::hex << std::uppercase << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value); -} - -template <typename T> void test_length(const char* length_spec) { - T min = std::numeric_limits<T>::min(), max = max_value<T>(); - test_length<T>(length_spec, 42); - test_length<T>(length_spec, -42); - test_length<T>(length_spec, min); - test_length<T>(length_spec, max); - long long long_long_min = std::numeric_limits<long long>::min(); - if (static_cast<long long>(min) > long_long_min) - test_length<T>(length_spec, static_cast<long long>(min) - 1); - unsigned long long long_long_max = max_value<long long>(); - if (static_cast<unsigned long long>(max) < long_long_max) - test_length<T>(length_spec, static_cast<long long>(max) + 1); - test_length<T>(length_spec, std::numeric_limits<short>::min()); - test_length<T>(length_spec, max_value<unsigned short>()); - test_length<T>(length_spec, std::numeric_limits<int>::min()); - test_length<T>(length_spec, max_value<int>()); - test_length<T>(length_spec, std::numeric_limits<unsigned>::min()); - test_length<T>(length_spec, max_value<unsigned>()); - test_length<T>(length_spec, std::numeric_limits<long long>::min()); - test_length<T>(length_spec, max_value<long long>()); - test_length<T>(length_spec, std::numeric_limits<unsigned long long>::min()); - test_length<T>(length_spec, max_value<unsigned long long>()); -} - -TEST(printf_test, length) { - test_length<char>("hh"); - test_length<signed char>("hh"); - test_length<unsigned char>("hh"); - test_length<short>("h"); - test_length<unsigned short>("h"); - test_length<long>("l"); - test_length<unsigned long>("l"); - test_length<long long>("ll"); - test_length<unsigned long long>("ll"); - test_length<intmax_t>("j"); - test_length<size_t>("z"); - test_length<std::ptrdiff_t>("t"); - long double max = max_value<long double>(); - EXPECT_PRINTF(fmt::format("{:.6}", max), "%g", max); - EXPECT_PRINTF(fmt::format("{:.6}", max), "%Lg", max); -} - -TEST(printf_test, bool) { - EXPECT_PRINTF("1", "%d", true); - EXPECT_PRINTF("true", "%s", true); -} - -TEST(printf_test, int) { - EXPECT_PRINTF("-42", "%d", -42); - EXPECT_PRINTF("-42", "%i", -42); - unsigned u = 0 - 42u; - EXPECT_PRINTF(fmt::format("{}", u), "%u", -42); - EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42); - EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42); - EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42); -} - -TEST(printf_test, long_long) { - // fmt::printf allows passing long long arguments to %d without length - // specifiers. - long long max = max_value<long long>(); - EXPECT_PRINTF(fmt::format("{}", max), "%d", max); -} - -TEST(printf_test, float) { - EXPECT_PRINTF("392.650000", "%f", 392.65); - EXPECT_PRINTF("392.65", "%.2f", 392.65); - EXPECT_PRINTF("392.6", "%.1f", 392.65); - EXPECT_PRINTF("393", "%.f", 392.65); - EXPECT_PRINTF("392.650000", "%F", 392.65); - char buffer[256]; - safe_sprintf(buffer, "%e", 392.65); - EXPECT_PRINTF(buffer, "%e", 392.65); - safe_sprintf(buffer, "%E", 392.65); - EXPECT_PRINTF(buffer, "%E", 392.65); - EXPECT_PRINTF("392.65", "%g", 392.65); - EXPECT_PRINTF("392.65", "%G", 392.65); - EXPECT_PRINTF("392", "%g", 392.0); - EXPECT_PRINTF("392", "%G", 392.0); - EXPECT_PRINTF("4.56e-07", "%g", 0.000000456); - safe_sprintf(buffer, "%a", -392.65); - EXPECT_EQ(buffer, format("{:a}", -392.65)); - safe_sprintf(buffer, "%A", -392.65); - EXPECT_EQ(buffer, format("{:A}", -392.65)); -} - -TEST(printf_test, inf) { - double inf = std::numeric_limits<double>::infinity(); - for (const char* type = "fega"; *type; ++type) { - EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf); - char upper = static_cast<char>(std::toupper(*type)); - EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf); - } -} - -TEST(printf_test, char) { - EXPECT_PRINTF("x", "%c", 'x'); - int max = max_value<int>(); - EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max); - // EXPECT_PRINTF("x", "%lc", L'x'); - EXPECT_PRINTF(L"x", L"%c", L'x'); - EXPECT_PRINTF(fmt::format(L"{}", static_cast<wchar_t>(max)), L"%c", max); -} - -TEST(printf_test, string) { - EXPECT_PRINTF("abc", "%s", "abc"); - const char* null_str = nullptr; - EXPECT_PRINTF("(null)", "%s", null_str); - EXPECT_PRINTF(" (null)", "%10s", null_str); - EXPECT_PRINTF(L"abc", L"%s", L"abc"); - const wchar_t* null_wstr = nullptr; - EXPECT_PRINTF(L"(null)", L"%s", null_wstr); - EXPECT_PRINTF(L" (null)", L"%10s", null_wstr); -} - -TEST(printf_test, pointer) { - int n; - void* p = &n; - EXPECT_PRINTF(fmt::format("{}", p), "%p", p); - p = nullptr; - EXPECT_PRINTF("(nil)", "%p", p); - EXPECT_PRINTF(" (nil)", "%10p", p); - const char* s = "test"; - EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); - const char* null_str = nullptr; - EXPECT_PRINTF("(nil)", "%p", null_str); - - p = &n; - EXPECT_PRINTF(fmt::format(L"{}", p), L"%p", p); - p = nullptr; - EXPECT_PRINTF(L"(nil)", L"%p", p); - EXPECT_PRINTF(L" (nil)", L"%10p", p); - const wchar_t* w = L"test"; - EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w); - const wchar_t* null_wstr = nullptr; - EXPECT_PRINTF(L"(nil)", L"%p", null_wstr); -} - -enum test_enum { answer = 42 }; - -TEST(printf_test, enum) { - EXPECT_PRINTF("42", "%d", answer); - volatile test_enum volatile_enum = answer; - EXPECT_PRINTF("42", "%d", volatile_enum); -} - -#if FMT_USE_FCNTL -TEST(printf_test, examples) { - const char* weekday = "Thursday"; - const char* month = "August"; - int day = 21; - EXPECT_WRITE(stdout, fmt::printf("%1$s, %3$d %2$s", weekday, month, day), - "Thursday, 21 August"); -} - -TEST(printf_test, printf_error) { - fmt::file read_end, write_end; - fmt::file::pipe(read_end, write_end); - int result = fmt::fprintf(read_end.fdopen("r").get(), "test"); - EXPECT_LT(result, 0); -} -#endif - -TEST(printf_test, wide_string) { - EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); -} - -TEST(printf_test, printf_custom) { - EXPECT_EQ("abc", test_sprintf("%s", test_string("abc"))); -} - -TEST(printf_test, vprintf) { - fmt::format_arg_store<fmt::printf_context, int> as{42}; - fmt::basic_format_args<fmt::printf_context> args(as); - EXPECT_EQ(fmt::vsprintf("%d", args), "42"); - EXPECT_WRITE(stdout, fmt::vprintf("%d", args), "42"); - EXPECT_WRITE(stdout, fmt::vfprintf(stdout, "%d", args), "42"); -} - -template <typename... Args> -void check_format_string_regression(fmt::string_view s, const Args&... args) { - fmt::sprintf(s, args...); -} - -TEST(printf_test, check_format_string_regression) { - check_format_string_regression("%c%s", 'x', ""); -} - -TEST(printf_test, fixed_large_exponent) { - EXPECT_EQ("1000000000000000000000", fmt::sprintf("%.*f", -13, 1e21)); -} - -TEST(printf_test, vsprintf_make_args_example) { - fmt::format_arg_store<fmt::printf_context, int, const char*> as{42, - "something"}; - fmt::basic_format_args<fmt::printf_context> args(as); - EXPECT_EQ("[42] something happened", fmt::vsprintf("[%d] %s happened", args)); - auto as2 = fmt::make_printf_args(42, "something"); - fmt::basic_format_args<fmt::printf_context> args2(as2); - EXPECT_EQ("[42] something happened", - fmt::vsprintf("[%d] %s happened", args2)); - EXPECT_EQ("[42] something happened", - fmt::vsprintf("[%d] %s happened", - {fmt::make_printf_args(42, "something")})); -} - -TEST(printf_test, vsprintf_make_wargs_example) { - fmt::format_arg_store<fmt::wprintf_context, int, const wchar_t*> as{ - 42, L"something"}; - fmt::basic_format_args<fmt::wprintf_context> args(as); - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", args)); - auto as2 = fmt::make_wprintf_args(42, L"something"); - fmt::basic_format_args<fmt::wprintf_context> args2(as2); - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", args2)); - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", - {fmt::make_wprintf_args(42, L"something")})); -} diff --git a/contrib/libs/fmt/test/printf-test/ya.make b/contrib/libs/fmt/test/printf-test/ya.make deleted file mode 100644 index 1d93b49d90..0000000000 --- a/contrib/libs/fmt/test/printf-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - printf-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/ranges-odr-test.cc b/contrib/libs/fmt/test/ranges-odr-test.cc deleted file mode 100644 index 031354d3c2..0000000000 --- a/contrib/libs/fmt/test/ranges-odr-test.cc +++ /dev/null @@ -1,17 +0,0 @@ -// Formatting library for C++ - the core API -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <vector> - -#include "fmt/ranges.h" -#include "gtest/gtest.h" - -// call fmt::format from another translation unit to test ODR -TEST(ranges_odr_test, format_vector) { - auto v = std::vector<int>{1, 2, 3, 5, 7, 11}; - EXPECT_EQ(fmt::format("{}", v), "[1, 2, 3, 5, 7, 11]"); -} diff --git a/contrib/libs/fmt/test/ranges-test.cc b/contrib/libs/fmt/test/ranges-test.cc deleted file mode 100644 index 63cb8c8bca..0000000000 --- a/contrib/libs/fmt/test/ranges-test.cc +++ /dev/null @@ -1,363 +0,0 @@ -// Formatting library for C++ - the core API -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. -// -// Copyright (c) 2018 - present, Remotion (Igor Schulz) -// All Rights Reserved -// {fmt} support for ranges, containers and types tuple interface. - -#include "fmt/ranges.h" - -#include <map> -#include <string> -#include <vector> - -#include "gtest/gtest.h" - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 601 -# define FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY -#endif - -#if !FMT_MSC_VER || FMT_MSC_VER > 1910 -# define FMT_RANGES_TEST_ENABLE_JOIN -# define FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT -#endif - -#ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY -TEST(ranges_test, format_array) { - int arr[] = {1, 2, 3, 5, 7, 11}; - EXPECT_EQ(fmt::format("{}", arr), "[1, 2, 3, 5, 7, 11]"); -} - -TEST(ranges_test, format_2d_array) { - int arr[][2] = {{1, 2}, {3, 5}, {7, 11}}; - EXPECT_EQ(fmt::format("{}", arr), "[[1, 2], [3, 5], [7, 11]]"); -} - -TEST(ranges_test, format_array_of_literals) { - const char* arr[] = {"1234", "abcd"}; - EXPECT_EQ(fmt::format("{}", arr), "[\"1234\", \"abcd\"]"); -} -#endif // FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY - -TEST(ranges_test, format_vector) { - auto v = std::vector<int>{1, 2, 3, 5, 7, 11}; - EXPECT_EQ(fmt::format("{}", v), "[1, 2, 3, 5, 7, 11]"); -} - -TEST(ranges_test, format_vector2) { - auto v = std::vector<std::vector<int>>{{1, 2}, {3, 5}, {7, 11}}; - EXPECT_EQ(fmt::format("{}", v), "[[1, 2], [3, 5], [7, 11]]"); -} - -TEST(ranges_test, format_map) { - auto m = std::map<std::string, int>{{"one", 1}, {"two", 2}}; - EXPECT_EQ(fmt::format("{}", m), "{\"one\": 1, \"two\": 2}"); -} - -TEST(ranges_test, format_set) { - EXPECT_EQ(fmt::format("{}", std::set<std::string>{"one", "two"}), - "{\"one\", \"two\"}"); -} - -TEST(ranges_test, format_pair) { - auto p = std::pair<int, float>(42, 1.5f); - EXPECT_EQ(fmt::format("{}", p), "(42, 1.5)"); -} - -TEST(ranges_test, format_tuple) { - auto t = - std::tuple<int, float, std::string, char>(42, 1.5f, "this is tuple", 'i'); - EXPECT_EQ(fmt::format("{}", t), "(42, 1.5, \"this is tuple\", 'i')"); - EXPECT_EQ(fmt::format("{}", std::tuple<>()), "()"); -} - -#ifdef FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT -struct tuple_like { - int i; - std::string str; - - template <size_t N> fmt::enable_if_t<N == 0, int> get() const noexcept { - return i; - } - template <size_t N> - fmt::enable_if_t<N == 1, fmt::string_view> get() const noexcept { - return str; - } -}; - -template <size_t N> -auto get(const tuple_like& t) noexcept -> decltype(t.get<N>()) { - return t.get<N>(); -} - -namespace std { -template <> -struct tuple_size<tuple_like> : std::integral_constant<size_t, 2> {}; - -template <size_t N> struct tuple_element<N, tuple_like> { - using type = decltype(std::declval<tuple_like>().get<N>()); -}; -} // namespace std - -TEST(ranges_test, format_struct) { - auto t = tuple_like{42, "foo"}; - EXPECT_EQ(fmt::format("{}", t), "(42, \"foo\")"); -} -#endif // FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT - -TEST(ranges_test, format_to) { - char buf[10]; - auto end = fmt::format_to(buf, "{}", std::vector<int>{1, 2, 3}); - *end = '\0'; - EXPECT_STREQ(buf, "[1, 2, 3]"); -} - -struct path_like { - const path_like* begin() const; - const path_like* end() const; - - operator std::string() const; -}; - -TEST(ranges_test, path_like) { - EXPECT_FALSE((fmt::is_range<path_like, char>::value)); -} - -#ifdef FMT_USE_STRING_VIEW -struct string_like { - const char* begin(); - const char* end(); - explicit operator fmt::string_view() const { return "foo"; } - explicit operator std::string_view() const { return "foo"; } -}; - -TEST(ranges_test, format_string_like) { - EXPECT_EQ(fmt::format("{}", string_like()), "foo"); -} -#endif // FMT_USE_STRING_VIEW - -// A range that provides non-const only begin()/end() to test fmt::join handles -// that. -// -// Some ranges (e.g. those produced by range-v3's views::filter()) can cache -// information during iteration so they only provide non-const begin()/end(). -template <typename T> class non_const_only_range { - private: - std::vector<T> vec; - - public: - using const_iterator = typename ::std::vector<T>::const_iterator; - - template <typename... Args> - explicit non_const_only_range(Args&&... args) - : vec(std::forward<Args>(args)...) {} - - const_iterator begin() { return vec.begin(); } - const_iterator end() { return vec.end(); } -}; - -template <typename T> class noncopyable_range { - private: - std::vector<T> vec; - - public: - using const_iterator = typename ::std::vector<T>::const_iterator; - - template <typename... Args> - explicit noncopyable_range(Args&&... args) - : vec(std::forward<Args>(args)...) {} - - noncopyable_range(noncopyable_range const&) = delete; - noncopyable_range(noncopyable_range&) = delete; - - const_iterator begin() const { return vec.begin(); } - const_iterator end() const { return vec.end(); } -}; - -TEST(ranges_test, range) { - noncopyable_range<int> w(3u, 0); - EXPECT_EQ(fmt::format("{}", w), "[0, 0, 0]"); - EXPECT_EQ(fmt::format("{}", noncopyable_range<int>(3u, 0)), "[0, 0, 0]"); - - non_const_only_range<int> x(3u, 0); - EXPECT_EQ(fmt::format("{}", x), "[0, 0, 0]"); - EXPECT_EQ(fmt::format("{}", non_const_only_range<int>(3u, 0)), "[0, 0, 0]"); - - auto y = std::vector<int>(3u, 0); - EXPECT_EQ(fmt::format("{}", y), "[0, 0, 0]"); - EXPECT_EQ(fmt::format("{}", std::vector<int>(3u, 0)), "[0, 0, 0]"); - - const auto z = std::vector<int>(3u, 0); - EXPECT_EQ(fmt::format("{}", z), "[0, 0, 0]"); -} - -enum test_enum { foo }; - -TEST(ranges_test, enum_range) { - auto v = std::vector<test_enum>{test_enum::foo}; - EXPECT_EQ(fmt::format("{}", v), "[0]"); -} - -#if !FMT_MSC_VER -struct unformattable {}; - -TEST(ranges_test, unformattable_range) { - EXPECT_FALSE((fmt::has_formatter<std::vector<unformattable>, - fmt::format_context>::value)); -} -#endif - -#ifdef FMT_RANGES_TEST_ENABLE_JOIN -TEST(ranges_test, join_tuple) { - // Value tuple args. - auto t1 = std::tuple<char, int, float>('a', 1, 2.0f); - EXPECT_EQ(fmt::format("({})", fmt::join(t1, ", ")), "(a, 1, 2)"); - - // Testing lvalue tuple args. - int x = 4; - auto t2 = std::tuple<char, int&>('b', x); - EXPECT_EQ(fmt::format("{}", fmt::join(t2, " + ")), "b + 4"); - - // Empty tuple. - auto t3 = std::tuple<>(); - EXPECT_EQ(fmt::format("{}", fmt::join(t3, "|")), ""); - - // Single element tuple. - auto t4 = std::tuple<float>(4.0f); - EXPECT_EQ(fmt::format("{}", fmt::join(t4, "/")), "4"); - -# if FMT_TUPLE_JOIN_SPECIFIERS - // Specs applied to each element. - auto t5 = std::tuple<int, int, long>(-3, 100, 1); - EXPECT_EQ(fmt::format("{:+03}", fmt::join(t5, ", ")), "-03, +100, +01"); - - auto t6 = std::tuple<float, double, long double>(3, 3.14, 3.1415); - EXPECT_EQ(fmt::format("{:5.5f}", fmt::join(t6, ", ")), - "3.00000, 3.14000, 3.14150"); - - // Testing lvalue tuple args. - int y = -1; - auto t7 = std::tuple<int, int&, const int&>(3, y, y); - EXPECT_EQ(fmt::format("{:03}", fmt::join(t7, ", ")), "003, -01, -01"); -# endif -} - -TEST(ranges_test, join_initializer_list) { - EXPECT_EQ(fmt::format("{}", fmt::join({1, 2, 3}, ", ")), "1, 2, 3"); - EXPECT_EQ(fmt::format("{}", fmt::join({"fmt", "rocks", "!"}, " ")), - "fmt rocks !"); -} - -struct zstring_sentinel {}; - -bool operator==(const char* p, zstring_sentinel) { return *p == '\0'; } -bool operator!=(const char* p, zstring_sentinel) { return *p != '\0'; } - -struct zstring { - const char* p; - const char* begin() const { return p; } - zstring_sentinel end() const { return {}; } -}; - -# ifdef __cpp_lib_ranges -struct cpp20_only_range { - struct iterator { - int val = 0; - - using value_type = int; - using difference_type = std::ptrdiff_t; - using iterator_concept = std::input_iterator_tag; - - iterator() = default; - iterator(int i) : val(i) {} - int operator*() const { return val; } - iterator& operator++() { - ++val; - return *this; - } - void operator++(int) { ++*this; } - bool operator==(const iterator& rhs) const { return val == rhs.val; } - }; - - int lo; - int hi; - - iterator begin() const { return iterator(lo); } - iterator end() const { return iterator(hi); } -}; - -static_assert(std::input_iterator<cpp20_only_range::iterator>); -# endif - -TEST(ranges_test, join_sentinel) { - auto hello = zstring{"hello"}; - EXPECT_EQ(fmt::format("{}", hello), "['h', 'e', 'l', 'l', 'o']"); - EXPECT_EQ(fmt::format("{}", fmt::join(hello, "_")), "h_e_l_l_o"); -} - -TEST(ranges_test, join_range) { - noncopyable_range<int> w(3u, 0); - EXPECT_EQ(fmt::format("{}", fmt::join(w, ",")), "0,0,0"); - EXPECT_EQ(fmt::format("{}", fmt::join(noncopyable_range<int>(3u, 0), ",")), - "0,0,0"); - - non_const_only_range<int> x(3u, 0); - EXPECT_EQ(fmt::format("{}", fmt::join(x, ",")), "0,0,0"); - EXPECT_EQ(fmt::format("{}", fmt::join(non_const_only_range<int>(3u, 0), ",")), - "0,0,0"); - - auto y = std::vector<int>(3u, 0); - EXPECT_EQ(fmt::format("{}", fmt::join(y, ",")), "0,0,0"); - EXPECT_EQ(fmt::format("{}", fmt::join(std::vector<int>(3u, 0), ",")), - "0,0,0"); - - const auto z = std::vector<int>(3u, 0); - EXPECT_EQ(fmt::format("{}", fmt::join(z, ",")), "0,0,0"); - -# ifdef __cpp_lib_ranges - EXPECT_EQ(fmt::format("{}", cpp20_only_range{.lo = 0, .hi = 5}), - "[0, 1, 2, 3, 4]"); - EXPECT_EQ( - fmt::format("{}", fmt::join(cpp20_only_range{.lo = 0, .hi = 5}, ",")), - "0,1,2,3,4"); -# endif -} -#endif // FMT_RANGES_TEST_ENABLE_JOIN - -TEST(ranges_test, is_printable) { - using fmt::detail::is_printable; - EXPECT_TRUE(is_printable(0x0323)); - EXPECT_FALSE(is_printable(0x0378)); - EXPECT_FALSE(is_printable(0x110000)); -} - -TEST(ranges_test, escape_string) { - using vec = std::vector<std::string>; - EXPECT_EQ(fmt::format("{}", vec{"\n\r\t\"\\"}), "[\"\\n\\r\\t\\\"\\\\\"]"); - EXPECT_EQ(fmt::format("{}", vec{"\x07"}), "[\"\\x07\"]"); - EXPECT_EQ(fmt::format("{}", vec{"\x7f"}), "[\"\\x7f\"]"); - EXPECT_EQ(fmt::format("{}", vec{"n\xcc\x83"}), "[\"n\xcc\x83\"]"); - - if (fmt::detail::is_utf8()) { - EXPECT_EQ(fmt::format("{}", vec{"\xcd\xb8"}), "[\"\\u0378\"]"); - // Unassigned Unicode code points. - EXPECT_EQ(fmt::format("{}", vec{"\xf0\xaa\x9b\x9e"}), "[\"\\U0002a6de\"]"); - EXPECT_EQ(fmt::format("{}", vec{"\xf4\x8f\xbf\xc0"}), - "[\"\\xf4\\x8f\\xbf\\xc0\"]"); - } -} - -#ifdef FMT_USE_STRING_VIEW -struct convertible_to_string_view { - operator std::string_view() const { return "foo"; } -}; - -TEST(ranges_test, escape_convertible_to_string_view) { - EXPECT_EQ(fmt::format("{}", std::vector<convertible_to_string_view>(1)), - "[\"foo\"]"); -} -#endif // FMT_USE_STRING_VIEW diff --git a/contrib/libs/fmt/test/ranges-test/ya.make b/contrib/libs/fmt/test/ranges-test/ya.make deleted file mode 100644 index 251070a677..0000000000 --- a/contrib/libs/fmt/test/ranges-test/ya.make +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - ranges-odr-test.cc - ranges-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/scan-test.cc b/contrib/libs/fmt/test/scan-test.cc deleted file mode 100644 index 7e327ea3f5..0000000000 --- a/contrib/libs/fmt/test/scan-test.cc +++ /dev/null @@ -1,116 +0,0 @@ -// Formatting library for C++ - scanning API test -// -// Copyright (c) 2019 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "scan.h" - -#include <time.h> - -#include <climits> - -#include "gmock/gmock.h" -#include "gtest-extra.h" - -TEST(scan_test, read_text) { - auto s = fmt::string_view("foo"); - auto end = fmt::scan(s, "foo"); - EXPECT_EQ(end, s.end()); - EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input"); -} - -TEST(scan_test, read_int) { - auto n = int(); - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - fmt::scan("-42", "{}", n); - EXPECT_EQ(n, -42); -} - -TEST(scan_test, read_longlong) { - long long n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - fmt::scan("-42", "{}", n); - EXPECT_EQ(n, -42); -} - -TEST(scan_test, read_uint) { - auto n = unsigned(); - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, - "invalid input"); -} - -TEST(scan_test, read_ulonglong) { - unsigned long long n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, - "invalid input"); -} - -TEST(scan_test, read_string) { - auto s = std::string(); - fmt::scan("foo", "{}", s); - EXPECT_EQ(s, "foo"); -} - -TEST(scan_test, read_string_view) { - auto s = fmt::string_view(); - fmt::scan("foo", "{}", s); - EXPECT_EQ(s, "foo"); -} - -#ifndef _WIN32 -namespace fmt { -template <> struct scanner<tm> { - std::string format; - - scan_parse_context::iterator parse(scan_parse_context& ctx) { - auto it = ctx.begin(); - if (it != ctx.end() && *it == ':') ++it; - auto end = it; - while (end != ctx.end() && *end != '}') ++end; - format.reserve(detail::to_unsigned(end - it + 1)); - format.append(it, end); - format.push_back('\0'); - return end; - } - - template <class ScanContext> - typename ScanContext::iterator scan(tm& t, ScanContext& ctx) { - auto result = strptime(ctx.begin(), format.c_str(), &t); - if (!result) throw format_error("failed to parse time"); - return result; - } -}; -} // namespace fmt - -TEST(scan_test, read_custom) { - auto input = "Date: 1985-10-25"; - auto t = tm(); - fmt::scan(input, "Date: {0:%Y-%m-%d}", t); - EXPECT_EQ(t.tm_year, 85); - EXPECT_EQ(t.tm_mon, 9); - EXPECT_EQ(t.tm_mday, 25); -} -#endif - -TEST(scan_test, invalid_format) { - EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, - "argument index out of range"); - EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error, - "invalid format string"); -} - -TEST(scan_test, example) { - auto key = std::string(); - auto value = int(); - fmt::scan("answer = 42", "{} = {}", key, value); - EXPECT_EQ(key, "answer"); - EXPECT_EQ(value, 42); -} diff --git a/contrib/libs/fmt/test/scan-test/ya.make b/contrib/libs/fmt/test/scan-test/ya.make deleted file mode 100644 index f1a6fff1c9..0000000000 --- a/contrib/libs/fmt/test/scan-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - scan-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/scan.h b/contrib/libs/fmt/test/scan.h deleted file mode 100644 index 41748ae895..0000000000 --- a/contrib/libs/fmt/test/scan.h +++ /dev/null @@ -1,241 +0,0 @@ -// Formatting library for C++ - scanning API proof of concept -// -// Copyright (c) 2019 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <array> -#include <cassert> -#include <climits> - -#include "fmt/format.h" - -FMT_BEGIN_NAMESPACE -template <typename T, typename Char = char> struct scanner { - // A deleted default constructor indicates a disabled scanner. - scanner() = delete; -}; - -class scan_parse_context { - private: - string_view format_; - - public: - using iterator = string_view::iterator; - - explicit FMT_CONSTEXPR scan_parse_context(string_view format) - : format_(format) {} - - FMT_CONSTEXPR iterator begin() const { return format_.begin(); } - FMT_CONSTEXPR iterator end() const { return format_.end(); } - - void advance_to(iterator it) { - format_.remove_prefix(detail::to_unsigned(it - begin())); - } -}; - -struct scan_context { - private: - string_view input_; - - public: - using iterator = const char*; - - explicit scan_context(string_view input) : input_(input) {} - - iterator begin() const { return input_.data(); } - iterator end() const { return begin() + input_.size(); } - - void advance_to(iterator it) { - input_.remove_prefix(detail::to_unsigned(it - begin())); - } -}; - -namespace detail { -enum class scan_type { - none_type, - int_type, - uint_type, - long_long_type, - ulong_long_type, - string_type, - string_view_type, - custom_type -}; - -struct custom_scan_arg { - void* value; - void (*scan)(void* arg, scan_parse_context& parse_ctx, scan_context& ctx); -}; - -class scan_arg { - public: - scan_type type; - union { - int* int_value; - unsigned* uint_value; - long long* long_long_value; - unsigned long long* ulong_long_value; - std::string* string; - fmt::string_view* string_view; - custom_scan_arg custom; - // TODO: more types - }; - - scan_arg() : type(scan_type::none_type) {} - scan_arg(int& value) : type(scan_type::int_type), int_value(&value) {} - scan_arg(unsigned& value) : type(scan_type::uint_type), uint_value(&value) {} - scan_arg(long long& value) - : type(scan_type::long_long_type), long_long_value(&value) {} - scan_arg(unsigned long long& value) - : type(scan_type::ulong_long_type), ulong_long_value(&value) {} - scan_arg(std::string& value) : type(scan_type::string_type), string(&value) {} - scan_arg(fmt::string_view& value) - : type(scan_type::string_view_type), string_view(&value) {} - template <typename T> scan_arg(T& value) : type(scan_type::custom_type) { - custom.value = &value; - custom.scan = scan_custom_arg<T>; - } - - private: - template <typename T> - static void scan_custom_arg(void* arg, scan_parse_context& parse_ctx, - scan_context& ctx) { - scanner<T> s; - parse_ctx.advance_to(s.parse(parse_ctx)); - ctx.advance_to(s.scan(*static_cast<T*>(arg), ctx)); - } -}; -} // namespace detail - -struct scan_args { - int size; - const detail::scan_arg* data; - - template <size_t N> - scan_args(const std::array<detail::scan_arg, N>& store) - : size(N), data(store.data()) { - static_assert(N < INT_MAX, "too many arguments"); - } -}; - -namespace detail { - -struct scan_handler : error_handler { - private: - scan_parse_context parse_ctx_; - scan_context scan_ctx_; - scan_args args_; - int next_arg_id_; - scan_arg arg_; - - template <typename T = unsigned> T read_uint() { - T value = 0; - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - while (it != end) { - char c = *it++; - if (c < '0' || c > '9') on_error("invalid input"); - // TODO: check overflow - value = value * 10 + static_cast<unsigned>(c - '0'); - } - scan_ctx_.advance_to(it); - return value; - } - - template <typename T = int> T read_int() { - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - bool negative = it != end && *it == '-'; - if (negative) ++it; - scan_ctx_.advance_to(it); - const auto value = read_uint<typename std::make_unsigned<T>::type>(); - if (negative) return -static_cast<T>(value); - return static_cast<T>(value); - } - - public: - scan_handler(string_view format, string_view input, scan_args args) - : parse_ctx_(format), scan_ctx_(input), args_(args), next_arg_id_(0) {} - - const char* pos() const { return scan_ctx_.begin(); } - - void on_text(const char* begin, const char* end) { - auto size = to_unsigned(end - begin); - auto it = scan_ctx_.begin(); - if (it + size > scan_ctx_.end() || - !std::equal(begin, end, make_checked(it, size))) { - on_error("invalid input"); - } - scan_ctx_.advance_to(it + size); - } - - FMT_CONSTEXPR int on_arg_id() { return on_arg_id(next_arg_id_++); } - FMT_CONSTEXPR int on_arg_id(int id) { - if (id >= args_.size) on_error("argument index out of range"); - arg_ = args_.data[id]; - return id; - } - FMT_CONSTEXPR int on_arg_id(string_view id) { - if (id.data()) on_error("invalid format"); - return 0; - } - - void on_replacement_field(int, const char*) { - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - switch (arg_.type) { - case scan_type::int_type: - *arg_.int_value = read_int(); - break; - case scan_type::uint_type: - *arg_.uint_value = read_uint(); - break; - case scan_type::long_long_type: - *arg_.long_long_value = read_int<long long>(); - break; - case scan_type::ulong_long_type: - *arg_.ulong_long_value = read_uint<unsigned long long>(); - break; - case scan_type::string_type: - while (it != end && *it != ' ') arg_.string->push_back(*it++); - scan_ctx_.advance_to(it); - break; - case scan_type::string_view_type: { - auto s = it; - while (it != end && *it != ' ') ++it; - *arg_.string_view = fmt::string_view(s, to_unsigned(it - s)); - scan_ctx_.advance_to(it); - break; - } - case scan_type::none_type: - case scan_type::custom_type: - assert(false); - } - } - - const char* on_format_specs(int, const char* begin, const char*) { - if (arg_.type != scan_type::custom_type) return begin; - parse_ctx_.advance_to(begin); - arg_.custom.scan(arg_.custom.value, parse_ctx_, scan_ctx_); - return parse_ctx_.begin(); - } -}; -} // namespace detail - -template <typename... Args> -std::array<detail::scan_arg, sizeof...(Args)> make_scan_args(Args&... args) { - return {{args...}}; -} - -string_view::iterator vscan(string_view input, string_view format_str, - scan_args args) { - detail::scan_handler h(format_str, input, args); - detail::parse_format_string<false>(format_str, h); - return input.begin() + (h.pos() - &*input.begin()); -} - -template <typename... Args> -string_view::iterator scan(string_view input, string_view format_str, - Args&... args) { - return vscan(input, format_str, make_scan_args(args...)); -} -FMT_END_NAMESPACE diff --git a/contrib/libs/fmt/test/test-assert.h b/contrib/libs/fmt/test/test-assert.h deleted file mode 100644 index ab7b2bf732..0000000000 --- a/contrib/libs/fmt/test/test-assert.h +++ /dev/null @@ -1,39 +0,0 @@ -// Formatting library for C++ - test version of FMT_ASSERT -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_TEST_ASSERT_H_ -#define FMT_TEST_ASSERT_H_ - -#include <stdexcept> - -void throw_assertion_failure(const char* message); -#define FMT_ASSERT(condition, message) \ - if (!(condition)) throw_assertion_failure(message); - -#include "gtest/gtest.h" - -class assertion_failure : public std::logic_error { - public: - explicit assertion_failure(const char* message) : std::logic_error(message) {} - - private: - virtual void avoid_weak_vtable(); -}; - -void assertion_failure::avoid_weak_vtable() {} - -// We use a separate function (rather than throw directly from FMT_ASSERT) to -// avoid GCC's -Wterminate warning when FMT_ASSERT is used in a destructor. -inline void throw_assertion_failure(const char* message) { - throw assertion_failure(message); -} - -// Expects an assertion failure. -#define EXPECT_ASSERT(stmt, message) \ - FMT_TEST_THROW_(stmt, assertion_failure, message, GTEST_NONFATAL_FAILURE_) - -#endif // FMT_TEST_ASSERT_H_ diff --git a/contrib/libs/fmt/test/unicode-test.cc b/contrib/libs/fmt/test/unicode-test.cc deleted file mode 100644 index 63c828dd8f..0000000000 --- a/contrib/libs/fmt/test/unicode-test.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Formatting library for C++ - Unicode tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <iomanip> -#include <locale> -#include <vector> - -#include "fmt/chrono.h" -#include "gmock/gmock.h" -#include "util.h" // get_locale - -using testing::Contains; - -TEST(unicode_test, is_utf8) { EXPECT_TRUE(fmt::detail::is_utf8()); } - -TEST(unicode_test, legacy_locale) { - auto loc = get_locale("ru_RU.CP1251", "Russian_Russia.1251"); - if (loc == std::locale::classic()) return; - - auto s = std::string(); - try { - s = fmt::format(loc, "День недели: {:L}", fmt::weekday(1)); - } catch (const fmt::format_error& e) { - // Formatting can fail due to an unsupported encoding. - fmt::print("Format error: {}\n", e.what()); - return; - } - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 500 - auto&& os = std::ostringstream(); - os.imbue(loc); - auto tm = std::tm(); - tm.tm_wday = 1; - os << std::put_time(&tm, "%a"); - auto wd = os.str(); - if (wd == "??") { - EXPECT_EQ(s, "День недели: ??"); - fmt::print("std::locale gives ?? as a weekday.\n"); - return; - } -#endif - EXPECT_THAT((std::vector<std::string>{"День недели: пн", "День недели: Пн"}), - Contains(s)); -} diff --git a/contrib/libs/fmt/test/unicode-test/ya.make b/contrib/libs/fmt/test/unicode-test/ya.make deleted file mode 100644 index 96544c014b..0000000000 --- a/contrib/libs/fmt/test/unicode-test/ya.make +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -ADDINCL( - contrib/libs/fmt/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_HEADER_ONLY=1 - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt) - -SRCS( - src/os.cc - test/gtest-extra.cc - test/unicode-test.cc - test/util.cc -) - -END() diff --git a/contrib/libs/fmt/test/util.cc b/contrib/libs/fmt/test/util.cc deleted file mode 100644 index f4cb74ca0a..0000000000 --- a/contrib/libs/fmt/test/util.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Formatting library for C++ - test utilities -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "util.h" - -#include <cstring> - -const char* const file_content = "Don't panic!"; - -fmt::buffered_file open_buffered_file(FILE** fp) { -#if FMT_USE_FCNTL - fmt::file read_end, write_end; - fmt::file::pipe(read_end, write_end); - write_end.write(file_content, std::strlen(file_content)); - write_end.close(); - fmt::buffered_file f = read_end.fdopen("r"); - if (fp) *fp = f.get(); -#else - fmt::buffered_file f("test-file", "w"); - fputs(file_content, f.get()); - if (fp) *fp = f.get(); -#endif - return f; -} - -std::locale do_get_locale(const char* name) { - try { - return std::locale(name); - } catch (const std::runtime_error&) { - } - return std::locale::classic(); -} - -std::locale get_locale(const char* name, const char* alt_name) { - auto loc = do_get_locale(name); - if (loc == std::locale::classic() && alt_name) { - loc = do_get_locale(alt_name); - } - if (loc == std::locale::classic()) - fmt::print(stderr, "{} locale is missing.\n", name); - return loc; -} diff --git a/contrib/libs/fmt/test/util.h b/contrib/libs/fmt/test/util.h deleted file mode 100644 index 2e58ad950c..0000000000 --- a/contrib/libs/fmt/test/util.h +++ /dev/null @@ -1,85 +0,0 @@ -// Formatting library for C++ - test utilities -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <cstdarg> -#include <cstdio> -#include <locale> -#include <string> - -#ifdef FMT_MODULE_TEST -import fmt; -#else -# include "fmt/os.h" -#endif // FMT_MODULE_TEST - -#ifdef _MSC_VER -# define FMT_VSNPRINTF vsprintf_s -#else -# define FMT_VSNPRINTF vsnprintf -#endif - -template <size_t SIZE> -void safe_sprintf(char (&buffer)[SIZE], const char* format, ...) { - std::va_list args; - va_start(args, format); - FMT_VSNPRINTF(buffer, SIZE, format, args); - va_end(args); -} - -extern const char* const file_content; - -// Opens a buffered file for reading. -fmt::buffered_file open_buffered_file(FILE** fp = nullptr); - -inline FILE* safe_fopen(const char* filename, const char* mode) { -#if defined(_WIN32) && !defined(__MINGW32__) - // Fix MSVC warning about "unsafe" fopen. - FILE* f = nullptr; - errno = fopen_s(&f, filename, mode); - return f; -#else - return std::fopen(filename, mode); -#endif -} - -template <typename Char> class basic_test_string { - private: - std::basic_string<Char> value_; - - static const Char empty[]; - - public: - explicit basic_test_string(const Char* value = empty) : value_(value) {} - - const std::basic_string<Char>& value() const { return value_; } -}; - -template <typename Char> const Char basic_test_string<Char>::empty[] = {0}; - -typedef basic_test_string<char> test_string; -typedef basic_test_string<wchar_t> test_wstring; - -template <typename Char> -std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, - const basic_test_string<Char>& s) { - os << s.value(); - return os; -} - -class date { - int year_, month_, day_; - - public: - date(int year, int month, int day) : year_(year), month_(month), day_(day) {} - - int year() const { return year_; } - int month() const { return month_; } - int day() const { return day_; } -}; - -// Returns a locale with the given name if available or classic locale othewise. -std::locale get_locale(const char* name, const char* alt_name = nullptr); diff --git a/contrib/libs/fmt/test/xchar-test.cc b/contrib/libs/fmt/test/xchar-test.cc deleted file mode 100644 index 346cd21262..0000000000 --- a/contrib/libs/fmt/test/xchar-test.cc +++ /dev/null @@ -1,502 +0,0 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/xchar.h" - -#include <complex> -#include <cwchar> -#include <vector> - -#include "fmt/chrono.h" -#include "fmt/color.h" -#include "fmt/ostream.h" -#include "fmt/ranges.h" -#include "gtest-extra.h" // Contains -#include "util.h" // get_locale - -using fmt::detail::max_value; -using testing::Contains; - -namespace test_ns { -template <typename Char> class test_string { - private: - std::basic_string<Char> s_; - - public: - test_string(const Char* s) : s_(s) {} - const Char* data() const { return s_.data(); } - size_t length() const { return s_.size(); } - operator const Char*() const { return s_.c_str(); } -}; - -template <typename Char> -fmt::basic_string_view<Char> to_string_view(const test_string<Char>& s) { - return {s.data(), s.length()}; -} - -struct non_string {}; -} // namespace test_ns - -template <typename T> class is_string_test : public testing::Test {}; - -using string_char_types = testing::Types<char, wchar_t, char16_t, char32_t>; -TYPED_TEST_SUITE(is_string_test, string_char_types); - -template <typename Char> -struct derived_from_string_view : fmt::basic_string_view<Char> {}; - -TYPED_TEST(is_string_test, is_string) { - EXPECT_TRUE(fmt::detail::is_string<TypeParam*>::value); - EXPECT_TRUE(fmt::detail::is_string<const TypeParam*>::value); - EXPECT_TRUE(fmt::detail::is_string<TypeParam[2]>::value); - EXPECT_TRUE(fmt::detail::is_string<const TypeParam[2]>::value); - EXPECT_TRUE(fmt::detail::is_string<std::basic_string<TypeParam>>::value); - EXPECT_TRUE(fmt::detail::is_string<fmt::basic_string_view<TypeParam>>::value); - EXPECT_TRUE( - fmt::detail::is_string<derived_from_string_view<TypeParam>>::value); - using fmt_string_view = fmt::detail::std_string_view<TypeParam>; - EXPECT_TRUE(std::is_empty<fmt_string_view>::value != - fmt::detail::is_string<fmt_string_view>::value); - EXPECT_TRUE(fmt::detail::is_string<test_ns::test_string<TypeParam>>::value); - EXPECT_FALSE(fmt::detail::is_string<test_ns::non_string>::value); -} - -// std::is_constructible is broken in MSVC until version 2015. -#if !FMT_MSC_VER || FMT_MSC_VER >= 1900 -struct explicitly_convertible_to_wstring_view { - explicit operator fmt::wstring_view() const { return L"foo"; } -}; - -TEST(xchar_test, format_explicitly_convertible_to_wstring_view) { - EXPECT_EQ(L"foo", - fmt::format(L"{}", explicitly_convertible_to_wstring_view())); -} -#endif - -TEST(xchar_test, format) { - EXPECT_EQ(L"42", fmt::format(L"{}", 42)); - EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2)); - EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc")); - EXPECT_EQ(L"z", fmt::format(L"{}", L'z')); - EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error); - EXPECT_EQ(L"true", fmt::format(L"{}", true)); - EXPECT_EQ(L"a", fmt::format(L"{0}", 'a')); - EXPECT_EQ(L"a", fmt::format(L"{0}", L'a')); - EXPECT_EQ(L"Cyrillic letter \x42e", - fmt::format(L"Cyrillic letter {}", L'\x42e')); - EXPECT_EQ(L"abc1", fmt::format(L"{}c{}", L"ab", 1)); -} - -TEST(xchar_test, is_formattable) { - static_assert(!fmt::is_formattable<const wchar_t*>::value, ""); -} - -TEST(xchar_test, compile_time_string) { -#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L - EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42)); -#endif -} - -#if __cplusplus > 201103L -struct custom_char { - int value; - custom_char() = default; - - template <typename T> - constexpr custom_char(T val) : value(static_cast<int>(val)) {} - - operator int() const { return value; } -}; - -int to_ascii(custom_char c) { return c; } - -FMT_BEGIN_NAMESPACE -template <> struct is_char<custom_char> : std::true_type {}; -FMT_END_NAMESPACE - -TEST(xchar_test, format_custom_char) { - const custom_char format[] = {'{', '}', 0}; - auto result = fmt::format(format, custom_char('x')); - EXPECT_EQ(result.size(), 1); - EXPECT_EQ(result[0], custom_char('x')); -} -#endif - -// Convert a char8_t string to std::string. Otherwise GTest will insist on -// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423. -template <typename S> std::string from_u8str(const S& str) { - return std::string(str.begin(), str.end()); -} - -TEST(xchar_test, format_utf8_precision) { - using str_type = std::basic_string<fmt::detail::char8_type>; - auto format = - str_type(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}")); - auto str = str_type(reinterpret_cast<const fmt::detail::char8_type*>( - u8"caf\u00e9s")); // cafés - auto result = fmt::format(format, str); - EXPECT_EQ(fmt::detail::compute_width(result), 4); - EXPECT_EQ(result.size(), 5); - EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); -} - -TEST(xchar_test, format_to) { - auto buf = std::vector<wchar_t>(); - fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0'); - EXPECT_STREQ(buf.data(), L"42"); -} - -TEST(xchar_test, vformat_to) { - using wcontext = fmt::wformat_context; - fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42); - auto wargs = fmt::basic_format_args<wcontext>(&warg, 1); - auto w = std::wstring(); - fmt::vformat_to(std::back_inserter(w), L"{}", wargs); - EXPECT_EQ(L"42", w); - w.clear(); - fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs); - EXPECT_EQ(L"42", w); -} - -TEST(format_test, wide_format_to_n) { - wchar_t buffer[4]; - buffer[3] = L'x'; - auto result = fmt::format_to_n(buffer, 3, L"{}", 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); - buffer[0] = L'x'; - buffer[1] = L'x'; - buffer[2] = L'x'; - result = fmt::format_to_n(buffer, 3, L"{}", L'A'); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); - result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C'); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); -} - -#if FMT_USE_USER_DEFINED_LITERALS -TEST(xchar_test, format_udl) { - using namespace fmt::literals; - EXPECT_EQ(L"{}c{}"_format(L"ab", 1), fmt::format(L"{}c{}", L"ab", 1)); -} - -TEST(xchar_test, named_arg_udl) { - using namespace fmt::literals; - auto udl_a = - fmt::format(L"{first}{second}{first}{third}", L"first"_a = L"abra", - L"second"_a = L"cad", L"third"_a = 99); - EXPECT_EQ( - fmt::format(L"{first}{second}{first}{third}", fmt::arg(L"first", L"abra"), - fmt::arg(L"second", L"cad"), fmt::arg(L"third", 99)), - udl_a); -} -#endif // FMT_USE_USER_DEFINED_LITERALS - -TEST(xchar_test, print) { - // Check that the wide print overload compiles. - if (fmt::detail::const_check(false)) fmt::print(L"test"); -} - -TEST(xchar_test, join) { - int v[3] = {1, 2, 3}; - EXPECT_EQ(fmt::format(L"({})", fmt::join(v, v + 3, L", ")), L"(1, 2, 3)"); - auto t = std::tuple<wchar_t, int, float>('a', 1, 2.0f); - EXPECT_EQ(fmt::format(L"({})", fmt::join(t, L", ")), L"(a, 1, 2)"); -} - -enum streamable_enum {}; - -std::wostream& operator<<(std::wostream& os, streamable_enum) { - return os << L"streamable_enum"; -} - -enum unstreamable_enum {}; - -TEST(xchar_test, enum) { - EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum())); - EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum())); -} - -TEST(xchar_test, sign_not_truncated) { - wchar_t format_str[] = { - L'{', L':', - '+' | static_cast<wchar_t>(1 << fmt::detail::num_bits<char>()), L'}', 0}; - EXPECT_THROW(fmt::format(format_str, 42), fmt::format_error); -} - -namespace fake_qt { -class QString { - public: - QString(const wchar_t* s) : s_(s) {} - const wchar_t* utf16() const FMT_NOEXCEPT { return s_.data(); } - int size() const FMT_NOEXCEPT { return static_cast<int>(s_.size()); } - - private: - std::wstring s_; -}; - -fmt::basic_string_view<wchar_t> to_string_view(const QString& s) FMT_NOEXCEPT { - return {s.utf16(), static_cast<size_t>(s.size())}; -} -} // namespace fake_qt - -TEST(format_test, format_foreign_strings) { - using fake_qt::QString; - EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42"); - EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42"); -} - -TEST(xchar_test, chrono) { - auto tm = std::tm(); - tm.tm_year = 116; - tm.tm_mon = 3; - tm.tm_mday = 25; - tm.tm_hour = 11; - tm.tm_min = 22; - tm.tm_sec = 33; - EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm), - "The date is 2016-04-25 11:22:33."); - EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42))); - EXPECT_EQ(fmt::format(L"{:%F}", tm), L"2016-04-25"); - EXPECT_EQ(fmt::format(L"{:%T}", tm), L"11:22:33"); -} - -std::wstring system_wcsftime(const std::wstring& format, const std::tm* timeptr, - std::locale* locptr = nullptr) { - auto loc = locptr ? *locptr : std::locale::classic(); - auto& facet = std::use_facet<std::time_put<wchar_t>>(loc); - std::wostringstream os; - os.imbue(loc); - facet.put(os, os, L' ', timeptr, format.c_str(), - format.c_str() + format.size()); -#ifdef _WIN32 - // Workaround a bug in older versions of Universal CRT. - auto str = os.str(); - if (str == L"-0000") str = L"+0000"; - return str; -#else - return os.str(); -#endif -} - -TEST(chrono_test, time_point) { - auto t1 = std::chrono::system_clock::now(); - - std::vector<std::wstring> spec_list = { - L"%%", L"%n", L"%t", L"%Y", L"%EY", L"%y", L"%Oy", L"%Ey", L"%C", - L"%EC", L"%G", L"%g", L"%b", L"%h", L"%B", L"%m", L"%Om", L"%U", - L"%OU", L"%W", L"%OW", L"%V", L"%OV", L"%j", L"%d", L"%Od", L"%e", - L"%Oe", L"%a", L"%A", L"%w", L"%Ow", L"%u", L"%Ou", L"%H", L"%OH", - L"%I", L"%OI", L"%M", L"%OM", L"%S", L"%OS", L"%x", L"%Ex", L"%X", - L"%EX", L"%D", L"%F", L"%R", L"%T", L"%p", L"%z", L"%Z"}; - spec_list.push_back(L"%Y-%m-%d %H:%M:%S"); -#ifndef _WIN32 - // Disabled on Windows, because these formats is not consistent among - // platforms. - spec_list.insert(spec_list.end(), {L"%c", L"%Ec", L"%r"}); -#endif - - for (const auto& spec : spec_list) { - auto t = std::chrono::system_clock::to_time_t(t1); - auto tm = *std::localtime(&t); - - auto sys_output = system_wcsftime(spec, &tm); - - auto fmt_spec = fmt::format(L"{{:{}}}", spec); - EXPECT_EQ(sys_output, fmt::format(fmt_spec, t1)); - EXPECT_EQ(sys_output, fmt::format(fmt_spec, tm)); - } -} - -TEST(xchar_test, color) { - EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), L"rgb(255,20,30) wide"), - L"\x1b[38;2;255;020;030mrgb(255,20,30) wide\x1b[0m"); -} - -TEST(xchar_test, ostream) { - std::wostringstream wos; - fmt::print(wos, L"Don't {}!", L"panic"); - EXPECT_EQ(L"Don't panic!", wos.str()); -} - -TEST(xchar_test, to_wstring) { EXPECT_EQ(L"42", fmt::to_wstring(42)); } - -#ifndef FMT_STATIC_THOUSANDS_SEPARATOR -template <typename Char> struct numpunct : std::numpunct<Char> { - protected: - Char do_decimal_point() const override { return '?'; } - std::string do_grouping() const override { return "\03"; } - Char do_thousands_sep() const override { return '~'; } -}; - -template <typename Char> struct no_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const override { return '.'; } - std::string do_grouping() const override { return ""; } - Char do_thousands_sep() const override { return ','; } -}; - -template <typename Char> struct special_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const override { return '.'; } - std::string do_grouping() const override { return "\03\02"; } - Char do_thousands_sep() const override { return ','; } -}; - -template <typename Char> struct small_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const override { return '.'; } - std::string do_grouping() const override { return "\01"; } - Char do_thousands_sep() const override { return ','; } -}; - -TEST(locale_test, localized_double) { - auto loc = std::locale(std::locale(), new numpunct<char>()); - EXPECT_EQ("1?23", fmt::format(loc, "{:L}", 1.23)); - EXPECT_EQ("1?230000", fmt::format(loc, "{:Lf}", 1.23)); - EXPECT_EQ("1~234?5", fmt::format(loc, "{:L}", 1234.5)); - EXPECT_EQ("12~000", fmt::format(loc, "{:L}", 12000.0)); -} - -TEST(locale_test, format) { - auto loc = std::locale(std::locale(), new numpunct<char>()); - EXPECT_EQ("1234567", fmt::format(std::locale(), "{:L}", 1234567)); - EXPECT_EQ("1~234~567", fmt::format(loc, "{:L}", 1234567)); - EXPECT_EQ("-1~234~567", fmt::format(loc, "{:L}", -1234567)); - EXPECT_EQ("-256", fmt::format(loc, "{:L}", -256)); - fmt::format_arg_store<fmt::format_context, int> as{1234567}; - EXPECT_EQ("1~234~567", fmt::vformat(loc, "{:L}", fmt::format_args(as))); - auto s = std::string(); - fmt::format_to(std::back_inserter(s), loc, "{:L}", 1234567); - EXPECT_EQ("1~234~567", s); - - auto no_grouping_loc = std::locale(std::locale(), new no_grouping<char>()); - EXPECT_EQ("1234567", fmt::format(no_grouping_loc, "{:L}", 1234567)); - - auto special_grouping_loc = - std::locale(std::locale(), new special_grouping<char>()); - EXPECT_EQ("1,23,45,678", fmt::format(special_grouping_loc, "{:L}", 12345678)); - EXPECT_EQ("12,345", fmt::format(special_grouping_loc, "{:L}", 12345)); - - auto small_grouping_loc = - std::locale(std::locale(), new small_grouping<char>()); - EXPECT_EQ("4,2,9,4,9,6,7,2,9,5", - fmt::format(small_grouping_loc, "{:L}", max_value<uint32_t>())); -} - -TEST(locale_test, format_detault_align) { - auto loc = std::locale({}, new special_grouping<char>()); - EXPECT_EQ(" 12,345", fmt::format(loc, "{:8L}", 12345)); -} - -TEST(locale_test, format_plus) { - auto loc = std::locale({}, new special_grouping<char>()); - EXPECT_EQ("+100", fmt::format(loc, "{:+L}", 100)); -} - -TEST(locale_test, wformat) { - auto loc = std::locale(std::locale(), new numpunct<wchar_t>()); - EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567)); - EXPECT_EQ(L"1~234~567", fmt::format(loc, L"{:L}", 1234567)); - using wcontext = fmt::buffer_context<wchar_t>; - fmt::format_arg_store<wcontext, int> as{1234567}; - EXPECT_EQ(L"1~234~567", - fmt::vformat(loc, L"{:L}", fmt::basic_format_args<wcontext>(as))); - EXPECT_EQ(L"1234567", fmt::format(std::locale("C"), L"{:L}", 1234567)); - - auto no_grouping_loc = std::locale(std::locale(), new no_grouping<wchar_t>()); - EXPECT_EQ(L"1234567", fmt::format(no_grouping_loc, L"{:L}", 1234567)); - - auto special_grouping_loc = - std::locale(std::locale(), new special_grouping<wchar_t>()); - EXPECT_EQ(L"1,23,45,678", - fmt::format(special_grouping_loc, L"{:L}", 12345678)); - - auto small_grouping_loc = - std::locale(std::locale(), new small_grouping<wchar_t>()); - EXPECT_EQ(L"4,2,9,4,9,6,7,2,9,5", - fmt::format(small_grouping_loc, L"{:L}", max_value<uint32_t>())); -} - -TEST(locale_test, double_formatter) { - auto loc = std::locale(std::locale(), new special_grouping<char>()); - auto f = fmt::formatter<int>(); - auto parse_ctx = fmt::format_parse_context("L"); - f.parse(parse_ctx); - char buf[10] = {}; - fmt::basic_format_context<char*, char> format_ctx( - buf, {}, fmt::detail::locale_ref(loc)); - *f.format(12345, format_ctx) = 0; - EXPECT_STREQ("12,345", buf); -} - -FMT_BEGIN_NAMESPACE -template <class charT> struct formatter<std::complex<double>, charT> { - private: - detail::dynamic_format_specs<char> specs_; - - public: - FMT_CONSTEXPR typename basic_format_parse_context<charT>::iterator parse( - basic_format_parse_context<charT>& ctx) { - using handler_type = - detail::dynamic_specs_handler<basic_format_parse_context<charT>>; - detail::specs_checker<handler_type> handler(handler_type(specs_, ctx), - detail::type::string_type); - auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); - detail::parse_float_type_spec(specs_, ctx.error_handler()); - return it; - } - - template <class FormatContext> - typename FormatContext::iterator format(const std::complex<double>& c, - FormatContext& ctx) { - detail::handle_dynamic_spec<detail::precision_checker>( - specs_.precision, specs_.precision_ref, ctx); - auto specs = std::string(); - if (specs_.precision > 0) specs = fmt::format(".{}", specs_.precision); - if (specs_.type == presentation_type::fixed_lower) specs += 'f'; - auto real = fmt::format(ctx.locale().template get<std::locale>(), - fmt::runtime("{:" + specs + "}"), c.real()); - auto imag = fmt::format(ctx.locale().template get<std::locale>(), - fmt::runtime("{:" + specs + "}"), c.imag()); - auto fill_align_width = std::string(); - if (specs_.width > 0) fill_align_width = fmt::format(">{}", specs_.width); - return format_to(ctx.out(), runtime("{:" + fill_align_width + "}"), - c.real() != 0 ? fmt::format("({}+{}i)", real, imag) - : fmt::format("{}i", imag)); - } -}; -FMT_END_NAMESPACE - -TEST(locale_test, complex) { - std::string s = fmt::format("{}", std::complex<double>(1, 2)); - EXPECT_EQ(s, "(1+2i)"); - EXPECT_EQ(fmt::format("{:.2f}", std::complex<double>(1, 2)), "(1.00+2.00i)"); - EXPECT_EQ(fmt::format("{:8}", std::complex<double>(1, 2)), " (1+2i)"); -} - -TEST(locale_test, chrono_weekday) { - auto loc = get_locale("ru_RU.UTF-8", "Russian_Russia.1251"); - auto loc_old = std::locale::global(loc); - auto mon = fmt::weekday(1); - EXPECT_EQ(fmt::format(L"{}", mon), L"Mon"); - if (loc != std::locale::classic()) { - // {L"\x43F\x43D", L"\x41F\x43D", L"\x43F\x43D\x434", L"\x41F\x43D\x434"} - // {L"пн", L"Пн", L"пнд", L"Пнд"} - EXPECT_THAT( - (std::vector<std::wstring>{L"\x43F\x43D", L"\x41F\x43D", - L"\x43F\x43D\x434", L"\x41F\x43D\x434"}), - Contains(fmt::format(loc, L"{:L}", mon))); - } - std::locale::global(loc_old); -} - -#endif // FMT_STATIC_THOUSANDS_SEPARATOR diff --git a/contrib/libs/fmt/test/xchar-test/ya.make b/contrib/libs/fmt/test/xchar-test/ya.make deleted file mode 100644 index d0a5e4c043..0000000000 --- a/contrib/libs/fmt/test/xchar-test/ya.make +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by devtools/yamaker. - -GTEST() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - xchar-test.cc -) - -END() diff --git a/contrib/libs/fmt/test/ya.make b/contrib/libs/fmt/test/ya.make deleted file mode 100644 index 46905a71d7..0000000000 --- a/contrib/libs/fmt/test/ya.make +++ /dev/null @@ -1,57 +0,0 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/restricted/googletest/googlemock - contrib/restricted/googletest/googletest -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DGTEST_HAS_STD_WSTRING=1 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCS( - gtest-extra.cc - util.cc -) - -END() - -RECURSE( - args-test - assert-test - color-test - compile-fp-test - compile-test - core-test - enforce-checks-test - format-impl-test - format-test - gtest-extra-test - os-test - ostream-test - posix-mock-test - printf-test - ranges-test - scan-test -) - -IF (NOT MUSL AND NOT OS_WINDOWS) - # Generated by devtools/yamaker. - RECURSE( - chrono-test - unicode-test - xchar-test - ) -ENDIF() diff --git a/contrib/libs/fmt/ya.make b/contrib/libs/fmt/ya.make index eb118a5dde..ad452c6e83 100644 --- a/contrib/libs/fmt/ya.make +++ b/contrib/libs/fmt/ya.make @@ -1,11 +1,7 @@ -# Generated by devtools/yamaker from nixpkgs 22.05. +# Generated by devtools/yamaker from nixpkgs 22.11. LIBRARY() -VERSION(8.1.1) - -ORIGINAL_SOURCE(https://github.com/fmtlib/fmt/archive/8.1.1.tar.gz) - LICENSE( Apache-2.0 WITH LLVM-exception AND MIT AND @@ -15,6 +11,10 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) +VERSION(8.1.1) + +ORIGINAL_SOURCE(https://github.com/fmtlib/fmt/archive/8.1.1.tar.gz) + ADDINCL( GLOBAL contrib/libs/fmt/include ) @@ -33,7 +33,3 @@ SRCS( ) END() - -RECURSE( - test -) |