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) {
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));
}
......
......@@ -240,7 +240,7 @@ dynamic dynamic::getDefault(const dynamic& k, dynamic&& v) && {
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 (!idx.isInt()) {
throw_exception<TypeError>("int64", idx.type());
......@@ -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 {
if (auto* ar = get_nothrow<Array>()) {
return ar->size();
......
......@@ -449,9 +449,20 @@ struct dynamic : private boost::operators<dynamic> {
* Using these with dynamic objects that are not arrays or objects
* will throw a TypeError.
*/
const dynamic* get_ptr(dynamic const&) const&;
dynamic* get_ptr(dynamic const&) &;
dynamic* get_ptr(dynamic const&) && = delete;
private:
const dynamic* get_ptrImpl(dynamic const&) const&;
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.
......
......@@ -219,6 +219,37 @@ TEST(Dynamic, ObjectHeterogeneousAccess) {
EXPECT_THROW(obj.at(StringPiece{b}), 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()
EXPECT_EQ(obj.find(empty)->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