#pragma once #include "string_builder.h" namespace NYT { //////////////////////////////////////////////////////////////////////////////// /* * Format: a type-safe and fast formatting utility. * * Basically works as a type-safe analogue of |sprintf| and is expected to * be backwards-compatible with the latter. * * Like Go's |Sprintf|, supports the ultimate format specifier |v| * causing arguments to be emitted in default format. * This is the default and preferred way of formatting things, * which should be used in newer code. * * |Format| may currently invoke |sprintf| internally for emitting numeric and some other * types. You can always write your own optimized implementation, if you wish :) * * In additional to the usual |sprintf|, supports a number of non-standard flags: * * |q| Causes the argument to be surrounded with single quotes (|'|). * Applies to all types. * * |Q| Causes the argument to be surrounded with double quotes (|"|). * Applies to all types. * * |l| The argument is emitted in "lowercase" style. * Only applies to enums and bools. * * The following argument types are supported: * * Strings (including |const char*|, |TStringBuf|, and |TString|) and chars: * Emitted as is. Fast. * * Numerics and pointers: * Emitted using |sprintf|. Maybe not that fast. * * |bool|: * Emitted either as |True| and |False| or |true| and |false| (if lowercase mode is ON). * * Enums: * Emitted in either camel (|SomeName|) or in lowercase-with-underscores style * (|some_name|, if lowercase mode is ON). * * Nullables: * |std::nullopt| is emitted as ||. * * All others: * Emitted as strings by calling |ToString|. * */ template void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args); template void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args); template TString Format(const char (&format)[Length], TArgs&&... args); template TString Format(TStringBuf format, TArgs&&... args); //////////////////////////////////////////////////////////////////////////////// template struct TFormattableView { using TBegin = std::decay_t().begin())>; using TEnd = std::decay_t().end())>; TBegin RangeBegin; TEnd RangeEnd; TFormatter Formatter; size_t Limit = std::numeric_limits::max(); TBegin begin() const; TEnd end() const; }; //! Annotates a given #range with #formatter to be applied to each item. template TFormattableView MakeFormattableView( const TRange& range, TFormatter&& formatter); template TFormattableView MakeShrunkFormattableView( const TRange& range, TFormatter&& formatter, size_t limit); //////////////////////////////////////////////////////////////////////////////// template struct TFormatterWrapper { TFormatter Formatter; }; template TFormatterWrapper MakeFormatterWrapper( TFormatter&& formatter); //////////////////////////////////////////////////////////////////////////////// template class TLazyMultiValueFormatter; template void FormatValue( TStringBuilderBase* builder, const TLazyMultiValueFormatter& value, TStringBuf /*format*/); //! A wrapper for a bunch of values that formats them lazily on demand. /*! * The intended use of this class is when you need to use the same formatted string * in several places in the function (e.g. log message tags) and want both to avoid * code duplication and premature formatting of the values until necessary. * * NB: lvalues are captured by reference without lifetime extension. */ template class TLazyMultiValueFormatter : private TNonCopyable { public: TLazyMultiValueFormatter(TStringBuf format, TArgs&&... args); friend void FormatValue<>( TStringBuilderBase* builder, const TLazyMultiValueFormatter& value, TStringBuf /*format*/); private: const TStringBuf Format_; const std::tuple Args_; }; template auto MakeLazyMultiValueFormatter(TStringBuf format, Args&&... args); //////////////////////////////////////////////////////////////////////////////// } // namespace NYT #define FORMAT_INL_H_ #include "format-inl.h" #undef FORMAT_INL_H_