#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 namespace NYT { //////////////////////////////////////////////////////////////////////////////// template template requires std::constructible_from consteval TBasicFormatString::TBasicFormatString(const T& fmt) : Format_(fmt) { CheckFormattability(); #if !defined(NDEBUG) && !defined(YT_DISABLE_FORMAT_STATIC_ANALYSIS) NDetail::TFormatAnalyser::ValidateFormat...>(Format_); #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()) { // 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