Use std::string in folly::dynamic
authorPavlo Kushnir <pavlo@fb.com>
Tue, 26 Apr 2016 09:27:37 +0000 (02:27 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Tue, 26 Apr 2016 09:35:20 +0000 (02:35 -0700)
Summary: Why not kill fbstring entirely? There are some legitimate use cases. For example, `folly::IOBuf` supports `moveToFbstring()` method which is impossible to implement with `std::string`.

Reviewed By: joeg, snarkmaster

Differential Revision: D3189410

fb-gh-sync-id: 9bb9090ca6012ac32ba9fb79041b26ec4888781f
fbshipit-source-id: 9bb9090ca6012ac32ba9fb79041b26ec4888781f

15 files changed:
folly/DynamicConverter.h
folly/Unicode.cpp
folly/Unicode.h
folly/dynamic-inl.h
folly/dynamic.cpp
folly/dynamic.h
folly/experimental/DynamicParser-inl.h
folly/experimental/DynamicParser.h
folly/experimental/JSONSchema.cpp
folly/experimental/StringKeyedUnorderedMap.h
folly/experimental/bser/Load.cpp
folly/json.cpp
folly/json.h
folly/test/DynamicTest.cpp
folly/test/JsonTest.cpp

index 591f55a..08b7260 100644 (file)
@@ -243,7 +243,7 @@ struct DynamicConverter<folly::fbstring> {
 template <>
 struct DynamicConverter<std::string> {
   static std::string convert(const dynamic& d) {
-    return d.asString().toStdString();
+    return d.asString();
   }
 };
 
index 493c899..c36bd07 100644 (file)
@@ -20,8 +20,8 @@ namespace folly {
 
 //////////////////////////////////////////////////////////////////////
 
-fbstring codePointToUtf8(char32_t cp) {
-  fbstring result;
+std::string codePointToUtf8(char32_t cp) {
+  std::string result;
 
   // Based on description from http://en.wikipedia.org/wiki/UTF-8.
 
index ecd0ae1..542dc10 100644 (file)
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include <folly/FBString.h>
+#include <string>
 
 namespace folly {
 
@@ -29,7 +29,7 @@ namespace folly {
  *
  * Return value is undefined if `cp' is an invalid code point.
  */
-fbstring codePointToUtf8(char32_t cp);
+std::string codePointToUtf8(char32_t cp);
 
 //////////////////////////////////////////////////////////////////////
 
index b357d3e..91057ee 100644 (file)
@@ -40,18 +40,35 @@ struct hash< ::folly::dynamic> {
 
 // This is a higher-order preprocessor macro to aid going from runtime
 // types to the compile time type system.
-#define FB_DYNAMIC_APPLY(type, apply) do {         \
-  switch ((type)) {                             \
-  case NULLT:   apply(void*);          break;   \
-  case ARRAY:   apply(Array);          break;   \
-  case BOOL:    apply(bool);           break;   \
-  case DOUBLE:  apply(double);         break;   \
-  case INT64:   apply(int64_t);        break;   \
-  case OBJECT:  apply(ObjectImpl);     break;   \
-  case STRING:  apply(fbstring);       break;   \
-  default:      CHECK(0); abort();              \
-  }                                             \
-} while (0)
+#define FB_DYNAMIC_APPLY(type, apply) \
+  do {                                \
+    switch ((type)) {                 \
+      case NULLT:                     \
+        apply(void*);                 \
+        break;                        \
+      case ARRAY:                     \
+        apply(Array);                 \
+        break;                        \
+      case BOOL:                      \
+        apply(bool);                  \
+        break;                        \
+      case DOUBLE:                    \
+        apply(double);                \
+        break;                        \
+      case INT64:                     \
+        apply(int64_t);               \
+        break;                        \
+      case OBJECT:                    \
+        apply(ObjectImpl);            \
+        break;                        \
+      case STRING:                    \
+        apply(std::string);           \
+        break;                        \
+      default:                        \
+        CHECK(0);                     \
+        abort();                      \
+    }                                 \
+  } while (0)
 
 //////////////////////////////////////////////////////////////////////
 
@@ -271,31 +288,23 @@ inline dynamic::dynamic(ObjectMaker (*)())
 inline dynamic::dynamic(StringPiece s)
   : type_(STRING)
 {
-  new (&u_.string) fbstring(s.data(), s.size());
+  new (&u_.string) std::string(s.data(), s.size());
 }
 
 inline dynamic::dynamic(char const* s)
   : type_(STRING)
 {
-  new (&u_.string) fbstring(s);
+  new (&u_.string) std::string(s);
 }
 
 inline dynamic::dynamic(std::string const& s)
   : type_(STRING)
 {
-  new (&u_.string) fbstring(s);
+  new (&u_.string) std::string(s);
 }
 
-inline dynamic::dynamic(fbstring const& s)
-  : type_(STRING)
-{
-  new (&u_.string) fbstring(s);
-}
-
-inline dynamic::dynamic(fbstring&& s)
-  : type_(STRING)
-{
-  new (&u_.string) fbstring(std::move(s));
+inline dynamic::dynamic(std::string&& s) : type_(STRING) {
+  new (&u_.string) std::string(std::move(s));
 }
 
 inline dynamic::dynamic(std::initializer_list<dynamic> il)
@@ -391,7 +400,9 @@ inline dynamic::IterableProxy<dynamic::const_item_iterator> dynamic::items()
   return &(get<ObjectImpl>());
 }
 
-inline bool dynamic::isString() const { return get_nothrow<fbstring>(); }
+inline bool dynamic::isString() const {
+  return get_nothrow<std::string>();
+}
 inline bool dynamic::isObject() const { return get_nothrow<ObjectImpl>(); }
 inline bool dynamic::isBool()   const { return get_nothrow<bool>(); }
 inline bool dynamic::isArray()  const { return get_nothrow<Array>(); }
@@ -404,29 +415,49 @@ inline dynamic::Type dynamic::type() const {
   return type_;
 }
 
-inline fbstring dynamic::asString() const { return asImpl<fbstring>(); }
-inline double   dynamic::asDouble() const { return asImpl<double>(); }
-inline int64_t  dynamic::asInt()    const { return asImpl<int64_t>(); }
-inline bool     dynamic::asBool()   const { return asImpl<bool>(); }
+inline std::string dynamic::asString() const {
+  return asImpl<std::string>();
+}
+inline double dynamic::asDouble() const {
+  return asImpl<double>();
+}
+inline int64_t dynamic::asInt() const {
+  return asImpl<int64_t>();
+}
+inline bool dynamic::asBool() const {
+  return asImpl<bool>();
+}
 
-inline const fbstring& dynamic::getString() const& { return get<fbstring>(); }
+inline const std::string& dynamic::getString() const& {
+  return get<std::string>();
+}
 inline double          dynamic::getDouble() const& { return get<double>(); }
 inline int64_t         dynamic::getInt()    const& { return get<int64_t>(); }
 inline bool            dynamic::getBool()   const& { return get<bool>(); }
 
-inline fbstring& dynamic::getString() & { return get<fbstring>(); }
+inline std::string& dynamic::getString()& {
+  return get<std::string>();
+}
 inline double&   dynamic::getDouble() & { return get<double>(); }
 inline int64_t&  dynamic::getInt()    & { return get<int64_t>(); }
 inline bool&     dynamic::getBool()   & { return get<bool>(); }
 
-inline fbstring dynamic::getString() && { return std::move(get<fbstring>()); }
+inline std::string dynamic::getString()&& {
+  return std::move(get<std::string>());
+}
 inline double   dynamic::getDouble() && { return get<double>(); }
 inline int64_t  dynamic::getInt()    && { return get<int64_t>(); }
 inline bool     dynamic::getBool()   && { return get<bool>(); }
 
-inline const char* dynamic::data()  const& { return get<fbstring>().data();  }
-inline const char* dynamic::c_str() const& { return get<fbstring>().c_str(); }
-inline StringPiece dynamic::stringPiece() const { return get<fbstring>(); }
+inline const char* dynamic::data() const& {
+  return get<std::string>().data();
+}
+inline const char* dynamic::c_str() const& {
+  return get<std::string>().c_str();
+}
+inline StringPiece dynamic::stringPiece() const {
+  return get<std::string>();
+}
 
 template<class T>
 struct dynamic::CompareOp {
@@ -442,7 +473,7 @@ struct dynamic::CompareOp<dynamic::ObjectImpl> {
 
 inline dynamic& dynamic::operator+=(dynamic const& o) {
   if (type() == STRING && o.type() == STRING) {
-    *getAddress<fbstring>() += *o.getAddress<fbstring>();
+    *getAddress<std::string>() += *o.getAddress<std::string>();
     return *this;
   }
   *this = detail::numericOp<std::plus>(*this, o);
@@ -646,7 +677,7 @@ inline void dynamic::pop_back() {
 
 FOLLY_DYNAMIC_DEC_TYPEINFO(void*,               "null",    dynamic::NULLT)
 FOLLY_DYNAMIC_DEC_TYPEINFO(bool,                "boolean", dynamic::BOOL)
-FOLLY_DYNAMIC_DEC_TYPEINFO(fbstring,            "string",  dynamic::STRING)
+FOLLY_DYNAMIC_DEC_TYPEINFO(std::string, "string", dynamic::STRING)
 FOLLY_DYNAMIC_DEC_TYPEINFO(dynamic::Array,      "array",   dynamic::ARRAY)
 FOLLY_DYNAMIC_DEC_TYPEINFO(double,              "double",  dynamic::DOUBLE)
 FOLLY_DYNAMIC_DEC_TYPEINFO(int64_t,             "int64",   dynamic::INT64)
@@ -660,7 +691,8 @@ T dynamic::asImpl() const {
   case INT64:    return to<T>(*get_nothrow<int64_t>());
   case DOUBLE:   return to<T>(*get_nothrow<double>());
   case BOOL:     return to<T>(*get_nothrow<bool>());
-  case STRING:   return to<T>(*get_nothrow<fbstring>());
+  case STRING:
+    return to<T>(*get_nothrow<std::string>());
   default:
     throw TypeError("int/double/bool/string", type());
   }
@@ -708,8 +740,11 @@ template<> struct dynamic::GetAddrImpl<int64_t> {
 template<> struct dynamic::GetAddrImpl<double> {
   static double* get(Data& d) noexcept { return &d.doubl; }
 };
-template<> struct dynamic::GetAddrImpl<fbstring> {
-  static fbstring* get(Data& d) noexcept { return &d.string; }
+template <>
+struct dynamic::GetAddrImpl<std::string> {
+  static std::string* get(Data& d) noexcept {
+    return &d.string;
+  }
 };
 template<> struct dynamic::GetAddrImpl<dynamic::ObjectImpl> {
   static_assert(sizeof(ObjectImpl) <= sizeof(Data::objectBuffer),
@@ -807,7 +842,7 @@ class FormatValue<dynamic> {
       FormatValue<int64_t>(val_.asInt()).format(arg, cb);
       break;
     case dynamic::STRING:
-      FormatValue<fbstring>(val_.asString()).format(arg, cb);
+      FormatValue<std::string>(val_.asString()).format(arg, cb);
       break;
     case dynamic::DOUBLE:
       FormatValue<double>(val_.asDouble()).format(arg, cb);
@@ -816,7 +851,7 @@ class FormatValue<dynamic> {
       FormatValue(val_.at(arg.splitIntKey())).format(arg, cb);
       break;
     case dynamic::OBJECT:
-      FormatValue(val_.at(arg.splitKey().toFbstring())).format(arg, cb);
+      FormatValue(val_.at(arg.splitKey().toString())).format(arg, cb);
       break;
     }
   }
index 94f8760..7015d8b 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <folly/dynamic.h>
+#include <folly/Hash.h>
 
 namespace folly {
 
@@ -27,7 +28,7 @@ namespace folly {
 
 FOLLY_DYNAMIC_DEF_TYPEINFO(void*)
 FOLLY_DYNAMIC_DEF_TYPEINFO(bool)
-FOLLY_DYNAMIC_DEF_TYPEINFO(fbstring)
+FOLLY_DYNAMIC_DEF_TYPEINFO(std::string)
 FOLLY_DYNAMIC_DEF_TYPEINFO(dynamic::Array)
 FOLLY_DYNAMIC_DEF_TYPEINFO(double)
 FOLLY_DYNAMIC_DEF_TYPEINFO(int64_t)
@@ -57,18 +58,35 @@ TypeError::~TypeError() = default;
 
 // This is a higher-order preprocessor macro to aid going from runtime
 // types to the compile time type system.
-#define FB_DYNAMIC_APPLY(type, apply) do {         \
-  switch ((type)) {                             \
-  case NULLT:   apply(void*);          break;   \
-  case ARRAY:   apply(Array);          break;   \
-  case BOOL:    apply(bool);           break;   \
-  case DOUBLE:  apply(double);         break;   \
-  case INT64:   apply(int64_t);        break;   \
-  case OBJECT:  apply(ObjectImpl);     break;   \
-  case STRING:  apply(fbstring);       break;   \
-  default:      CHECK(0); abort();              \
-  }                                             \
-} while (0)
+#define FB_DYNAMIC_APPLY(type, apply) \
+  do {                                \
+    switch ((type)) {                 \
+      case NULLT:                     \
+        apply(void*);                 \
+        break;                        \
+      case ARRAY:                     \
+        apply(Array);                 \
+        break;                        \
+      case BOOL:                      \
+        apply(bool);                  \
+        break;                        \
+      case DOUBLE:                    \
+        apply(double);                \
+        break;                        \
+      case INT64:                     \
+        apply(int64_t);               \
+        break;                        \
+      case OBJECT:                    \
+        apply(ObjectImpl);            \
+        break;                        \
+      case STRING:                    \
+        apply(std::string);           \
+        break;                        \
+      default:                        \
+        CHECK(0);                     \
+        abort();                      \
+    }                                 \
+  } while (0)
 
 bool dynamic::operator<(dynamic const& o) const {
   if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) {
@@ -227,7 +245,7 @@ std::size_t dynamic::size() const {
   if (auto* obj = get_nothrow<ObjectImpl>()) {
     return obj->size();
   }
-  if (auto* str = get_nothrow<fbstring>()) {
+  if (auto* str = get_nothrow<std::string>()) {
     return str->size();
   }
   throw TypeError("array/object", type());
@@ -248,13 +266,16 @@ std::size_t dynamic::hash() const {
   case NULLT:
     throw TypeError("not null/object/array", type());
   case INT64:
-    return std::hash<int64_t>()(asInt());
+    return std::hash<int64_t>()(getInt());
   case DOUBLE:
-    return std::hash<double>()(asDouble());
+    return std::hash<double>()(getDouble());
   case BOOL:
-    return std::hash<bool>()(asBool());
-  case STRING:
-    return std::hash<fbstring>()(asString());
+    return std::hash<bool>()(getBool());
+  case STRING: {
+    // keep it compatible with FBString
+    const auto& str = getString();
+    return ::folly::hash::fnv32_buf(str.data(), str.size());
+  }
   default:
     CHECK(0); abort();
   }
index c2ab2a4..ea407b3 100644 (file)
@@ -74,7 +74,6 @@
 
 #include <boost/operators.hpp>
 
-#include <folly/FBString.h>
 #include <folly/Range.h>
 #include <folly/Traits.h>
 
@@ -157,8 +156,7 @@ public:
   /* implicit */ dynamic(StringPiece val);
   /* implicit */ dynamic(char const* val);
   /* implicit */ dynamic(std::string const& val);
-  /* implicit */ dynamic(fbstring const& val);
-  /* implicit */ dynamic(fbstring&& val);
+  /* implicit */ dynamic(std::string&& val);
 
   /*
    * This is part of the plumbing for array() and object(), above.
@@ -291,7 +289,7 @@ public:
    * since arrays and objects are generally best dealt with as a
    * dynamic.
    */
-  fbstring asString() const;
+  std::string asString() const;
   double   asDouble() const;
   int64_t  asInt() const;
   bool     asBool() const;
@@ -301,15 +299,15 @@ public:
    *
    * These will throw a TypeError if the dynamic has a different type.
    */
-  const fbstring& getString() const&;
+  const std::string& getString() const&;
   double          getDouble() const&;
   int64_t         getInt() const&;
   bool            getBool() const&;
-  fbstring& getString() &;
+  std::string& getString() &;
   double&   getDouble() &;
   int64_t&  getInt() &;
   bool&     getBool() &;
-  fbstring getString() &&;
+  std::string getString() &&;
   double   getDouble() &&;
   int64_t  getInt() &&;
   bool     getBool() &&;
@@ -566,7 +564,7 @@ private:
     bool boolean;
     double doubl;
     int64_t integer;
-    fbstring string;
+    std::string string;
 
     /*
      * Objects are placement new'd here.  We have to use a char buffer
index 7620f72..f3dc0c3 100644 (file)
@@ -125,7 +125,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
 // std::string
 template <typename Fn> EnableForArgTypes<Fn, std::string>
 invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
-  fn(v.asString().toStdString());
+  fn(v.asString());
 }
 
 //
@@ -157,7 +157,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
 // folly::dynamic, std::string
 template <typename Fn> EnableForArgTypes<Fn, folly::dynamic, std::string>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k, v.asString().toStdString());
+  fn(k, v.asString());
 }
 
 // Convert the key to std::string.
@@ -165,27 +165,27 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
 // std::string, folly::dynamic (no conversion of value)
 template <typename Fn> EnableForArgTypes<Fn, std::string, folly::dynamic>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asString().toStdString(), v);
+  fn(k.asString(), v);
 }
 // std::string, int64_t
 template <typename Fn> EnableForArgTypes<Fn, std::string, int64_t>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asString().toStdString(), v.asInt());
+  fn(k.asString(), v.asInt());
 }
 // std::string, bool
 template <typename Fn> EnableForArgTypes<Fn, std::string, bool>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asString().toStdString(), v.asBool());
+  fn(k.asString(), v.asBool());
 }
 // std::string, double
 template <typename Fn> EnableForArgTypes<Fn, std::string, double>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asString().toStdString(), v.asDouble());
+  fn(k.asString(), v.asDouble());
 }
 // std::string, std::string
 template <typename Fn> EnableForArgTypes<Fn, std::string, std::string>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asString().toStdString(), v.asString().toStdString());
+  fn(k.asString(), v.asString());
 }
 
 // Convert the key to int64_t (good for arrays).
@@ -213,7 +213,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
 // int64_t, std::string
 template <typename Fn> EnableForArgTypes<Fn, int64_t, std::string>
 invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
-  fn(k.asInt(), v.asString().toStdString());
+  fn(k.asInt(), v.asString());
 }
 }  // namespace detail
 
index 0509f8a..4124d8c 100644 (file)
@@ -97,7 +97,7 @@ namespace folly {
  * NB: The key alone should be rarely needed, but these callback styles
  *     provide it with no conversion overhead, and only minimal verbosity:
  *       [&](const std::string& k, const folly::dynamic&) {}
- *       [&]() { auto k = p.key().asString().toStdString(); }
+ *       [&]() { auto k = p.key().asString(); }
  *
  * == How `releaseErrors()` can make your parse lossless ==
  *
index 96d53d5..a550cee 100644 (file)
@@ -95,7 +95,7 @@ struct SchemaValidatorContext final {
   explicit SchemaValidatorContext(const dynamic& s) : schema(s) {}
 
   const dynamic& schema;
-  std::unordered_map<fbstring, IValidator*> refs;
+  std::unordered_map<std::string, IValidator*> refs;
 };
 
 /**
@@ -231,7 +231,7 @@ struct SizeValidator final : IValidator {
 struct StringPatternValidator final : IValidator {
   explicit StringPatternValidator(const dynamic& schema) {
     if (schema.isString()) {
-      regex_ = boost::regex(schema.getString().toStdString());
+      regex_ = boost::regex(schema.getString());
     }
   }
 
@@ -240,7 +240,7 @@ struct StringPatternValidator final : IValidator {
     if (!value.isString() || regex_.empty()) {
       return none;
     }
-    if (!boost::regex_search(value.getString().toStdString(), regex_)) {
+    if (!boost::regex_search(value.getString(), regex_)) {
       return makeError("string matching regex", value);
     }
     return none;
@@ -360,7 +360,7 @@ struct RequiredValidator final : IValidator {
   }
 
  private:
-  std::vector<fbstring> properties_;
+  std::vector<std::string> properties_;
 };
 
 struct PropertiesValidator final : IValidator {
@@ -381,7 +381,7 @@ struct PropertiesValidator final : IValidator {
       for (const auto& pair : patternProperties->items()) {
         if (pair.first.isString()) {
           patternPropertyValidators_.emplace_back(
-              boost::regex(pair.first.getString().toStdString()),
+              boost::regex(pair.first.getString()),
               SchemaValidator::make(context, pair.second));
         }
       }
@@ -405,7 +405,7 @@ struct PropertiesValidator final : IValidator {
       if (!pair.first.isString()) {
         continue;
       }
-      const fbstring& key = pair.first.getString();
+      const std::string& key = pair.first.getString();
       auto it = propertyValidators_.find(key);
       bool matched = false;
       if (it != propertyValidators_.end()) {
@@ -415,7 +415,7 @@ struct PropertiesValidator final : IValidator {
         matched = true;
       }
 
-      const std::string& strkey = key.toStdString();
+      const std::string& strkey = key;
       for (const auto& ppv : patternPropertyValidators_) {
         if (boost::regex_search(strkey, ppv.first)) {
           if (auto se = vc.validate(ppv.second.get(), pair.second)) {
@@ -440,7 +440,8 @@ struct PropertiesValidator final : IValidator {
     return none;
   }
 
-  std::unordered_map<fbstring, std::unique_ptr<IValidator>> propertyValidators_;
+  std::unordered_map<std::string, std::unique_ptr<IValidator>>
+      propertyValidators_;
   std::vector<std::pair<boost::regex, std::unique_ptr<IValidator>>>
       patternPropertyValidators_;
   std::unique_ptr<IValidator> additionalPropertyValidator_;
@@ -457,7 +458,7 @@ struct DependencyValidator final : IValidator {
         continue;
       }
       if (pair.second.isArray()) {
-        auto p = make_pair(pair.first.getString(), std::vector<fbstring>());
+        auto p = make_pair(pair.first.getString(), std::vector<std::string>());
         for (const auto& item : pair.second) {
           if (item.isString()) {
             p.second.push_back(item.getString());
@@ -496,8 +497,8 @@ struct DependencyValidator final : IValidator {
     return none;
   }
 
-  std::vector<std::pair<fbstring, std::vector<fbstring>>> propertyDep_;
-  std::vector<std::pair<fbstring, std::unique_ptr<IValidator>>> schemaDep_;
+  std::vector<std::pair<std::string, std::vector<std::string>>> propertyDep_;
+  std::vector<std::pair<std::string, std::unique_ptr<IValidator>>> schemaDep_;
 };
 
 struct EnumValidator final : IValidator {
index 59aa139..475c1ae 100644 (file)
@@ -164,6 +164,7 @@ public:
 
   using Base::at;
   using Base::find;
+  using Base::count;
 
   template <class... Args>
   std::pair<iterator, bool> emplace(StringPiece key, Args&&... args) {
index 9898de8..4d311f9 100644 (file)
@@ -49,9 +49,9 @@ static int64_t decodeInt(Cursor& curs) {
   }
 }
 
-static fbstring decodeString(Cursor& curs) {
+static std::string decodeString(Cursor& curs) {
   auto len = decodeInt(curs);
-  folly::fbstring str;
+  std::string str;
 
   if (len < 0) {
     throw std::range_error("string length must not be negative");
index a2b81d5..9d2a536 100644 (file)
@@ -118,13 +118,11 @@ char32_t decodeUtf8(
 }
 
 struct Printer {
-  explicit Printer(fbstring& out,
-                   unsigned* indentLevel,
-                   serialization_opts const* opts)
-    : out_(out)
-    , indentLevel_(indentLevel)
-    , opts_(*opts)
-  {}
+  explicit Printer(
+      std::string& out,
+      unsigned* indentLevel,
+      serialization_opts const* opts)
+      : out_(out), indentLevel_(indentLevel), opts_(*opts) {}
 
   void operator()(dynamic const& v) const {
     switch (v.type()) {
@@ -244,7 +242,7 @@ private:
 
   void newline() const {
     if (indentLevel_) {
-      out_ += to<fbstring>('\n', fbstring(*indentLevel_ * 2, ' '));
+      out_ += to<std::string>('\n', std::string(*indentLevel_ * 2, ' '));
     }
   }
 
@@ -253,9 +251,9 @@ private:
   }
 
 private:
 fbstring& out_;
 unsigned* const indentLevel_;
 serialization_opts const& opts_;
std::string& out_;
+ unsigned* const indentLevel_;
+ serialization_opts const& opts_;
 };
 
   //////////////////////////////////////////////////////////////////////
@@ -394,7 +392,7 @@ private:
 };
 
 dynamic parseValue(Input& in);
-fbstring parseString(Input& in);
+std::string parseString(Input& in);
 dynamic parseNumber(Input& in);
 
 dynamic parseObject(Input& in) {
@@ -527,7 +525,7 @@ dynamic parseNumber(Input& in) {
   return val;
 }
 
-fbstring decodeUnicodeEscape(Input& in) {
+std::string decodeUnicodeEscape(Input& in) {
   auto hexVal = [&] (char c) -> unsigned {
     return c >= '0' && c <= '9' ? c - '0' :
            c >= 'a' && c <= 'f' ? c - 'a' + 10 :
@@ -575,11 +573,11 @@ fbstring decodeUnicodeEscape(Input& in) {
   return codePointToUtf8(codePoint);
 }
 
-fbstring parseString(Input& in) {
+std::string parseString(Input& in) {
   assert(*in == '\"');
   ++in;
 
-  fbstring ret;
+  std::string ret;
   for (;;) {
     auto range = in.skipWhile(
       [] (char c) { return c != '\"' && c != '\\'; }
@@ -602,8 +600,8 @@ fbstring parseString(Input& in) {
       case 'r':     ret.push_back('\r'); ++in; break;
       case 't':     ret.push_back('\t'); ++in; break;
       case 'u':     ++in; ret += decodeUnicodeEscape(in); break;
-      default:      in.error(to<fbstring>("unknown escape ", *in,
-                                          " in string").c_str());
+      default:
+        in.error(to<std::string>("unknown escape ", *in, " in string").c_str());
       }
       continue;
     }
@@ -650,8 +648,8 @@ dynamic parseValue(Input& in) {
 
 //////////////////////////////////////////////////////////////////////
 
-fbstring serialize(dynamic const& dyn, serialization_opts const& opts) {
-  fbstring ret;
+std::string serialize(dynamic const& dyn, serialization_opts const& opts) {
+  std::string ret;
   unsigned indentLevel = 0;
   Printer p(ret, opts.pretty_formatting ? &indentLevel : nullptr, &opts);
   p(dyn);
@@ -659,9 +657,10 @@ fbstring serialize(dynamic const& dyn, serialization_opts const& opts) {
 }
 
 // Escape a string so that it is legal to print it in JSON text.
-void escapeString(StringPiece input,
-                  fbstring& out,
-                  const serialization_opts& opts) {
+void escapeString(
+    StringPiece input,
+    std::string& out,
+    const serialization_opts& opts) {
   auto hexDigit = [] (int c) -> char {
     return c < 10 ? c + '0' : c - 10 + 'a';
   };
@@ -732,8 +731,8 @@ void escapeString(StringPiece input,
   out.push_back('\"');
 }
 
-fbstring stripComments(StringPiece jsonC) {
-  fbstring result;
+std::string stripComments(StringPiece jsonC) {
+  std::string result;
   enum class State {
     None,
     InString,
@@ -813,11 +812,11 @@ dynamic parseJson(
   return ret;
 }
 
-fbstring toJson(dynamic const& dyn) {
+std::string toJson(dynamic const& dyn) {
   return json::serialize(dyn, json::serialization_opts());
 }
 
-fbstring toPrettyJson(dynamic const& dyn) {
+std::string toPrettyJson(dynamic const& dyn) {
   json::serialization_opts opts;
   opts.pretty_formatting = true;
   return json::serialize(dyn, opts);
index b3ed871..272d610 100644 (file)
@@ -41,9 +41,9 @@
 #pragma once
 
 #include <iosfwd>
+#include <string>
 
 #include <folly/dynamic.h>
-#include <folly/FBString.h>
 #include <folly/Range.h>
 
 namespace folly {
@@ -122,21 +122,22 @@ namespace json {
    * For the most common use cases there are simpler functions in the
    * main folly namespace below.
    */
-  fbstring serialize(dynamic const&, serialization_opts const&);
+  std::string serialize(dynamic const&, serialization_opts const&);
 
   /*
    * Escape a string so that it is legal to print it in JSON text and
    * append the result to out.
    */
 
-  void escapeString(StringPiece input,
-                    fbstring& out,
-                    const serialization_opts& opts);
+  void escapeString(
+      StringPiece input,
+      std::string& out,
+      const serialization_opts& opts);
 
   /*
    * Strip all C99-like comments (i.e. // and / * ... * /)
    */
-  fbstring stripComments(StringPiece jsonC);
+  std::string stripComments(StringPiece jsonC);
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -151,13 +152,13 @@ dynamic parseJson(StringPiece);
 /*
  * Serialize a dynamic into a json string.
  */
-fbstring toJson(dynamic const&);
+std::string toJson(dynamic const&);
 
 /*
  * Same as the above, except format the json with some minimal
  * indentation.
  */
-fbstring toPrettyJson(dynamic const&);
+std::string toPrettyJson(dynamic const&);
 
 /*
  * Printer for GTest.
index fcae9a1..0fa5bdc 100644 (file)
@@ -50,7 +50,7 @@ TEST(Dynamic, ObjectBasics) {
 
   EXPECT_EQ(*newObject.keys().begin(), newObject.items().begin()->first);
   EXPECT_EQ(*newObject.values().begin(), newObject.items().begin()->second);
-  std::vector<std::pair<folly::fbstring, dynamic>> found;
+  std::vector<std::pair<std::string, dynamic>> found;
   found.emplace_back(newObject.keys().begin()->asString(),
                      *newObject.values().begin());
 
@@ -353,8 +353,8 @@ TEST(Dynamic, Assignment) {
   }
 }
 
-folly::fbstring make_long_string() {
-  return folly::fbstring(100, 'a');
+std::string make_long_string() {
+  return std::string(100, 'a');
 }
 
 TEST(Dynamic, GetDefault) {
index 7f69c49..64430ff 100644 (file)
@@ -155,14 +155,14 @@ TEST(Json, BoolConversion) {
 TEST(Json, JavascriptSafe) {
   auto badDouble = (1ll << 63ll) + 1;
   dynamic badDyn = badDouble;
-  EXPECT_EQ(folly::toJson(badDouble), folly::to<folly::fbstring>(badDouble));
+  EXPECT_EQ(folly::toJson(badDouble), folly::to<std::string>(badDouble));
   folly::json::serialization_opts opts;
   opts.javascript_safe = true;
   EXPECT_ANY_THROW(folly::json::serialize(badDouble, opts));
 
   auto okDouble = 1ll << 63ll;
   dynamic okDyn = okDouble;
-  EXPECT_EQ(folly::toJson(okDouble), folly::to<folly::fbstring>(okDouble));
+  EXPECT_EQ(folly::toJson(okDouble), folly::to<std::string>(okDouble));
 }
 
 TEST(Json, Produce) {
@@ -178,10 +178,8 @@ TEST(Json, Produce) {
   // Check Infinity/Nan
   folly::json::serialization_opts opts;
   opts.allow_nan_inf = true;
-  EXPECT_EQ("Infinity",
-            folly::json::serialize(parseJson("Infinity"), opts).toStdString());
-  EXPECT_EQ("NaN",
-            folly::json::serialize(parseJson("NaN"), opts).toStdString());
+  EXPECT_EQ("Infinity", folly::json::serialize(parseJson("Infinity"), opts));
+  EXPECT_EQ("NaN", folly::json::serialize(parseJson("NaN"), opts));
 }
 
 TEST(Json, JsonEscape) {
@@ -260,10 +258,10 @@ TEST(Json, JsonNonAsciiEncoding) {
 TEST(Json, UTF8Retention) {
 
   // test retention with valid utf8 strings
-  folly::fbstring input = "\u2665";
-  folly::fbstring jsonInput = folly::toJson(input);
-  folly::fbstring output = folly::parseJson(jsonInput).asString();
-  folly::fbstring jsonOutput = folly::toJson(output);
+  std::string input = "\u2665";
+  std::string jsonInput = folly::toJson(input);
+  std::string output = folly::parseJson(jsonInput).asString();
+  std::string jsonOutput = folly::toJson(output);
 
   EXPECT_EQ(input, output);
   EXPECT_EQ(jsonInput, jsonOutput);
@@ -282,10 +280,10 @@ TEST(Json, UTF8EncodeNonAsciiRetention) {
   opts.encode_non_ascii = true;
 
   // test encode_non_ascii valid utf8 strings
-  folly::fbstring input = "\u2665";
-  folly::fbstring jsonInput = folly::json::serialize(input, opts);
-  folly::fbstring output = folly::parseJson(jsonInput).asString();
-  folly::fbstring jsonOutput = folly::json::serialize(output, opts);
+  std::string input = "\u2665";
+  std::string jsonInput = folly::json::serialize(input, opts);
+  std::string output = folly::parseJson(jsonInput).asString();
+  std::string jsonOutput = folly::json::serialize(output, opts);
 
   EXPECT_EQ(input, output);
   EXPECT_EQ(jsonInput, jsonOutput);
@@ -402,7 +400,7 @@ TEST(Json, ParseDoubleFallback) {
 TEST(Json, ParseNumbersAsStrings) {
   folly::json::serialization_opts opts;
   opts.parse_numbers_as_strings = true;
-  auto parse = [&](folly::fbstring number) {
+  auto parse = [&](std::string number) {
     return parseJson(number, opts).asString();
   };