Format-inl.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. /*
  2. * Copyright 2012-present 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. #ifndef FOLLY_FORMAT_H_
  17. #error This file may only be included from Format.h.
  18. #endif
  19. #include <array>
  20. #include <cinttypes>
  21. #include <deque>
  22. #include <map>
  23. #include <unordered_map>
  24. #include <vector>
  25. #include <folly/Exception.h>
  26. #include <folly/FormatTraits.h>
  27. #include <folly/MapUtil.h>
  28. #include <folly/Traits.h>
  29. #include <folly/lang/Exception.h>
  30. #include <folly/portability/Windows.h>
  31. // Ignore -Wformat-nonliteral warnings within this file
  32. FOLLY_PUSH_WARNING
  33. FOLLY_GNU_DISABLE_WARNING("-Wformat-nonliteral")
  34. namespace folly {
  35. namespace detail {
  36. // Updates the end of the buffer after the comma separators have been added.
  37. void insertThousandsGroupingUnsafe(char* start_buffer, char** end_buffer);
  38. extern const std::array<std::array<char, 2>, 256> formatHexUpper;
  39. extern const std::array<std::array<char, 2>, 256> formatHexLower;
  40. extern const std::array<std::array<char, 3>, 512> formatOctal;
  41. extern const std::array<std::array<char, 8>, 256> formatBinary;
  42. const size_t kMaxHexLength = 2 * sizeof(uintmax_t);
  43. const size_t kMaxOctalLength = 3 * sizeof(uintmax_t);
  44. const size_t kMaxBinaryLength = 8 * sizeof(uintmax_t);
  45. /**
  46. * Convert an unsigned to hex, using repr (which maps from each possible
  47. * 2-hex-bytes value to the 2-character representation).
  48. *
  49. * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
  50. * the supplied buffer and returns the offset of the beginning of the string
  51. * from the start of the buffer. The formatted string will be in range
  52. * [buf+begin, buf+bufLen).
  53. */
  54. template <class Uint>
  55. size_t uintToHex(
  56. char* buffer,
  57. size_t bufLen,
  58. Uint v,
  59. std::array<std::array<char, 2>, 256> const& repr) {
  60. // 'v >>= 7, v >>= 1' is no more than a work around to get rid of shift size
  61. // warning when Uint = uint8_t (it's false as v >= 256 implies sizeof(v) > 1).
  62. for (; !less_than<unsigned, 256>(v); v >>= 7, v >>= 1) {
  63. auto b = v & 0xff;
  64. bufLen -= 2;
  65. buffer[bufLen] = repr[b][0];
  66. buffer[bufLen + 1] = repr[b][1];
  67. }
  68. buffer[--bufLen] = repr[v][1];
  69. if (v >= 16) {
  70. buffer[--bufLen] = repr[v][0];
  71. }
  72. return bufLen;
  73. }
  74. /**
  75. * Convert an unsigned to hex, using lower-case letters for the digits
  76. * above 9. See the comments for uintToHex.
  77. */
  78. template <class Uint>
  79. inline size_t uintToHexLower(char* buffer, size_t bufLen, Uint v) {
  80. return uintToHex(buffer, bufLen, v, formatHexLower);
  81. }
  82. /**
  83. * Convert an unsigned to hex, using upper-case letters for the digits
  84. * above 9. See the comments for uintToHex.
  85. */
  86. template <class Uint>
  87. inline size_t uintToHexUpper(char* buffer, size_t bufLen, Uint v) {
  88. return uintToHex(buffer, bufLen, v, formatHexUpper);
  89. }
  90. /**
  91. * Convert an unsigned to octal.
  92. *
  93. * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
  94. * the supplied buffer and returns the offset of the beginning of the string
  95. * from the start of the buffer. The formatted string will be in range
  96. * [buf+begin, buf+bufLen).
  97. */
  98. template <class Uint>
  99. size_t uintToOctal(char* buffer, size_t bufLen, Uint v) {
  100. auto& repr = formatOctal;
  101. // 'v >>= 7, v >>= 2' is no more than a work around to get rid of shift size
  102. // warning when Uint = uint8_t (it's false as v >= 512 implies sizeof(v) > 1).
  103. for (; !less_than<unsigned, 512>(v); v >>= 7, v >>= 2) {
  104. auto b = v & 0x1ff;
  105. bufLen -= 3;
  106. buffer[bufLen] = repr[b][0];
  107. buffer[bufLen + 1] = repr[b][1];
  108. buffer[bufLen + 2] = repr[b][2];
  109. }
  110. buffer[--bufLen] = repr[v][2];
  111. if (v >= 8) {
  112. buffer[--bufLen] = repr[v][1];
  113. }
  114. if (v >= 64) {
  115. buffer[--bufLen] = repr[v][0];
  116. }
  117. return bufLen;
  118. }
  119. /**
  120. * Convert an unsigned to binary.
  121. *
  122. * Just like folly::detail::uintToBuffer in Conv.h, writes at the *end* of
  123. * the supplied buffer and returns the offset of the beginning of the string
  124. * from the start of the buffer. The formatted string will be in range
  125. * [buf+begin, buf+bufLen).
  126. */
  127. template <class Uint>
  128. size_t uintToBinary(char* buffer, size_t bufLen, Uint v) {
  129. auto& repr = formatBinary;
  130. if (v == 0) {
  131. buffer[--bufLen] = '0';
  132. return bufLen;
  133. }
  134. for (; v; v >>= 7, v >>= 1) {
  135. auto b = v & 0xff;
  136. bufLen -= 8;
  137. memcpy(buffer + bufLen, &(repr[b][0]), 8);
  138. }
  139. while (buffer[bufLen] == '0') {
  140. ++bufLen;
  141. }
  142. return bufLen;
  143. }
  144. } // namespace detail
  145. template <class Derived, bool containerMode, class... Args>
  146. BaseFormatter<Derived, containerMode, Args...>::BaseFormatter(
  147. StringPiece str,
  148. Args&&... args)
  149. : str_(str), values_(std::forward<Args>(args)...) {}
  150. template <class Derived, bool containerMode, class... Args>
  151. template <class Output>
  152. void BaseFormatter<Derived, containerMode, Args...>::operator()(
  153. Output& out) const {
  154. // Copy raw string (without format specifiers) to output;
  155. // not as simple as we'd like, as we still need to translate "}}" to "}"
  156. // and throw if we see any lone "}"
  157. auto outputString = [&out](StringPiece s) {
  158. auto p = s.begin();
  159. auto end = s.end();
  160. while (p != end) {
  161. auto q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
  162. if (!q) {
  163. out(StringPiece(p, end));
  164. break;
  165. }
  166. ++q;
  167. out(StringPiece(p, q));
  168. p = q;
  169. if (p == end || *p != '}') {
  170. throw_exception<BadFormatArg>(
  171. "folly::format: single '}' in format string");
  172. }
  173. ++p;
  174. }
  175. };
  176. auto p = str_.begin();
  177. auto end = str_.end();
  178. int nextArg = 0;
  179. bool hasDefaultArgIndex = false;
  180. bool hasExplicitArgIndex = false;
  181. while (p != end) {
  182. auto q = static_cast<const char*>(memchr(p, '{', size_t(end - p)));
  183. if (!q) {
  184. outputString(StringPiece(p, end));
  185. break;
  186. }
  187. outputString(StringPiece(p, q));
  188. p = q + 1;
  189. if (p == end) {
  190. throw_exception<BadFormatArg>(
  191. "folly::format: '}' at end of format string");
  192. }
  193. // "{{" -> "{"
  194. if (*p == '{') {
  195. out(StringPiece(p, 1));
  196. ++p;
  197. continue;
  198. }
  199. // Format string
  200. q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
  201. if (q == nullptr) {
  202. throw_exception<BadFormatArg>("folly::format: missing ending '}'");
  203. }
  204. FormatArg arg(StringPiece(p, q));
  205. p = q + 1;
  206. int argIndex = 0;
  207. auto piece = arg.splitKey<true>(); // empty key component is okay
  208. if (containerMode) { // static
  209. arg.enforce(
  210. arg.width != FormatArg::kDynamicWidth,
  211. "dynamic field width not supported in vformat()");
  212. if (piece.empty()) {
  213. arg.setNextIntKey(nextArg++);
  214. hasDefaultArgIndex = true;
  215. } else {
  216. arg.setNextKey(piece);
  217. hasExplicitArgIndex = true;
  218. }
  219. } else {
  220. if (piece.empty()) {
  221. if (arg.width == FormatArg::kDynamicWidth) {
  222. arg.enforce(
  223. arg.widthIndex == FormatArg::kNoIndex,
  224. "cannot provide width arg index without value arg index");
  225. int sizeArg = nextArg++;
  226. arg.width = asDerived().getSizeArg(size_t(sizeArg), arg);
  227. }
  228. argIndex = nextArg++;
  229. hasDefaultArgIndex = true;
  230. } else {
  231. if (arg.width == FormatArg::kDynamicWidth) {
  232. arg.enforce(
  233. arg.widthIndex != FormatArg::kNoIndex,
  234. "cannot provide value arg index without width arg index");
  235. arg.width = asDerived().getSizeArg(size_t(arg.widthIndex), arg);
  236. }
  237. try {
  238. argIndex = to<int>(piece);
  239. } catch (const std::out_of_range&) {
  240. arg.error("argument index must be integer");
  241. }
  242. arg.enforce(argIndex >= 0, "argument index must be non-negative");
  243. hasExplicitArgIndex = true;
  244. }
  245. }
  246. if (hasDefaultArgIndex && hasExplicitArgIndex) {
  247. throw_exception<BadFormatArg>(
  248. "folly::format: may not have both default and explicit arg indexes");
  249. }
  250. asDerived().doFormat(size_t(argIndex), arg, out);
  251. }
  252. }
  253. template <class Derived, bool containerMode, class... Args>
  254. void writeTo(
  255. FILE* fp,
  256. const BaseFormatter<Derived, containerMode, Args...>& formatter) {
  257. auto writer = [fp](StringPiece sp) {
  258. size_t n = fwrite(sp.data(), 1, sp.size(), fp);
  259. if (n < sp.size()) {
  260. throwSystemError("Formatter writeTo", "fwrite failed");
  261. }
  262. };
  263. formatter(writer);
  264. }
  265. namespace format_value {
  266. template <class FormatCallback>
  267. void formatString(StringPiece val, FormatArg& arg, FormatCallback& cb) {
  268. if (arg.width != FormatArg::kDefaultWidth && arg.width < 0) {
  269. throw_exception<BadFormatArg>("folly::format: invalid width");
  270. }
  271. if (arg.precision != FormatArg::kDefaultPrecision && arg.precision < 0) {
  272. throw_exception<BadFormatArg>("folly::format: invalid precision");
  273. }
  274. if (arg.precision != FormatArg::kDefaultPrecision &&
  275. val.size() > static_cast<size_t>(arg.precision)) {
  276. val.reset(val.data(), static_cast<size_t>(arg.precision));
  277. }
  278. constexpr int padBufSize = 128;
  279. char padBuf[padBufSize];
  280. // Output padding, no more than padBufSize at once
  281. auto pad = [&padBuf, &cb, padBufSize](int chars) {
  282. while (chars) {
  283. int n = std::min(chars, padBufSize);
  284. cb(StringPiece(padBuf, size_t(n)));
  285. chars -= n;
  286. }
  287. };
  288. int padRemaining = 0;
  289. if (arg.width != FormatArg::kDefaultWidth &&
  290. val.size() < static_cast<size_t>(arg.width)) {
  291. char fill = arg.fill == FormatArg::kDefaultFill ? ' ' : arg.fill;
  292. int padChars = static_cast<int>(arg.width - val.size());
  293. memset(padBuf, fill, size_t(std::min(padBufSize, padChars)));
  294. switch (arg.align) {
  295. case FormatArg::Align::DEFAULT:
  296. case FormatArg::Align::LEFT:
  297. padRemaining = padChars;
  298. break;
  299. case FormatArg::Align::CENTER:
  300. pad(padChars / 2);
  301. padRemaining = padChars - padChars / 2;
  302. break;
  303. case FormatArg::Align::RIGHT:
  304. case FormatArg::Align::PAD_AFTER_SIGN:
  305. pad(padChars);
  306. break;
  307. default:
  308. abort();
  309. break;
  310. }
  311. }
  312. cb(val);
  313. if (padRemaining) {
  314. pad(padRemaining);
  315. }
  316. }
  317. template <class FormatCallback>
  318. void formatNumber(
  319. StringPiece val,
  320. int prefixLen,
  321. FormatArg& arg,
  322. FormatCallback& cb) {
  323. // precision means something different for numbers
  324. arg.precision = FormatArg::kDefaultPrecision;
  325. if (arg.align == FormatArg::Align::DEFAULT) {
  326. arg.align = FormatArg::Align::RIGHT;
  327. } else if (prefixLen && arg.align == FormatArg::Align::PAD_AFTER_SIGN) {
  328. // Split off the prefix, then do any padding if necessary
  329. cb(val.subpiece(0, size_t(prefixLen)));
  330. val.advance(size_t(prefixLen));
  331. arg.width = std::max(arg.width - prefixLen, 0);
  332. }
  333. format_value::formatString(val, arg, cb);
  334. }
  335. template <
  336. class FormatCallback,
  337. class Derived,
  338. bool containerMode,
  339. class... Args>
  340. void formatFormatter(
  341. const BaseFormatter<Derived, containerMode, Args...>& formatter,
  342. FormatArg& arg,
  343. FormatCallback& cb) {
  344. if (arg.width == FormatArg::kDefaultWidth &&
  345. arg.precision == FormatArg::kDefaultPrecision) {
  346. // nothing to do
  347. formatter(cb);
  348. } else if (
  349. arg.align != FormatArg::Align::LEFT &&
  350. arg.align != FormatArg::Align::DEFAULT) {
  351. // We can only avoid creating a temporary string if we align left,
  352. // as we'd need to know the size beforehand otherwise
  353. format_value::formatString(formatter.fbstr(), arg, cb);
  354. } else {
  355. auto fn = [&arg, &cb](StringPiece sp) mutable {
  356. int sz = static_cast<int>(sp.size());
  357. if (arg.precision != FormatArg::kDefaultPrecision) {
  358. sz = std::min(arg.precision, sz);
  359. sp.reset(sp.data(), size_t(sz));
  360. arg.precision -= sz;
  361. }
  362. if (!sp.empty()) {
  363. cb(sp);
  364. if (arg.width != FormatArg::kDefaultWidth) {
  365. arg.width = std::max(arg.width - sz, 0);
  366. }
  367. }
  368. };
  369. formatter(fn);
  370. if (arg.width != FormatArg::kDefaultWidth && arg.width != 0) {
  371. // Rely on formatString to do appropriate padding
  372. format_value::formatString(StringPiece(), arg, cb);
  373. }
  374. }
  375. }
  376. } // namespace format_value
  377. // Definitions for default FormatValue classes
  378. // Integral types (except bool)
  379. template <class T>
  380. class FormatValue<
  381. T,
  382. typename std::enable_if<
  383. std::is_integral<T>::value && !std::is_same<T, bool>::value>::type> {
  384. public:
  385. explicit FormatValue(T val) : val_(val) {}
  386. T getValue() const {
  387. return val_;
  388. }
  389. template <class FormatCallback>
  390. void format(FormatArg& arg, FormatCallback& cb) const {
  391. arg.validate(FormatArg::Type::INTEGER);
  392. doFormat(arg, cb);
  393. }
  394. template <class FormatCallback>
  395. void doFormat(FormatArg& arg, FormatCallback& cb) const {
  396. char presentation = arg.presentation;
  397. if (presentation == FormatArg::kDefaultPresentation) {
  398. presentation = std::is_same<T, char>::value ? 'c' : 'd';
  399. }
  400. // Do all work as unsigned, we'll add the prefix ('0' or '0x' if necessary)
  401. // and sign ourselves.
  402. typedef typename std::make_unsigned<T>::type UT;
  403. UT uval;
  404. char sign;
  405. if (std::is_signed<T>::value) {
  406. if (folly::is_negative(val_)) {
  407. uval = UT(-static_cast<UT>(val_));
  408. sign = '-';
  409. } else {
  410. uval = static_cast<UT>(val_);
  411. switch (arg.sign) {
  412. case FormatArg::Sign::PLUS_OR_MINUS:
  413. sign = '+';
  414. break;
  415. case FormatArg::Sign::SPACE_OR_MINUS:
  416. sign = ' ';
  417. break;
  418. default:
  419. sign = '\0';
  420. break;
  421. }
  422. }
  423. } else {
  424. uval = static_cast<UT>(val_);
  425. sign = '\0';
  426. arg.enforce(
  427. arg.sign == FormatArg::Sign::DEFAULT,
  428. "sign specifications not allowed for unsigned values");
  429. }
  430. // max of:
  431. // #x: 0x prefix + 16 bytes = 18 bytes
  432. // #o: 0 prefix + 22 bytes = 23 bytes
  433. // #b: 0b prefix + 64 bytes = 65 bytes
  434. // ,d: 26 bytes (including thousands separators!)
  435. // + nul terminator
  436. // + 3 for sign and prefix shenanigans (see below)
  437. constexpr size_t valBufSize = 69;
  438. char valBuf[valBufSize];
  439. char* valBufBegin = nullptr;
  440. char* valBufEnd = nullptr;
  441. int prefixLen = 0;
  442. switch (presentation) {
  443. case 'n': {
  444. arg.enforce(
  445. !arg.basePrefix,
  446. "base prefix not allowed with '",
  447. presentation,
  448. "' specifier");
  449. arg.enforce(
  450. !arg.thousandsSeparator,
  451. "cannot use ',' with the '",
  452. presentation,
  453. "' specifier");
  454. valBufBegin = valBuf + 3; // room for sign and base prefix
  455. #if defined(__ANDROID__)
  456. int len = snprintf(
  457. valBufBegin,
  458. (valBuf + valBufSize) - valBufBegin,
  459. "%" PRIuMAX,
  460. static_cast<uintmax_t>(uval));
  461. #else
  462. int len = snprintf(
  463. valBufBegin,
  464. size_t((valBuf + valBufSize) - valBufBegin),
  465. "%ju",
  466. static_cast<uintmax_t>(uval));
  467. #endif
  468. // valBufSize should always be big enough, so this should never
  469. // happen.
  470. assert(len < valBuf + valBufSize - valBufBegin);
  471. valBufEnd = valBufBegin + len;
  472. break;
  473. }
  474. case 'd':
  475. arg.enforce(
  476. !arg.basePrefix,
  477. "base prefix not allowed with '",
  478. presentation,
  479. "' specifier");
  480. valBufBegin = valBuf + 3; // room for sign and base prefix
  481. // Use uintToBuffer, faster than sprintf
  482. valBufEnd = valBufBegin + uint64ToBufferUnsafe(uval, valBufBegin);
  483. if (arg.thousandsSeparator) {
  484. detail::insertThousandsGroupingUnsafe(valBufBegin, &valBufEnd);
  485. }
  486. break;
  487. case 'c':
  488. arg.enforce(
  489. !arg.basePrefix,
  490. "base prefix not allowed with '",
  491. presentation,
  492. "' specifier");
  493. arg.enforce(
  494. !arg.thousandsSeparator,
  495. "thousands separator (',') not allowed with '",
  496. presentation,
  497. "' specifier");
  498. valBufBegin = valBuf + 3;
  499. *valBufBegin = static_cast<char>(uval);
  500. valBufEnd = valBufBegin + 1;
  501. break;
  502. case 'o':
  503. case 'O':
  504. arg.enforce(
  505. !arg.thousandsSeparator,
  506. "thousands separator (',') not allowed with '",
  507. presentation,
  508. "' specifier");
  509. valBufEnd = valBuf + valBufSize - 1;
  510. valBufBegin =
  511. 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(
  519. !arg.thousandsSeparator,
  520. "thousands separator (',') not allowed with '",
  521. presentation,
  522. "' specifier");
  523. valBufEnd = valBuf + valBufSize - 1;
  524. valBufBegin =
  525. valBuf + detail::uintToHexLower(valBuf, valBufSize - 1, uval);
  526. if (arg.basePrefix) {
  527. *--valBufBegin = 'x';
  528. *--valBufBegin = '0';
  529. prefixLen = 2;
  530. }
  531. break;
  532. case 'X':
  533. arg.enforce(
  534. !arg.thousandsSeparator,
  535. "thousands separator (',') not allowed with '",
  536. presentation,
  537. "' specifier");
  538. valBufEnd = valBuf + valBufSize - 1;
  539. valBufBegin =
  540. valBuf + detail::uintToHexUpper(valBuf, valBufSize - 1, 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(
  550. !arg.thousandsSeparator,
  551. "thousands separator (',') not allowed with '",
  552. presentation,
  553. "' specifier");
  554. valBufEnd = valBuf + valBufSize - 1;
  555. valBufBegin =
  556. valBuf + detail::uintToBinary(valBuf, valBufSize - 1, uval);
  557. if (arg.basePrefix) {
  558. *--valBufBegin = presentation; // 0b or 0B
  559. *--valBufBegin = '0';
  560. prefixLen = 2;
  561. }
  562. break;
  563. default:
  564. arg.error("invalid specifier '", presentation, "'");
  565. }
  566. if (sign) {
  567. *--valBufBegin = sign;
  568. ++prefixLen;
  569. }
  570. format_value::formatNumber(
  571. StringPiece(valBufBegin, valBufEnd), prefixLen, arg, cb);
  572. }
  573. private:
  574. T val_;
  575. };
  576. // Bool
  577. template <>
  578. class FormatValue<bool> {
  579. public:
  580. explicit FormatValue(bool val) : val_(val) {}
  581. template <class FormatCallback>
  582. void format(FormatArg& arg, FormatCallback& cb) const {
  583. if (arg.presentation == FormatArg::kDefaultPresentation) {
  584. arg.validate(FormatArg::Type::OTHER);
  585. format_value::formatString(val_ ? "true" : "false", arg, cb);
  586. } else { // number
  587. FormatValue<int>(val_).format(arg, cb);
  588. }
  589. }
  590. private:
  591. bool val_;
  592. };
  593. // double
  594. template <>
  595. class FormatValue<double> {
  596. public:
  597. explicit FormatValue(double val) : val_(val) {}
  598. template <class FormatCallback>
  599. void format(FormatArg& arg, FormatCallback& cb) const {
  600. fbstring piece;
  601. int prefixLen;
  602. formatHelper(piece, prefixLen, arg);
  603. format_value::formatNumber(piece, prefixLen, arg, cb);
  604. }
  605. private:
  606. void formatHelper(fbstring& piece, int& prefixLen, FormatArg& arg) const;
  607. double val_;
  608. };
  609. // float (defer to double)
  610. template <>
  611. class FormatValue<float> {
  612. public:
  613. explicit FormatValue(float val) : val_(val) {}
  614. template <class FormatCallback>
  615. void format(FormatArg& arg, FormatCallback& cb) const {
  616. FormatValue<double>(val_).format(arg, cb);
  617. }
  618. private:
  619. float val_;
  620. };
  621. // String-y types (implicitly convertible to StringPiece, except char*)
  622. template <class T>
  623. class FormatValue<
  624. T,
  625. typename std::enable_if<
  626. (!std::is_pointer<T>::value ||
  627. !std::is_same<
  628. char,
  629. typename std::decay<typename std::remove_pointer<T>::type>::type>::
  630. value) &&
  631. std::is_convertible<T, StringPiece>::value>::type> {
  632. public:
  633. explicit FormatValue(StringPiece val) : val_(val) {}
  634. template <class FormatCallback>
  635. void format(FormatArg& arg, FormatCallback& cb) const {
  636. if (arg.keyEmpty()) {
  637. arg.validate(FormatArg::Type::OTHER);
  638. arg.enforce(
  639. arg.presentation == FormatArg::kDefaultPresentation ||
  640. arg.presentation == 's',
  641. "invalid specifier '",
  642. arg.presentation,
  643. "'");
  644. format_value::formatString(val_, arg, cb);
  645. } else {
  646. FormatValue<char>(val_.at(size_t(arg.splitIntKey()))).format(arg, cb);
  647. }
  648. }
  649. private:
  650. StringPiece val_;
  651. };
  652. // Null
  653. template <>
  654. class FormatValue<std::nullptr_t> {
  655. public:
  656. explicit FormatValue(std::nullptr_t) {}
  657. template <class FormatCallback>
  658. void format(FormatArg& arg, FormatCallback& cb) const {
  659. arg.validate(FormatArg::Type::OTHER);
  660. arg.enforce(
  661. arg.presentation == FormatArg::kDefaultPresentation,
  662. "invalid specifier '",
  663. arg.presentation,
  664. "'");
  665. format_value::formatString("(null)", arg, cb);
  666. }
  667. };
  668. // Partial specialization of FormatValue for char*
  669. template <class T>
  670. class FormatValue<
  671. T*,
  672. typename std::enable_if<
  673. std::is_same<char, typename std::decay<T>::type>::value>::type> {
  674. public:
  675. explicit FormatValue(T* val) : val_(val) {}
  676. template <class FormatCallback>
  677. void format(FormatArg& arg, FormatCallback& cb) const {
  678. if (arg.keyEmpty()) {
  679. if (!val_) {
  680. FormatValue<std::nullptr_t>(nullptr).format(arg, cb);
  681. } else {
  682. FormatValue<StringPiece>(val_).format(arg, cb);
  683. }
  684. } else {
  685. FormatValue<typename std::decay<T>::type>(val_[arg.splitIntKey()])
  686. .format(arg, cb);
  687. }
  688. }
  689. private:
  690. T* val_;
  691. };
  692. // Partial specialization of FormatValue for void*
  693. template <class T>
  694. class FormatValue<
  695. T*,
  696. typename std::enable_if<
  697. std::is_same<void, typename std::decay<T>::type>::value>::type> {
  698. public:
  699. explicit FormatValue(T* val) : val_(val) {}
  700. template <class FormatCallback>
  701. void format(FormatArg& arg, FormatCallback& cb) const {
  702. if (!val_) {
  703. FormatValue<std::nullptr_t>(nullptr).format(arg, cb);
  704. } else {
  705. // Print as a pointer, in hex.
  706. arg.validate(FormatArg::Type::OTHER);
  707. arg.enforce(
  708. arg.presentation == FormatArg::kDefaultPresentation,
  709. "invalid specifier '",
  710. arg.presentation,
  711. "'");
  712. arg.basePrefix = true;
  713. arg.presentation = 'x';
  714. if (arg.align == FormatArg::Align::DEFAULT) {
  715. arg.align = FormatArg::Align::LEFT;
  716. }
  717. FormatValue<uintptr_t>(reinterpret_cast<uintptr_t>(val_))
  718. .doFormat(arg, cb);
  719. }
  720. }
  721. private:
  722. T* val_;
  723. };
  724. template <class T, class = void>
  725. class TryFormatValue {
  726. public:
  727. template <class FormatCallback>
  728. static void
  729. formatOrFail(T& /* value */, FormatArg& arg, FormatCallback& /* cb */) {
  730. arg.error("No formatter available for this type");
  731. }
  732. };
  733. template <class T>
  734. class TryFormatValue<
  735. T,
  736. typename std::enable_if<
  737. 0 < sizeof(FormatValue<typename std::decay<T>::type>)>::type> {
  738. public:
  739. template <class FormatCallback>
  740. static void formatOrFail(T& value, FormatArg& arg, FormatCallback& cb) {
  741. FormatValue<typename std::decay<T>::type>(value).format(arg, cb);
  742. }
  743. };
  744. // Partial specialization of FormatValue for other pointers
  745. template <class T>
  746. class FormatValue<
  747. T*,
  748. typename std::enable_if<
  749. !std::is_same<char, typename std::decay<T>::type>::value &&
  750. !std::is_same<void, typename std::decay<T>::type>::value>::type> {
  751. public:
  752. explicit FormatValue(T* val) : val_(val) {}
  753. template <class FormatCallback>
  754. void format(FormatArg& arg, FormatCallback& cb) const {
  755. if (arg.keyEmpty()) {
  756. FormatValue<void*>((void*)val_).format(arg, cb);
  757. } else {
  758. TryFormatValue<T>::formatOrFail(val_[arg.splitIntKey()], arg, cb);
  759. }
  760. }
  761. private:
  762. T* val_;
  763. };
  764. namespace detail {
  765. // std::array
  766. template <class T, size_t N>
  767. struct IndexableTraits<std::array<T, N>>
  768. : public IndexableTraitsSeq<std::array<T, N>> {};
  769. // std::vector
  770. template <class T, class A>
  771. struct IndexableTraits<std::vector<T, A>>
  772. : public IndexableTraitsSeq<std::vector<T, A>> {};
  773. // std::deque
  774. template <class T, class A>
  775. struct IndexableTraits<std::deque<T, A>>
  776. : public IndexableTraitsSeq<std::deque<T, A>> {};
  777. // std::map with integral keys
  778. template <class K, class T, class C, class A>
  779. struct IndexableTraits<
  780. std::map<K, T, C, A>,
  781. typename std::enable_if<std::is_integral<K>::value>::type>
  782. : public IndexableTraitsAssoc<std::map<K, T, C, A>> {};
  783. // std::unordered_map with integral keys
  784. template <class K, class T, class H, class E, class A>
  785. struct IndexableTraits<
  786. std::unordered_map<K, T, H, E, A>,
  787. typename std::enable_if<std::is_integral<K>::value>::type>
  788. : public IndexableTraitsAssoc<std::unordered_map<K, T, H, E, A>> {};
  789. } // namespace detail
  790. // Partial specialization of FormatValue for integer-indexable containers
  791. template <class T>
  792. class FormatValue<T, typename detail::IndexableTraits<T>::enabled> {
  793. public:
  794. explicit FormatValue(const T& val) : val_(val) {}
  795. template <class FormatCallback>
  796. void format(FormatArg& arg, FormatCallback& cb) const {
  797. FormatValue<typename std::decay<
  798. typename detail::IndexableTraits<T>::value_type>::type>(
  799. detail::IndexableTraits<T>::at(val_, arg.splitIntKey()))
  800. .format(arg, cb);
  801. }
  802. private:
  803. const T& val_;
  804. };
  805. template <class Container, class Value>
  806. class FormatValue<
  807. detail::DefaultValueWrapper<Container, Value>,
  808. typename detail::IndexableTraits<Container>::enabled> {
  809. public:
  810. explicit FormatValue(const detail::DefaultValueWrapper<Container, Value>& val)
  811. : val_(val) {}
  812. template <class FormatCallback>
  813. void format(FormatArg& arg, FormatCallback& cb) const {
  814. FormatValue<typename std::decay<
  815. typename detail::IndexableTraits<Container>::value_type>::type>(
  816. detail::IndexableTraits<Container>::at(
  817. val_.container, arg.splitIntKey(), val_.defaultValue))
  818. .format(arg, cb);
  819. }
  820. private:
  821. const detail::DefaultValueWrapper<Container, Value>& val_;
  822. };
  823. namespace detail {
  824. // Define enabled, key_type, convert from StringPiece to the key types
  825. // that we support
  826. template <class T>
  827. struct KeyFromStringPiece;
  828. // std::string
  829. template <>
  830. struct KeyFromStringPiece<std::string> : public FormatTraitsBase {
  831. typedef std::string key_type;
  832. static std::string convert(StringPiece s) {
  833. return s.toString();
  834. }
  835. typedef void enabled;
  836. };
  837. // fbstring
  838. template <>
  839. struct KeyFromStringPiece<fbstring> : public FormatTraitsBase {
  840. typedef fbstring key_type;
  841. static fbstring convert(StringPiece s) {
  842. return s.to<fbstring>();
  843. }
  844. };
  845. // StringPiece
  846. template <>
  847. struct KeyFromStringPiece<StringPiece> : public FormatTraitsBase {
  848. typedef StringPiece key_type;
  849. static StringPiece convert(StringPiece s) {
  850. return s;
  851. }
  852. };
  853. // Base class for associative types keyed by strings
  854. template <class T>
  855. struct KeyableTraitsAssoc : public FormatTraitsBase {
  856. typedef typename T::key_type key_type;
  857. typedef typename T::value_type::second_type value_type;
  858. static const value_type& at(const T& map, StringPiece key) {
  859. if (auto ptr = get_ptr(map, KeyFromStringPiece<key_type>::convert(key))) {
  860. return *ptr;
  861. }
  862. throw_exception<FormatKeyNotFoundException>(key);
  863. }
  864. static const value_type&
  865. at(const T& map, StringPiece key, const value_type& dflt) {
  866. auto pos = map.find(KeyFromStringPiece<key_type>::convert(key));
  867. return pos != map.end() ? pos->second : dflt;
  868. }
  869. };
  870. // Define enabled, key_type, value_type, at() for supported string-keyed
  871. // types
  872. template <class T, class Enabled = void>
  873. struct KeyableTraits;
  874. // std::map with string key
  875. template <class K, class T, class C, class A>
  876. struct KeyableTraits<
  877. std::map<K, T, C, A>,
  878. typename KeyFromStringPiece<K>::enabled>
  879. : public KeyableTraitsAssoc<std::map<K, T, C, A>> {};
  880. // std::unordered_map with string key
  881. template <class K, class T, class H, class E, class A>
  882. struct KeyableTraits<
  883. std::unordered_map<K, T, H, E, A>,
  884. typename KeyFromStringPiece<K>::enabled>
  885. : public KeyableTraitsAssoc<std::unordered_map<K, T, H, E, A>> {};
  886. } // namespace detail
  887. // Partial specialization of FormatValue for string-keyed containers
  888. template <class T>
  889. class FormatValue<T, typename detail::KeyableTraits<T>::enabled> {
  890. public:
  891. explicit FormatValue(const T& val) : val_(val) {}
  892. template <class FormatCallback>
  893. void format(FormatArg& arg, FormatCallback& cb) const {
  894. FormatValue<typename std::decay<
  895. typename detail::KeyableTraits<T>::value_type>::type>(
  896. detail::KeyableTraits<T>::at(val_, arg.splitKey()))
  897. .format(arg, cb);
  898. }
  899. private:
  900. const T& val_;
  901. };
  902. template <class Container, class Value>
  903. class FormatValue<
  904. detail::DefaultValueWrapper<Container, Value>,
  905. typename detail::KeyableTraits<Container>::enabled> {
  906. public:
  907. explicit FormatValue(const detail::DefaultValueWrapper<Container, Value>& val)
  908. : val_(val) {}
  909. template <class FormatCallback>
  910. void format(FormatArg& arg, FormatCallback& cb) const {
  911. FormatValue<typename std::decay<
  912. typename detail::KeyableTraits<Container>::value_type>::type>(
  913. detail::KeyableTraits<Container>::at(
  914. val_.container, arg.splitKey(), val_.defaultValue))
  915. .format(arg, cb);
  916. }
  917. private:
  918. const detail::DefaultValueWrapper<Container, Value>& val_;
  919. };
  920. // Partial specialization of FormatValue for pairs
  921. template <class A, class B>
  922. class FormatValue<std::pair<A, B>> {
  923. public:
  924. explicit FormatValue(const std::pair<A, B>& val) : val_(val) {}
  925. template <class FormatCallback>
  926. void format(FormatArg& arg, FormatCallback& cb) const {
  927. int key = arg.splitIntKey();
  928. switch (key) {
  929. case 0:
  930. FormatValue<typename std::decay<A>::type>(val_.first).format(arg, cb);
  931. break;
  932. case 1:
  933. FormatValue<typename std::decay<B>::type>(val_.second).format(arg, cb);
  934. break;
  935. default:
  936. arg.error("invalid index for pair");
  937. }
  938. }
  939. private:
  940. const std::pair<A, B>& val_;
  941. };
  942. // Partial specialization of FormatValue for tuples
  943. template <class... Args>
  944. class FormatValue<std::tuple<Args...>> {
  945. typedef std::tuple<Args...> Tuple;
  946. public:
  947. explicit FormatValue(const Tuple& val) : val_(val) {}
  948. template <class FormatCallback>
  949. void format(FormatArg& arg, FormatCallback& cb) const {
  950. int key = arg.splitIntKey();
  951. arg.enforce(key >= 0, "tuple index must be non-negative");
  952. doFormat(size_t(key), arg, cb);
  953. }
  954. private:
  955. static constexpr size_t valueCount = std::tuple_size<Tuple>::value;
  956. template <size_t K, class Callback>
  957. typename std::enable_if<K == valueCount>::type
  958. doFormatFrom(size_t i, FormatArg& arg, Callback& /* cb */) const {
  959. arg.error("tuple index out of range, max=", i);
  960. }
  961. template <size_t K, class Callback>
  962. typename std::enable_if<(K < valueCount)>::type
  963. doFormatFrom(size_t i, FormatArg& arg, Callback& cb) const {
  964. if (i == K) {
  965. FormatValue<typename std::decay<
  966. typename std::tuple_element<K, Tuple>::type>::type>(std::get<K>(val_))
  967. .format(arg, cb);
  968. } else {
  969. doFormatFrom<K + 1>(i, arg, cb);
  970. }
  971. }
  972. template <class Callback>
  973. void doFormat(size_t i, FormatArg& arg, Callback& cb) const {
  974. return doFormatFrom<0>(i, arg, cb);
  975. }
  976. const Tuple& val_;
  977. };
  978. // Partial specialization of FormatValue for nested Formatters
  979. template <bool containerMode, class... Args, template <bool, class...> class F>
  980. class FormatValue<
  981. F<containerMode, Args...>,
  982. typename std::enable_if<
  983. detail::IsFormatter<F<containerMode, Args...>>::value>::type> {
  984. typedef typename F<containerMode, Args...>::BaseType FormatterValue;
  985. public:
  986. explicit FormatValue(const FormatterValue& f) : f_(f) {}
  987. template <class FormatCallback>
  988. void format(FormatArg& arg, FormatCallback& cb) const {
  989. format_value::formatFormatter(f_, arg, cb);
  990. }
  991. private:
  992. const FormatterValue& f_;
  993. };
  994. /**
  995. * Formatter objects can be appended to strings, and therefore they're
  996. * compatible with folly::toAppend and folly::to.
  997. */
  998. template <class Tgt, class Derived, bool containerMode, class... Args>
  999. typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
  1000. const BaseFormatter<Derived, containerMode, Args...>& value,
  1001. Tgt* result) {
  1002. value.appendTo(*result);
  1003. }
  1004. } // namespace folly
  1005. FOLLY_POP_WARNING