Return rvalue references from &&-qualified members of dynamic
authorTom Jackson <tjackson@fb.com>
Fri, 16 Sep 2016 17:09:32 +0000 (10:09 -0700)
committerFacebook Github Bot 4 <facebook-github-bot-4-bot@fb.com>
Fri, 16 Sep 2016 17:23:30 +0000 (10:23 -0700)
Summary: Let the caller do a move, don't force one.

Reviewed By: yfeldblum

Differential Revision: D3873129

fbshipit-source-id: 40c6bf564bcbf794830c99ea1248a9c1bb30e9b0

folly/dynamic-inl.h
folly/dynamic.h
folly/test/DynamicTest.cpp

index ae48421723519649dbc74bf7e1c20ee42e09df84..909c5b28204f664b4199bb631f686ff47b70e66c 100644 (file)
@@ -437,7 +437,7 @@ inline double&   dynamic::getDouble() & { return get<double>(); }
 inline int64_t&  dynamic::getInt()    & { return get<int64_t>(); }
 inline bool&     dynamic::getBool()   & { return get<bool>(); }
 
-inline std::string dynamic::getString()&& {
+inline std::string&& dynamic::getString()&& {
   return std::move(get<std::string>());
 }
 inline double   dynamic::getDouble() && { return get<double>(); }
@@ -520,7 +520,7 @@ inline dynamic const& dynamic::operator[](dynamic const& idx) const& {
   return at(idx);
 }
 
-inline dynamic dynamic::operator[](dynamic const& idx) && {
+inline dynamic&& dynamic::operator[](dynamic const& idx) && {
   return std::move((*this)[idx]);
 }
 
@@ -549,7 +549,7 @@ inline dynamic& dynamic::at(dynamic const& idx) & {
   return const_cast<dynamic&>(const_cast<dynamic const*>(this)->at(idx));
 }
 
-inline dynamic dynamic::at(dynamic const& idx) && {
+inline dynamic&& dynamic::at(dynamic const& idx) && {
   return std::move(at(idx));
 }
 
index 19b0c2b05470e98ad900673ef4e61231bb7f73c5..7087975931b11b4300b2d2c25ed726cc638b92ce 100644 (file)
@@ -306,7 +306,7 @@ public:
   double&   getDouble() &;
   int64_t&  getInt() &;
   bool&     getBool() &;
-  std::string getString() &&;
+  std::string&& getString() &&;
   double   getDouble() &&;
   int64_t  getInt() &&;
   bool     getBool() &&;
@@ -383,7 +383,7 @@ public:
    */
   dynamic const& at(dynamic const&) const&;
   dynamic&       at(dynamic const&) &;
-  dynamic        at(dynamic const&) &&;
+  dynamic&&      at(dynamic const&) &&;
 
   /*
    * Like 'at', above, except it returns either a pointer to the contained
@@ -414,7 +414,7 @@ public:
    */
   dynamic&       operator[](dynamic const&) &;
   dynamic const& operator[](dynamic const&) const&;
-  dynamic        operator[](dynamic const&) &&;
+  dynamic&&      operator[](dynamic const&) &&;
 
   /*
    * Only defined for objects, throws TypeError otherwise.
index 624118e44872b2681f8de4459981aed91493c011..27d51dc66a2fea85a809ac6e02065f27170cf66d 100644 (file)
@@ -408,6 +408,9 @@ TEST(Dynamic, GetString) {
   EXPECT_EQ(s + " hello", d.getString());
 
   EXPECT_EQ(s, std::move(m).getString());
+  EXPECT_EQ(s, m.getString());
+  auto moved = std::move(m).getString();
+  EXPECT_EQ(s, moved);
   EXPECT_NE(dynamic(s), m);
 }
 
@@ -451,7 +454,10 @@ TEST(Dynamic, At) {
   EXPECT_EQ(dynamic(make_long_string() + " hello"), dd.at("key1"));
   EXPECT_EQ(dynamic(make_long_string() + " hello"), dd.at("key1"));
 
-  EXPECT_EQ(ds, std::move(md).at("key1"));
+  EXPECT_EQ(ds, std::move(md).at("key1")); // move available, but not performed
+  EXPECT_EQ(ds, md.at("key1"));
+  dynamic moved = std::move(md).at("key1"); // move performed
+  EXPECT_EQ(ds, moved);
   EXPECT_NE(ds, md.at("key1"));
 }
 
@@ -468,7 +474,10 @@ TEST(Dynamic, Brackets) {
   EXPECT_EQ(dynamic(make_long_string() + " hello"), dd["key1"]);
   EXPECT_EQ(dynamic(make_long_string() + " hello"), dd["key1"]);
 
-  EXPECT_EQ(ds, std::move(md)["key1"]);
+  EXPECT_EQ(ds, std::move(md)["key1"]); // move available, but not performed
+  EXPECT_EQ(ds, md["key1"]);
+  dynamic moved = std::move(md)["key1"]; // move performed
+  EXPECT_EQ(ds, moved);
   EXPECT_NE(ds, md["key1"]);
 }