mirror of
				https://github.com/Tencent/rapidjson.git
				synced 2025-10-28 11:31:57 +01:00 
			
		
		
		
	Add XXXByPointer() helper functions
This commit is contained in:
		| @@ -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()); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Milo Yip
					Milo Yip