Commit b2d72ef7 authored by Milo Yip's avatar Milo Yip

Add XXXByPointer() helper functions

parent cf0ff19c
......@@ -427,6 +427,7 @@ public:
typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
//!@name Constructors and destructor.
//@{
......@@ -1661,7 +1662,6 @@ template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typenam
class GenericDocument : public GenericValue<Encoding, Allocator> {
public:
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
//! Constructor
......
......@@ -325,6 +325,72 @@ private:
bool valid_;
};
template <typename T>
typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
return pointer.Create(root, a);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
const Pointer pointer(source, N - 1);
return pointer.Create(root, a);
}
template <typename T>
typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
return pointer.Get(root);
}
template <typename T>
const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer) {
return pointer.Get(root);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N]) {
const Pointer pointer(source, N - 1);
return pointer.Get(root);
}
template <typename T, typename CharType, size_t N>
const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N]) {
const Pointer pointer(source, N - 1);
return pointer.Get(root);
}
template <typename T>
typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
return pointer.GetWithDefault(root, defaultValue, a);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
const Pointer pointer(source, N - 1);
return pointer.GetWithDefault(root, defaultValue, a);
}
template <typename T>
typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
return pointer.Set(root, value, a);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
const Pointer pointer(source, N - 1);
return pointer.Set(root, value , a);
}
template <typename T>
typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
return pointer.Swap(root, value, a);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
const Pointer pointer(source, N - 1);
return pointer.Swap(root, value, a);
}
typedef GenericPointer<Value> Pointer;
RAPIDJSON_NAMESPACE_END
......
......@@ -244,9 +244,18 @@ TEST(Pointer, Assignment) {
TEST(Pointer, Create) {
Document d;
EXPECT_EQ(&d, &Pointer("").Create(d, d.GetAllocator()));
EXPECT_EQ(&d["foo"], &Pointer("/foo").Create(d, d.GetAllocator()));
EXPECT_EQ(&d["foo"][0], &Pointer("/foo/0").Create(d, d.GetAllocator()));
{
Value* v = &Pointer("").Create(d, d.GetAllocator());
EXPECT_EQ(&d, v);
}
{
Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
EXPECT_EQ(&d["foo"], v);
}
{
Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
EXPECT_EQ(&d["foo"][0], v);
}
}
TEST(Pointer, Get) {
......@@ -265,6 +274,7 @@ TEST(Pointer, Get) {
EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
}
TEST(Pointer, GetWithDefault) {
......@@ -298,3 +308,65 @@ TEST(Pointer, Swap) {
EXPECT_STREQ("baz", d["foo"][0].GetString());
EXPECT_STREQ("bar", d["foo"][1].GetString());
}
TEST(Pointer, CreateValueByPointer) {
Document d;
Document::AllocatorType& a = d.GetAllocator();
{
Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
EXPECT_EQ(&d["foo"][0], &v);
}
{
Value& v = CreateValueByPointer(d, "/foo/1", a);
EXPECT_EQ(&d["foo"][1], &v);
}
}
TEST(Pointer, GetValueByPointer) {
Document d;
d.Parse(kJson);
EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
// const version
const Value& v = d;
EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
}
TEST(Pointer, GetValueByPointerWithDefault) {
Document d;
d.Parse(kJson);
Document::AllocatorType& a = d.GetAllocator();
const Value v("qux");
EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
}
TEST(Pointer, SetValueByPointer) {
Document d;
d.Parse(kJson);
Document::AllocatorType& a = d.GetAllocator();
SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
EXPECT_EQ(123, d["foo"][0].GetInt());
SetValueByPointer(d, "/foo/2", Value(456).Move(), a);
EXPECT_EQ(456, d["foo"][2].GetInt());
}
TEST(Pointer, SwapValueByPointer) {
Document d;
d.Parse(kJson);
Document::AllocatorType& a = d.GetAllocator();
SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
EXPECT_STREQ("baz", d["foo"][0].GetString());
EXPECT_STREQ("bar", d["foo"][1].GetString());
SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
EXPECT_STREQ("bar", d["foo"][0].GetString());
EXPECT_STREQ("baz", d["foo"][1].GetString());
}
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