Unverified Commit bfdcf491 authored by Milo Yip's avatar Milo Yip Committed by GitHub

Merge pull request #1426 from ylavic/pointer_less_than

Add "less than" operator to Pointer.
parents 8549e3db b56eb285
......@@ -386,6 +386,33 @@ public:
*/
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
//! Less than operator.
/*!
\note Invalid pointers are always greater than valid ones.
*/
bool operator<(const GenericPointer& rhs) const {
if (!IsValid())
return false;
if (!rhs.IsValid())
return true;
if (tokenCount_ != rhs.tokenCount_)
return tokenCount_ < rhs.tokenCount_;
for (size_t i = 0; i < tokenCount_; i++) {
if (tokens_[i].index != rhs.tokens_[i].index)
return tokens_[i].index < rhs.tokens_[i].index;
if (tokens_[i].length != rhs.tokens_[i].length)
return tokens_[i].length < rhs.tokens_[i].length;
if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
return cmp < 0;
}
return false;
}
//@}
//!@name Stringify
......
......@@ -15,7 +15,9 @@
#include "unittest.h"
#include "rapidjson/pointer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/ostreamwrapper.h"
#include <sstream>
#include <map>
#include <algorithm>
using namespace rapidjson;
......@@ -1524,6 +1526,79 @@ TEST(Pointer, Ambiguity) {
}
}
TEST(Pointer, LessThan) {
static const struct {
const char *str;
bool valid;
} pointers[] = {
{ "/a/b", true },
{ "/a", true },
{ "/d/1", true },
{ "/d/2/z", true },
{ "/d/2/3", true },
{ "/d/2", true },
{ "/a/c", true },
{ "/e/f~g", false },
{ "/d/2/zz", true },
{ "/d/1", true },
{ "/d/2/z", true },
{ "/e/f~~g", false },
{ "/e/f~0g", true },
{ "/e/f~1g", true },
{ "/e/f.g", true },
{ "", true }
};
static const char *ordered_pointers[] = {
"",
"/a",
"/a/b",
"/a/c",
"/d/1",
"/d/1",
"/d/2",
"/e/f.g",
"/e/f~1g",
"/e/f~0g",
"/d/2/3",
"/d/2/z",
"/d/2/z",
"/d/2/zz",
NULL, // was invalid "/e/f~g"
NULL // was invalid "/e/f~~g"
};
typedef MemoryPoolAllocator<> AllocatorType;
typedef GenericPointer<Value, AllocatorType> PointerType;
typedef std::multimap<PointerType, size_t> PointerMap;
PointerMap map;
PointerMap::iterator it;
AllocatorType allocator;
size_t i;
EXPECT_EQ(sizeof(pointers) / sizeof(pointers[0]),
sizeof(ordered_pointers) / sizeof(ordered_pointers[0]));
for (i = 0; i < sizeof(pointers) / sizeof(pointers[0]); ++i) {
it = map.insert(PointerMap::value_type(PointerType(pointers[i].str, &allocator), i));
if (!it->first.IsValid()) {
EXPECT_EQ(++it, map.end());
}
}
for (i = 0, it = map.begin(); it != map.end(); ++it, ++i) {
EXPECT_TRUE(it->second < sizeof(pointers) / sizeof(pointers[0]));
EXPECT_EQ(it->first.IsValid(), pointers[it->second].valid);
EXPECT_TRUE(i < sizeof(ordered_pointers) / sizeof(ordered_pointers[0]));
EXPECT_EQ(it->first.IsValid(), !!ordered_pointers[i]);
if (it->first.IsValid()) {
std::stringstream ss;
OStreamWrapper os(ss);
EXPECT_TRUE(it->first.Stringify(os));
EXPECT_EQ(ss.str(), pointers[it->second].str);
EXPECT_EQ(ss.str(), ordered_pointers[i]);
}
}
}
// https://github.com/Tencent/rapidjson/issues/483
namespace myjson {
......
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