X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FFormat.h;h=3837d1079e9636b31d529a32d39f990e0805057d;hb=598926c4529b459ce535657ec76ac792f4ec010e;hp=7c9929a9751411826d7b42a979e1b6090afb717d;hpb=e8d259542762e9611ce98724b14510c88dfa91dd;p=folly.git diff --git a/folly/Format.h b/folly/Format.h index 7c9929a9..3837d107 100644 --- a/folly/Format.h +++ b/folly/Format.h @@ -46,14 +46,15 @@ class FormatValue; // meta-attribute to identify formatters in this sea of template weirdness namespace detail { class FormatterTag {}; -}; +} // namespace detail /** * Formatter class. * - * Note that this class is tricky, as it keeps *references* to its arguments - * (and doesn't copy the passed-in format string). Thankfully, you can't use - * this directly, you have to use format(...) below. + * Note that this class is tricky, as it keeps *references* to its lvalue + * arguments (while it takes ownership of the temporaries), and it doesn't + * copy the passed-in format string. Thankfully, you can't use this + * directly, you have to use format(...) below. */ /* BaseFormatter class. @@ -103,14 +104,13 @@ class BaseFormatter { } /** - * metadata to identify generated children of BaseFormatter + * Metadata to identify generated children of BaseFormatter */ typedef detail::FormatterTag IsFormatter; typedef BaseFormatter BaseType; private: - typedef std::tuple::type>...> - ValueTuple; + typedef std::tuple ValueTuple; static constexpr size_t valueCount = std::tuple_size::value; Derived const& asDerived() const { @@ -166,7 +166,7 @@ class BaseFormatter { K::type getSizeArgFrom(size_t i, const FormatArg& arg) const { if (i == K) { - return getValue(std::get(values_), arg); + return getValue(getFormatValue(), arg); } return getSizeArgFrom(i, arg); } @@ -188,10 +188,19 @@ class BaseFormatter { // for the exclusive use of format() (below). This way, you can't create // a Formatter object, but can handle references to it (for streaming, // conversion to string, etc) -- which is good, as Formatter objects are - // dangerous (they hold references, possibly to temporaries) + // dangerous (they may hold references). BaseFormatter(BaseFormatter&&) = default; BaseFormatter& operator=(BaseFormatter&&) = default; + template + using ArgType = typename std::tuple_element::type; + + template + FormatValue>::type> getFormatValue() const { + return FormatValue>::type>( + std::get(values_)); + } + ValueTuple values_; }; @@ -213,7 +222,7 @@ class Formatter : public BaseFormatter< template void doFormatArg(FormatArg& arg, Callback& cb) const { - std::get(this->values_).format(arg, cb); + this->template getFormatValue().format(arg, cb); } friend class BaseFormatter< @@ -313,7 +322,7 @@ struct DefaultValueWrapper { const Container& container; const Value& defaultValue; }; -} // namespace +} // namespace detail template detail::DefaultValueWrapper defaulted( @@ -423,7 +432,7 @@ struct IsFormatter< typename std::enable_if< std::is_same::value>:: type> : public std::true_type {}; -} // folly::detail +} // namespace detail // Deprecated API. formatChecked() et. al. now behave identically to their // non-Checked counterparts.