Commit c09be5f4 authored by Amol Bhave's avatar Amol Bhave Committed by Facebook Github Bot

use heterogenous operations for get_ptr(dynamic)

Summary:
This diff adds support for doing heterogenous lookups
to the dynamic::get_ptr(dynamic) function.

Reviewed By: yfeldblum

Differential Revision: D10007208

fbshipit-source-id: 2453f3fe8ab36dfd9e5627aa75cf8eb7aee51699
parent bdb2a715
...@@ -689,7 +689,19 @@ inline dynamic& dynamic::setDefault(K&& k, const dynamic& v) { ...@@ -689,7 +689,19 @@ inline dynamic& dynamic::setDefault(K&& k, const dynamic& v) {
return obj.emplace(std::forward<K>(k), v).first->second; return obj.emplace(std::forward<K>(k), v).first->second;
} }
inline dynamic* dynamic::get_ptr(dynamic const& idx) & { template <typename K>
dynamic::IfIsNonStringDynamicConvertible<K, dynamic const*> dynamic::get_ptr(
K&& k) const& {
return get_ptrImpl(std::forward<K>(k));
}
template <typename K>
dynamic::IfIsNonStringDynamicConvertible<K, dynamic*> dynamic::get_ptr(
K&& idx) & {
return const_cast<dynamic*>(const_cast<dynamic const*>(this)->get_ptr(idx));
}
inline dynamic* dynamic::get_ptr(StringPiece idx) & {
return const_cast<dynamic*>(const_cast<dynamic const*>(this)->get_ptr(idx)); return const_cast<dynamic*>(const_cast<dynamic const*>(this)->get_ptr(idx));
} }
......
...@@ -240,7 +240,7 @@ dynamic dynamic::getDefault(const dynamic& k, dynamic&& v) && { ...@@ -240,7 +240,7 @@ dynamic dynamic::getDefault(const dynamic& k, dynamic&& v) && {
return std::move(it == obj.end() ? v : it->second); return std::move(it == obj.end() ? v : it->second);
} }
const dynamic* dynamic::get_ptr(dynamic const& idx) const& { const dynamic* dynamic::get_ptrImpl(dynamic const& idx) const& {
if (auto* parray = get_nothrow<Array>()) { if (auto* parray = get_nothrow<Array>()) {
if (!idx.isInt()) { if (!idx.isInt()) {
throw_exception<TypeError>("int64", idx.type()); throw_exception<TypeError>("int64", idx.type());
...@@ -260,6 +260,18 @@ const dynamic* dynamic::get_ptr(dynamic const& idx) const& { ...@@ -260,6 +260,18 @@ const dynamic* dynamic::get_ptr(dynamic const& idx) const& {
} }
} }
const dynamic* dynamic::get_ptr(StringPiece idx) const& {
auto* pobject = get_nothrow<ObjectImpl>();
if (!pobject) {
throw_exception<TypeError>("object", type());
}
auto it = pobject->find(idx);
if (it == pobject->end()) {
return nullptr;
}
return &it->second;
}
std::size_t dynamic::size() const { std::size_t dynamic::size() const {
if (auto* ar = get_nothrow<Array>()) { if (auto* ar = get_nothrow<Array>()) {
return ar->size(); return ar->size();
......
...@@ -449,9 +449,20 @@ struct dynamic : private boost::operators<dynamic> { ...@@ -449,9 +449,20 @@ struct dynamic : private boost::operators<dynamic> {
* Using these with dynamic objects that are not arrays or objects * Using these with dynamic objects that are not arrays or objects
* will throw a TypeError. * will throw a TypeError.
*/ */
const dynamic* get_ptr(dynamic const&) const&; private:
dynamic* get_ptr(dynamic const&) &; const dynamic* get_ptrImpl(dynamic const&) const&;
dynamic* get_ptr(dynamic const&) && = delete;
public:
template <typename K>
IfIsNonStringDynamicConvertible<K, const dynamic*> get_ptr(K&&) const&;
template <typename K>
IfIsNonStringDynamicConvertible<K, dynamic*> get_ptr(K&&) &;
template <typename K>
IfIsNonStringDynamicConvertible<K, dynamic*> get_ptr(K&&) && = delete;
const dynamic* get_ptr(StringPiece) const&;
dynamic* get_ptr(StringPiece) &;
dynamic* get_ptr(StringPiece) && = delete;
/* /*
* This works for access to both objects and arrays. * This works for access to both objects and arrays.
......
...@@ -219,6 +219,37 @@ TEST(Dynamic, ObjectHeterogeneousAccess) { ...@@ -219,6 +219,37 @@ TEST(Dynamic, ObjectHeterogeneousAccess) {
EXPECT_THROW(obj.at(StringPiece{b}), std::out_of_range); EXPECT_THROW(obj.at(StringPiece{b}), std::out_of_range);
EXPECT_THROW(obj.at(StaticStrings::kBar), std::out_of_range); EXPECT_THROW(obj.at(StaticStrings::kBar), std::out_of_range);
// get_ptr()
EXPECT_NE(obj.get_ptr(empty), nullptr);
EXPECT_EQ(*obj.get_ptr(empty), 456);
EXPECT_NE(obj.get_ptr(nullptr), nullptr);
EXPECT_EQ(*obj.get_ptr(nullptr), 456);
EXPECT_NE(obj.get_ptr(foo), nullptr);
EXPECT_EQ(*obj.get_ptr(foo), 789);
EXPECT_NE(obj.get_ptr(a), nullptr);
EXPECT_EQ(*obj.get_ptr(a), 123);
EXPECT_NE(obj.get_ptr(StaticStrings::kA), nullptr);
EXPECT_EQ(*obj.get_ptr(StaticStrings::kA), 123);
EXPECT_NE(obj.get_ptr("a"), nullptr);
EXPECT_EQ(*obj.get_ptr("a"), 123);
EXPECT_NE(obj.get_ptr(sp), nullptr);
EXPECT_EQ(*obj.get_ptr(sp), 123);
EXPECT_NE(obj.get_ptr(StringPiece{"a"}), nullptr);
EXPECT_EQ(*obj.get_ptr(StringPiece{"a"}), 123);
EXPECT_NE(obj.get_ptr(StaticStrings::kFoo), nullptr);
EXPECT_EQ(*obj.get_ptr(StaticStrings::kFoo), 789);
EXPECT_NE(obj.get_ptr(std::string{"a"}), nullptr);
EXPECT_EQ(*obj.get_ptr(std::string{"a"}), 123);
EXPECT_NE(obj.get_ptr(str), nullptr);
EXPECT_EQ(*obj.get_ptr(str), 123);
EXPECT_EQ(obj.get_ptr(b), nullptr);
EXPECT_EQ(obj.get_ptr(StringPiece{b}), nullptr);
EXPECT_EQ(obj.get_ptr(StaticStrings::kBar), nullptr);
// find() // find()
EXPECT_EQ(obj.find(empty)->second, 456); EXPECT_EQ(obj.find(empty)->second, 456);
EXPECT_EQ(obj.find(nullptr)->second, 456); EXPECT_EQ(obj.find(nullptr)->second, 456);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment