Make dynamic::object callable with initializer lists
authorJordan DeLong <jdelong@fb.com>
Mon, 17 Dec 2012 19:12:47 +0000 (11:12 -0800)
committerJordan DeLong <jdelong@fb.com>
Sat, 19 Jan 2013 00:37:10 +0000 (16:37 -0800)
Summary:
Using perfect forwarding here prevents the ability to create
dynamic arrays.

Test Plan: Added unit test case that compiles now with this.

Reviewed By: tudorb@fb.com

FB internal diff: D660662

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

index 4a9d99107c097cb9cc712883b312440fc0e24714..34b988e7d86fbc029536b4c023e507d5506a5feb 100644 (file)
@@ -197,9 +197,22 @@ private:
   dynamic val_;
 };
 
-template<class... Args>
-inline dynamic::ObjectMaker dynamic::object(Args&&... args) {
-  return dynamic::ObjectMaker(std::forward<Args>(args)...);
+// This looks like a case for perfect forwarding, but our use of
+// std::initializer_list for constructing dynamic arrays makes it less
+// functional than doing this manually.
+inline dynamic::ObjectMaker dynamic::object() { return ObjectMaker(); }
+inline dynamic::ObjectMaker dynamic::object(dynamic&& a, dynamic&& b) {
+  return ObjectMaker(std::move(a), std::move(b));
+}
+inline dynamic::ObjectMaker dynamic::object(dynamic const& a, dynamic&& b) {
+  return ObjectMaker(a, std::move(b));
+}
+inline dynamic::ObjectMaker dynamic::object(dynamic&& a, dynamic const& b) {
+  return ObjectMaker(std::move(a), b);
+}
+inline dynamic::ObjectMaker
+dynamic::object(dynamic const& a, dynamic const& b) {
+  return ObjectMaker(a, b);
 }
 
 //////////////////////////////////////////////////////////////////////
index 4f02bd0c000b6139fcfe0954d0c6dd82475651cb..c0cdc6261ae9225e1e018215447e2a7ad9304c46 100644 (file)
@@ -133,7 +133,11 @@ private:
   struct ObjectMaker;
 
 public:
-  template<class... Args> static ObjectMaker object(Args&&...);
+  static ObjectMaker object();
+  static ObjectMaker object(dynamic&&, dynamic&&);
+  static ObjectMaker object(dynamic const&, dynamic&&);
+  static ObjectMaker object(dynamic&&, dynamic const&);
+  static ObjectMaker object(dynamic const&, dynamic const&);
 
   /*
    * String compatibility constructors.
index c1d6f943d84e0a64bf530e45cb5674ed10262c12..ff89c1709d0c4c2a2bb457fcf89795907d769136 100644 (file)
@@ -263,6 +263,14 @@ TEST(Dynamic, GetSetDefaultTest) {
   EXPECT_ANY_THROW(d4.setDefault("foo", "bar"));
 }
 
+TEST(Dynamic, ObjectForwarding) {
+  // Make sure dynamic::object can be constructed the same way as any
+  // dynamic.
+  dynamic d = dynamic::object("asd", {"foo", "bar"});
+  dynamic d2 = dynamic::object("key2", {"value", "words"})
+                              ("key", "value1");
+}
+
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
   google::ParseCommandLineFlags(&argc, &argv, true);