add pop_back to arrays
[folly.git] / folly / dynamic.h
1 /*
2  * Copyright 2012 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"] = { "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", { "a", "array" })
43  *     ;
44  *
45  * Also see folly/json.h for the serialization and deserialization
46  * functions for JSON.
47  *
48  * Note: dynamic is not DefaultConstructible.  Rationale:
49  *
50  *   - The intuitive thing to initialize a defaulted dynamic to would
51  *     be nullptr.
52  *
53  *   - However, the expression dynamic d = {} is required to call the
54  *     default constructor by the standard, which is confusing
55  *     behavior for dynamic unless the default constructor creates an
56  *     empty array.
57  *
58  * Additional documentation is in folly/docs/Dynamic.md.
59  *
60  * @author Jordan DeLong <delong.j@fb.com>
61  */
62
63 #ifndef FOLLY_DYNAMIC_H_
64 #define FOLLY_DYNAMIC_H_
65
66 #include <unordered_map>
67 #include <memory>
68 #include <string>
69 #include <utility>
70 #include <ostream>
71 #include <type_traits>
72 #include <initializer_list>
73 #include <vector>
74 #include <cstdint>
75 #include <boost/operators.hpp>
76
77 #include "folly/Traits.h"
78 #include "folly/FBString.h"
79
80 namespace folly {
81
82 //////////////////////////////////////////////////////////////////////
83
84 struct dynamic;
85 struct TypeError;
86
87 //////////////////////////////////////////////////////////////////////
88
89 struct dynamic : private boost::operators<dynamic> {
90   enum Type {
91     NULLT,
92     ARRAY,
93     BOOL,
94     DOUBLE,
95     INT64,
96     OBJECT,
97     STRING,
98   };
99
100   /*
101    * We support direct iteration of arrays, and indirect iteration of objects.
102    * See begin(), end(), keys(), values(), and items() for more.
103    *
104    * Array iterators dereference as the elements in the array.
105    * Object key iterators dereference as the keys in the object.
106    * Object value iterators dereference as the values in the object.
107    * Object item iterators dereference as pairs of (key, value).
108    */
109 private:
110   typedef std::vector<dynamic> Array;
111 public:
112   typedef Array::const_iterator const_iterator;
113   struct const_key_iterator;
114   struct const_value_iterator;
115   struct const_item_iterator;
116
117   /*
118    * Creation routines for making dynamic objects.  Objects are maps
119    * from key to value (so named due to json-related origins here).
120    *
121    * Example:
122    *
123    *   // Make a fairly complex dynamic:
124    *   dynamic d = dynamic::object("key", "value1")
125    *                              ("key2", { "value", "with", 4, "words" });
126    *
127    *   // Build an object in a few steps:
128    *   dynamic d = dynamic::object;
129    *   d["key"] = 12;
130    *   d["something_else"] = { 1, 2, 3, nullptr };
131    */
132 private:
133   struct ObjectMaker;
134
135 public:
136   template<class... Args> static ObjectMaker object(Args&&...);
137
138   /*
139    * String compatibility constructors.
140    */
141   /* implicit */ dynamic(char const* val);
142   /* implicit */ dynamic(std::string const& val);
143
144   /*
145    * This is part of the plumbing for object(), above.  Used to create
146    * a new object dynamic.
147    */
148   /* implicit */ dynamic(ObjectMaker (*)());
149   /* implicit */ dynamic(ObjectMaker const&) = delete;
150   /* implicit */ dynamic(ObjectMaker&&);
151
152   /*
153    * Create a new array from an initializer list.
154    *
155    * For example:
156    *
157    *   dynamic v = { 1, 2, 3, "foo" };
158    */
159   /* implicit */ dynamic(std::initializer_list<dynamic> il);
160
161   /*
162    * Conversion constructors from most of the other types.
163    */
164   template<class T> /* implicit */ dynamic(T t);
165
166   /*
167    * Create a dynamic that is an array of the values from the supplied
168    * iterator range.
169    */
170   template<class Iterator> dynamic(Iterator first, Iterator last);
171
172   dynamic(dynamic const&);
173   dynamic(dynamic&&);
174   ~dynamic();
175
176   /*
177    * "Deep" equality comparison.  This will compare all the way down
178    * an object or array, and is potentially expensive.
179    */
180   bool operator==(dynamic const& o) const;
181
182   /*
183    * For all types except object this returns the natural ordering on
184    * those types.  For objects, we throw TypeError.
185    */
186   bool operator<(dynamic const& o) const;
187
188   /*
189    * General operators.
190    *
191    * These throw TypeError when used with types or type combinations
192    * that don't support them.
193    *
194    * These functions may also throw if you use 64-bit integers with
195    * doubles when the integers are too big to fit in a double.
196    */
197   dynamic& operator+=(dynamic const&);
198   dynamic& operator-=(dynamic const&);
199   dynamic& operator*=(dynamic const&);
200   dynamic& operator/=(dynamic const&);
201   dynamic& operator%=(dynamic const&);
202   dynamic& operator|=(dynamic const&);
203   dynamic& operator&=(dynamic const&);
204   dynamic& operator^=(dynamic const&);
205   dynamic& operator++();
206   dynamic& operator--();
207
208   /*
209    * Assignment from other dynamics.  Because of the implicit conversion
210    * to dynamic from its potential types, you can use this to change the
211    * type pretty intuitively.
212    *
213    * Basic guarantee only.
214    */
215   dynamic& operator=(dynamic const&);
216   dynamic& operator=(dynamic&&);
217
218   /*
219    * For simple dynamics (not arrays or objects), this prints the
220    * value to an std::ostream in the expected way.  Respects the
221    * formatting manipulators that have been sent to the stream
222    * already.
223    *
224    * If the dynamic holds an object or array, this prints them in a
225    * format very similar to JSON.  (It will in fact actually be JSON
226    * as long as the dynamic validly represents a JSON object---i.e. it
227    * can't have non-string keys.)
228    */
229   friend std::ostream& operator<<(std::ostream&, dynamic const&);
230
231   /*
232    * Returns true if this dynamic is of the specified type.
233    */
234   bool isString() const;
235   bool isObject() const;
236   bool isBool() const;
237   bool isNull() const;
238   bool isArray() const;
239   bool isDouble() const;
240   bool isInt() const;
241
242   /*
243    * Returns: isInt() || isDouble().
244    */
245   bool isNumber() const;
246
247   /*
248    * Returns the type of this dynamic.
249    */
250   Type type() const;
251
252   /*
253    * Extract a value while trying to convert to the specified type.
254    * Throws exceptions if we cannot convert from the real type to the
255    * requested type.
256    *
257    * Note you can only use this to access integral types or strings,
258    * since arrays and objects are generally best delt with as a
259    * dynamic.
260    */
261   fbstring asString() const;
262   double   asDouble() const;
263   int64_t  asInt() const;
264   bool     asBool() const;
265
266   /*
267    * Returns: true if this dynamic is null, an empty array, an empty
268    * object, or an empty string.
269    */
270   bool empty() const;
271
272   /*
273    * If this is an array or an object, returns the number of elements
274    * contained.  If it is a string, returns the length.  Otherwise
275    * throws TypeError.
276    */
277   std::size_t size() const;
278
279   /*
280    * You can iterate over the values of the array.  Calling these on
281    * non-arrays will throw a TypeError.
282    */
283   const_iterator begin()  const;
284   const_iterator end()    const;
285
286 private:
287   /*
288    * Helper object returned by keys(), values(), and items().
289    */
290   template <class T> struct IterableProxy;
291
292 public:
293   /*
294    * You can iterate over the keys, values, or items (std::pair of key and
295    * value) in an object.  Calling these on non-objects will throw a TypeError.
296    */
297   IterableProxy<const_key_iterator> keys() const;
298   IterableProxy<const_value_iterator> values() const;
299   IterableProxy<const_item_iterator> items() const;
300
301   /*
302    * AssociativeContainer-style find interface for objects.  Throws if
303    * this is not an object.
304    *
305    * Returns: end() if the key is not present, or an iterator pointing
306    * to the item.
307    */
308   const_item_iterator find(dynamic const&) const;
309
310   /*
311    * If this is an object, returns whether it contains a field with
312    * the given name.  Otherwise throws TypeError.
313    */
314   std::size_t count(dynamic const&) const;
315
316   /*
317    * For objects or arrays, provides access to sub-fields by index or
318    * field name.
319    *
320    * Using these with dynamic objects that are not arrays or objects
321    * will throw a TypeError.  Using an index that is out of range or
322    * object-element that's not present throws std::out_of_range.
323    */
324   dynamic const& at(dynamic const&) const;
325   dynamic&       at(dynamic const&);
326
327   /*
328    * This works for access to both objects and arrays.
329    *
330    * In the case of an array, the index must be an integer, and this will throw
331    * std::out_of_range if it is less than zero or greater than size().
332    *
333    * In the case of an object, the non-const overload inserts a null
334    * value if the key isn't present.  The const overload will throw
335    * std::out_of_range if the key is not present.
336    *
337    * These functions do not invalidate iterators.
338    */
339   dynamic&       operator[](dynamic const&);
340   dynamic const& operator[](dynamic const&) const;
341
342   /*
343    * Only defined for objects, throws TypeError otherwise.
344    *
345    * getDefault will return the value associated with the supplied key, the
346    * supplied default otherwise. setDefault will set the key to the supplied
347    * default if it is not yet set, otherwise leaving it. setDefault returns
348    * a reference to the existing value if present, the new value otherwise.
349    */
350   dynamic
351   getDefault(const dynamic& k, const dynamic& v = dynamic::object) const;
352   dynamic&& getDefault(const dynamic& k, dynamic&& v) const;
353   template<class K, class V = dynamic>
354   dynamic& setDefault(K&& k, V&& v = dynamic::object);
355
356   /*
357    * Resizes an array so it has at n elements, using the supplied
358    * default to fill new elements.  Throws TypeError if this dynamic
359    * is not an array.
360    *
361    * May invalidate iterators.
362    *
363    * Post: size() == n
364    */
365   void resize(std::size_t n, dynamic const& = nullptr);
366
367   /*
368    * Inserts the supplied key-value pair to an object, or throws if
369    * it's not an object.
370    *
371    * Invalidates iterators.
372    */
373   template<class K, class V> void insert(K&&, V&& val);
374
375   /*
376    * Erase an element from a dynamic object, by key.
377    *
378    * Invalidates iterators to the element being erased.
379    *
380    * Returns the number of elements erased (i.e. 1 or 0).
381    */
382   std::size_t erase(dynamic const& key);
383
384   /*
385    * Erase an element from a dynamic object or array, using an
386    * iterator or an iterator range.
387    *
388    * In arrays, invalidates iterators to elements after the element
389    * being erased.  In objects, invalidates iterators to the elements
390    * being erased.
391    *
392    * Returns a new iterator to the first element beyond any elements
393    * removed, or end() if there are none.  (The iteration order does
394    * not change.)
395    */
396   const_iterator erase(const_iterator it);
397   const_iterator erase(const_iterator first, const_iterator last);
398
399   const_key_iterator erase(const_key_iterator it);
400   const_key_iterator erase(const_key_iterator first, const_key_iterator last);
401
402   const_value_iterator erase(const_value_iterator it);
403   const_value_iterator erase(const_value_iterator first,
404                              const_value_iterator last);
405
406   const_item_iterator erase(const_item_iterator it);
407   const_item_iterator erase(const_item_iterator first,
408                             const_item_iterator last);
409   /*
410    * Append elements to an array.  If this is not an array, throws
411    * TypeError.
412    *
413    * Invalidates iterators.
414    */
415   void push_back(dynamic const&);
416   void push_back(dynamic&&);
417
418   /*
419    * Remove an element from the back of an array.  If this is not an array,
420    * throws TypeError.
421    *
422    * Does not invalidate iterators.
423    */
424   void pop_back();
425
426   /*
427    * Get a hash code.  This function is called by a std::hash<>
428    * specialization, also.
429    *
430    * Throws TypeError if this is an object, array, or null.
431    */
432   std::size_t hash() const;
433
434 private:
435   friend struct TypeError;
436   struct ObjectImpl;
437   struct ObjectMaker;
438   template<class T> struct TypeInfo;
439   template<class T> struct CompareOp;
440   template<class T> struct GetAddrImpl;
441   template<class T> struct PrintImpl;
442
443   template<class T> T const& get() const;
444   template<class T> T&       get();
445   template<class T> T*       get_nothrow();
446   template<class T> T const* get_nothrow() const;
447   template<class T> T*       getAddress();
448   template<class T> T const* getAddress() const;
449
450   template<class T> T asImpl() const;
451
452   static char const* typeName(Type);
453   void destroy();
454   void print(std::ostream&) const;
455   void print_as_pseudo_json(std::ostream&) const; // see json.cpp
456
457 private:
458   Type type_;
459   union Data {
460     explicit Data() : nul(nullptr) {}
461     ~Data() {}
462
463     // XXX: gcc does an ICE if we use std::nullptr_t instead of void*
464     // here.  See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50361
465     void* nul;
466     Array array;
467     bool boolean;
468     double doubl;
469     int64_t integer;
470     fbstring string;
471
472     /*
473      * Objects are placement new'd here.  We have to use a char buffer
474      * because we don't know the type here (std::unordered_map<> with
475      * dynamic would be parameterizing a std:: template with an
476      * incomplete type right now).  (Note that in contrast we know it
477      * is ok to do this with fbvector because we own it.)
478      */
479     typename std::aligned_storage<
480       sizeof(std::unordered_map<int,int>),
481       alignof(std::unordered_map<int,int>)
482     >::type objectBuffer;
483   } u_;
484 };
485
486 //////////////////////////////////////////////////////////////////////
487
488 }
489
490 #include "folly/dynamic-inl.h"
491
492 #endif