X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fdynamic.h;h=c2ab2a4bb4d035fb0158297568a799673bb2dd4a;hb=015f5dc525643e73a517cf22046ded72c5b6224d;hp=47740627c711b7fbbbea4137f7d2a77949a7e735;hpb=d635918842772c47aea45dc114792071950089df;p=folly.git diff --git a/folly/dynamic.h b/folly/dynamic.h index 47740627..c2ab2a4b 100644 --- a/folly/dynamic.h +++ b/folly/dynamic.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ * 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); @@ -39,7 +39,7 @@ * // 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 @@ -60,22 +60,23 @@ * @author Jordan DeLong */ -#ifndef FOLLY_DYNAMIC_H_ -#define FOLLY_DYNAMIC_H_ +#pragma once -#include +#include +#include #include -#include -#include #include +#include #include -#include +#include +#include #include -#include + #include -#include "folly/Traits.h" -#include "folly/FBString.h" +#include +#include +#include namespace folly { @@ -110,29 +111,40 @@ private: typedef std::vector Array; public: typedef Array::const_iterator const_iterator; + typedef dynamic value_type; struct const_key_iterator; struct const_value_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") - * ("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; - * d["something_else"] = { 1, 2, 3, nullptr }; + * d["something_else"] = dynamic::array(1, 2, 3, nullptr); */ private: + struct PrivateTag {}; + struct EmptyArrayTag {}; struct ObjectMaker; public: + static void array(EmptyArrayTag); + template + static dynamic array(Args&& ...args); + static ObjectMaker object(); static ObjectMaker object(dynamic&&, dynamic&&); static ObjectMaker object(dynamic const&, dynamic&&); @@ -142,13 +154,17 @@ public: /* * String compatibility constructors. */ + /* implicit */ dynamic(StringPiece val); /* implicit */ dynamic(char const* val); /* implicit */ dynamic(std::string const& val); + /* implicit */ dynamic(fbstring const& 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&&); @@ -160,7 +176,15 @@ public: * * 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 il); + dynamic(std::initializer_list il, PrivateTag); + FOLLY_DEPRECATED( + "Initializer list syntax is deprecated (#10300209). Use dynamic::array.") + dynamic& operator=(std::initializer_list il); /* * Conversion constructors from most of the other types. @@ -174,8 +198,8 @@ public: template dynamic(Iterator first, Iterator last); dynamic(dynamic const&); - dynamic(dynamic&&); - ~dynamic(); + dynamic(dynamic&&) noexcept; + ~dynamic() noexcept; /* * "Deep" equality comparison. This will compare all the way down @@ -217,7 +241,7 @@ public: * Basic guarantee only. */ dynamic& operator=(dynamic const&); - dynamic& operator=(dynamic&&); + dynamic& operator=(dynamic&&) noexcept; /* * For simple dynamics (not arrays or objects), this prints the @@ -272,14 +296,35 @@ public: int64_t asInt() const; bool asBool() const; + /* + * Extract the value stored in this dynamic without type conversion. + * + * These will throw a TypeError if the dynamic has a different type. + */ + const fbstring& getString() const&; + double getDouble() const&; + int64_t getInt() const&; + bool getBool() const&; + fbstring& getString() &; + double& getDouble() &; + int64_t& getInt() &; + bool& getBool() &; + fbstring getString() &&; + double getDouble() &&; + int64_t getInt() &&; + bool getBool() &&; + /* * It is occasionally useful to access a string's internal pointer * directly, without the type conversion of `asString()`. * * These will throw a TypeError if the dynamic is not a string. */ - const char* data() const; - const char* c_str() const; + const char* data() const&; + const char* data() && = delete; + const char* c_str() const&; + const char* c_str() && = delete; + StringPiece stringPiece() const; /* * Returns: true if this dynamic is null, an empty array, an empty @@ -325,7 +370,6 @@ public: */ const_item_iterator find(dynamic const&) const; - /* * If this is an object, returns whether it contains a field with * the given name. Otherwise throws TypeError. @@ -340,8 +384,9 @@ public: * will throw a TypeError. Using an index that is out of range or * object-element that's not present throws std::out_of_range. */ - dynamic const& at(dynamic const&) const; - dynamic& at(dynamic const&); + dynamic const& at(dynamic const&) const&; + dynamic& at(dynamic const&) &; + dynamic at(dynamic const&) &&; /* * Like 'at', above, except it returns either a pointer to the contained @@ -354,8 +399,9 @@ public: * Using these with dynamic objects that are not arrays or objects * will throw a TypeError. */ - const dynamic* get_ptr(dynamic const&) const; - dynamic* get_ptr(dynamic const&); + const dynamic* get_ptr(dynamic const&) const&; + dynamic* get_ptr(dynamic const&) &; + dynamic* get_ptr(dynamic const&) && = delete; /* * This works for access to both objects and arrays. @@ -369,8 +415,9 @@ public: * * These functions do not invalidate iterators. */ - dynamic& operator[](dynamic const&); - dynamic const& operator[](dynamic const&) const; + dynamic& operator[](dynamic const&) &; + dynamic const& operator[](dynamic const&) const&; + dynamic operator[](dynamic const&) &&; /* * Only defined for objects, throws TypeError otherwise. @@ -381,8 +428,10 @@ public: * a reference to the existing value if present, the new value otherwise. */ dynamic - getDefault(const dynamic& k, const dynamic& v = dynamic::object) const; - dynamic&& getDefault(const dynamic& k, dynamic&& v) const; + getDefault(const dynamic& k, const dynamic& v = dynamic::object) const&; + dynamic getDefault(const dynamic& k, dynamic&& v) const&; + dynamic getDefault(const dynamic& k, const dynamic& v = dynamic::object) &&; + dynamic getDefault(const dynamic& k, dynamic&& v) &&; template dynamic& setDefault(K&& k, V&& v = dynamic::object); @@ -405,6 +454,23 @@ public: */ template void insert(K&&, V&& val); + /* + * These functions merge two folly dynamic objects. + * The "update" and "update_missing" functions extend the object by + * inserting the key/value pairs of mergeObj into the current object. + * For update, if key is duplicated between the two objects, it + * will overwrite with the value of the object being inserted (mergeObj). + * For "update_missing", it will prefer the value in the original object + * + * The "merge" function creates a new object consisting of the key/value + * pairs of both mergeObj1 and mergeObj2 + * If the key is duplicated between the two objects, + * it will prefer value in the second object (mergeObj2) + */ + void update(const dynamic& mergeObj); + void update_missing(const dynamic& other); + static dynamic merge(const dynamic& mergeObj1, const dynamic& mergeObj2); + /* * Erase an element from a dynamic object, by key. * @@ -474,15 +540,16 @@ private: template T const& get() const; template T& get(); - template T* get_nothrow(); - template T const* get_nothrow() const; - template T* getAddress(); - template T const* getAddress() const; + template T* get_nothrow() & noexcept; + template T const* get_nothrow() const& noexcept; + template T* get_nothrow() && noexcept = delete; + template T* getAddress() noexcept; + template T const* getAddress() const noexcept; template T asImpl() const; static char const* typeName(Type); - void destroy(); + void destroy() noexcept; void print(std::ostream&) const; void print_as_pseudo_json(std::ostream&) const; // see json.cpp @@ -508,7 +575,7 @@ private: * incomplete type right now). (Note that in contrast we know it * is ok to do this with fbvector because we own it.) */ - typename std::aligned_storage< + std::aligned_storage< sizeof(std::unordered_map), alignof(std::unordered_map) >::type objectBuffer; @@ -519,6 +586,4 @@ private: } -#include "folly/dynamic-inl.h" - -#endif +#include