Avoid std::initializer_list ctor in folly::dynamic::array
authorYedidya Feldblum <yfeldblum@fb.com>
Mon, 23 May 2016 06:35:19 +0000 (23:35 -0700)
committerFacebook Github Bot 1 <facebook-github-bot-1-bot@fb.com>
Mon, 23 May 2016 06:38:25 +0000 (23:38 -0700)
Summary:
[Folly] Avoid `std::initializer_list` ctor in `folly::dynamic::array`.

This will help deprecate the dangerous initializer-list constructor. The init-list construction is dangerous because its semantics vary by compiler and by compiler version.

Reviewed By: ot

Differential Revision: D3333148

fbshipit-source-id: 031e7593b7e28b299d5eeeb5ce7aed9216dd3a5c

folly/dynamic-inl.h
folly/dynamic.h

index 91057eea2fc3d75a4d915d7688449c70d4dcf075..920f627c084e2661bbf94693d8d4a6d4b4632287 100644 (file)
@@ -209,8 +209,7 @@ inline void dynamic::array(EmptyArrayTag) {}
 
 template <class... Args>
 inline dynamic dynamic::array(Args&& ...args) {
-  return dynamic(std::initializer_list<dynamic>{std::forward<Args>(args)...},
-                 PrivateTag());
+  return dynamic(Array{std::forward<Args>(args)...}, PrivateTag());
 }
 
 // This looks like a case for perfect forwarding, but our use of
@@ -308,17 +307,10 @@ inline dynamic::dynamic(std::string&& s) : type_(STRING) {
 }
 
 inline dynamic::dynamic(std::initializer_list<dynamic> il)
-  : dynamic(std::move(il), PrivateTag()) {
-}
-
-inline dynamic::dynamic(std::initializer_list<dynamic> il, PrivateTag)
-  : type_(ARRAY)
-{
-  new (&u_.array) Array(il.begin(), il.end());
-}
+    : dynamic(Array(std::move(il)), PrivateTag()) {}
 
 inline dynamic& dynamic::operator=(std::initializer_list<dynamic> il) {
-  (*this) = dynamic(il, PrivateTag());
+  (*this) = dynamic(Array(std::move(il)), PrivateTag());
   return *this;
 }
 
@@ -668,6 +660,10 @@ inline void dynamic::pop_back() {
 
 //////////////////////////////////////////////////////////////////////
 
+inline dynamic::dynamic(Array&& r, PrivateTag) : type_(ARRAY) {
+  new (&u_.array) Array(std::move(r));
+}
+
 #define FOLLY_DYNAMIC_DEC_TYPEINFO(T, str, val) \
   template <> struct dynamic::TypeInfo<T> { \
     static constexpr const char* name = str; \
index ea407b303c621d9e83895a706273a2dd58854547..cc75cdfaf9c6dd88bafde4e2faca17aa300fd771 100644 (file)
@@ -179,7 +179,6 @@ public:
   FOLLY_DEPRECATED(
       "Initializer list syntax is deprecated (#10300209). Use dynamic::array.")
   /* implicit */ dynamic(std::initializer_list<dynamic> il);
-  dynamic(std::initializer_list<dynamic> il, PrivateTag);
   FOLLY_DEPRECATED(
       "Initializer list syntax is deprecated (#10300209). Use dynamic::array.")
   dynamic& operator=(std::initializer_list<dynamic> il);
@@ -536,6 +535,8 @@ private:
   template<class T> struct GetAddrImpl;
   template<class T> struct PrintImpl;
 
+  dynamic(Array&& array, PrivateTag);
+
   template<class T> T const& get() const;
   template<class T> T&       get();
   template<class T> T*       get_nothrow() & noexcept;