X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FDynamicConverter.h;h=d64dcc2827bcada3ba2ba986a311d53364de605e;hb=edec0c3fd0bb5f709eb8988fed2c782177274197;hp=7068d88ea0e81918090df6e64ea92f65d0be0a30;hpb=333ed393c83190fc6935837c3e61e4f9bc38e2bc;p=folly.git diff --git a/folly/DynamicConverter.h b/folly/DynamicConverter.h index 7068d88e..d64dcc28 100644 --- a/folly/DynamicConverter.h +++ b/folly/DynamicConverter.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Facebook, Inc. + * Copyright 2014 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,9 +19,10 @@ #ifndef DYNAMIC_CONVERTER_H #define DYNAMIC_CONVERTER_H -#include "folly/dynamic.h" +#include namespace folly { template T convertTo(const dynamic&); + template dynamic toDynamic(const T&); } /** @@ -40,7 +41,7 @@ namespace folly { #include #include #include -#include "folly/Likely.h" +#include namespace folly { @@ -51,6 +52,7 @@ namespace dynamicconverter_detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type); BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator); +BOOST_MPL_HAS_XXX_TRAIT_DEF(mapped_type); template struct class_is_container { typedef std::reverse_iterator some_iterator; @@ -59,6 +61,12 @@ template struct class_is_container { std::is_constructible::value }; }; +template struct class_is_range { + enum { value = has_value_type::value && + has_iterator::value }; +}; + + template struct is_container : std::conditional< std::is_class::value, @@ -66,6 +74,19 @@ template struct is_container std::false_type >::type {}; +template struct is_range + : std::conditional< + std::is_class::value, + class_is_range, + std::false_type + >::type {}; + +template struct is_map + : std::integral_constant< + bool, + is_range::value && has_mapped_type::value + > {}; + } // namespace dynamicconverter_detail /////////////////////////////////////////////////////////////////////////////// @@ -157,13 +178,14 @@ conversionIterator(const It& it) { /////////////////////////////////////////////////////////////////////////////// // DynamicConverter specializations -template struct DynamicConverter; - /** * Each specialization of DynamicConverter has the function - * 'static T convert(const dynamic& d);' + * 'static T convert(const dynamic&);' */ +// default - intentionally unimplemented +template struct DynamicConverter; + // boolean template <> struct DynamicConverter { @@ -178,7 +200,7 @@ struct DynamicConverter::value && !std::is_same::value>::type> { static T convert(const dynamic& d) { - return static_cast(d.asInt()); + return folly::to(d.asInt()); } }; @@ -187,7 +209,7 @@ template struct DynamicConverter::value>::type> { static T convert(const dynamic& d) { - return static_cast(d.asDouble()); + return folly::to(d.asDouble()); } }; @@ -243,13 +265,75 @@ struct DynamicConverter +struct DynamicConstructor { + static dynamic construct(const C& x) { + return dynamic(x); + } +}; + +// maps +template +struct DynamicConstructor::value>::type> { + static dynamic construct(const C& x) { + dynamic d = dynamic::object; + for (auto& pair : x) { + d.insert(toDynamic(pair.first), toDynamic(pair.second)); + } + return d; + } +}; + +// other ranges +template +struct DynamicConstructor::value && + !std::is_constructible::value && + dynamicconverter_detail::is_range::value>::type> { + static dynamic construct(const C& x) { + dynamic d = {}; + for (auto& item : x) { + d.push_back(toDynamic(item)); + } + return d; + } +}; + +// pair +template +struct DynamicConstructor, void> { + static dynamic construct(const std::pair& x) { + dynamic d = {}; + d.push_back(toDynamic(x.first)); + d.push_back(toDynamic(x.second)); + return d; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// implementation template T convertTo(const dynamic& d) { return DynamicConverter::type>::convert(d); } +template +dynamic toDynamic(const T& x) { + return DynamicConstructor::type>::construct(x); +} + } // namespace folly #endif // DYNAMIC_CONVERTER_H