Update SSLContext to use folly::Random and discrete_distribution
[folly.git] / folly / DynamicConverter.h
index 2c3d2c1d9691b01a20fc3e704f78df885aec5723..4c8b910cc466a3af4d03ccb40e455391c2ae1250 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 #ifndef DYNAMIC_CONVERTER_H
 #define DYNAMIC_CONVERTER_H
 
-#include "folly/dynamic.h"
+#include <folly/dynamic.h>
 namespace folly {
   template <typename T> T convertTo(const dynamic&);
   template <typename T> dynamic toDynamic(const T&);
@@ -41,7 +41,7 @@ namespace folly {
 #include <iterator>
 #include <boost/iterator/iterator_adaptor.hpp>
 #include <boost/mpl/has_xxx.hpp>
-#include "folly/Likely.h"
+#include <folly/Likely.h>
 
 namespace folly {
 
@@ -54,13 +54,20 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type);
 BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator);
 BOOST_MPL_HAS_XXX_TRAIT_DEF(mapped_type);
 
-template <typename T> struct class_is_container {
-  typedef std::reverse_iterator<T*> some_iterator;
+template <typename T> struct iterator_class_is_container {
+  typedef std::reverse_iterator<typename T::iterator> some_iterator;
   enum { value = has_value_type<T>::value &&
-                 has_iterator<T>::value &&
               std::is_constructible<T, some_iterator, some_iterator>::value };
 };
 
+template <typename T>
+using class_is_container = typename
+  std::conditional<
+    has_iterator<T>::value,
+    iterator_class_is_container<T>,
+    std::false_type
+  >::type;
+
 template <typename T> struct class_is_range {
   enum { value = has_value_type<T>::value &&
                  has_iterator<T>::value };
@@ -81,7 +88,7 @@ template <typename T> struct is_range
       std::false_type
     >::type {};
 
-template <typename T> struct is_associative_container
+template <typename T> struct is_map
   : std::integral_constant<
       bool,
       is_range<T>::value && has_mapped_type<T>::value
@@ -168,7 +175,7 @@ public:
 
 // conversion factory
 template <typename T, typename It>
-static inline std::move_iterator<Transformer<T, It>>
+inline std::move_iterator<Transformer<T, It>>
 conversionIterator(const It& it) {
   return std::make_move_iterator(Transformer<T, It>(it));
 }
@@ -178,13 +185,14 @@ conversionIterator(const It& it) {
 ///////////////////////////////////////////////////////////////////////////////
 // DynamicConverter specializations
 
-template <typename T, typename Enable = void> struct DynamicConverter;
-
 /**
  * Each specialization of DynamicConverter has the function
- *     'static T convert(const dynamic& d);'
+ *     'static T convert(const dynamic&);'
  */
 
+// default - intentionally unimplemented
+template <typename T, typename Enable = void> struct DynamicConverter;
+
 // boolean
 template <>
 struct DynamicConverter<bool> {
@@ -199,7 +207,7 @@ struct DynamicConverter<T,
     typename std::enable_if<std::is_integral<T>::value &&
                             !std::is_same<T, bool>::value>::type> {
   static T convert(const dynamic& d) {
-    return static_cast<T>(d.asInt());
+    return folly::to<T>(d.asInt());
   }
 };
 
@@ -208,7 +216,7 @@ template <typename T>
 struct DynamicConverter<T,
     typename std::enable_if<std::is_floating_point<T>::value>::type> {
   static T convert(const dynamic& d) {
-    return static_cast<T>(d.asDouble());
+    return folly::to<T>(d.asDouble());
   }
 };
 
@@ -261,9 +269,17 @@ struct DynamicConverter<C,
       throw TypeError("object or array", d.type());
     }
   }
-
 };
 
+///////////////////////////////////////////////////////////////////////////////
+// DynamicConstructor specializations
+
+/**
+ * Each specialization of DynamicConstructor has the function
+ *     'static dynamic construct(const C&);'
+ */
+
+// default
 template <typename C, typename Enable = void>
 struct DynamicConstructor {
   static dynamic construct(const C& x) {
@@ -271,10 +287,11 @@ struct DynamicConstructor {
   }
 };
 
+// maps
 template<typename C>
 struct DynamicConstructor<C,
     typename std::enable_if<
-      dynamicconverter_detail::is_associative_container<C>::value>::type> {
+      dynamicconverter_detail::is_map<C>::value>::type> {
   static dynamic construct(const C& x) {
     dynamic d = dynamic::object;
     for (auto& pair : x) {
@@ -284,10 +301,11 @@ struct DynamicConstructor<C,
   }
 };
 
+// other ranges
 template<typename C>
 struct DynamicConstructor<C,
     typename std::enable_if<
-      !dynamicconverter_detail::is_associative_container<C>::value &&
+      !dynamicconverter_detail::is_map<C>::value &&
       !std::is_constructible<StringPiece, const C&>::value &&
       dynamicconverter_detail::is_range<C>::value>::type> {
   static dynamic construct(const C& x) {
@@ -299,6 +317,7 @@ struct DynamicConstructor<C,
   }
 };
 
+// pair
 template<typename A, typename B>
 struct DynamicConstructor<std::pair<A, B>, void> {
   static dynamic construct(const std::pair<A, B>& x) {
@@ -310,7 +329,7 @@ struct DynamicConstructor<std::pair<A, B>, void> {
 };
 
 ///////////////////////////////////////////////////////////////////////////////
-// convertTo implementation
+// implementation
 
 template <typename T>
 T convertTo(const dynamic& d) {
@@ -325,4 +344,3 @@ dynamic toDynamic(const T& x) {
 } // namespace folly
 
 #endif // DYNAMIC_CONVERTER_H
-