add makeSystemError*() helper functions
[folly.git] / folly / dynamic.h
index 7087975931b11b4300b2d2c25ed726cc638b92ce..ad88edc525ff324d8322c5f67154e1fa3f661641 100644 (file)
@@ -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.
  * 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 <delong.j@fb.com>
@@ -63,7 +53,6 @@
 #pragma once
 
 #include <cstdint>
-#include <initializer_list>
 #include <memory>
 #include <ostream>
 #include <string>
@@ -96,6 +85,7 @@ struct dynamic : private boost::operators<dynamic> {
     OBJECT,
     STRING,
   };
+  template <class T, class Enable = void> struct NumericTypeHelper;
 
   /*
    * We support direct iteration of arrays, and indirect iteration of objects.
@@ -106,15 +96,21 @@ struct dynamic : private boost::operators<dynamic> {
    * Object value iterators dereference as the values in the object.
    * Object item iterators dereference as pairs of (key, value).
    */
-private:
+ private:
   typedef std::vector<dynamic> 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
@@ -134,29 +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 <class... Args>
   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(std::string&& val);
+  /* implicit */ dynamic(std::string val);
 
   /*
    * This is part of the plumbing for array() and object(), above.
@@ -168,31 +165,18 @@ public:
   /* implicit */ dynamic(ObjectMaker&&);
 
   /*
-   * Create a new array from an initializer list.
-   *
-   * For example:
-   *
-   *   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);
-  FOLLY_DEPRECATED(
-      "Initializer list syntax is deprecated (#10300209). Use dynamic::array.")
-  dynamic& operator=(std::initializer_list<dynamic> il);
-
-  /*
-   * Conversion constructors from most of the other types.
+   * Constructors for integral and float types.
+   * Other types are SFINAEd out with NumericTypeHelper.
    */
-  template<class T> /* implicit */ dynamic(T t);
+  template <class T, class NumericType = typename NumericTypeHelper<T>::type>
+  /* implicit */ dynamic(T t);
 
   /*
    * Create a dynamic that is an array of the values from the supplied
    * iterator range.
    */
-  template<class Iterator> dynamic(Iterator first, Iterator last);
+  template <class Iterator>
+  explicit dynamic(Iterator first, Iterator last);
 
   dynamic(dynamic const&);
   dynamic(dynamic&&) noexcept;
@@ -342,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 <class T> 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.
@@ -357,6 +343,8 @@ public:
   IterableProxy<const_key_iterator> keys() const;
   IterableProxy<const_value_iterator> values() const;
   IterableProxy<const_item_iterator> items() const;
+  IterableProxy<value_iterator> values();
+  IterableProxy<item_iterator> items();
 
   /*
    * AssociativeContainer-style find interface for objects.  Throws if
@@ -366,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
@@ -429,15 +418,15 @@ 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<class K, class V>
+  template <class K, class V>
   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<class K>
+  template <class K>
   dynamic& setDefault(K&& k, dynamic&& v);
-  template<class K>
+  template <class K>
   dynamic& setDefault(K&& k, const dynamic& v = dynamic::object);
 
   /*
@@ -457,7 +446,7 @@ public:
    *
    * Invalidates iterators.
    */
-  template<class K, class V> void insert(K&&, V&& val);
+  template <class K, class V> void insert(K&&, V&& val);
 
   /*
    * These functions merge two folly dynamic objects.
@@ -497,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.
@@ -535,40 +522,38 @@ public:
    */
   std::size_t hash() const;
 
-private:
+ private:
   friend struct TypeError;
   struct ObjectImpl;
-  template<class T> struct TypeInfo;
-  template<class T> struct CompareOp;
-  template<class T> struct GetAddrImpl;
-  template<class T> struct PrintImpl;
+  template <class T> struct TypeInfo;
+  template <class T> struct CompareOp;
+  template <class T> struct GetAddrImpl;
+  template <class T> struct PrintImpl;
 
-  dynamic(Array&& array, PrivateTag);
+  explicit dynamic(Array&& array);
 
-  template<class T> T const& get() const;
-  template<class T> T&       get();
-  template<class T> T*       get_nothrow() & noexcept;
-  template<class T> T const* get_nothrow() const& noexcept;
-  template<class T> T*       get_nothrow() && noexcept = delete;
-  template<class T> T*       getAddress() noexcept;
-  template<class T> T const* getAddress() const noexcept;
+  template <class T> T const& get() const;
+  template <class T> T&       get();
+  template <class T> T*       get_nothrow() & noexcept;
+  template <class T> T const* get_nothrow() const& noexcept;
+  template <class T> T*       get_nothrow() && noexcept = delete;
+  template <class T> T*       getAddress() noexcept;
+  template <class T> T const* getAddress() const noexcept;
 
-  template<class T> T asImpl() const;
+  template <class T> 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;
@@ -591,6 +576,6 @@ private:
 
 //////////////////////////////////////////////////////////////////////
 
-}
+} // namespace folly
 
 #include <folly/dynamic-inl.h>