#pragma once
-#include <folly/dynamic.h>
+#include <iterator>
+#include <type_traits>
+
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/mpl/has_xxx.hpp>
+
+#include <folly/Likely.h>
+#include <folly/Optional.h>
#include <folly/Traits.h>
+#include <folly/dynamic.h>
namespace folly {
- template <typename T> T convertTo(const dynamic&);
- template <typename T> dynamic toDynamic(const T&);
-}
+template <typename T>
+T convertTo(const dynamic&);
+template <typename T>
+dynamic toDynamic(const T&);
+} // namespace folly
/**
* convertTo returns a well-typed representation of the input dynamic.
* See docs/DynamicConverter.md for supported types and customization
*/
-
-#include <type_traits>
-#include <iterator>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/mpl/has_xxx.hpp>
-#include <folly/Likely.h>
-
namespace folly {
///////////////////////////////////////////////////////////////////////////////
namespace dynamicconverter_detail {
-template<typename T>
+template <typename T>
struct Dereferencer {
static inline void derefToCache(
- T* /* mem */, const dynamic::const_item_iterator& /* it */) {
+ Optional<T>* /* mem */,
+ const dynamic::const_item_iterator& /* it */) {
throw TypeError("array", dynamic::Type::OBJECT);
}
- static inline void derefToCache(T* mem, const dynamic::const_iterator& it) {
- new (mem) T(convertTo<T>(*it));
+ static inline void derefToCache(
+ Optional<T>* mem,
+ const dynamic::const_iterator& it) {
+ mem->emplace(convertTo<T>(*it));
}
};
-template<typename F, typename S>
+template <typename F, typename S>
struct Dereferencer<std::pair<F, S>> {
- static inline void
- derefToCache(std::pair<F, S>* mem, const dynamic::const_item_iterator& it) {
- new (mem) std::pair<F, S>(
- convertTo<F>(it->first), convertTo<S>(it->second)
- );
+ static inline void derefToCache(
+ Optional<std::pair<F, S>>* mem,
+ const dynamic::const_item_iterator& it) {
+ mem->emplace(convertTo<F>(it->first), convertTo<S>(it->second));
}
// Intentional duplication of the code in Dereferencer
template <typename T>
- static inline void derefToCache(T* mem, const dynamic::const_iterator& it) {
- new (mem) T(convertTo<T>(*it));
+ static inline void derefToCache(
+ Optional<T>* mem,
+ const dynamic::const_iterator& it) {
+ mem->emplace(convertTo<T>(*it));
}
};
typedef typename T::value_type ttype;
- mutable ttype cache_;
- mutable bool valid_;
+ mutable Optional<ttype> cache_;
void increment() {
++this->base_reference();
- valid_ = false;
+ cache_ = none;
}
ttype& dereference() const {
- if (LIKELY(!valid_)) {
- cache_.~ttype();
+ if (!cache_) {
Dereferencer<ttype>::derefToCache(&cache_, this->base_reference());
- valid_ = true;
}
- return cache_;
+ return cache_.value();
}
public:
- explicit Transformer(const It& it)
- : Transformer::iterator_adaptor_(it), valid_(false) {}
+ explicit Transformer(const It& it) : Transformer::iterator_adaptor_(it) {}
};
// conversion factory
};
// pair
-template<typename A, typename B>
+template <typename A, typename B>
struct DynamicConstructor<std::pair<A, B>, void> {
static dynamic construct(const std::pair<A, B>& x) {
dynamic d = dynamic::array;
return DynamicConverter<typename std::remove_cv<T>::type>::convert(d);
}
-template<typename T>
+template <typename T>
dynamic toDynamic(const T& x) {
return DynamicConstructor<typename std::remove_cv<T>::type>::construct(x);
}