Skip to content

Commit

Permalink
Merge 54d8493 into 66eb606
Browse files Browse the repository at this point in the history
  • Loading branch information
ylavic committed Dec 11, 2018
2 parents 66eb606 + 54d8493 commit 5270e7a
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
34 changes: 34 additions & 0 deletions include/rapidjson/pointer.h
Expand Up @@ -356,6 +356,40 @@ class GenericPointer {
*/
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }

//! Less than operator.
/*!
\note Invalid pointers are never lesser than valid ones.
*/
bool operator<(const GenericPointer& rhs) const {
if (!rhs.IsValid())
return true;
if (!IsValid())
return false;

size_t i = 0, lCount = tokenCount_, rCount = rhs.tokenCount_;
for (;;) {
if (!lCount)
return true;
if (!rCount)
return false;

const Token &lTokens = tokens_[i], &rTokens = rhs.tokens_[i];
if (lTokens.index != rTokens.index)
return lTokens.index < rTokens.index;

if (lTokens.length > rTokens.length)
return std::memcmp(lTokens.name, rTokens.name, sizeof(Ch) * rTokens.length) < 0;

int comp = std::memcmp(lTokens.name, rTokens.name, sizeof(Ch) * lTokens.length);
if (comp || lTokens.length != rTokens.length)
return comp <= 0;

lCount--;
rCount--;
i++;
}
}

//@}

//!@name Stringify
Expand Down
68 changes: 68 additions & 0 deletions test/unittest/pointertest.cpp
Expand Up @@ -15,7 +15,9 @@
#include "unittest.h"
#include "rapidjson/pointer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/ostreamwrapper.h"
#include <sstream>
#include <set>

using namespace rapidjson;

Expand Down Expand Up @@ -1493,6 +1495,72 @@ TEST(Pointer, Ambiguity) {
}
}

TEST(Pointer, LessThan) {
static const char *pointers[] = {
"/a/b",
"/a/c",
"/a",
"/d/1",
"/d/2/z",
"/d/2/3",
"/d/2",
"/d/2/zz",
"/d/1",
"/d/2/z",
"/e/f~g",
"/e/f~0g",
"/e/f~1g",
"/e/f~~g",
"#/e/f%2fg",
"/e/f.g",
""
};
static struct {
const char *string;
bool valid;
} ordered_pointers[] = {
{ "", true },
{ "/a", true },
{ "/a/b", true },
{ "/a/c", true },
{ "/d/1", true },
{ "/d/1", true },
{ "/d/2", true },
{ "/d/2/3", true },
{ "/d/2/z", true },
{ "/d/2/z", true },
{ "/d/2/zz", true },
{ "/e/f.g", true },
{ "/e/f~1g", true },
{ "/e/f~1g", true }, // was "#/e/f%2fg"
{ "/e/f~0g", true },
{ "/e/f~g", false },
{ "/e/f~~g", false }
};
MemoryPoolAllocator<> allocator;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
typedef std::multiset<PointerType> PointerSet;
PointerSet set;
size_t i;

for (i = 0; i < sizeof(pointers) / sizeof(*pointers); ++i) {
set.insert(PointerType(pointers[i], &allocator));
}

i = 0;
for (PointerSet::iterator it = set.begin(); it != set.end(); ++it) {
EXPECT_TRUE(i < sizeof(ordered_pointers) / sizeof(*ordered_pointers));
EXPECT_EQ(it->IsValid(), ordered_pointers[i].valid);
if (it->IsValid()) {
std::stringstream ss;
OStreamWrapper os(ss);
EXPECT_TRUE(it->Stringify(os));
EXPECT_EQ(ss.str(), ordered_pointers[i].string);
}
i++;
}
}

// https://github.com/Tencent/rapidjson/issues/483
namespace myjson {

Expand Down

0 comments on commit 5270e7a

Please sign in to comment.