/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define FOLLY_FORMATARG_H_
#include <stdexcept>
-#include "folly/Conv.h"
-#include "folly/Likely.h"
-#include "folly/Portability.h"
-#include "folly/Range.h"
+#include <folly/Conv.h>
+#include <folly/Likely.h>
+#include <folly/Portability.h>
+#include <folly/Range.h>
namespace folly {
+class BadFormatArg : public std::invalid_argument {
+ public:
+ explicit BadFormatArg(const std::string& msg)
+ : std::invalid_argument(msg) {}
+};
+
/**
* Parsed format argument.
*/
sign(Sign::DEFAULT),
basePrefix(false),
thousandsSeparator(false),
+ trailingDot(false),
width(kDefaultWidth),
precision(kDefaultPrecision),
presentation(kDefaultPresentation),
template <typename... Args>
std::string errorStr(Args&&... args) const;
template <typename... Args>
- void error(Args&&... args) const FOLLY_NORETURN;
+ FOLLY_NORETURN void error(Args&&... args) const;
/**
* Full argument string, as passed in to the constructor.
*/
bool thousandsSeparator;
+ /**
+ * Force a trailing decimal on doubles which could be rendered as ints
+ */
+ bool trailingDot;
+
/**
* Field width
*/
template <typename... Args>
inline void FormatArg::error(Args&&... args) const {
- throw std::invalid_argument(errorStr(std::forward<Args>(args)...));
+ throw BadFormatArg(errorStr(std::forward<Args>(args)...));
}
template <bool emptyOk>
inline StringPiece FormatArg::splitKey() {
- CHECK(nextKeyMode_ != NextKeyMode::INT) << errorStr("integer key expected");
+ enforce(nextKeyMode_ != NextKeyMode::INT, "integer key expected");
return doSplitKey<emptyOk>();
}
inline StringPiece FormatArg::doSplitKey() {
if (nextKeyMode_ == NextKeyMode::STRING) {
nextKeyMode_ = NextKeyMode::NONE;
- CHECK(emptyOk || !nextKey_.empty()) << errorStr("non-empty key required");
+ if (!emptyOk) { // static
+ enforce(!nextKey_.empty(), "non-empty key required");
+ }
return nextKey_;
}
if (key_.empty()) {
- CHECK(emptyOk) << errorStr("non-empty key required");
+ if (!emptyOk) { // static
+ error("non-empty key required");
+ }
return StringPiece();
}
if (e[-1] == ']') {
--e;
p = static_cast<const char*>(memchr(b, '[', e - b));
- CHECK(p) << errorStr("unmatched ']'");
+ enforce(p, "unmatched ']'");
} else {
p = static_cast<const char*>(memchr(b, '.', e - b));
}
p = e;
key_.clear();
}
- CHECK(emptyOk || b != p) << errorStr("non-empty key required");
-
+ if (!emptyOk) { // static
+ enforce(b != p, "non-empty key required");
+ }
return StringPiece(b, p);
}
try {
return to<int>(doSplitKey<true>());
} catch (const std::out_of_range& e) {
- LOG(FATAL) << errorStr("integer key required");
+ error("integer key required");
return 0; // unreached
}
}
} // namespace folly
#endif /* FOLLY_FORMATARG_H_ */
-