Summary:After DR95 the single braces dispatch to the copy constructor
(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467),
so it is not possible anymore to initialize a singleton dynamic array
using the braces syntax. The initializer list constructor already had
a special case for empty lists, which unconditionally called the
default constructor if defined.
This diff deprecates the braces syntax and defines the following alternative:
```
dynamic empty = dynamic::array;
dynamic a = dynamic::array(1, 2, "foo");
```
Reviewed By: luciang, yfeldblum
Differential Revision:
D3013423
fb-gh-sync-id:
a0cf09dfd96e9806044f7c3bf3592c637a9bc932
shipit-source-id:
a0cf09dfd96e9806044f7c3bf3592c637a9bc932
- * dynamic d = { { 1, 2, 3 }, { 4, 5 } }; // a vector of vector of int
+ * dynamic d = dynamic::array(
+ * dynamic::array(1, 2, 3),
+ * dynamic::array(4, 5)); // a vector of vector of int
* auto vvi = convertTo<fbvector<fbvector<int>>>(d);
*
* See docs/DynamicConverter.md for supported types and customization
* auto vvi = convertTo<fbvector<fbvector<int>>>(d);
*
* See docs/DynamicConverter.md for supported types and customization
!std::is_constructible<StringPiece, const C&>::value &&
dynamicconverter_detail::is_range<C>::value>::type> {
static dynamic construct(const C& x) {
!std::is_constructible<StringPiece, const C&>::value &&
dynamicconverter_detail::is_range<C>::value>::type> {
static dynamic construct(const C& x) {
+ dynamic d = dynamic::array;
for (auto& item : x) {
d.push_back(toDynamic(item));
}
for (auto& item : x) {
d.push_back(toDynamic(item));
}
template<typename A, typename B>
struct DynamicConstructor<std::pair<A, B>, void> {
static dynamic construct(const std::pair<A, B>& x) {
template<typename A, typename B>
struct DynamicConstructor<std::pair<A, B>, void> {
static dynamic construct(const std::pair<A, B>& x) {
+ dynamic d = dynamic::array;
d.push_back(toDynamic(x.first));
d.push_back(toDynamic(x.second));
return d;
d.push_back(toDynamic(x.first));
d.push_back(toDynamic(x.second));
return d;
dynamic boolean = false;
// Arrays can be initialized with brackets.
dynamic boolean = false;
// Arrays can be initialized with brackets.
- dynamic array = { "array ", "of ", 4, " elements" };
+ dynamic array = dynamic::array("array ", "of ", 4, " elements");
assert(array.size() == 4);
assert(array.size() == 4);
- dynamic emptyArray = {};
+ dynamic emptyArray = dynamic::array;
assert(emptyArray.empty());
// Maps from dynamics to dynamics are called objects. The
assert(emptyArray.empty());
// Maps from dynamics to dynamics are called objects. The
You can iterate over dynamic arrays as you would over any C++ sequence container.
``` Cpp
You can iterate over dynamic arrays as you would over any C++ sequence container.
``` Cpp
- dynamic array = {2, 3, "foo"};
+ dynamic array = dynamic::array(2, 3, "foo");
for (auto& val : array) {
doSomethingWith(val);
for (auto& val : array) {
doSomethingWith(val);
// Building the same document programatically.
dynamic sonOfAJ = dynamic::object
("key", 12)
// Building the same document programatically.
dynamic sonOfAJ = dynamic::object
("key", 12)
- ("key2", { false, nullptr, true, "yay" });
+ ("key2", dynamic::array(false, nullptr, true, "yay"));
// Printing. (See also folly::toPrettyJson)
auto str = folly::toJson(sonOfAJ);
// Printing. (See also folly::toPrettyJson)
auto str = folly::toJson(sonOfAJ);
+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());
+}
+
// 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.
// 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.
+
+// TODO(ott, 10300209): When the initializer_list constructor is gone,
+// simplify this.
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() { return ObjectMaker(); }
inline dynamic::ObjectMaker dynamic::object(dynamic&& a, dynamic&& b) {
return ObjectMaker(std::move(a), std::move(b));
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
+inline dynamic::dynamic(void (*)(EmptyArrayTag))
+ : type_(ARRAY)
+{
+ new (&u_.array) Array();
+}
+
inline dynamic::dynamic(ObjectMaker (*)())
: type_(OBJECT)
{
inline dynamic::dynamic(ObjectMaker (*)())
: type_(OBJECT)
{
new (&u_.string) fbstring(std::move(s));
}
new (&u_.string) fbstring(std::move(s));
}
-inline dynamic& dynamic::operator=(std::initializer_list<dynamic> il) {
- (*this) = dynamic(il);
- return *this;
+inline dynamic::dynamic(std::initializer_list<dynamic> il)
+ : dynamic(std::move(il), PrivateTag()) {
-inline dynamic::dynamic(std::initializer_list<dynamic> il)
+inline dynamic::dynamic(std::initializer_list<dynamic> il, PrivateTag)
: type_(ARRAY)
{
new (&u_.array) Array(il.begin(), il.end());
}
: type_(ARRAY)
{
new (&u_.array) Array(il.begin(), il.end());
}
+inline dynamic& dynamic::operator=(std::initializer_list<dynamic> il) {
+ (*this) = dynamic(il, PrivateTag());
+ return *this;
+}
+
inline dynamic::dynamic(ObjectMaker&& maker)
: type_(OBJECT)
{
inline dynamic::dynamic(ObjectMaker&& maker)
: type_(OBJECT)
{
}
inline void dynamic::resize(std::size_t sz, dynamic const& c) {
}
inline void dynamic::resize(std::size_t sz, dynamic const& c) {
- auto& array = get<Array>();
- array.resize(sz, c);
+ auto& arr = get<Array>();
+ arr.resize(sz, c);
}
inline void dynamic::push_back(dynamic const& v) {
}
inline void dynamic::push_back(dynamic const& v) {
- auto& array = get<Array>();
- array.push_back(v);
+ auto& arr = get<Array>();
+ arr.push_back(v);
}
inline void dynamic::push_back(dynamic&& v) {
}
inline void dynamic::push_back(dynamic&& v) {
- auto& array = get<Array>();
- array.push_back(std::move(v));
+ auto& arr = get<Array>();
+ arr.push_back(std::move(v));
}
inline void dynamic::pop_back() {
}
inline void dynamic::pop_back() {
- auto& array = get<Array>();
- array.pop_back();
+ auto& arr = get<Array>();
+ arr.pop_back();
}
//////////////////////////////////////////////////////////////////////
}
//////////////////////////////////////////////////////////////////////
* dynamic str = "string";
* dynamic map = dynamic::object;
* map[str] = twelve;
* dynamic str = "string";
* dynamic map = dynamic::object;
* map[str] = twelve;
- * map[str + "another_str"] = { "array", "of", 4, "elements" };
+ * map[str + "another_str"] = dynamic::array("array", "of", 4, "elements");
* map.insert("null_element", nullptr);
* ++map[str];
* assert(map[str] == 13);
* map.insert("null_element", nullptr);
* ++map[str];
* assert(map[str] == 13);
* // Building a complex object with a sub array inline:
* dynamic d = dynamic::object
* ("key", "value")
* // Building a complex object with a sub array inline:
* dynamic d = dynamic::object
* ("key", "value")
- * ("key2", { "a", "array" })
+ * ("key2", dynamic::array("a", "array"))
* ;
*
* Also see folly/json.h for the serialization and deserialization
* ;
*
* Also see folly/json.h for the serialization and deserialization
struct const_item_iterator;
/*
struct const_item_iterator;
/*
- * Creation routines for making dynamic objects. Objects are maps
- * from key to value (so named due to json-related origins here).
+ * Creation routines for making dynamic objects and arrays. Objects
+ * are maps from key to value (so named due to json-related origins
+ * here).
*
* Example:
*
* // Make a fairly complex dynamic:
* dynamic d = dynamic::object("key", "value1")
*
* Example:
*
* // Make a fairly complex dynamic:
* dynamic d = dynamic::object("key", "value1")
- * ("key2", { "value", "with", 4, "words" });
+ * ("key2", dynamic::array("value",
+ * "with",
+ * 4,
+ * "words"));
*
* // Build an object in a few steps:
* dynamic d = dynamic::object;
* d["key"] = 12;
*
* // Build an object in a few steps:
* dynamic d = dynamic::object;
* d["key"] = 12;
- * d["something_else"] = { 1, 2, 3, nullptr };
+ * d["something_else"] = dynamic::array(1, 2, 3, nullptr);
+ struct PrivateTag {};
+ struct EmptyArrayTag {};
struct ObjectMaker;
public:
struct ObjectMaker;
public:
+ static void array(EmptyArrayTag);
+ template <class... Args>
+ static dynamic array(Args&& ...args);
+
static ObjectMaker object();
static ObjectMaker object(dynamic&&, dynamic&&);
static ObjectMaker object(dynamic const&, dynamic&&);
static ObjectMaker object();
static ObjectMaker object(dynamic&&, dynamic&&);
static ObjectMaker object(dynamic const&, dynamic&&);
/* implicit */ dynamic(fbstring&& val);
/*
/* implicit */ dynamic(fbstring&& val);
/*
- * This is part of the plumbing for object(), above. Used to create
- * a new object dynamic.
+ * This is part of the plumbing for array() and object(), above.
+ * Used to create a new array or object dynamic.
+ /* implicit */ dynamic(void (*)(EmptyArrayTag));
/* implicit */ dynamic(ObjectMaker (*)());
/* implicit */ dynamic(ObjectMaker const&) = delete;
/* implicit */ dynamic(ObjectMaker&&);
/* implicit */ dynamic(ObjectMaker (*)());
/* implicit */ dynamic(ObjectMaker const&) = delete;
/* implicit */ dynamic(ObjectMaker&&);
*
* dynamic v = { 1, 2, 3, "foo" };
*/
*
* dynamic v = { 1, 2, 3, "foo" };
*/
+ // TODO(ott, 10300209): Remove once all uses have been eradicated.
+
+ FOLLY_DEPRECATED(
+ "Initializer list syntax is deprecated (#10300209). Use dynamic::array.")
/* implicit */ dynamic(std::initializer_list<dynamic> il);
/* 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);
/*
dynamic& operator=(std::initializer_list<dynamic> il);
/*
assert(*in == '[');
++in;
assert(*in == '[');
++in;
+ dynamic ret = dynamic::array;
in.skipWhitespace();
if (*in == ']') {
in.skipWhitespace();
if (*in == ']') {
auto i2 = convertTo<std::string>(d2);
EXPECT_EQ(i2, "13");
auto i2 = convertTo<std::string>(d2);
EXPECT_EQ(i2, "13");
- dynamic d3 = { 12, "Scala" };
+ dynamic d3 = dynamic::array(12, "Scala");
auto i3 = convertTo<std::pair<int, std::string>>(d3);
EXPECT_EQ(i3.first, 12);
EXPECT_EQ(i3.second, "Scala");
auto i3 = convertTo<std::pair<int, std::string>>(d3);
EXPECT_EQ(i3.first, 12);
EXPECT_EQ(i3.second, "Scala");
}
TEST(DynamicConverter, simple_fbvector) {
}
TEST(DynamicConverter, simple_fbvector) {
- dynamic d1 = { 1, 2, 3 };
+ dynamic d1 = dynamic::array(1, 2, 3);
auto i1 = convertTo<folly::fbvector<int>>(d1);
decltype(i1) i1b = { 1, 2, 3 };
EXPECT_EQ(i1, i1b);
}
TEST(DynamicConverter, simple_container) {
auto i1 = convertTo<folly::fbvector<int>>(d1);
decltype(i1) i1b = { 1, 2, 3 };
EXPECT_EQ(i1, i1b);
}
TEST(DynamicConverter, simple_container) {
- dynamic d1 = { 1, 2, 3 };
+ dynamic d1 = dynamic::array(1, 2, 3);
auto i1 = convertTo<std::vector<int>>(d1);
decltype(i1) i1b = { 1, 2, 3 };
EXPECT_EQ(i1, i1b);
auto i1 = convertTo<std::vector<int>>(d1);
decltype(i1) i1b = { 1, 2, 3 };
EXPECT_EQ(i1, i1b);
- dynamic d2 = { 1, 3, 5, 2, 4 };
+ dynamic d2 = dynamic::array(1, 3, 5, 2, 4);
auto i2 = convertTo<std::set<int>>(d2);
decltype(i2) i2b = { 1, 2, 3, 5, 4 };
EXPECT_EQ(i2, i2b);
auto i2 = convertTo<std::set<int>>(d2);
decltype(i2) i2b = { 1, 2, 3, 5, 4 };
EXPECT_EQ(i2, i2b);
decltype(i1) i1b = { { 1, "one" }, { 2, "two" } };
EXPECT_EQ(i1, i1b);
decltype(i1) i1b = { { 1, "one" }, { 2, "two" } };
EXPECT_EQ(i1, i1b);
- dynamic d2 = { { 3, "three" }, { 4, "four" } };
+ dynamic d2 = dynamic::array(dynamic::array(3, "three"),
+ dynamic::array(4, "four"));
auto i2 = convertTo<std::unordered_map<int, std::string>>(d2);
decltype(i2) i2b = { { 3, "three" }, { 4, "four" } };
EXPECT_EQ(i2, i2b);
auto i2 = convertTo<std::unordered_map<int, std::string>>(d2);
decltype(i2) i2b = { { 3, "three" }, { 4, "four" } };
EXPECT_EQ(i2, i2b);
decltype(i1) i1b = { { "1", "one" }, { "2", "two" } };
EXPECT_EQ(i1, i1b);
decltype(i1) i1b = { { "1", "one" }, { "2", "two" } };
EXPECT_EQ(i1, i1b);
- dynamic d2 = { { "3", "three" }, { "4", "four" } };
+ dynamic d2 = dynamic::array(dynamic::array("3", "three"),
+ dynamic::array("4", "four"));
auto i2 = convertTo<std::unordered_map<std::string, std::string>>(d2);
decltype(i2) i2b = { { "3", "three" }, { "4", "four" } };
EXPECT_EQ(i2, i2b);
auto i2 = convertTo<std::unordered_map<std::string, std::string>>(d2);
decltype(i2) i2b = { { "3", "three" }, { "4", "four" } };
EXPECT_EQ(i2, i2b);
}
TEST(DynamicConverter, nested_containers) {
}
TEST(DynamicConverter, nested_containers) {
- dynamic d1 = { { 1 }, { }, { 2, 3 } };
+ dynamic d1 = dynamic::array(dynamic::array(1),
+ dynamic::array(),
+ dynamic::array(2, 3));
auto i1 = convertTo<folly::fbvector<std::vector<uint8_t>>>(d1);
decltype(i1) i1b = { { 1 }, { }, { 2, 3 } };
EXPECT_EQ(i1, i1b);
auto i1 = convertTo<folly::fbvector<std::vector<uint8_t>>>(d1);
decltype(i1) i1b = { { 1 }, { }, { 2, 3 } };
EXPECT_EQ(i1, i1b);
- dynamic h2a = { "3", ".", "1", "4" };
- dynamic h2b = { "2", ".", "7", "2" };
+ dynamic h2a = dynamic::array("3", ".", "1", "4");
+ dynamic h2b = dynamic::array("2", ".", "7", "2");
dynamic d2 = dynamic::object(3.14, h2a)(2.72, h2b);
auto i2 = convertTo<std::map<double, std::vector<folly::fbstring>>>(d2);
decltype(i2) i2b =
dynamic d2 = dynamic::object(3.14, h2a)(2.72, h2b);
auto i2 = convertTo<std::map<double, std::vector<folly::fbstring>>>(d2);
decltype(i2) i2b =
auto i1 = convertTo<A>(d1);
EXPECT_EQ(i1.i, 17);
auto i1 = convertTo<A>(d1);
EXPECT_EQ(i1.i, 17);
- dynamic d2 = { dynamic::object("i", 18), dynamic::object("i", 19) };
+ dynamic d2 = dynamic::array(dynamic::object("i", 18),
+ dynamic::object("i", 19));
auto i2 = convertTo<std::vector<A>>(d2);
decltype(i2) i2b = { { 18 }, { 19 } };
EXPECT_EQ(i2, i2b);
auto i2 = convertTo<std::vector<A>>(d2);
decltype(i2) i2b = { { 18 }, { 19 } };
EXPECT_EQ(i2, i2b);
- ds1 = { "a", "e", "i", "o", "u" },
- ds2 = { "2", "3", "5", "7" },
- ds3 = { "Hello", "World" };
+ ds1 = dynamic::array("a", "e", "i", "o", "u"),
+ ds2 = dynamic::array("2", "3", "5", "7"),
+ ds3 = dynamic::array("Hello", "World");
- dv1 = {},
- dv2 = { ds1, ds2 },
- dv3({ ds3 });
+ dv1 = dynamic::array,
+ dv2 = dynamic::array(ds1, ds2),
+ dv3(dynamic::array(ds3));
dynamic
dm1 = dynamic::object(true, dv1)(false, dv2),
dynamic
dm1 = dynamic::object(true, dv1)(false, dv2),
- dm2 = { { true, dv3 } };
+ dm2 = dynamic::array(dynamic::array(true, dv3));
+ df1 = dynamic::array(dm1, dm2);
auto i = convertTo<std::vector<std::unordered_map<bool, std::vector<
auto i = convertTo<std::vector<std::unordered_map<bool, std::vector<
auto i4 = convertTo<const bool>(d4);
EXPECT_EQ(true, i4);
auto i4 = convertTo<const bool>(d4);
EXPECT_EQ(true, i4);
+ dynamic d5 = dynamic::array(1, 2);
auto i5 = convertTo<const std::pair<const int, const int>>(d5);
decltype(i5) i5b = { 1, 2 };
EXPECT_EQ(i5b, i5);
auto i5 = convertTo<const std::pair<const int, const int>>(d5);
decltype(i5) i5b = { 1, 2 };
EXPECT_EQ(i5b, i5);
using std::string;
{
vector<int> c { 1, 2, 3 };
using std::string;
{
vector<int> c { 1, 2, 3 };
- dynamic d = { 1, 2, 3 };
+ dynamic d = dynamic::array(1, 2, 3);
EXPECT_EQ(d, toDynamic(c));
}
EXPECT_EQ(d, toDynamic(c));
}
{
map<string, pair<string, int>> c { { "a", { "b", 3 } } };
{
map<string, pair<string, int>> c { { "a", { "b", 3 } } };
- dynamic d = dynamic::object("a", dynamic { "b", 3 });
+ dynamic d = dynamic::object("a", dynamic::array("b", 3));
EXPECT_EQ(d, toDynamic(c));
}
{
map<string, pair<string, int>> c { { "a", { "b", 3 } } };
EXPECT_EQ(d, toDynamic(c));
}
{
map<string, pair<string, int>> c { { "a", { "b", 3 } } };
- dynamic d = dynamic::object("a", dynamic { "b", 3 });
+ dynamic d = dynamic::object("a", dynamic::array("b", 3));
EXPECT_EQ(d, toDynamic(c));
}
EXPECT_EQ(d, toDynamic(c));
}
vector<int> vi { 2, 3, 4, 5 };
auto c = std::make_pair(range(vi.begin(), vi.begin() + 3),
range(vi.begin() + 1, vi.begin() + 4));
vector<int> vi { 2, 3, 4, 5 };
auto c = std::make_pair(range(vi.begin(), vi.begin() + 3),
range(vi.begin() + 1, vi.begin() + 4));
- dynamic d = { { 2, 3, 4 }, { 3, 4, 5 } };
+ dynamic d = dynamic::array(dynamic::array(2, 3, 4),
+ dynamic::array(3, 4, 5));
EXPECT_EQ(d, toDynamic(c));
}
}
EXPECT_EQ(d, toDynamic(c));
}
}
TEST(Dynamic, ArrayGenerator) {
// Make sure arrays can be used with folly::gen.
using namespace folly::gen;
TEST(Dynamic, ArrayGenerator) {
// Make sure arrays can be used with folly::gen.
using namespace folly::gen;
- dynamic arr { 1, 2, 3, 4 };
+ dynamic arr = dynamic::array(1, 2, 3, 4);
EXPECT_EQ(from(arr) | take(3) | member(&dynamic::asInt) | sum, 6);
}
EXPECT_EQ(from(arr) | take(3) | member(&dynamic::asInt) | sum, 6);
}
EXPECT_EQ(out.str(), "0xd 1e+02\n");
out.str("");
EXPECT_EQ(out.str(), "0xd 1e+02\n");
out.str("");
- dynamic arrr = { 1, 2, 3 };
+ dynamic arrr = dynamic::array(1, 2, 3);
out << arrr;
EXPECT_EQ(out.str(), "[1,2,3]");
out << arrr;
EXPECT_EQ(out.str(), "[1,2,3]");
EXPECT_EQ(out.str(), R"({"a":12})");
out.str("");
EXPECT_EQ(out.str(), R"({"a":12})");
out.str("");
- dynamic objy2 = { objy, dynamic::object(12, "str"),
- dynamic::object(true, false) };
+ dynamic objy2 = dynamic::array(objy,
+ dynamic::object(12, "str"),
+ dynamic::object(true, false));
out << objy2;
EXPECT_EQ(out.str(), R"([{"a":12},{12:"str"},{true:false}])");
}
out << objy2;
EXPECT_EQ(out.str(), R"([{"a":12},{12:"str"},{true:false}])");
}
EXPECT_TRUE(d3 == nullptr);
d3 = dynamic::object;
EXPECT_TRUE(d3.isObject());
EXPECT_TRUE(d3 == nullptr);
d3 = dynamic::object;
EXPECT_TRUE(d3.isObject());
- d3["foo"] = { 1, 2, 3 };
+ d3["foo"] = dynamic::array(1, 2, 3);
EXPECT_EQ(d3.count("foo"), 1);
d3[123] = 321;
EXPECT_EQ(d3.count("foo"), 1);
d3[123] = 321;
mergeObj1.update(mergeObj2);
EXPECT_EQ(mergeObj1, combinedPreferObj2);
mergeObj1.update(mergeObj2);
EXPECT_EQ(mergeObj1, combinedPreferObj2);
- dynamic arr = { 1, 2, 3, 4, 5, 6 };
+ dynamic arr = dynamic::array(1, 2, 3, 4, 5, 6);
EXPECT_THROW(mergeObj1.update(arr), std::exception);
mergeObj1 = origMergeObj1; // reset it
EXPECT_THROW(mergeObj1.update(arr), std::exception);
mergeObj1 = origMergeObj1; // reset it
}
TEST(Dynamic, ArrayErase) {
}
TEST(Dynamic, ArrayErase) {
- dynamic arr = { 1, 2, 3, 4, 5, 6 };
+ dynamic arr = dynamic::array(1, 2, 3, 4, 5, 6);
EXPECT_THROW(arr.erase(1), std::exception);
EXPECT_EQ(arr.size(), 6);
EXPECT_THROW(arr.erase(1), std::exception);
EXPECT_EQ(arr.size(), 6);
}
TEST(Dynamic, ArrayBasics) {
}
TEST(Dynamic, ArrayBasics) {
- dynamic array = { 1, 2, 3 };
+ dynamic array = dynamic::array(1, 2, 3);
EXPECT_EQ(array.size(), 3);
EXPECT_EQ(array.at(0), 1);
EXPECT_EQ(array.at(1), 2);
EXPECT_EQ(array.size(), 3);
EXPECT_EQ(array.at(0), 1);
EXPECT_EQ(array.at(1), 2);
}
TEST(Dynamic, DeepCopy) {
}
TEST(Dynamic, DeepCopy) {
- dynamic val = { "foo", "bar", { "foo1", "bar1" } };
+ dynamic val = dynamic::array("foo", "bar", dynamic::array("foo1", "bar1"));
EXPECT_EQ(val.at(2).at(0), "foo1");
EXPECT_EQ(val.at(2).at(1), "bar1");
dynamic val2 = val;
EXPECT_EQ(val.at(2).at(0), "foo1");
EXPECT_EQ(val.at(2).at(1), "bar1");
dynamic val2 = val;
EXPECT_EQ(val2.at(2).at(0), "foo3");
EXPECT_EQ(val2.at(2).at(1), "bar3");
EXPECT_EQ(val2.at(2).at(0), "foo3");
EXPECT_EQ(val2.at(2).at(1), "bar3");
- dynamic obj = dynamic::object("a", "b")
- ("c", {"d", "e", "f"})
- ;
+ dynamic obj =
+ dynamic::object("a", "b")
+ ("c", dynamic::array("d", "e", "f"));
EXPECT_EQ(obj.at("a"), "b");
dynamic obj2 = obj;
EXPECT_EQ(obj.at("a"), "b");
dynamic obj2 = obj;
- obj2.at("a") = {1, 2, 3};
+ obj2.at("a") = dynamic::array(1, 2, 3);
EXPECT_EQ(obj.at("a"), "b");
EXPECT_EQ(obj.at("a"), "b");
- dynamic expected = {1, 2, 3};
+ dynamic expected = dynamic::array(1, 2, 3);
EXPECT_EQ(obj2.at("a"), expected);
}
TEST(Dynamic, ArrayReassignment) {
dynamic o = 1;
EXPECT_EQ(obj2.at("a"), expected);
}
TEST(Dynamic, ArrayReassignment) {
dynamic o = 1;
-
- // After DR95 the single braces dispatch to the copy constructor.
- // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467
- dynamic d1 = {{o}};
+ dynamic d1 = dynamic::array(o);
EXPECT_EQ(dynamic::ARRAY, d1.type());
EXPECT_EQ(dynamic::ARRAY, d1.type());
+ d1 = dynamic::array(o);
EXPECT_EQ(dynamic::ARRAY, d1.type());
}
EXPECT_EQ(dynamic::ARRAY, d1.type());
}
dynamic d2 = dynamic::object("foo", "bar");
EXPECT_EQ(d2.setDefault("foo", "quux"), "bar");
dynamic d2 = dynamic::object("foo", "bar");
EXPECT_EQ(d2.setDefault("foo", "quux"), "bar");
- d2.setDefault("bar", dynamic({})).push_back(42);
+ d2.setDefault("bar", dynamic::array).push_back(42);
EXPECT_EQ(d2["bar"][0], 42);
dynamic d3 = dynamic::object, empty = dynamic::object;
EXPECT_EQ(d2["bar"][0], 42);
dynamic d3 = dynamic::object, empty = dynamic::object;
EXPECT_EQ(d3["foo"]["bar"], "baz");
// we do not allow getDefault/setDefault on arrays
EXPECT_EQ(d3["foo"]["bar"], "baz");
// we do not allow getDefault/setDefault on arrays
- dynamic d4 = dynamic({});
+ dynamic d4 = dynamic::array;
EXPECT_ANY_THROW(d4.getDefault("foo", "bar"));
EXPECT_ANY_THROW(d4.setDefault("foo", "bar"));
}
EXPECT_ANY_THROW(d4.getDefault("foo", "bar"));
EXPECT_ANY_THROW(d4.setDefault("foo", "bar"));
}
TEST(Dynamic, ObjectForwarding) {
// Make sure dynamic::object can be constructed the same way as any
// dynamic.
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"})
+ dynamic d = dynamic::object("asd", dynamic::array("foo", "bar"));
+ dynamic d2 = dynamic::object("key2", dynamic::array("value", "words"))
("key", "value1");
}
TEST(Dynamic, GetPtr) {
("key", "value1");
}
TEST(Dynamic, GetPtr) {
- dynamic array = { 1, 2, "three" };
+ dynamic array = dynamic::array(1, 2, "three");
EXPECT_TRUE(array.get_ptr(0));
EXPECT_FALSE(array.get_ptr(-1));
EXPECT_FALSE(array.get_ptr(3));
EXPECT_TRUE(array.get_ptr(0));
EXPECT_FALSE(array.get_ptr(-1));
EXPECT_FALSE(array.get_ptr(3));
}
TEST(Dynamic, Assignment) {
}
TEST(Dynamic, Assignment) {
- const dynamic ds[] = { { 1, 2, 3 },
+ const dynamic ds[] = { dynamic::array(1, 2, 3),
dynamic::object("a", true),
24,
26.5,
true,
"hello", };
dynamic::object("a", true),
24,
26.5,
true,
"hello", };
- const dynamic dd[] = { { 5, 6 },
+ const dynamic dd[] = { dynamic::array(5, 6),
dynamic::object("t", "T")(1, 7),
9000,
3.14159,
dynamic::object("t", "T")(1, 7),
9000,
3.14159,
("junk", 12)
("another", 32.2)
("a",
("junk", 12)
("another", 32.2)
("a",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",
on.allow_trailing_comma = true;
off.allow_trailing_comma = false;
on.allow_trailing_comma = true;
off.allow_trailing_comma = false;
+ dynamic arr = dynamic::array(1, 2);
EXPECT_EQ(arr, parseJson("[1, 2]", on));
EXPECT_EQ(arr, parseJson("[1, 2,]", on));
EXPECT_EQ(arr, parseJson("[1, 2, ]", on));
EXPECT_EQ(arr, parseJson("[1, 2]", on));
EXPECT_EQ(arr, parseJson("[1, 2,]", on));
EXPECT_EQ(arr, parseJson("[1, 2, ]", on));
("junk", 12)
("another", 32.2)
("a",
("junk", 12)
("another", 32.2)
("a",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",
dynamic::object("a", "b")
("c", "d"),
12.5,
"Yo Dawg",