Skip to content

Commit bfdcf49

Browse files
authored
Merge pull request Tencent#1426 from ylavic/pointer_less_than
Add "less than" operator to Pointer.
2 parents 8549e3d + b56eb28 commit bfdcf49

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

include/rapidjson/pointer.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,33 @@ class GenericPointer {
386386
*/
387387
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
388388

389+
//! Less than operator.
390+
/*!
391+
\note Invalid pointers are always greater than valid ones.
392+
*/
393+
bool operator<(const GenericPointer& rhs) const {
394+
if (!IsValid())
395+
return false;
396+
if (!rhs.IsValid())
397+
return true;
398+
399+
if (tokenCount_ != rhs.tokenCount_)
400+
return tokenCount_ < rhs.tokenCount_;
401+
402+
for (size_t i = 0; i < tokenCount_; i++) {
403+
if (tokens_[i].index != rhs.tokens_[i].index)
404+
return tokens_[i].index < rhs.tokens_[i].index;
405+
406+
if (tokens_[i].length != rhs.tokens_[i].length)
407+
return tokens_[i].length < rhs.tokens_[i].length;
408+
409+
if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
410+
return cmp < 0;
411+
}
412+
413+
return false;
414+
}
415+
389416
//@}
390417

391418
//!@name Stringify

test/unittest/pointertest.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#include "unittest.h"
1616
#include "rapidjson/pointer.h"
1717
#include "rapidjson/stringbuffer.h"
18+
#include "rapidjson/ostreamwrapper.h"
1819
#include <sstream>
20+
#include <map>
1921
#include <algorithm>
2022

2123
using namespace rapidjson;
@@ -1524,6 +1526,79 @@ TEST(Pointer, Ambiguity) {
15241526
}
15251527
}
15261528

1529+
TEST(Pointer, LessThan) {
1530+
static const struct {
1531+
const char *str;
1532+
bool valid;
1533+
} pointers[] = {
1534+
{ "/a/b", true },
1535+
{ "/a", true },
1536+
{ "/d/1", true },
1537+
{ "/d/2/z", true },
1538+
{ "/d/2/3", true },
1539+
{ "/d/2", true },
1540+
{ "/a/c", true },
1541+
{ "/e/f~g", false },
1542+
{ "/d/2/zz", true },
1543+
{ "/d/1", true },
1544+
{ "/d/2/z", true },
1545+
{ "/e/f~~g", false },
1546+
{ "/e/f~0g", true },
1547+
{ "/e/f~1g", true },
1548+
{ "/e/f.g", true },
1549+
{ "", true }
1550+
};
1551+
static const char *ordered_pointers[] = {
1552+
"",
1553+
"/a",
1554+
"/a/b",
1555+
"/a/c",
1556+
"/d/1",
1557+
"/d/1",
1558+
"/d/2",
1559+
"/e/f.g",
1560+
"/e/f~1g",
1561+
"/e/f~0g",
1562+
"/d/2/3",
1563+
"/d/2/z",
1564+
"/d/2/z",
1565+
"/d/2/zz",
1566+
NULL, // was invalid "/e/f~g"
1567+
NULL // was invalid "/e/f~~g"
1568+
};
1569+
typedef MemoryPoolAllocator<> AllocatorType;
1570+
typedef GenericPointer<Value, AllocatorType> PointerType;
1571+
typedef std::multimap<PointerType, size_t> PointerMap;
1572+
PointerMap map;
1573+
PointerMap::iterator it;
1574+
AllocatorType allocator;
1575+
size_t i;
1576+
1577+
EXPECT_EQ(sizeof(pointers) / sizeof(pointers[0]),
1578+
sizeof(ordered_pointers) / sizeof(ordered_pointers[0]));
1579+
1580+
for (i = 0; i < sizeof(pointers) / sizeof(pointers[0]); ++i) {
1581+
it = map.insert(PointerMap::value_type(PointerType(pointers[i].str, &allocator), i));
1582+
if (!it->first.IsValid()) {
1583+
EXPECT_EQ(++it, map.end());
1584+
}
1585+
}
1586+
1587+
for (i = 0, it = map.begin(); it != map.end(); ++it, ++i) {
1588+
EXPECT_TRUE(it->second < sizeof(pointers) / sizeof(pointers[0]));
1589+
EXPECT_EQ(it->first.IsValid(), pointers[it->second].valid);
1590+
EXPECT_TRUE(i < sizeof(ordered_pointers) / sizeof(ordered_pointers[0]));
1591+
EXPECT_EQ(it->first.IsValid(), !!ordered_pointers[i]);
1592+
if (it->first.IsValid()) {
1593+
std::stringstream ss;
1594+
OStreamWrapper os(ss);
1595+
EXPECT_TRUE(it->first.Stringify(os));
1596+
EXPECT_EQ(ss.str(), pointers[it->second].str);
1597+
EXPECT_EQ(ss.str(), ordered_pointers[i]);
1598+
}
1599+
}
1600+
}
1601+
15271602
// https://github.com/Tencent/rapidjson/issues/483
15281603
namespace myjson {
15291604

0 commit comments

Comments
 (0)