#ifndef FORMAT_STRING_INL_H_ #error "Direct inclusion of this file is not allowed, include format_string.h" // For the sake of sane code completion. #include "format_string.h" #endif #include namespace NYT { //////////////////////////////////////////////////////////////////////////////// template template requires std::constructible_from consteval TBasicFormatString::TBasicFormatString(const T& fmt) : Format_(fmt) { CheckFormattability(); #if !defined(YT_DISABLE_FORMAT_STATIC_ANALYSIS) std::tie(Markers, Escapes) = NDetail::TFormatAnalyser::AnalyzeFormat...>(Format_); #else std::ranges::fill_n(std::ranges::begin(Escapes), 1, -1); if constexpr (sizeof...(TArgs) != 0) { std::ranges::fill_n(std::ranges::begin(Markers), 1, std::tuple{0, 0}); } #endif } template TStringBuf TBasicFormatString::Get() const noexcept { return {Format_}; } template consteval void TBasicFormatString::CheckFormattability() { #if !defined(NDEBUG) && !defined(YT_DISABLE_FORMAT_STATIC_ANALYSIS) using TTuple = std::tuple...>; [] (std::index_sequence) { ([] { if constexpr (!CFormattable>) { CrashCompilerClassIsNotFormattable>(); } } (), ...); } (std::index_sequence_for()); #endif } template TBasicFormatString::TBasicFormatString(TRuntimeFormat fmt) : Format_(fmt.Get()) { std::ranges::fill_n(std::ranges::begin(Escapes), 1, -1); if constexpr (sizeof...(TArgs) != 0) { std::ranges::fill_n(std::ranges::begin(Markers), 1, std::tuple{0, 0}); } // NB(arkady-e1ppa): StaticFormat performs the // formattability check of the args in a way // that provides more useful information // than a simple static_assert with conjunction. // Additionally, the latter doesn't work properly // for older clang version. static constexpr auto argsChecker = [] { CheckFormattability(); return 42; } (); Y_UNUSED(argsChecker); } //////////////////////////////////////////////////////////////////////////////// } // namespace NYT