proxygen
folly::BaseFormatter< Derived, containerMode, Args > Class Template Reference

#include <Format.h>

Public Types

typedef detail::FormatterTag IsFormatter
 
typedef BaseFormatter BaseType
 

Public Member Functions

template<class Output >
void operator() (Output &out) const
 
template<class Str >
std::enable_if< IsSomeString< Str >::value >::type appendTo (Str &str) const
 
std::string str () const
 
fbstring fbstr () const
 

Private Types

typedef std::tuple< Args... > ValueTuple
 

Private Member Functions

Derived const & asDerived () const
 
template<size_t K, class Callback >
std::enable_if< K==valueCount >::type doFormatFrom (size_t i, FormatArg &arg, Callback &) const
 
template<size_t K, class Callback >
std::enable_if<(K< valueCount)>::type doFormatFrom (size_t i, FormatArg &arg, Callback &cb) const
 
template<class Callback >
void doFormat (size_t i, FormatArg &arg, Callback &cb) const
 
template<size_t K>
std::enable_if< K==valueCount, int >::type getSizeArgFrom (size_t i, const FormatArg &arg) const
 
template<class T >
std::enable_if< std::is_integral< T >::value &&!std::is_same< T, bool >::value, int >::type getValue (const FormatValue< T > &format, const FormatArg &) const
 
template<class T >
std::enable_if< !std::is_integral< T >::value||std::is_same< T, bool >::value, int >::type getValue (const FormatValue< T > &, const FormatArg &arg) const
 

Static Private Attributes

static constexpr size_t valueCount = std::tuple_size<ValueTuple>::value
 

Detailed Description

template<class Derived, bool containerMode, class... Args>
class folly::BaseFormatter< Derived, containerMode, Args >

Formatter class.

Note that this class is tricky, as it keeps references to its lvalue arguments (while it takes ownership of the temporaries), and it doesn't copy the passed-in format string. Thankfully, you can't use this directly, you have to use format(...) below.

Definition at line 72 of file Format.h.

Member Typedef Documentation

template<class Derived, bool containerMode, class... Args>
typedef BaseFormatter folly::BaseFormatter< Derived, containerMode, Args >::BaseType

Definition at line 112 of file Format.h.

template<class Derived, bool containerMode, class... Args>
typedef detail::FormatterTag folly::BaseFormatter< Derived, containerMode, Args >::IsFormatter

Metadata to identify generated children of BaseFormatter

Definition at line 111 of file Format.h.

template<class Derived, bool containerMode, class... Args>
typedef std::tuple<Args...> folly::BaseFormatter< Derived, containerMode, Args >::ValueTuple
private

Definition at line 115 of file Format.h.

Member Function Documentation

template<class Derived, bool containerMode, class... Args>
template<class Str >
std::enable_if<IsSomeString<Str>::value>::type folly::BaseFormatter< Derived, containerMode, Args >::appendTo ( Str &  str) const
inline

Append to a string.

Definition at line 84 of file Format.h.

85  {
86  auto appender = [&str](StringPiece s) { str.append(s.data(), s.size()); };
87  (*this)(appender);
88  }
static set< string > s
std::string str() const
Definition: Format.h:93
Range< const char * > StringPiece
template<class Derived, bool containerMode, class... Args>
Derived const& folly::BaseFormatter< Derived, containerMode, Args >::asDerived ( ) const
inlineprivate

Definition at line 118 of file Format.h.

118  {
119  return *static_cast<const Derived*>(this);
120  }
template<class Derived, bool containerMode, class... Args>
template<class Callback >
void folly::BaseFormatter< Derived, containerMode, Args >::doFormat ( size_t  i,
FormatArg arg,
Callback &  cb 
) const
inlineprivate

Definition at line 139 of file Format.h.

139  {
140  return doFormatFrom<0>(i, arg, cb);
141  }
template<class Derived, bool containerMode, class... Args>
template<size_t K, class Callback >
std::enable_if<K == valueCount>::type folly::BaseFormatter< Derived, containerMode, Args >::doFormatFrom ( size_t  i,
FormatArg arg,
Callback &   
) const
inlineprivate

Definition at line 124 of file Format.h.

124  {
125  arg.error("argument index out of range, max=", i);
126  }
template<class Derived, bool containerMode, class... Args>
template<size_t K, class Callback >
std::enable_if<(K < valueCount)>::type folly::BaseFormatter< Derived, containerMode, Args >::doFormatFrom ( size_t  i,
FormatArg arg,
Callback &  cb 
) const
inlineprivate

Definition at line 130 of file Format.h.

130  {
131  if (i == K) {
132  asDerived().template doFormatArg<K>(arg, cb);
133  } else {
134  doFormatFrom<K + 1>(i, arg, cb);
135  }
136  }
Derived const & asDerived() const
Definition: Format.h:118
template<class Derived, bool containerMode, class... Args>
fbstring folly::BaseFormatter< Derived, containerMode, Args >::fbstr ( ) const
inline

Conversion to fbstring

Definition at line 102 of file Format.h.

Referenced by folly::format_value::formatFormatter().

102  {
103  fbstring s;
104  appendTo(s);
105  return s;
106  }
std::enable_if< IsSomeString< Str >::value >::type appendTo(Str &str) const
Definition: Format.h:84
static set< string > s
basic_fbstring< char > fbstring
Definition: FBString.h:2904
template<class Derived, bool containerMode, class... Args>
template<size_t K>
std::enable_if<K == valueCount, int>::type folly::BaseFormatter< Derived, containerMode, Args >::getSizeArgFrom ( size_t  i,
const FormatArg arg 
) const
inlineprivate

Definition at line 144 of file Format.h.

146  {
147  arg.error("argument index out of range, max=", i);
148  }
template<class Derived, bool containerMode, class... Args>
template<class T >
std::enable_if< std::is_integral<T>::value && !std::is_same<T, bool>::value, int>::type folly::BaseFormatter< Derived, containerMode, Args >::getValue ( const FormatValue< T > &  format,
const FormatArg  
) const
inlineprivate

Definition at line 154 of file Format.h.

154  {
155  return static_cast<int>(format.getValue());
156  }
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
Definition: Format.h:271
template<class Derived, bool containerMode, class... Args>
template<class T >
std::enable_if< !std::is_integral<T>::value || std::is_same<T, bool>::value, int>::type folly::BaseFormatter< Derived, containerMode, Args >::getValue ( const FormatValue< T > &  ,
const FormatArg arg 
) const
inlineprivate

Definition at line 162 of file Format.h.

162  {
163  arg.error("dynamic field width argument must be integral");
164  }
template<class Derived , bool containerMode, class... Args>
template<class Output >
void folly::BaseFormatter< Derived, containerMode, Args >::operator() ( Output &  out) const

Append to output. out(StringPiece sp) may be called (more than once)

Definition at line 169 of file Format-inl.h.

References testing::Args(), folly::test::end(), and s.

170  {
171  // Copy raw string (without format specifiers) to output;
172  // not as simple as we'd like, as we still need to translate "}}" to "}"
173  // and throw if we see any lone "}"
174  auto outputString = [&out](StringPiece s) {
175  auto p = s.begin();
176  auto end = s.end();
177  while (p != end) {
178  auto q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
179  if (!q) {
180  out(StringPiece(p, end));
181  break;
182  }
183  ++q;
184  out(StringPiece(p, q));
185  p = q;
186 
187  if (p == end || *p != '}') {
188  throw_exception<BadFormatArg>(
189  "folly::format: single '}' in format string");
190  }
191  ++p;
192  }
193  };
194 
195  auto p = str_.begin();
196  auto end = str_.end();
197 
198  int nextArg = 0;
199  bool hasDefaultArgIndex = false;
200  bool hasExplicitArgIndex = false;
201  while (p != end) {
202  auto q = static_cast<const char*>(memchr(p, '{', size_t(end - p)));
203  if (!q) {
204  outputString(StringPiece(p, end));
205  break;
206  }
207  outputString(StringPiece(p, q));
208  p = q + 1;
209 
210  if (p == end) {
211  throw_exception<BadFormatArg>(
212  "folly::format: '}' at end of format string");
213  }
214 
215  // "{{" -> "{"
216  if (*p == '{') {
217  out(StringPiece(p, 1));
218  ++p;
219  continue;
220  }
221 
222  // Format string
223  q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
224  if (q == nullptr) {
225  throw_exception<BadFormatArg>("folly::format: missing ending '}'");
226  }
227  FormatArg arg(StringPiece(p, q));
228  p = q + 1;
229 
230  int argIndex = 0;
231  auto piece = arg.splitKey<true>(); // empty key component is okay
232  if (containerMode) { // static
233  arg.enforce(
234  arg.width != FormatArg::kDynamicWidth,
235  "dynamic field width not supported in vformat()");
236  if (piece.empty()) {
237  arg.setNextIntKey(nextArg++);
238  hasDefaultArgIndex = true;
239  } else {
240  arg.setNextKey(piece);
241  hasExplicitArgIndex = true;
242  }
243  } else {
244  if (piece.empty()) {
245  if (arg.width == FormatArg::kDynamicWidth) {
246  arg.enforce(
247  arg.widthIndex == FormatArg::kNoIndex,
248  "cannot provide width arg index without value arg index");
249  int sizeArg = nextArg++;
250  arg.width = asDerived().getSizeArg(size_t(sizeArg), arg);
251  }
252 
253  argIndex = nextArg++;
254  hasDefaultArgIndex = true;
255  } else {
256  if (arg.width == FormatArg::kDynamicWidth) {
257  arg.enforce(
258  arg.widthIndex != FormatArg::kNoIndex,
259  "cannot provide value arg index without width arg index");
260  arg.width = asDerived().getSizeArg(size_t(arg.widthIndex), arg);
261  }
262 
263  try {
264  argIndex = to<int>(piece);
265  } catch (const std::out_of_range&) {
266  arg.error("argument index must be integer");
267  }
268  arg.enforce(argIndex >= 0, "argument index must be non-negative");
269  hasExplicitArgIndex = true;
270  }
271  }
272 
273  if (hasDefaultArgIndex && hasExplicitArgIndex) {
274  throw_exception<BadFormatArg>(
275  "folly::format: may not have both default and explicit arg indexes");
276  }
277 
278  asDerived().doFormat(size_t(argIndex), arg, out);
279  }
280 }
Derived const & asDerived() const
Definition: Format.h:118
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
static constexpr int kNoIndex
Definition: FormatArg.h:143
static constexpr int kDynamicWidth
Definition: FormatArg.h:142
static set< string > s
Range< const char * > StringPiece
template<class Derived, bool containerMode, class... Args>
std::string folly::BaseFormatter< Derived, containerMode, Args >::str ( ) const
inline

Conversion to string

Definition at line 93 of file Format.h.

93  {
94  std::string s;
95  appendTo(s);
96  return s;
97  }
std::enable_if< IsSomeString< Str >::value >::type appendTo(Str &str) const
Definition: Format.h:84
const char * string
Definition: Conv.cpp:212
static set< string > s

Member Data Documentation

template<class Derived, bool containerMode, class... Args>
constexpr size_t folly::BaseFormatter< Derived, containerMode, Args >::valueCount = std::tuple_size<ValueTuple>::value
staticprivate

Definition at line 116 of file Format.h.


The documentation for this class was generated from the following files: