#error This file may only be included from Format.h.
#endif
-#include "folly/Exception.h"
-#include "folly/Traits.h"
+#include <folly/Exception.h>
+#include <folly/Traits.h>
// Ignore -Wformat-nonliteral warnings within this file
#pragma GCC diagnostic push
static const value_type& at(const C& c, int idx) {
return c.at(idx);
}
+
+ static const value_type& at(const C& c, int idx,
+ const value_type& dflt) {
+ return (idx >= 0 && idx < c.size()) ? c.at(idx) : dflt;
+ }
};
// Base class for associative types (maps)
static const value_type& at(const C& c, int idx) {
return c.at(static_cast<typename C::key_type>(idx));
}
+ static const value_type& at(const C& c, int idx,
+ const value_type& dflt) {
+ auto pos = c.find(static_cast<typename C::key_type>(idx));
+ return pos != c.end() ? pos->second : dflt;
+ }
};
// std::array
const T& val_;
};
+template <class Container, class Value>
+class FormatValue<
+ detail::DefaultValueWrapper<Container, Value>,
+ typename detail::IndexableTraits<Container>::enabled> {
+ public:
+ explicit FormatValue(const detail::DefaultValueWrapper<Container, Value>& val)
+ : val_(val) { }
+
+ template <class FormatCallback>
+ void format(FormatArg& arg, FormatCallback& cb) const {
+ FormatValue<typename std::decay<
+ typename detail::IndexableTraits<Container>::value_type>::type>(
+ detail::IndexableTraits<Container>::at(
+ val_.container,
+ arg.splitIntKey(),
+ val_.defaultValue)).format(arg, cb);
+ }
+
+ private:
+ const detail::DefaultValueWrapper<Container, Value>& val_;
+};
+
namespace detail {
// Define enabled, key_type, convert from StringPiece to the key types
static const value_type& at(const T& map, StringPiece key) {
return map.at(KeyFromStringPiece<key_type>::convert(key));
}
+ static const value_type& at(const T& map, StringPiece key,
+ const value_type& dflt) {
+ auto pos = map.find(KeyFromStringPiece<key_type>::convert(key));
+ return pos != map.end() ? pos->second : dflt;
+ }
};
// Define enabled, key_type, value_type, at() for supported string-keyed
const T& val_;
};
+template <class Container, class Value>
+class FormatValue<
+ detail::DefaultValueWrapper<Container, Value>,
+ typename detail::KeyableTraits<Container>::enabled> {
+ public:
+ explicit FormatValue(const detail::DefaultValueWrapper<Container, Value>& val)
+ : val_(val) { }
+
+ template <class FormatCallback>
+ void format(FormatArg& arg, FormatCallback& cb) const {
+ FormatValue<typename std::decay<
+ typename detail::KeyableTraits<Container>::value_type>::type>(
+ detail::KeyableTraits<Container>::at(
+ val_.container,
+ arg.splitKey(),
+ val_.defaultValue)).format(arg, cb);
+ }
+
+ private:
+ const detail::DefaultValueWrapper<Container, Value>& val_;
+};
+
// Partial specialization of FormatValue for pairs
template <class A, class B>
class FormatValue<std::pair<A, B>> {