aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/string/format.h
blob: 9708fe5906aa41cf6fee4a9a5c1fa8558493f6dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#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 |<null>|.
 *
 *  All others:
 *  Emitted as strings by calling |ToString|.
 *
 */

template <size_t Length, class... TArgs>
void Format(TStringBuilderBase* builder, const char (&format)[Length], TArgs&&... args);
template <class... TArgs>
void Format(TStringBuilderBase* builder, TStringBuf format, TArgs&&... args);

template <size_t Length, class... TArgs>
TString Format(const char (&format)[Length], TArgs&&... args);
template <class... TArgs>
TString Format(TStringBuf format, TArgs&&... args);

////////////////////////////////////////////////////////////////////////////////

template <class TRange, class TFormatter>
struct TFormattableView
{
    using TBegin = std::decay_t<decltype(std::declval<const TRange>().begin())>;
    using TEnd = std::decay_t<decltype(std::declval<const TRange>().end())>;

    TBegin RangeBegin;
    TEnd RangeEnd;
    TFormatter Formatter;
    size_t Limit = std::numeric_limits<size_t>::max();

    TBegin begin() const;
    TEnd end() const;
};

//! Annotates a given #range with #formatter to be applied to each item.
template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeFormattableView(
    const TRange& range,
    TFormatter&& formatter);

template <class TRange, class TFormatter>
TFormattableView<TRange, TFormatter> MakeShrunkFormattableView(
    const TRange& range,
    TFormatter&& formatter,
    size_t limit);

////////////////////////////////////////////////////////////////////////////////

template <class TFormatter>
struct TFormatterWrapper
{
    TFormatter Formatter;
};

template <class TFormatter>
TFormatterWrapper<TFormatter> MakeFormatterWrapper(
    TFormatter&& formatter);

////////////////////////////////////////////////////////////////////////////////

} // namespace NYT

#define FORMAT_INL_H_
#include "format-inl.h"
#undef FORMAT_INL_H_