Use FOLLY_DEPRECATED rather than directly using GCC specific attributes.
[folly.git] / folly / Format-inl.h
index 1239188cbe987900c047602c4dccb37a1f974e0e..ea9ce8752f06b7d8938ddd156a9e5310571fa386 100644 (file)
@@ -19,6 +19,7 @@
 #endif
 
 #include <array>
+#include <cinttypes>
 #include <deque>
 #include <map>
 #include <unordered_map>
@@ -225,6 +226,8 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(Output& out)
     int argIndex = 0;
     auto piece = arg.splitKey<true>();  // empty key component is okay
     if (containerMode) {  // static
+      arg.enforce(arg.width != FormatArg::kDynamicWidth,
+                  "dynamic field width not supported in vformat()");
       if (piece.empty()) {
         arg.setNextIntKey(nextArg++);
         hasDefaultArgIndex = true;
@@ -234,9 +237,22 @@ void BaseFormatter<Derived, containerMode, Args...>::operator()(Output& out)
       }
     } else {
       if (piece.empty()) {
+        if (arg.width == FormatArg::kDynamicWidth) {
+          arg.enforce(arg.widthIndex == FormatArg::kNoIndex,
+                      "cannot provide width arg index without value arg index");
+          int sizeArg = nextArg++;
+          arg.width = getSizeArg(sizeArg, arg);
+        }
+
         argIndex = nextArg++;
         hasDefaultArgIndex = true;
       } else {
+        if (arg.width == FormatArg::kDynamicWidth) {
+          arg.enforce(arg.widthIndex != FormatArg::kNoIndex,
+                      "cannot provide value arg index without width arg index");
+          arg.width = getSizeArg(arg.widthIndex, arg);
+        }
+
         try {
           argIndex = to<int>(piece);
         } catch (const std::out_of_range& e) {
@@ -402,6 +418,11 @@ class FormatValue<
   {
  public:
   explicit FormatValue(T val) : val_(val) { }
+
+  T getValue() const {
+    return val_;
+  }
+
   template <class FormatCallback>
   void format(FormatArg& arg, FormatCallback& cb) const {
     arg.validate(FormatArg::Type::INTEGER);
@@ -470,8 +491,24 @@ class FormatValue<
                   "' specifier");
 
       valBufBegin = valBuf + 3;  // room for sign and base prefix
+#ifdef _MSC_VER
+      char valBuf2[valBufSize];
+      snprintf(valBuf2, valBufSize, "%ju", static_cast<uintmax_t>(uval));
+      int len = GetNumberFormat(
+        LOCALE_USER_DEFAULT,
+        0,
+        valBuf2,
+        nullptr,
+        valBufBegin,
+        (int)((valBuf + valBufSize) - valBufBegin)
+      );
+#elif defined(__ANDROID__)
+      int len = snprintf(valBufBegin, (valBuf + valBufSize) - valBufBegin,
+                         "%" PRIuMAX, static_cast<uintmax_t>(uval));
+#else
       int len = snprintf(valBufBegin, (valBuf + valBufSize) - valBufBegin,
                          "%'ju", static_cast<uintmax_t>(uval));
+#endif
       // valBufSize should always be big enough, so this should never
       // happen.
       assert(len < valBuf + valBufSize - valBufBegin);