Make dynamic noexcept
[folly.git] / folly / FormatArg.h
index 99658121956bcfa9d0eaf276435d4f9bd3a13634..edd16a25cd25f141f1caf9d1e69489f7a706d4a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2014 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/Range.h"
-#include "folly/Likely.h"
-#include "folly/Conv.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.
  */
@@ -39,6 +46,7 @@ struct FormatArg {
       sign(Sign::DEFAULT),
       basePrefix(false),
       thousandsSeparator(false),
+      trailingDot(false),
       width(kDefaultWidth),
       precision(kDefaultPrecision),
       presentation(kDefaultPresentation),
@@ -71,7 +79,10 @@ struct FormatArg {
   }
 
   template <typename... Args>
-  void error(Args&&... args) const __attribute__((noreturn));
+  std::string errorStr(Args&&... args) const;
+  template <typename... Args>
+  FOLLY_NORETURN void error(Args&&... args) const;
+
   /**
    * Full argument string, as passed in to the constructor.
    */
@@ -118,6 +129,11 @@ struct FormatArg {
    */
   bool thousandsSeparator;
 
+  /**
+   * Force a trailing decimal on doubles which could be rendered as ints
+   */
+  bool trailingDot;
+
   /**
    * Field width
    */
@@ -184,11 +200,16 @@ struct FormatArg {
   NextKeyMode nextKeyMode_;
 };
 
+template <typename... Args>
+inline std::string FormatArg::errorStr(Args&&... args) const {
+  return to<std::string>(
+    "invalid format argument {", fullArgString, "}: ",
+    std::forward<Args>(args)...);
+}
+
 template <typename... Args>
 inline void FormatArg::error(Args&&... args) const {
-  throw std::invalid_argument(to<std::string>(
-      "folly::format: invalid format argument {", fullArgString, "}: ",
-      std::forward<Args>(args)...));
+  throw BadFormatArg(errorStr(std::forward<Args>(args)...));
 }
 
 template <bool emptyOk>
@@ -252,4 +273,3 @@ inline int FormatArg::splitIntKey() {
 }  // namespace folly
 
 #endif /* FOLLY_FORMATARG_H_ */
-