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