+void BaseFormatter<Derived, containerMode, Args...>::operator()(Output& out)
+ const {
+ // Catch BadFormatArg and range_error exceptions, and call
+ // handleFormatStrError().
+ //
+ // These exception types indicate a problem with the format string. Most
+ // format strings are string literals specified by the programmer. If they
+ // have a problem, this is usually a programmer bug. We want to crash to
+ // ensure that these are found early on during development.
+ //
+ // BadFormatArg is thrown by the Format.h code, while range_error is thrown
+ // by Conv.h, which is used in several places in our format string
+ // processing.
+ //
+ // (Note: This behavior is slightly dangerous. If the Output object throws a
+ // BadFormatArg or a range_error, we will also crash the program, even if it
+ // wasn't an issue with the format string. This seems highly unlikely
+ // though, and none of our current Output objects can throw these errors.)
+ //
+ // We also throw out_of_range errors if the format string references an
+ // argument that isn't present (or a key that isn't present in one of the
+ // argument containers). However, at the moment we don't crash on these
+ // errors, as it is likely that the container is dynamic at runtime.
+ try {
+ appendOutput(out);
+ } catch (const BadFormatArg& ex) {
+ handleFormatStrError();
+ } catch (const std::range_error& ex) {
+ handleFormatStrError();
+ }
+}
+
+template <class Derived, bool containerMode, class... Args>
+template <class Output>
+void BaseFormatter<Derived, containerMode, Args...>::appendOutput(Output& out)
+ const {