Explicitly refer to the std::chrono namespace to avoid conflicts with the folly:...
[folly.git] / folly / dynamic.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * This is a runtime dynamically typed value.  It holds types from a
19  * specific predetermined set of types (ints, bools, arrays, etc).  In
20  * particular, it can be used as a convenient in-memory representation
21  * for complete json objects.
22  *
23  * In general you can try to use these objects as if they were the
24  * type they represent (although in some cases with a slightly less
25  * complete interface than the raw type), and it'll just throw a
26  * TypeError if it is used in an illegal way.
27  *
28  * Some examples:
29  *
30  *   dynamic twelve = 12;
31  *   dynamic str = "string";
32  *   dynamic map = dynamic::object;
33  *   map[str] = twelve;
34  *   map[str + "another_str"] = dynamic::array("array", "of", 4, "elements");
35  *   map.insert("null_element", nullptr);
36  *   ++map[str];
37  *   assert(map[str] == 13);
38  *
39  *   // Building a complex object with a sub array inline:
40  *   dynamic d = dynamic::object
41  *     ("key", "value")
42  *     ("key2", dynamic::array("a", "array"))
43  *     ;
44  *
45  * Also see folly/json.h for the serialization and deserialization
46  * functions for JSON.
47  *
48  * Additional documentation is in folly/docs/Dynamic.md.
49  *
50  * @author Jordan DeLong <delong.j@fb.com>
51  */
52
53 #pragma once
54
55 #include <cstdint>
56 #include <memory>
57 #include <ostream>
58 #include <string>
59 #include <type_traits>
60 #include <unordered_map>
61 #include <utility>
62 #include <vector>
63
64 #include <boost/operators.hpp>
65
66 #include <folly/Range.h>
67 #include <folly/Traits.h>
68
69 namespace folly {
70
71 //////////////////////////////////////////////////////////////////////
72
73 struct dynamic;
74 struct TypeError;
75
76 //////////////////////////////////////////////////////////////////////
77
78 struct dynamic : private boost::operators<dynamic> {
79   enum Type {
80     NULLT,
81     ARRAY,
82     BOOL,
83     DOUBLE,
84     INT64,
85     OBJECT,
86     STRING,
87   };
88   template <class T, class Enable = void> struct NumericTypeHelper;
89
90   /*
91    * We support direct iteration of arrays, and indirect iteration of objects.
92    * See begin(), end(), keys(), values(), and items() for more.
93    *
94    * Array iterators dereference as the elements in the array.
95    * Object key iterators dereference as the keys in the object.
96    * Object value iterators dereference as the values in the object.
97    * Object item iterators dereference as pairs of (key, value).
98    */
99  private:
100   typedef std::vector<dynamic> Array;
101
102  public:
103   typedef Array::iterator iterator;
104   typedef Array::const_iterator const_iterator;
105   typedef dynamic value_type;
106
107   struct const_key_iterator;
108   struct const_value_iterator;
109   struct const_item_iterator;
110
111   struct value_iterator;
112   struct item_iterator;
113
114   /*
115    * Creation routines for making dynamic objects and arrays.  Objects
116    * are maps from key to value (so named due to json-related origins
117    * here).
118    *
119    * Example:
120    *
121    *   // Make a fairly complex dynamic:
122    *   dynamic d = dynamic::object("key", "value1")
123    *                              ("key2", dynamic::array("value",
124    *                                                      "with",
125    *                                                      4,
126    *                                                      "words"));
127    *
128    *   // Build an object in a few steps:
129    *   dynamic d = dynamic::object;
130    *   d["key"] = 12;
131    *   d["something_else"] = dynamic::array(1, 2, 3, nullptr);
132    */
133  private:
134   struct EmptyArrayTag {};
135   struct ObjectMaker;
136
137  public:
138   static void array(EmptyArrayTag);
139   template <class... Args>
140   static dynamic array(Args&& ...args);
141
142   static ObjectMaker object();
143   static ObjectMaker object(dynamic, dynamic);
144
145   /**
146    * Default constructor, initializes with nullptr.
147    */
148   dynamic();
149
150   /*
151    * String compatibility constructors.
152    */
153   /* implicit */ dynamic(std::nullptr_t);
154   /* implicit */ dynamic(StringPiece val);
155   /* implicit */ dynamic(char const* val);
156   /* implicit */ dynamic(std::string val);
157
158   /*
159    * This is part of the plumbing for array() and object(), above.
160    * Used to create a new array or object dynamic.
161    */
162   /* implicit */ dynamic(void (*)(EmptyArrayTag));
163   /* implicit */ dynamic(ObjectMaker (*)());
164   /* implicit */ dynamic(ObjectMaker const&) = delete;
165   /* implicit */ dynamic(ObjectMaker&&);
166
167   /*
168    * Constructors for integral and float types.
169    * Other types are SFINAEd out with NumericTypeHelper.
170    */
171   template <class T, class NumericType = typename NumericTypeHelper<T>::type>
172   /* implicit */ dynamic(T t);
173
174   /*
175    * Create a dynamic that is an array of the values from the supplied
176    * iterator range.
177    */
178   template <class Iterator>
179   explicit dynamic(Iterator first, Iterator last);
180
181   dynamic(dynamic const&);
182   dynamic(dynamic&&) noexcept;
183   ~dynamic() noexcept;
184
185   /*
186    * "Deep" equality comparison.  This will compare all the way down
187    * an object or array, and is potentially expensive.
188    */
189   bool operator==(dynamic const& o) const;
190
191   /*
192    * For all types except object this returns the natural ordering on
193    * those types.  For objects, we throw TypeError.
194    */
195   bool operator<(dynamic const& o) const;
196
197   /*
198    * General operators.
199    *
200    * These throw TypeError when used with types or type combinations
201    * that don't support them.
202    *
203    * These functions may also throw if you use 64-bit integers with
204    * doubles when the integers are too big to fit in a double.
205    */
206   dynamic& operator+=(dynamic const&);
207   dynamic& operator-=(dynamic const&);
208   dynamic& operator*=(dynamic const&);
209   dynamic& operator/=(dynamic const&);
210   dynamic& operator%=(dynamic const&);
211   dynamic& operator|=(dynamic const&);
212   dynamic& operator&=(dynamic const&);
213   dynamic& operator^=(dynamic const&);
214   dynamic& operator++();
215   dynamic& operator--();
216
217   /*
218    * Assignment from other dynamics.  Because of the implicit conversion
219    * to dynamic from its potential types, you can use this to change the
220    * type pretty intuitively.
221    *
222    * Basic guarantee only.
223    */
224   dynamic& operator=(dynamic const&);
225   dynamic& operator=(dynamic&&) noexcept;
226
227   /*
228    * For simple dynamics (not arrays or objects), this prints the
229    * value to an std::ostream in the expected way.  Respects the
230    * formatting manipulators that have been sent to the stream
231    * already.
232    *
233    * If the dynamic holds an object or array, this prints them in a
234    * format very similar to JSON.  (It will in fact actually be JSON
235    * as long as the dynamic validly represents a JSON object---i.e. it
236    * can't have non-string keys.)
237    */
238   friend std::ostream& operator<<(std::ostream&, dynamic const&);
239
240   /*
241    * Returns true if this dynamic is of the specified type.
242    */
243   bool isString() const;
244   bool isObject() const;
245   bool isBool() const;
246   bool isNull() const;
247   bool isArray() const;
248   bool isDouble() const;
249   bool isInt() const;
250
251   /*
252    * Returns: isInt() || isDouble().
253    */
254   bool isNumber() const;
255
256   /*
257    * Returns the type of this dynamic.
258    */
259   Type type() const;
260
261   /*
262    * Returns the type of this dynamic as a printable string.
263    */
264   const char* typeName() const;
265
266   /*
267    * Extract a value while trying to convert to the specified type.
268    * Throws exceptions if we cannot convert from the real type to the
269    * requested type.
270    *
271    * Note you can only use this to access integral types or strings,
272    * since arrays and objects are generally best dealt with as a
273    * dynamic.
274    */
275   std::string asString() const;
276   double   asDouble() const;
277   int64_t  asInt() const;
278   bool     asBool() const;
279
280   /*
281    * Extract the value stored in this dynamic without type conversion.
282    *
283    * These will throw a TypeError if the dynamic has a different type.
284    */
285   const std::string& getString() const&;
286   double          getDouble() const&;
287   int64_t         getInt() const&;
288   bool            getBool() const&;
289   std::string& getString() &;
290   double&   getDouble() &;
291   int64_t&  getInt() &;
292   bool&     getBool() &;
293   std::string&& getString() &&;
294   double   getDouble() &&;
295   int64_t  getInt() &&;
296   bool     getBool() &&;
297
298   /*
299    * It is occasionally useful to access a string's internal pointer
300    * directly, without the type conversion of `asString()`.
301    *
302    * These will throw a TypeError if the dynamic is not a string.
303    */
304   const char* data()  const&;
305   const char* data()  && = delete;
306   const char* c_str() const&;
307   const char* c_str() && = delete;
308   StringPiece stringPiece() const;
309
310   /*
311    * Returns: true if this dynamic is null, an empty array, an empty
312    * object, or an empty string.
313    */
314   bool empty() const;
315
316   /*
317    * If this is an array or an object, returns the number of elements
318    * contained.  If it is a string, returns the length.  Otherwise
319    * throws TypeError.
320    */
321   std::size_t size() const;
322
323   /*
324    * You can iterate over the values of the array.  Calling these on
325    * non-arrays will throw a TypeError.
326    */
327   const_iterator begin()  const;
328   const_iterator end()    const;
329   iterator begin();
330   iterator end();
331
332  private:
333   /*
334    * Helper object returned by keys(), values(), and items().
335    */
336   template <class T> struct IterableProxy;
337
338  public:
339   /*
340    * You can iterate over the keys, values, or items (std::pair of key and
341    * value) in an object.  Calling these on non-objects will throw a TypeError.
342    */
343   IterableProxy<const_key_iterator> keys() const;
344   IterableProxy<const_value_iterator> values() const;
345   IterableProxy<const_item_iterator> items() const;
346   IterableProxy<value_iterator> values();
347   IterableProxy<item_iterator> items();
348
349   /*
350    * AssociativeContainer-style find interface for objects.  Throws if
351    * this is not an object.
352    *
353    * Returns: items().end() if the key is not present, or a
354    * const_item_iterator pointing to the item.
355    */
356   const_item_iterator find(dynamic const&) const;
357   item_iterator find(dynamic const&);
358
359   /*
360    * If this is an object, returns whether it contains a field with
361    * the given name.  Otherwise throws TypeError.
362    */
363   std::size_t count(dynamic const&) const;
364
365   /*
366    * For objects or arrays, provides access to sub-fields by index or
367    * field name.
368    *
369    * Using these with dynamic objects that are not arrays or objects
370    * will throw a TypeError.  Using an index that is out of range or
371    * object-element that's not present throws std::out_of_range.
372    */
373   dynamic const& at(dynamic const&) const&;
374   dynamic&       at(dynamic const&) &;
375   dynamic&&      at(dynamic const&) &&;
376
377   /*
378    * Like 'at', above, except it returns either a pointer to the contained
379    * object or nullptr if it wasn't found. This allows a key to be tested for
380    * containment and retrieved in one operation. Example:
381    *
382    *   if (auto* found = d.get_ptr(key))
383    *     // use *found;
384    *
385    * Using these with dynamic objects that are not arrays or objects
386    * will throw a TypeError.
387    */
388   const dynamic* get_ptr(dynamic const&) const&;
389   dynamic* get_ptr(dynamic const&) &;
390   dynamic* get_ptr(dynamic const&) && = delete;
391
392   /*
393    * This works for access to both objects and arrays.
394    *
395    * In the case of an array, the index must be an integer, and this will throw
396    * std::out_of_range if it is less than zero or greater than size().
397    *
398    * In the case of an object, the non-const overload inserts a null
399    * value if the key isn't present.  The const overload will throw
400    * std::out_of_range if the key is not present.
401    *
402    * These functions do not invalidate iterators.
403    */
404   dynamic&       operator[](dynamic const&) &;
405   dynamic const& operator[](dynamic const&) const&;
406   dynamic&&      operator[](dynamic const&) &&;
407
408   /*
409    * Only defined for objects, throws TypeError otherwise.
410    *
411    * getDefault will return the value associated with the supplied key, the
412    * supplied default otherwise. setDefault will set the key to the supplied
413    * default if it is not yet set, otherwise leaving it. setDefault returns
414    * a reference to the existing value if present, the new value otherwise.
415    */
416   dynamic
417   getDefault(const dynamic& k, const dynamic& v = dynamic::object) const&;
418   dynamic getDefault(const dynamic& k, dynamic&& v) const&;
419   dynamic getDefault(const dynamic& k, const dynamic& v = dynamic::object) &&;
420   dynamic getDefault(const dynamic& k, dynamic&& v) &&;
421   template <class K, class V>
422   dynamic& setDefault(K&& k, V&& v);
423   // MSVC 2015 Update 3 needs these extra overloads because if V were a
424   // defaulted template parameter, it causes MSVC to consider v an rvalue
425   // reference rather than a universal reference, resulting in it not being
426   // able to find the correct overload to construct a dynamic with.
427   template <class K>
428   dynamic& setDefault(K&& k, dynamic&& v);
429   template <class K>
430   dynamic& setDefault(K&& k, const dynamic& v = dynamic::object);
431
432   /*
433    * Resizes an array so it has at n elements, using the supplied
434    * default to fill new elements.  Throws TypeError if this dynamic
435    * is not an array.
436    *
437    * May invalidate iterators.
438    *
439    * Post: size() == n
440    */
441   void resize(std::size_t n, dynamic const& = nullptr);
442
443   /*
444    * Inserts the supplied key-value pair to an object, or throws if
445    * it's not an object.
446    *
447    * Invalidates iterators.
448    */
449   template <class K, class V> void insert(K&&, V&& val);
450
451   /*
452    * These functions merge two folly dynamic objects.
453    * The "update" and "update_missing" functions extend the object by
454    *  inserting the key/value pairs of mergeObj into the current object.
455    *  For update, if key is duplicated between the two objects, it
456    *  will overwrite with the value of the object being inserted (mergeObj).
457    *  For "update_missing", it will prefer the value in the original object
458    *
459    * The "merge" function creates a new object consisting of the key/value
460    * pairs of both mergeObj1 and mergeObj2
461    * If the key is duplicated between the two objects,
462    *  it will prefer value in the second object (mergeObj2)
463    */
464   void update(const dynamic& mergeObj);
465   void update_missing(const dynamic& other);
466   static dynamic merge(const dynamic& mergeObj1, const dynamic& mergeObj2);
467
468   /*
469    * Erase an element from a dynamic object, by key.
470    *
471    * Invalidates iterators to the element being erased.
472    *
473    * Returns the number of elements erased (i.e. 1 or 0).
474    */
475   std::size_t erase(dynamic const& key);
476
477   /*
478    * Erase an element from a dynamic object or array, using an
479    * iterator or an iterator range.
480    *
481    * In arrays, invalidates iterators to elements after the element
482    * being erased.  In objects, invalidates iterators to the elements
483    * being erased.
484    *
485    * Returns a new iterator to the first element beyond any elements
486    * removed, or end() if there are none.  (The iteration order does
487    * not change.)
488    */
489   iterator erase(const_iterator it);
490   iterator erase(const_iterator first, const_iterator last);
491
492   const_key_iterator erase(const_key_iterator it);
493   const_key_iterator erase(const_key_iterator first, const_key_iterator last);
494
495   value_iterator erase(const_value_iterator it);
496   value_iterator erase(const_value_iterator first, const_value_iterator last);
497
498   item_iterator erase(const_item_iterator it);
499   item_iterator erase(const_item_iterator first, const_item_iterator last);
500   /*
501    * Append elements to an array.  If this is not an array, throws
502    * TypeError.
503    *
504    * Invalidates iterators.
505    */
506   void push_back(dynamic const&);
507   void push_back(dynamic&&);
508
509   /*
510    * Remove an element from the back of an array.  If this is not an array,
511    * throws TypeError.
512    *
513    * Does not invalidate iterators.
514    */
515   void pop_back();
516
517   /*
518    * Get a hash code.  This function is called by a std::hash<>
519    * specialization, also.
520    *
521    * Throws TypeError if this is an object, array, or null.
522    */
523   std::size_t hash() const;
524
525  private:
526   friend struct TypeError;
527   struct ObjectImpl;
528   template <class T> struct TypeInfo;
529   template <class T> struct CompareOp;
530   template <class T> struct GetAddrImpl;
531   template <class T> struct PrintImpl;
532
533   explicit dynamic(Array&& array);
534
535   template <class T> T const& get() const;
536   template <class T> T&       get();
537   template <class T> T*       get_nothrow() & noexcept;
538   template <class T> T const* get_nothrow() const& noexcept;
539   template <class T> T*       get_nothrow() && noexcept = delete;
540   template <class T> T*       getAddress() noexcept;
541   template <class T> T const* getAddress() const noexcept;
542
543   template <class T> T asImpl() const;
544
545   static char const* typeName(Type);
546   void destroy() noexcept;
547   void print(std::ostream&) const;
548   void print_as_pseudo_json(std::ostream&) const; // see json.cpp
549
550  private:
551   Type type_;
552   union Data {
553     explicit Data() : nul(nullptr) {}
554     ~Data() {}
555
556     std::nullptr_t nul;
557     Array array;
558     bool boolean;
559     double doubl;
560     int64_t integer;
561     std::string string;
562
563     /*
564      * Objects are placement new'd here.  We have to use a char buffer
565      * because we don't know the type here (std::unordered_map<> with
566      * dynamic would be parameterizing a std:: template with an
567      * incomplete type right now).  (Note that in contrast we know it
568      * is ok to do this with fbvector because we own it.)
569      */
570     std::aligned_storage<
571       sizeof(std::unordered_map<int,int>),
572       alignof(std::unordered_map<int,int>)
573     >::type objectBuffer;
574   } u_;
575 };
576
577 //////////////////////////////////////////////////////////////////////
578
579 } // namespace folly
580
581 #include <folly/dynamic-inl.h>