Skip to content

Commit 8549e3d

Browse files
authored
Merge pull request Tencent#1431 from ylavic/pointer_swap
Allow to (std::)Swap two pointers.
2 parents 66eb606 + 2ce91b8 commit 8549e3d

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

include/rapidjson/pointer.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,36 @@ class GenericPointer {
200200
return *this;
201201
}
202202

203+
//! Swap the content of this pointer with an other.
204+
/*!
205+
\param other The pointer to swap with.
206+
\note Constant complexity.
207+
*/
208+
GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
209+
internal::Swap(allocator_, other.allocator_);
210+
internal::Swap(ownAllocator_, other.ownAllocator_);
211+
internal::Swap(nameBuffer_, other.nameBuffer_);
212+
internal::Swap(tokens_, other.tokens_);
213+
internal::Swap(tokenCount_, other.tokenCount_);
214+
internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
215+
internal::Swap(parseErrorCode_, other.parseErrorCode_);
216+
return *this;
217+
}
218+
219+
//! free-standing swap function helper
220+
/*!
221+
Helper function to enable support for common swap implementation pattern based on \c std::swap:
222+
\code
223+
void swap(MyClass& a, MyClass& b) {
224+
using std::swap;
225+
swap(a.pointer, b.pointer);
226+
// ...
227+
}
228+
\endcode
229+
\see Swap()
230+
*/
231+
friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
232+
203233
//@}
204234

205235
//!@name Append token

test/unittest/pointertest.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "rapidjson/pointer.h"
1717
#include "rapidjson/stringbuffer.h"
1818
#include <sstream>
19+
#include <algorithm>
1920

2021
using namespace rapidjson;
2122

@@ -529,6 +530,36 @@ TEST(Pointer, Assignment) {
529530
}
530531
}
531532

533+
TEST(Pointer, Swap) {
534+
Pointer p("/foo/0");
535+
Pointer q(&p.GetAllocator());
536+
537+
q.Swap(p);
538+
EXPECT_EQ(&q.GetAllocator(), &p.GetAllocator());
539+
EXPECT_TRUE(p.IsValid());
540+
EXPECT_TRUE(q.IsValid());
541+
EXPECT_EQ(0u, p.GetTokenCount());
542+
EXPECT_EQ(2u, q.GetTokenCount());
543+
EXPECT_EQ(3u, q.GetTokens()[0].length);
544+
EXPECT_STREQ("foo", q.GetTokens()[0].name);
545+
EXPECT_EQ(1u, q.GetTokens()[1].length);
546+
EXPECT_STREQ("0", q.GetTokens()[1].name);
547+
EXPECT_EQ(0u, q.GetTokens()[1].index);
548+
549+
// std::swap compatibility
550+
std::swap(p, q);
551+
EXPECT_EQ(&p.GetAllocator(), &q.GetAllocator());
552+
EXPECT_TRUE(q.IsValid());
553+
EXPECT_TRUE(p.IsValid());
554+
EXPECT_EQ(0u, q.GetTokenCount());
555+
EXPECT_EQ(2u, p.GetTokenCount());
556+
EXPECT_EQ(3u, p.GetTokens()[0].length);
557+
EXPECT_STREQ("foo", p.GetTokens()[0].name);
558+
EXPECT_EQ(1u, p.GetTokens()[1].length);
559+
EXPECT_STREQ("0", p.GetTokens()[1].name);
560+
EXPECT_EQ(0u, p.GetTokens()[1].index);
561+
}
562+
532563
TEST(Pointer, Append) {
533564
{
534565
Pointer p;
@@ -867,7 +898,7 @@ TEST(Pointer, Set_NoAllocator) {
867898
#endif
868899
}
869900

870-
TEST(Pointer, Swap) {
901+
TEST(Pointer, Swap_Value) {
871902
Document d;
872903
d.Parse(kJson);
873904
Document::AllocatorType& a = d.GetAllocator();
@@ -876,7 +907,7 @@ TEST(Pointer, Swap) {
876907
EXPECT_STREQ("bar", d["foo"][1].GetString());
877908
}
878909

879-
TEST(Pointer, Swap_NoAllocator) {
910+
TEST(Pointer, Swap_Value_NoAllocator) {
880911
Document d;
881912
d.Parse(kJson);
882913
Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));

0 commit comments

Comments
 (0)