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