X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fdynamic-inl.h;h=48666de3ac343efa7ec93e7bc6882e53e712400b;hb=e38fcb3a67efeeaaa5a5906106dee6591bbe7e31;hp=41352ad070ac563ac7976a2c006a4065a9ec4e6c;hpb=0e4a41d08b742f799c7a2ea8224bbd87c214b715;p=folly.git diff --git a/folly/dynamic-inl.h b/folly/dynamic-inl.h index 41352ad0..48666de3 100644 --- a/folly/dynamic-inl.h +++ b/folly/dynamic-inl.h @@ -44,7 +44,7 @@ struct hash< ::folly::dynamic> { do { \ switch ((type)) { \ case NULLT: \ - apply(void*); \ + apply(std::nullptr_t); \ break; \ case ARRAY: \ apply(Array); \ @@ -78,7 +78,7 @@ struct TypeError : std::runtime_error { explicit TypeError(const std::string& expected, dynamic::Type actual); explicit TypeError(const std::string& expected, dynamic::Type actual1, dynamic::Type actual2); - ~TypeError(); + ~TypeError() override; }; @@ -174,10 +174,42 @@ inline dynamic::ObjectMaker dynamic::object(dynamic a, dynamic b) { ////////////////////////////////////////////////////////////////////// +struct dynamic::item_iterator : boost::iterator_adaptor< + dynamic::item_iterator, + dynamic::ObjectImpl::iterator> { + /* implicit */ item_iterator(base_type b) : iterator_adaptor_(b) {} + + using object_type = dynamic::ObjectImpl; + + private: + friend class boost::iterator_core_access; +}; + +struct dynamic::value_iterator : boost::iterator_adaptor< + dynamic::value_iterator, + dynamic::ObjectImpl::iterator, + dynamic> { + /* implicit */ value_iterator(base_type b) : iterator_adaptor_(b) {} + + using object_type = dynamic::ObjectImpl; + + private: + dynamic& dereference() const { + return base_reference()->second; + } + friend class boost::iterator_core_access; +}; + struct dynamic::const_item_iterator : boost::iterator_adaptor { /* implicit */ const_item_iterator(base_type b) : iterator_adaptor_(b) { } + /* implicit */ const_item_iterator(item_iterator i) + : iterator_adaptor_(i.base()) {} + /* implicit */ const_item_iterator(dynamic::ObjectImpl::iterator i) + : iterator_adaptor_(i) {} + + using object_type = dynamic::ObjectImpl const; private: friend class boost::iterator_core_access; @@ -189,6 +221,8 @@ struct dynamic::const_key_iterator dynamic const> { /* implicit */ const_key_iterator(base_type b) : iterator_adaptor_(b) { } + using object_type = dynamic::ObjectImpl const; + private: dynamic const& dereference() const { return base_reference()->first; @@ -201,6 +235,12 @@ struct dynamic::const_value_iterator dynamic::ObjectImpl::const_iterator, dynamic const> { /* implicit */ const_value_iterator(base_type b) : iterator_adaptor_(b) { } + /* implicit */ const_value_iterator(value_iterator i) + : iterator_adaptor_(i.base()) {} + /* implicit */ const_value_iterator(dynamic::ObjectImpl::iterator i) + : iterator_adaptor_(i) {} + + using object_type = dynamic::ObjectImpl const; private: dynamic const& dereference() const { @@ -270,6 +310,9 @@ inline dynamic::~dynamic() noexcept { destroy(); } template struct dynamic::NumericTypeHelper< T, typename std::enable_if::value>::type> { + static_assert( + !kIsObjC || sizeof(T) > sizeof(char), + "char-sized types are ambiguous in objc; cast to bool or wider type"); using type = int64_t; }; template <> @@ -307,12 +350,20 @@ inline dynamic::const_iterator dynamic::end() const { return get().end(); } +inline dynamic::iterator dynamic::begin() { + return get().begin(); +} +inline dynamic::iterator dynamic::end() { + return get().end(); +} + template struct dynamic::IterableProxy { - typedef It const_iterator; + typedef It iterator; typedef typename It::value_type value_type; + typedef typename It::object_type object_type; - /* implicit */ IterableProxy(const dynamic::ObjectImpl* o) : o_(o) { } + /* implicit */ IterableProxy(object_type* o) : o_(o) {} It begin() const { return o_->begin(); @@ -323,7 +374,7 @@ struct dynamic::IterableProxy { } private: - const dynamic::ObjectImpl* o_; + object_type* o_; }; inline dynamic::IterableProxy dynamic::keys() @@ -341,6 +392,14 @@ inline dynamic::IterableProxy dynamic::items() return &(get()); } +inline dynamic::IterableProxy dynamic::values() { + return &(get()); +} + +inline dynamic::IterableProxy dynamic::items() { + return &(get()); +} + inline bool dynamic::isString() const { return get_nothrow() != nullptr; } @@ -360,7 +419,7 @@ inline bool dynamic::isInt() const { return get_nothrow() != nullptr; } inline bool dynamic::isNull() const { - return get_nothrow() != nullptr; + return get_nothrow() != nullptr; } inline bool dynamic::isNumber() const { return isInt() || isDouble(); @@ -425,6 +484,12 @@ struct dynamic::CompareOp { return false; } }; +template<> +struct dynamic::CompareOp { + static bool comp(std::nullptr_t const&, std::nullptr_t const&) { + return true; + } +}; inline dynamic& dynamic::operator+=(dynamic const& o) { if (type() == STRING && o.type() == STRING) { @@ -527,6 +592,9 @@ inline std::size_t dynamic::count(dynamic const& key) const { inline dynamic::const_item_iterator dynamic::find(dynamic const& key) const { return get().find(key); } +inline dynamic::item_iterator dynamic::find(dynamic const& key) { + return get().find(key); +} template inline void dynamic::insert(K&& key, V&& val) { auto& obj = get(); @@ -574,7 +642,7 @@ inline std::size_t dynamic::erase(dynamic const& key) { return obj.erase(key); } -inline dynamic::const_iterator dynamic::erase(const_iterator it) { +inline dynamic::iterator dynamic::erase(const_iterator it) { auto& arr = get(); // std::vector doesn't have an erase method that works on const iterators, // even though the standard says it should, so this hack converts to a @@ -586,30 +654,31 @@ inline dynamic::const_key_iterator dynamic::erase(const_key_iterator it) { return const_key_iterator(get().erase(it.base())); } -inline dynamic::const_key_iterator dynamic::erase(const_key_iterator first, - const_key_iterator last) { +inline dynamic::const_key_iterator dynamic::erase( + const_key_iterator first, + const_key_iterator last) { return const_key_iterator(get().erase(first.base(), last.base())); } -inline dynamic::const_value_iterator dynamic::erase(const_value_iterator it) { - return const_value_iterator(get().erase(it.base())); +inline dynamic::value_iterator dynamic::erase(const_value_iterator it) { + return value_iterator(get().erase(it.base())); } -inline dynamic::const_value_iterator dynamic::erase(const_value_iterator first, - const_value_iterator last) { - return const_value_iterator(get().erase(first.base(), - last.base())); +inline dynamic::value_iterator dynamic::erase( + const_value_iterator first, + const_value_iterator last) { + return value_iterator(get().erase(first.base(), last.base())); } -inline dynamic::const_item_iterator dynamic::erase(const_item_iterator it) { - return const_item_iterator(get().erase(it.base())); +inline dynamic::item_iterator dynamic::erase(const_item_iterator it) { + return item_iterator(get().erase(it.base())); } -inline dynamic::const_item_iterator dynamic::erase(const_item_iterator first, - const_item_iterator last) { - return const_item_iterator(get().erase(first.base(), - last.base())); +inline dynamic::item_iterator dynamic::erase( + const_item_iterator first, + const_item_iterator last) { + return item_iterator(get().erase(first.base(), last.base())); } inline void dynamic::resize(std::size_t sz, dynamic const& c) { @@ -645,7 +714,7 @@ inline dynamic::dynamic(Array&& r) : type_(ARRAY) { }; \ // -FOLLY_DYNAMIC_DEC_TYPEINFO(void*, "null", dynamic::NULLT) +FOLLY_DYNAMIC_DEC_TYPEINFO(std::nullptr_t, "null", dynamic::NULLT) FOLLY_DYNAMIC_DEC_TYPEINFO(bool, "boolean", dynamic::BOOL) FOLLY_DYNAMIC_DEC_TYPEINFO(std::string, "string", dynamic::STRING) FOLLY_DYNAMIC_DEC_TYPEINFO(dynamic::Array, "array", dynamic::ARRAY) @@ -695,8 +764,8 @@ T const* dynamic::getAddress() const noexcept { } template struct dynamic::GetAddrImpl {}; -template<> struct dynamic::GetAddrImpl { - static void** get(Data& d) noexcept { return &d.nul; } +template<> struct dynamic::GetAddrImpl { + static std::nullptr_t* get(Data& d) noexcept { return &d.nul; } }; template<> struct dynamic::GetAddrImpl { static Array* get(Data& d) noexcept { return &d.array; } @@ -755,11 +824,10 @@ struct dynamic::PrintImpl { }; // Otherwise, null, being (void*)0, would print as 0. template <> -struct dynamic::PrintImpl { +struct dynamic::PrintImpl { static void print(dynamic const& /* d */, std::ostream& out, - void* const& nul) { - DCHECK_EQ((void*)0, nul); + std::nullptr_t const&) { out << "null"; } };