X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fdynamic.h;h=ad88edc525ff324d8322c5f67154e1fa3f661641;hp=c2ab2a4bb4d035fb0158297568a799673bb2dd4a;hb=b92bbedce7866bf3760863604e1af1e8e42db24a;hpb=dee8a5180aa542d98d1b71c74f83a006e4627952 diff --git a/folly/dynamic.h b/folly/dynamic.h index c2ab2a4b..ad88edc5 100644 --- a/folly/dynamic.h +++ b/folly/dynamic.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,16 +45,6 @@ * Also see folly/json.h for the serialization and deserialization * functions for JSON. * - * Note: dynamic is not DefaultConstructible. Rationale: - * - * - The intuitive thing to initialize a defaulted dynamic to would - * be nullptr. - * - * - However, the expression dynamic d = {} is required to call the - * default constructor by the standard, which is confusing - * behavior for dynamic unless the default constructor creates an - * empty array. - * * Additional documentation is in folly/docs/Dynamic.md. * * @author Jordan DeLong @@ -63,7 +53,6 @@ #pragma once #include -#include #include #include #include @@ -74,7 +63,6 @@ #include -#include #include #include @@ -97,6 +85,7 @@ struct dynamic : private boost::operators { OBJECT, STRING, }; + template struct NumericTypeHelper; /* * We support direct iteration of arrays, and indirect iteration of objects. @@ -107,15 +96,21 @@ struct dynamic : private boost::operators { * Object value iterators dereference as the values in the object. * Object item iterators dereference as pairs of (key, value). */ -private: + private: typedef std::vector Array; -public: + + public: + typedef Array::iterator iterator; typedef Array::const_iterator const_iterator; typedef dynamic value_type; + struct const_key_iterator; struct const_value_iterator; struct const_item_iterator; + struct value_iterator; + struct item_iterator; + /* * Creation routines for making dynamic objects and arrays. Objects * are maps from key to value (so named due to json-related origins @@ -135,30 +130,30 @@ public: * d["key"] = 12; * d["something_else"] = dynamic::array(1, 2, 3, nullptr); */ -private: - struct PrivateTag {}; + private: struct EmptyArrayTag {}; struct ObjectMaker; -public: + 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&&); - static ObjectMaker object(dynamic&&, dynamic const&); - static ObjectMaker object(dynamic const&, dynamic const&); + static ObjectMaker object(dynamic, dynamic); + + /** + * Default constructor, initializes with nullptr. + */ + dynamic(); /* * String compatibility constructors. */ + /* implicit */ dynamic(std::nullptr_t); /* implicit */ dynamic(StringPiece val); /* implicit */ dynamic(char const* val); - /* implicit */ dynamic(std::string const& val); - /* implicit */ dynamic(fbstring const& val); - /* implicit */ dynamic(fbstring&& val); + /* implicit */ dynamic(std::string val); /* * This is part of the plumbing for array() and object(), above. @@ -170,32 +165,18 @@ public: /* implicit */ dynamic(ObjectMaker&&); /* - * Create a new array from an initializer list. - * - * For example: - * - * dynamic v = { 1, 2, 3, "foo" }; + * Constructors for integral and float types. + * Other types are SFINAEd out with NumericTypeHelper. */ - // 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. - */ - template /* implicit */ dynamic(T t); + template ::type> + /* implicit */ dynamic(T t); /* * Create a dynamic that is an array of the values from the supplied * iterator range. */ - template dynamic(Iterator first, Iterator last); + template + explicit dynamic(Iterator first, Iterator last); dynamic(dynamic const&); dynamic(dynamic&&) noexcept; @@ -291,7 +272,7 @@ public: * since arrays and objects are generally best dealt with as a * dynamic. */ - fbstring asString() const; + std::string asString() const; double asDouble() const; int64_t asInt() const; bool asBool() const; @@ -301,15 +282,15 @@ public: * * These will throw a TypeError if the dynamic has a different type. */ - const fbstring& getString() const&; + const std::string& getString() const&; double getDouble() const&; int64_t getInt() const&; bool getBool() const&; - fbstring& getString() &; + std::string& getString() &; double& getDouble() &; int64_t& getInt() &; bool& getBool() &; - fbstring getString() &&; + std::string&& getString() &&; double getDouble() &&; int64_t getInt() &&; bool getBool() &&; @@ -345,14 +326,16 @@ public: */ const_iterator begin() const; const_iterator end() const; + iterator begin(); + iterator end(); -private: + private: /* * Helper object returned by keys(), values(), and items(). */ template struct IterableProxy; -public: + public: /* * You can iterate over the keys, values, or items (std::pair of key and * value) in an object. Calling these on non-objects will throw a TypeError. @@ -360,6 +343,8 @@ public: IterableProxy keys() const; IterableProxy values() const; IterableProxy items() const; + IterableProxy values(); + IterableProxy items(); /* * AssociativeContainer-style find interface for objects. Throws if @@ -369,6 +354,7 @@ public: * const_item_iterator pointing to the item. */ const_item_iterator find(dynamic const&) const; + item_iterator find(dynamic const&); /* * If this is an object, returns whether it contains a field with @@ -386,7 +372,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 @@ -417,7 +403,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. @@ -432,8 +418,16 @@ public: 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); + template + dynamic& setDefault(K&& k, V&& v); + // MSVC 2015 Update 3 needs these extra overloads because if V were a + // defaulted template parameter, it causes MSVC to consider v an rvalue + // reference rather than a universal reference, resulting in it not being + // able to find the correct overload to construct a dynamic with. + template + dynamic& setDefault(K&& k, dynamic&& v); + template + dynamic& setDefault(K&& k, const dynamic& v = dynamic::object); /* * Resizes an array so it has at n elements, using the supplied @@ -452,7 +446,7 @@ public: * * Invalidates iterators. */ - template void insert(K&&, V&& val); + template void insert(K&&, V&& val); /* * These functions merge two folly dynamic objects. @@ -492,19 +486,17 @@ public: * removed, or end() if there are none. (The iteration order does * not change.) */ - const_iterator erase(const_iterator it); - const_iterator erase(const_iterator first, const_iterator last); + iterator erase(const_iterator it); + iterator erase(const_iterator first, const_iterator last); const_key_iterator erase(const_key_iterator it); const_key_iterator erase(const_key_iterator first, const_key_iterator last); - const_value_iterator erase(const_value_iterator it); - const_value_iterator erase(const_value_iterator first, - const_value_iterator last); + value_iterator erase(const_value_iterator it); + value_iterator erase(const_value_iterator first, const_value_iterator last); - const_item_iterator erase(const_item_iterator it); - const_item_iterator erase(const_item_iterator first, - const_item_iterator last); + item_iterator erase(const_item_iterator it); + item_iterator erase(const_item_iterator first, const_item_iterator last); /* * Append elements to an array. If this is not an array, throws * TypeError. @@ -530,43 +522,43 @@ public: */ std::size_t hash() const; -private: + private: friend struct TypeError; struct ObjectImpl; - template struct TypeInfo; - template struct CompareOp; - template struct GetAddrImpl; - template struct PrintImpl; + template struct TypeInfo; + template struct CompareOp; + template struct GetAddrImpl; + template struct PrintImpl; + + explicit dynamic(Array&& array); - template T const& get() const; - template T& get(); - 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 const& get() const; + template T& get(); + 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; + template T asImpl() const; static char const* typeName(Type); void destroy() noexcept; void print(std::ostream&) const; void print_as_pseudo_json(std::ostream&) const; // see json.cpp -private: + private: Type type_; union Data { explicit Data() : nul(nullptr) {} ~Data() {} - // XXX: gcc does an ICE if we use std::nullptr_t instead of void* - // here. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50361 - void* nul; + std::nullptr_t nul; Array array; bool boolean; double doubl; int64_t integer; - fbstring string; + std::string string; /* * Objects are placement new'd here. We have to use a char buffer @@ -584,6 +576,6 @@ private: ////////////////////////////////////////////////////////////////////// -} +} // namespace folly #include