in folly/Format-inl.h [171:280]
void BaseFormatter<Derived, containerMode, Args...>::operator()(
Output& out) const {
// Copy raw string (without format specifiers) to output;
// not as simple as we'd like, as we still need to translate "}}" to "}"
// and throw if we see any lone "}"
auto outputString = [&out](StringPiece s) {
auto p = s.begin();
auto end = s.end();
while (p != end) {
auto q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
if (!q) {
out(StringPiece(p, end));
break;
}
++q;
out(StringPiece(p, q));
p = q;
if (p == end || *p != '}') {
throw_exception<BadFormatArg>(
"folly::format: single '}' in format string");
}
++p;
}
};
auto p = str_.begin();
auto end = str_.end();
int nextArg = 0;
bool hasDefaultArgIndex = false;
bool hasExplicitArgIndex = false;
while (p != end) {
auto q = static_cast<const char*>(memchr(p, '{', size_t(end - p)));
if (!q) {
outputString(StringPiece(p, end));
break;
}
outputString(StringPiece(p, q));
p = q + 1;
if (p == end) {
throw_exception<BadFormatArg>(
"folly::format: '}' at end of format string");
}
// "{{" -> "{"
if (*p == '{') {
out(StringPiece(p, 1));
++p;
continue;
}
// Format string
q = static_cast<const char*>(memchr(p, '}', size_t(end - p)));
if (q == nullptr) {
throw_exception<BadFormatArg>("folly::format: missing ending '}'");
}
FormatArg arg(StringPiece(p, q));
p = q + 1;
int argIndex = 0;
auto piece = arg.splitKey<true>(); // empty key component is okay
if (containerMode) { // static
arg.enforce(
arg.width != FormatArg::kDynamicWidth,
"dynamic field width not supported in vformat()");
if (piece.empty()) {
arg.setNextIntKey(nextArg++);
hasDefaultArgIndex = true;
} else {
arg.setNextKey(piece);
hasExplicitArgIndex = true;
}
} else {
if (piece.empty()) {
if (arg.width == FormatArg::kDynamicWidth) {
arg.enforce(
arg.widthIndex == FormatArg::kNoIndex,
"cannot provide width arg index without value arg index");
int sizeArg = nextArg++;
arg.width = asDerived().getSizeArg(size_t(sizeArg), arg);
}
argIndex = nextArg++;
hasDefaultArgIndex = true;
} else {
if (arg.width == FormatArg::kDynamicWidth) {
arg.enforce(
arg.widthIndex != FormatArg::kNoIndex,
"cannot provide value arg index without width arg index");
arg.width = asDerived().getSizeArg(size_t(arg.widthIndex), arg);
}
auto result = tryTo<int>(piece);
arg.enforce(result, "argument index must be integer");
argIndex = *result;
arg.enforce(argIndex >= 0, "argument index must be non-negative");
hasExplicitArgIndex = true;
}
}
if (hasDefaultArgIndex && hasExplicitArgIndex) {
throw_exception<BadFormatArg>(
"folly::format: may not have both default and explicit arg indexes");
}
asDerived().doFormat(size_t(argIndex), arg, out);
}
}