add formatChecked(), which does not crash on bad format strings
[folly.git] / folly / Format-inl.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_FORMAT_H_
18 #error This file may only be included from Format.h.
19 #endif
20
21 #include "folly/Exception.h"
22 #include "folly/Traits.h"
23
24 namespace folly {
25
26 namespace detail {
27
28 extern const char formatHexUpper[256][2];
29 extern const char formatHexLower[256][2];
30 extern const char formatOctal[512][3];
31 extern const char formatBinary[256][8];
32
33 const size_t kMaxHexLength = 2 * sizeof(uintmax_t);
34 const size_t kMaxOctalLength = 3 * sizeof(uintmax_t);
35 const size_t kMaxBinaryLength = 8 * sizeof(uintmax_t);
36
37 /**
38  * Convert an unsigned to hex, using repr (which maps from each possible
39  * 2-hex-bytes value to the 2-character representation).
40  *
41  * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
42  * the supplied buffer and returns the offset of the beginning of the string
43  * from the start of the buffer.  The formatted string will be in range
44  * [buf+begin, buf+bufLen).
45  */
46 template <class Uint>
47 size_t uintToHex(char* buffer, size_t bufLen, Uint v,
48                  const char (&repr)[256][2]) {
49   // 'v >>= 7, v >>= 1' is no more than a work around to get rid of shift size
50   // warning when Uint = uint8_t (it's false as v >= 256 implies sizeof(v) > 1).
51   for (; !less_than<unsigned, 256>(v); v >>= 7, v >>= 1) {
52     auto b = v & 0xff;
53     bufLen -= 2;
54     buffer[bufLen] = repr[b][0];
55     buffer[bufLen + 1] = repr[b][1];
56   }
57   buffer[--bufLen] = repr[v][1];
58   if (v >= 16) {
59     buffer[--bufLen] = repr[v][0];
60   }
61   return bufLen;
62 }
63
64 /**
65  * Convert an unsigned to hex, using lower-case letters for the digits
66  * above 9.  See the comments for uintToHex.
67  */
68 template <class Uint>
69 inline size_t uintToHexLower(char* buffer, size_t bufLen, Uint v) {
70   return uintToHex(buffer, bufLen, v, formatHexLower);
71 }
72
73 /**
74  * Convert an unsigned to hex, using upper-case letters for the digits
75  * above 9.  See the comments for uintToHex.
76  */
77 template <class Uint>
78 inline size_t uintToHexUpper(char* buffer, size_t bufLen, Uint v) {
79   return uintToHex(buffer, bufLen, v, formatHexUpper);
80 }
81
82 /**
83  * Convert an unsigned to octal.
84  *
85  * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
86  * the supplied buffer and returns the offset of the beginning of the string
87  * from the start of the buffer.  The formatted string will be in range
88  * [buf+begin, buf+bufLen).
89  */
90 template <class Uint>
91 size_t uintToOctal(char* buffer, size_t bufLen, Uint v) {
92   auto& repr = formatOctal;
93   // 'v >>= 7, v >>= 2' is no more than a work around to get rid of shift size
94   // warning when Uint = uint8_t (it's false as v >= 512 implies sizeof(v) > 1).
95   for (; !less_than<unsigned, 512>(v); v >>= 7, v >>= 2) {
96     auto b = v & 0x1ff;
97     bufLen -= 3;
98     buffer[bufLen] = repr[b][0];
99     buffer[bufLen + 1] = repr[b][1];
100     buffer[bufLen + 2] = repr[b][2];
101   }
102   buffer[--bufLen] = repr[v][2];
103   if (v >= 8) {
104     buffer[--bufLen] = repr[v][1];
105   }
106   if (v >= 64) {
107     buffer[--bufLen] = repr[v][0];
108   }
109   return bufLen;
110 }
111
112 /**
113  * Convert an unsigned to binary.
114  *
115  * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
116  * the supplied buffer and returns the offset of the beginning of the string
117  * from the start of the buffer.  The formatted string will be in range
118  * [buf+begin, buf+bufLen).
119  */
120 template <class Uint>
121 size_t uintToBinary(char* buffer, size_t bufLen, Uint v) {
122   auto& repr = formatBinary;
123   if (v == 0) {
124     buffer[--bufLen] = '0';
125     return bufLen;
126   }
127   for (; v; v >>= 7, v >>= 1) {
128     auto b = v & 0xff;
129     bufLen -= 8;
130     memcpy(buffer + bufLen, &(repr[b][0]), 8);
131   }
132   while (buffer[bufLen] == '0') {
133     ++bufLen;
134   }
135   return bufLen;
136 }
137
138 }  // namespace detail
139
140
141 template <bool containerMode, class... Args>
142 Formatter<containerMode, Args...>::Formatter(StringPiece str, Args&&... args)
143   : str_(str),
144     values_(FormatValue<typename std::decay<Args>::type>(
145         std::forward<Args>(args))...) {
146   static_assert(!containerMode || sizeof...(Args) == 1,
147                 "Exactly one argument required in container mode");
148 }
149
150 template <bool containerMode, class... Args>
151 void Formatter<containerMode, Args...>::handleFormatStrError() const {
152   if (crashOnError_) {
153     LOG(FATAL) << "folly::format: bad format string \"" << str_ << "\": " <<
154       folly::exceptionStr(std::current_exception());
155   }
156   throw;
157 }
158
159 template <bool containerMode, class... Args>
160 template <class Output>
161 void Formatter<containerMode, Args...>::operator()(Output& out) const {
162   // Catch BadFormatArg and range_error exceptions, and call
163   // handleFormatStrError().
164   //
165   // These exception types indicate a problem with the format string.  Most
166   // format strings are string literals specified by the programmer.  If they
167   // have a problem, this is usually a programmer bug.  We want to crash to
168   // ensure that these are found early on during development.
169   //
170   // BadFormatArg is thrown by the Format.h code, while range_error is thrown
171   // by Conv.h, which is used in several places in our format string
172   // processing.
173   //
174   // (Note: This behavior is slightly dangerous.  If the Output object throws a
175   // BadFormatArg or a range_error, we will also crash the program, even if it
176   // wasn't an issue with the format string.  This seems highly unlikely
177   // though, and none of our current Output objects can throw these errors.)
178   //
179   // We also throw out_of_range errors if the format string references an
180   // argument that isn't present (or a key that isn't present in one of the
181   // argument containers).  However, at the moment we don't crash on these
182   // errors, as it is likely that the container is dynamic at runtime.
183   try {
184     appendOutput(out);
185   } catch (const BadFormatArg& ex) {
186     handleFormatStrError();
187   } catch (const std::range_error& ex) {
188     handleFormatStrError();
189   }
190 }
191
192 template <bool containerMode, class... Args>
193 template <class Output>
194 void Formatter<containerMode, Args...>::appendOutput(Output& out) const {
195   auto p = str_.begin();
196   auto end = str_.end();
197
198   // Copy raw string (without format specifiers) to output;
199   // not as simple as we'd like, as we still need to translate "}}" to "}"
200   // and throw if we see any lone "}"
201   auto outputString = [&out] (StringPiece s) {
202     auto p = s.begin();
203     auto end = s.end();
204     while (p != end) {
205       auto q = static_cast<const char*>(memchr(p, '}', end - p));
206       if (!q) {
207         out(StringPiece(p, end));
208         break;
209       }
210       ++q;
211       out(StringPiece(p, q));
212       p = q;
213
214       if (p == end || *p != '}') {
215         throw BadFormatArg("folly::format: single '}' in format string");
216       }
217       ++p;
218     }
219   };
220
221   int nextArg = 0;
222   bool hasDefaultArgIndex = false;
223   bool hasExplicitArgIndex = false;
224   while (p != end) {
225     auto q = static_cast<const char*>(memchr(p, '{', end - p));
226     if (!q) {
227       outputString(StringPiece(p, end));
228       break;
229     }
230     outputString(StringPiece(p, q));
231     p = q + 1;
232
233     if (p == end) {
234       throw BadFormatArg("folly::format: '}' at end of format string");
235     }
236
237     // "{{" -> "{"
238     if (*p == '{') {
239       out(StringPiece(p, 1));
240       ++p;
241       continue;
242     }
243
244     // Format string
245     q = static_cast<const char*>(memchr(p, '}', end - p));
246     if (q == nullptr) {
247       throw BadFormatArg("folly::format: missing ending '}'");
248     }
249     FormatArg arg(StringPiece(p, q));
250     p = q + 1;
251
252     int argIndex = 0;
253     auto piece = arg.splitKey<true>();  // empty key component is okay
254     if (containerMode) {  // static
255       if (piece.empty()) {
256         arg.setNextIntKey(nextArg++);
257         hasDefaultArgIndex = true;
258       } else {
259         arg.setNextKey(piece);
260         hasExplicitArgIndex = true;
261       }
262     } else {
263       if (piece.empty()) {
264         argIndex = nextArg++;
265         hasDefaultArgIndex = true;
266       } else {
267         try {
268           argIndex = to<int>(piece);
269         } catch (const std::out_of_range& e) {
270           arg.error("argument index must be integer");
271         }
272         arg.enforce(argIndex >= 0, "argument index must be non-negative");
273         hasExplicitArgIndex = true;
274       }
275     }
276
277     if (hasDefaultArgIndex && hasExplicitArgIndex) {
278       throw BadFormatArg(
279           "folly::format: may not have both default and explicit arg indexes");
280     }
281
282     doFormat(argIndex, arg, out);
283   }
284 }
285
286 template <bool containerMode, class... Args>
287 void writeTo(FILE* fp, const Formatter<containerMode, Args...>& formatter) {
288   auto writer = [fp] (StringPiece sp) {
289     ssize_t n = fwrite(sp.data(), 1, sp.size(), fp);
290     if (n < sp.size()) {
291       throwSystemError("Formatter writeTo", "fwrite failed");
292     }
293   };
294   formatter(writer);
295 }
296
297 namespace format_value {
298
299 template <class FormatCallback>
300 void formatString(StringPiece val, FormatArg& arg, FormatCallback& cb) {
301   if (arg.precision != FormatArg::kDefaultPrecision &&
302       val.size() > arg.precision) {
303     val.reset(val.data(), arg.precision);
304   }
305
306   constexpr int padBufSize = 128;
307   char padBuf[padBufSize];
308
309   // Output padding, no more than padBufSize at once
310   auto pad = [&padBuf, &cb, padBufSize] (int chars) {
311     while (chars) {
312       int n = std::min(chars, padBufSize);
313       cb(StringPiece(padBuf, n));
314       chars -= n;
315     }
316   };
317
318   int padRemaining = 0;
319   if (arg.width != FormatArg::kDefaultWidth && val.size() < arg.width) {
320     char fill = arg.fill == FormatArg::kDefaultFill ? ' ' : arg.fill;
321     int padChars = arg.width - val.size();
322     memset(padBuf, fill, std::min(padBufSize, padChars));
323
324     switch (arg.align) {
325     case FormatArg::Align::DEFAULT:
326     case FormatArg::Align::LEFT:
327       padRemaining = padChars;
328       break;
329     case FormatArg::Align::CENTER:
330       pad(padChars / 2);
331       padRemaining = padChars - padChars / 2;
332       break;
333     case FormatArg::Align::RIGHT:
334     case FormatArg::Align::PAD_AFTER_SIGN:
335       pad(padChars);
336       break;
337     default:
338       abort();
339       break;
340     }
341   }
342
343   cb(val);
344
345   if (padRemaining) {
346     pad(padRemaining);
347   }
348 }
349
350 template <class FormatCallback>
351 void formatNumber(StringPiece val, int prefixLen, FormatArg& arg,
352                   FormatCallback& cb) {
353   // precision means something different for numbers
354   arg.precision = FormatArg::kDefaultPrecision;
355   if (arg.align == FormatArg::Align::DEFAULT) {
356     arg.align = FormatArg::Align::RIGHT;
357   } else if (prefixLen && arg.align == FormatArg::Align::PAD_AFTER_SIGN) {
358     // Split off the prefix, then do any padding if necessary
359     cb(val.subpiece(0, prefixLen));
360     val.advance(prefixLen);
361     arg.width = std::max(arg.width - prefixLen, 0);
362   }
363   format_value::formatString(val, arg, cb);
364 }
365
366 template <class FormatCallback, bool containerMode, class... Args>
367 void formatFormatter(const Formatter<containerMode, Args...>& formatter,
368                      FormatArg& arg,
369                      FormatCallback& cb) {
370   if (arg.width == FormatArg::kDefaultWidth &&
371       arg.precision == FormatArg::kDefaultPrecision) {
372     // nothing to do
373     formatter(cb);
374   } else if (arg.align != FormatArg::Align::LEFT &&
375              arg.align != FormatArg::Align::DEFAULT) {
376     // We can only avoid creating a temporary string if we align left,
377     // as we'd need to know the size beforehand otherwise
378     format_value::formatString(formatter.fbstr(), arg, cb);
379   } else {
380     auto fn = [&arg, &cb] (StringPiece sp) mutable {
381       int sz = static_cast<int>(sp.size());
382       if (arg.precision != FormatArg::kDefaultPrecision) {
383         sz = std::min(arg.precision, sz);
384         sp.reset(sp.data(), sz);
385         arg.precision -= sz;
386       }
387       if (!sp.empty()) {
388         cb(sp);
389         if (arg.width != FormatArg::kDefaultWidth) {
390           arg.width = std::max(arg.width - sz, 0);
391         }
392       }
393     };
394     formatter(fn);
395     if (arg.width != FormatArg::kDefaultWidth && arg.width != 0) {
396       // Rely on formatString to do appropriate padding
397       format_value::formatString(StringPiece(), arg, cb);
398     }
399   }
400 }
401
402 }  // namespace format_value
403
404 // Definitions for default FormatValue classes
405
406 // Integral types (except bool)
407 template <class T>
408 class FormatValue<
409   T, typename std::enable_if<
410     std::is_integral<T>::value &&
411     !std::is_same<T, bool>::value>::type>
412   {
413  public:
414   explicit FormatValue(T val) : val_(val) { }
415   template <class FormatCallback>
416   void format(FormatArg& arg, FormatCallback& cb) const {
417     arg.validate(FormatArg::Type::INTEGER);
418     doFormat(arg, cb);
419   }
420
421   template <class FormatCallback>
422   void doFormat(FormatArg& arg, FormatCallback& cb) const {
423     char presentation = arg.presentation;
424     if (presentation == FormatArg::kDefaultPresentation) {
425       presentation = std::is_same<T, char>::value ? 'c' : 'd';
426     }
427
428     // Do all work as unsigned, we'll add the prefix ('0' or '0x' if necessary)
429     // and sign ourselves.
430     typedef typename std::make_unsigned<T>::type UT;
431     UT uval;
432     char sign;
433     if (std::is_signed<T>::value) {
434       if (folly::is_negative(val_)) {
435         uval = static_cast<UT>(-val_);
436         sign = '-';
437       } else {
438         uval = static_cast<UT>(val_);
439         switch (arg.sign) {
440         case FormatArg::Sign::PLUS_OR_MINUS:
441           sign = '+';
442           break;
443         case FormatArg::Sign::SPACE_OR_MINUS:
444           sign = ' ';
445           break;
446         default:
447           sign = '\0';
448           break;
449         }
450       }
451     } else {
452       uval = val_;
453       sign = '\0';
454
455       arg.enforce(arg.sign == FormatArg::Sign::DEFAULT,
456                   "sign specifications not allowed for unsigned values");
457     }
458
459     // max of:
460     // #x: 0x prefix + 16 bytes = 18 bytes
461     // #o: 0 prefix + 22 bytes = 23 bytes
462     // #b: 0b prefix + 64 bytes = 65 bytes
463     // ,d: 26 bytes (including thousands separators!)
464     // + nul terminator
465     // + 3 for sign and prefix shenanigans (see below)
466     constexpr size_t valBufSize = 69;
467     char valBuf[valBufSize];
468     char* valBufBegin = nullptr;
469     char* valBufEnd = nullptr;
470
471     // Defer to sprintf
472     auto useSprintf = [&] (const char* format) mutable {
473       valBufBegin = valBuf + 3;  // room for sign and base prefix
474       valBufEnd = valBufBegin + sprintf(valBufBegin, format,
475                                         static_cast<uintmax_t>(uval));
476     };
477
478     int prefixLen = 0;
479
480     switch (presentation) {
481     case 'n':  // TODO(tudorb): locale awareness?
482     case 'd':
483       arg.enforce(!arg.basePrefix,
484                   "base prefix not allowed with '", presentation,
485                   "' specifier");
486       if (arg.thousandsSeparator) {
487         useSprintf("%'ju");
488       } else {
489         // Use uintToBuffer, faster than sprintf
490         valBufBegin = valBuf + 3;
491         valBufEnd = valBufBegin + uint64ToBufferUnsafe(uval, valBufBegin);
492       }
493       break;
494     case 'c':
495       arg.enforce(!arg.basePrefix,
496                   "base prefix not allowed with '", presentation,
497                   "' specifier");
498       arg.enforce(!arg.thousandsSeparator,
499                   "thousands separator (',') not allowed with '",
500                   presentation, "' specifier");
501       valBufBegin = valBuf + 3;
502       *valBufBegin = static_cast<char>(uval);
503       valBufEnd = valBufBegin + 1;
504       break;
505     case 'o':
506     case 'O':
507       arg.enforce(!arg.thousandsSeparator,
508                   "thousands separator (',') not allowed with '",
509                   presentation, "' specifier");
510       valBufEnd = valBuf + valBufSize - 1;
511       valBufBegin = valBuf + detail::uintToOctal(valBuf, valBufSize - 1, uval);
512       if (arg.basePrefix) {
513         *--valBufBegin = '0';
514         prefixLen = 1;
515       }
516       break;
517     case 'x':
518       arg.enforce(!arg.thousandsSeparator,
519                   "thousands separator (',') not allowed with '",
520                   presentation, "' specifier");
521       valBufEnd = valBuf + valBufSize - 1;
522       valBufBegin = valBuf + detail::uintToHexLower(valBuf, valBufSize - 1,
523                                                     uval);
524       if (arg.basePrefix) {
525         *--valBufBegin = 'x';
526         *--valBufBegin = '0';
527         prefixLen = 2;
528       }
529       break;
530     case 'X':
531       arg.enforce(!arg.thousandsSeparator,
532                   "thousands separator (',') not allowed with '",
533                   presentation, "' specifier");
534       valBufEnd = valBuf + valBufSize - 1;
535       valBufBegin = valBuf + detail::uintToHexUpper(valBuf, valBufSize - 1,
536                                                     uval);
537       if (arg.basePrefix) {
538         *--valBufBegin = 'X';
539         *--valBufBegin = '0';
540         prefixLen = 2;
541       }
542       break;
543     case 'b':
544     case 'B':
545       arg.enforce(!arg.thousandsSeparator,
546                   "thousands separator (',') not allowed with '",
547                   presentation, "' specifier");
548       valBufEnd = valBuf + valBufSize - 1;
549       valBufBegin = valBuf + detail::uintToBinary(valBuf, valBufSize - 1,
550                                                   uval);
551       if (arg.basePrefix) {
552         *--valBufBegin = presentation;  // 0b or 0B
553         *--valBufBegin = '0';
554         prefixLen = 2;
555       }
556       break;
557     default:
558       arg.error("invalid specifier '", presentation, "'");
559     }
560
561     if (sign) {
562       *--valBufBegin = sign;
563       ++prefixLen;
564     }
565
566     format_value::formatNumber(StringPiece(valBufBegin, valBufEnd), prefixLen,
567                                arg, cb);
568   }
569
570  private:
571   T val_;
572 };
573
574 // Bool
575 template <>
576 class FormatValue<bool> {
577  public:
578   explicit FormatValue(bool val) : val_(val) { }
579
580   template <class FormatCallback>
581   void format(FormatArg& arg, FormatCallback& cb) const {
582     if (arg.presentation == FormatArg::kDefaultPresentation) {
583       arg.validate(FormatArg::Type::OTHER);
584       format_value::formatString(val_ ? "true" : "false", arg, cb);
585     } else {  // number
586       FormatValue<int>(val_).format(arg, cb);
587     }
588   }
589
590  private:
591   bool val_;
592 };
593
594 // double
595 template <>
596 class FormatValue<double> {
597  public:
598   explicit FormatValue(double val) : val_(val) { }
599
600   template <class FormatCallback>
601   void format(FormatArg& arg, FormatCallback& cb) const {
602     using ::double_conversion::DoubleToStringConverter;
603     using ::double_conversion::StringBuilder;
604
605     arg.validate(FormatArg::Type::FLOAT);
606
607     if (arg.presentation == FormatArg::kDefaultPresentation) {
608       arg.presentation = 'g';
609     }
610
611     const char* infinitySymbol = isupper(arg.presentation) ? "INF" : "inf";
612     const char* nanSymbol = isupper(arg.presentation) ? "NAN" : "nan";
613     char exponentSymbol = isupper(arg.presentation) ? 'E' : 'e';
614
615     if (arg.precision == FormatArg::kDefaultPrecision) {
616       arg.precision = 6;
617     }
618
619     // 2+: for null terminator and optional sign shenanigans.
620     char buf[2 + std::max({
621         (2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint +
622          DoubleToStringConverter::kMaxFixedDigitsAfterPoint),
623         (8 + DoubleToStringConverter::kMaxExponentialDigits),
624         (7 + DoubleToStringConverter::kMaxPrecisionDigits)})];
625     StringBuilder builder(buf + 1, sizeof(buf) - 1);
626
627     char plusSign;
628     switch (arg.sign) {
629     case FormatArg::Sign::PLUS_OR_MINUS:
630       plusSign = '+';
631       break;
632     case FormatArg::Sign::SPACE_OR_MINUS:
633       plusSign = ' ';
634       break;
635     default:
636       plusSign = '\0';
637       break;
638     };
639
640     double val = val_;
641     switch (arg.presentation) {
642     case '%':
643       val *= 100;
644     case 'f':
645     case 'F':
646       {
647         if (arg.precision >
648             DoubleToStringConverter::kMaxFixedDigitsAfterPoint) {
649           arg.precision = DoubleToStringConverter::kMaxFixedDigitsAfterPoint;
650         }
651         DoubleToStringConverter conv(
652             DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
653             infinitySymbol,
654             nanSymbol,
655             exponentSymbol,
656             -4, arg.precision,
657             0, 0);
658         arg.enforce(conv.ToFixed(val, arg.precision, &builder),
659                     "fixed double conversion failed");
660       }
661       break;
662     case 'e':
663     case 'E':
664       {
665         if (arg.precision > DoubleToStringConverter::kMaxExponentialDigits) {
666           arg.precision = DoubleToStringConverter::kMaxExponentialDigits;
667         }
668
669         DoubleToStringConverter conv(
670             DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
671             infinitySymbol,
672             nanSymbol,
673             exponentSymbol,
674             -4, arg.precision,
675             0, 0);
676         arg.enforce(conv.ToExponential(val, arg.precision, &builder));
677       }
678       break;
679     case 'n':  // should be locale-aware, but isn't
680     case 'g':
681     case 'G':
682       {
683         if (arg.precision < DoubleToStringConverter::kMinPrecisionDigits) {
684           arg.precision = DoubleToStringConverter::kMinPrecisionDigits;
685         } else if (arg.precision >
686                    DoubleToStringConverter::kMaxPrecisionDigits) {
687           arg.precision = DoubleToStringConverter::kMaxPrecisionDigits;
688         }
689         DoubleToStringConverter conv(
690             DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
691             infinitySymbol,
692             nanSymbol,
693             exponentSymbol,
694             -4, arg.precision,
695             0, 0);
696         arg.enforce(conv.ToShortest(val, &builder));
697       }
698       break;
699     default:
700       arg.error("invalid specifier '", arg.presentation, "'");
701     }
702
703     int len = builder.position();
704     builder.Finalize();
705     DCHECK_GT(len, 0);
706
707     // Add '+' or ' ' sign if needed
708     char* p = buf + 1;
709     // anything that's neither negative nor nan
710     int prefixLen = 0;
711     if (plusSign && (*p != '-' && *p != 'n' && *p != 'N')) {
712       *--p = plusSign;
713       ++len;
714       prefixLen = 1;
715     } else if (*p == '-') {
716       prefixLen = 1;
717     }
718
719     format_value::formatNumber(StringPiece(p, len), prefixLen, arg, cb);
720   }
721
722  private:
723   double val_;
724 };
725
726 // float (defer to double)
727 template <>
728 class FormatValue<float> {
729  public:
730   explicit FormatValue(float val) : val_(val) { }
731
732   template <class FormatCallback>
733   void format(FormatArg& arg, FormatCallback& cb) const {
734     FormatValue<double>(val_).format(arg, cb);
735   }
736
737  private:
738   float val_;
739 };
740
741 // Sring-y types (implicitly convertible to StringPiece, except char*)
742 template <class T>
743 class FormatValue<
744   T, typename std::enable_if<
745       (!std::is_pointer<T>::value ||
746        !std::is_same<char, typename std::decay<
747           typename std::remove_pointer<T>::type>::type>::value) &&
748       std::is_convertible<T, StringPiece>::value>::type>
749   {
750  public:
751   explicit FormatValue(StringPiece val) : val_(val) { }
752
753   template <class FormatCallback>
754   void format(FormatArg& arg, FormatCallback& cb) const {
755     if (arg.keyEmpty()) {
756       arg.validate(FormatArg::Type::OTHER);
757       arg.enforce(arg.presentation == FormatArg::kDefaultPresentation ||
758                   arg.presentation == 's',
759                   "invalid specifier '", arg.presentation, "'");
760       format_value::formatString(val_, arg, cb);
761     } else {
762       FormatValue<char>(val_.at(arg.splitIntKey())).format(arg, cb);
763     }
764   }
765
766  private:
767   StringPiece val_;
768 };
769
770 // Null
771 template <>
772 class FormatValue<std::nullptr_t> {
773  public:
774   explicit FormatValue(std::nullptr_t) { }
775
776   template <class FormatCallback>
777   void format(FormatArg& arg, FormatCallback& cb) const {
778     arg.validate(FormatArg::Type::OTHER);
779     arg.enforce(arg.presentation == FormatArg::kDefaultPresentation,
780                 "invalid specifier '", arg.presentation, "'");
781     format_value::formatString("(null)", arg, cb);
782   }
783 };
784
785 // Partial specialization of FormatValue for char*
786 template <class T>
787 class FormatValue<
788   T*,
789   typename std::enable_if<
790       std::is_same<char, typename std::decay<T>::type>::value>::type>
791   {
792  public:
793   explicit FormatValue(T* val) : val_(val) { }
794
795   template <class FormatCallback>
796   void format(FormatArg& arg, FormatCallback& cb) const {
797     if (arg.keyEmpty()) {
798       if (!val_) {
799         FormatValue<std::nullptr_t>(nullptr).format(arg, cb);
800       } else {
801         FormatValue<StringPiece>(val_).format(arg, cb);
802       }
803     } else {
804       FormatValue<typename std::decay<T>::type>(
805           val_[arg.splitIntKey()]).format(arg, cb);
806     }
807   }
808
809  private:
810   T* val_;
811 };
812
813 // Partial specialization of FormatValue for void*
814 template <class T>
815 class FormatValue<
816   T*,
817   typename std::enable_if<
818       std::is_same<void, typename std::decay<T>::type>::value>::type>
819   {
820  public:
821   explicit FormatValue(T* val) : val_(val) { }
822
823   template <class FormatCallback>
824   void format(FormatArg& arg, FormatCallback& cb) const {
825     if (!val_) {
826       FormatValue<std::nullptr_t>(nullptr).format(arg, cb);
827     } else {
828       // Print as a pointer, in hex.
829       arg.validate(FormatArg::Type::OTHER);
830       arg.enforce(arg.presentation == FormatArg::kDefaultPresentation,
831                   "invalid specifier '", arg.presentation, "'");
832       arg.basePrefix = true;
833       arg.presentation = 'x';
834       if (arg.align == FormatArg::Align::DEFAULT) {
835         arg.align = FormatArg::Align::LEFT;
836       }
837       FormatValue<uintptr_t>(
838           reinterpret_cast<uintptr_t>(val_)).doFormat(arg, cb);
839     }
840   }
841
842  private:
843   T* val_;
844 };
845
846 template <class T, class = void>
847 class TryFormatValue {
848  public:
849   template <class FormatCallback>
850   static void formatOrFail(T& value, FormatArg& arg, FormatCallback& cb) {
851     arg.error("No formatter available for this type");
852   }
853 };
854
855 template <class T>
856 class TryFormatValue<
857   T,
858   typename std::enable_if<
859       0 < sizeof(FormatValue<typename std::decay<T>::type>)>::type>
860   {
861  public:
862   template <class FormatCallback>
863   static void formatOrFail(T& value, FormatArg& arg, FormatCallback& cb) {
864     FormatValue<typename std::decay<T>::type>(value).format(arg, cb);
865   }
866 };
867
868 // Partial specialization of FormatValue for other pointers
869 template <class T>
870 class FormatValue<
871   T*,
872   typename std::enable_if<
873       !std::is_same<char, typename std::decay<T>::type>::value &&
874       !std::is_same<void, typename std::decay<T>::type>::value>::type>
875   {
876  public:
877   explicit FormatValue(T* val) : val_(val) { }
878
879   template <class FormatCallback>
880   void format(FormatArg& arg, FormatCallback& cb) const {
881     if (arg.keyEmpty()) {
882       FormatValue<void*>((void*)val_).format(arg, cb);
883     } else {
884       TryFormatValue<T>::formatOrFail(val_[arg.splitIntKey()], arg, cb);
885     }
886   }
887  private:
888   T* val_;
889 };
890
891 namespace detail {
892
893 // Shortcut, so we don't have to use enable_if everywhere
894 struct FormatTraitsBase {
895   typedef void enabled;
896 };
897
898 // Traits that define enabled, value_type, and at() for anything
899 // indexable with integral keys: pointers, arrays, vectors, and maps
900 // with integral keys
901 template <class T, class Enable=void> struct IndexableTraits;
902
903 // Base class for sequences (vectors, deques)
904 template <class C>
905 struct IndexableTraitsSeq : public FormatTraitsBase {
906   typedef C container_type;
907   typedef typename C::value_type value_type;
908   static const value_type& at(const C& c, int idx) {
909     return c.at(idx);
910   }
911 };
912
913 // Base class for associative types (maps)
914 template <class C>
915 struct IndexableTraitsAssoc : public FormatTraitsBase {
916   typedef typename C::value_type::second_type value_type;
917   static const value_type& at(const C& c, int idx) {
918     return c.at(static_cast<typename C::key_type>(idx));
919   }
920 };
921
922 // std::array
923 template <class T, size_t N>
924 struct IndexableTraits<std::array<T, N>>
925   : public IndexableTraitsSeq<std::array<T, N>> {
926 };
927
928 // std::vector
929 template <class T, class A>
930 struct IndexableTraits<std::vector<T, A>>
931   : public IndexableTraitsSeq<std::vector<T, A>> {
932 };
933
934 // std::deque
935 template <class T, class A>
936 struct IndexableTraits<std::deque<T, A>>
937   : public IndexableTraitsSeq<std::deque<T, A>> {
938 };
939
940 // fbvector
941 template <class T, class A>
942 struct IndexableTraits<fbvector<T, A>>
943   : public IndexableTraitsSeq<fbvector<T, A>> {
944 };
945
946 // small_vector
947 template <class T, size_t M, class A, class B, class C>
948 struct IndexableTraits<small_vector<T, M, A, B, C>>
949   : public IndexableTraitsSeq<small_vector<T, M, A, B, C>> {
950 };
951
952 // std::map with integral keys
953 template <class K, class T, class C, class A>
954 struct IndexableTraits<
955   std::map<K, T, C, A>,
956   typename std::enable_if<std::is_integral<K>::value>::type>
957   : public IndexableTraitsAssoc<std::map<K, T, C, A>> {
958 };
959
960 // std::unordered_map with integral keys
961 template <class K, class T, class H, class E, class A>
962 struct IndexableTraits<
963   std::unordered_map<K, T, H, E, A>,
964   typename std::enable_if<std::is_integral<K>::value>::type>
965   : public IndexableTraitsAssoc<std::unordered_map<K, T, H, E, A>> {
966 };
967
968 }  // namespace detail
969
970 // Partial specialization of FormatValue for integer-indexable containers
971 template <class T>
972 class FormatValue<
973   T,
974   typename detail::IndexableTraits<T>::enabled> {
975  public:
976   explicit FormatValue(const T& val) : val_(val) { }
977
978   template <class FormatCallback>
979   void format(FormatArg& arg, FormatCallback& cb) const {
980     FormatValue<typename std::decay<
981       typename detail::IndexableTraits<T>::value_type>::type>(
982         detail::IndexableTraits<T>::at(
983             val_, arg.splitIntKey())).format(arg, cb);
984   }
985
986  private:
987   const T& val_;
988 };
989
990 namespace detail {
991
992 // Define enabled, key_type, convert from StringPiece to the key types
993 // that we support
994 template <class T> struct KeyFromStringPiece;
995
996 // std::string
997 template <>
998 struct KeyFromStringPiece<std::string> : public FormatTraitsBase {
999   typedef std::string key_type;
1000   static std::string convert(StringPiece s) {
1001     return s.toString();
1002   }
1003   typedef void enabled;
1004 };
1005
1006 // fbstring
1007 template <>
1008 struct KeyFromStringPiece<fbstring> : public FormatTraitsBase {
1009   typedef fbstring key_type;
1010   static fbstring convert(StringPiece s) {
1011     return s.toFbstring();
1012   }
1013 };
1014
1015 // StringPiece
1016 template <>
1017 struct KeyFromStringPiece<StringPiece> : public FormatTraitsBase {
1018   typedef StringPiece key_type;
1019   static StringPiece convert(StringPiece s) {
1020     return s;
1021   }
1022 };
1023
1024 // Base class for associative types keyed by strings
1025 template <class T> struct KeyableTraitsAssoc : public FormatTraitsBase {
1026   typedef typename T::key_type key_type;
1027   typedef typename T::value_type::second_type value_type;
1028   static const value_type& at(const T& map, StringPiece key) {
1029     return map.at(KeyFromStringPiece<key_type>::convert(key));
1030   }
1031 };
1032
1033 // Define enabled, key_type, value_type, at() for supported string-keyed
1034 // types
1035 template <class T, class Enabled=void> struct KeyableTraits;
1036
1037 // std::map with string key
1038 template <class K, class T, class C, class A>
1039 struct KeyableTraits<
1040   std::map<K, T, C, A>,
1041   typename KeyFromStringPiece<K>::enabled>
1042   : public KeyableTraitsAssoc<std::map<K, T, C, A>> {
1043 };
1044
1045 // std::unordered_map with string key
1046 template <class K, class T, class H, class E, class A>
1047 struct KeyableTraits<
1048   std::unordered_map<K, T, H, E, A>,
1049   typename KeyFromStringPiece<K>::enabled>
1050   : public KeyableTraitsAssoc<std::unordered_map<K, T, H, E, A>> {
1051 };
1052
1053 }  // namespace detail
1054
1055 // Partial specialization of FormatValue for string-keyed containers
1056 template <class T>
1057 class FormatValue<
1058   T,
1059   typename detail::KeyableTraits<T>::enabled> {
1060  public:
1061   explicit FormatValue(const T& val) : val_(val) { }
1062
1063   template <class FormatCallback>
1064   void format(FormatArg& arg, FormatCallback& cb) const {
1065     FormatValue<typename std::decay<
1066       typename detail::KeyableTraits<T>::value_type>::type>(
1067         detail::KeyableTraits<T>::at(
1068             val_, arg.splitKey())).format(arg, cb);
1069   }
1070
1071  private:
1072   const T& val_;
1073 };
1074
1075 // Partial specialization of FormatValue for pairs
1076 template <class A, class B>
1077 class FormatValue<std::pair<A, B>> {
1078  public:
1079   explicit FormatValue(const std::pair<A, B>& val) : val_(val) { }
1080
1081   template <class FormatCallback>
1082   void format(FormatArg& arg, FormatCallback& cb) const {
1083     int key = arg.splitIntKey();
1084     switch (key) {
1085     case 0:
1086       FormatValue<typename std::decay<A>::type>(val_.first).format(arg, cb);
1087       break;
1088     case 1:
1089       FormatValue<typename std::decay<B>::type>(val_.second).format(arg, cb);
1090       break;
1091     default:
1092       arg.error("invalid index for pair");
1093     }
1094   }
1095
1096  private:
1097   const std::pair<A, B>& val_;
1098 };
1099
1100 // Partial specialization of FormatValue for tuples
1101 template <class... Args>
1102 class FormatValue<std::tuple<Args...>> {
1103   typedef std::tuple<Args...> Tuple;
1104  public:
1105   explicit FormatValue(const Tuple& val) : val_(val) { }
1106
1107   template <class FormatCallback>
1108   void format(FormatArg& arg, FormatCallback& cb) const {
1109     int key = arg.splitIntKey();
1110     arg.enforce(key >= 0, "tuple index must be non-negative");
1111     doFormat(key, arg, cb);
1112   }
1113
1114  private:
1115   static constexpr size_t valueCount = std::tuple_size<Tuple>::value;
1116
1117   template <size_t K, class Callback>
1118   typename std::enable_if<K == valueCount>::type
1119   doFormatFrom(size_t i, FormatArg& arg, Callback& cb) const {
1120     arg.enforce("tuple index out of range, max=", i);
1121   }
1122
1123   template <size_t K, class Callback>
1124   typename std::enable_if<(K < valueCount)>::type
1125   doFormatFrom(size_t i, FormatArg& arg, Callback& cb) const {
1126     if (i == K) {
1127       FormatValue<typename std::decay<
1128         typename std::tuple_element<K, Tuple>::type>::type>(
1129           std::get<K>(val_)).format(arg, cb);
1130     } else {
1131       doFormatFrom<K+1>(i, arg, cb);
1132     }
1133   }
1134
1135   template <class Callback>
1136   void doFormat(size_t i, FormatArg& arg, Callback& cb) const {
1137     return doFormatFrom<0>(i, arg, cb);
1138   }
1139
1140   const Tuple& val_;
1141 };
1142
1143 // Partial specialization of FormatValue for nested Formatters
1144 template <bool containerMode, class... Args>
1145 class FormatValue<Formatter<containerMode, Args...>, void> {
1146   typedef Formatter<containerMode, Args...> FormatterValue;
1147  public:
1148   explicit FormatValue(const FormatterValue& f) : f_(f) { }
1149
1150   template <class FormatCallback>
1151   void format(FormatArg& arg, FormatCallback& cb) const {
1152     format_value::formatFormatter(f_, arg, cb);
1153   }
1154  private:
1155   const FormatterValue& f_;
1156 };
1157
1158 /**
1159  * Formatter objects can be appended to strings, and therefore they're
1160  * compatible with folly::toAppend and folly::to.
1161  */
1162 template <class Tgt, bool containerMode, class... Args>
1163 typename std::enable_if<
1164    IsSomeString<Tgt>::value>::type
1165 toAppend(const Formatter<containerMode, Args...>& value, Tgt * result) {
1166   value.appendTo(*result);
1167 }
1168
1169 }  // namespace folly