From c1e5151608785e0102f71eb7de9ce2bafc822bff Mon Sep 17 00:00:00 2001 From: Jordan DeLong Date: Mon, 17 Dec 2012 11:12:47 -0800 Subject: [PATCH] Make dynamic::object callable with initializer lists 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 | 19 ++++++++++++++++--- folly/dynamic.h | 6 +++++- folly/test/DynamicTest.cpp | 8 ++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/folly/dynamic-inl.h b/folly/dynamic-inl.h index 4a9d9910..34b988e7 100644 --- a/folly/dynamic-inl.h +++ b/folly/dynamic-inl.h @@ -197,9 +197,22 @@ private: dynamic val_; }; -template -inline dynamic::ObjectMaker dynamic::object(Args&&... args) { - return dynamic::ObjectMaker(std::forward(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); } ////////////////////////////////////////////////////////////////////// diff --git a/folly/dynamic.h b/folly/dynamic.h index 4f02bd0c..c0cdc626 100644 --- a/folly/dynamic.h +++ b/folly/dynamic.h @@ -133,7 +133,11 @@ private: struct ObjectMaker; public: - template 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. diff --git a/folly/test/DynamicTest.cpp b/folly/test/DynamicTest.cpp index c1d6f943..ff89c170 100644 --- a/folly/test/DynamicTest.cpp +++ b/folly/test/DynamicTest.cpp @@ -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); -- 2.34.1