Skip to content

Commit

Permalink
string_view, Key2
Browse files Browse the repository at this point in the history
  • Loading branch information
OlegRomanenko committed Jan 20, 2023
1 parent 012be85 commit 2034422
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 33 deletions.
8 changes: 8 additions & 0 deletions include/rapidjson/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(LIB rapidjson)

include_directories(.)

file(GLOB LIB_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)

#Custom target for headers only lib
add_custom_target(${LIB} SOURCES ${LIB_HEADERS})
78 changes: 45 additions & 33 deletions include/rapidjson/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class GenericDocument;
But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
https://code.google.com/p/rapidjson/issues/detail?id=64
*/
template <typename Encoding, typename Allocator>
template <typename Encoding, typename Allocator>
class GenericMember {
public:
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
Expand Down Expand Up @@ -492,6 +492,11 @@ template<typename CharType>
inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
}

template<typename CharType>
inline GenericStringRef<CharType> StringRef(std::basic_string_view<CharType> str) {
return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
}
#endif

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -518,23 +523,23 @@ namespace internal {
template <typename ValueType, typename T>
struct TypeHelper {};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, bool> {
static bool Is(const ValueType& v) { return v.IsBool(); }
static bool Get(const ValueType& v) { return v.GetBool(); }
static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, int> {
static bool Is(const ValueType& v) { return v.IsInt(); }
static int Get(const ValueType& v) { return v.GetInt(); }
static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, unsigned> {
static bool Is(const ValueType& v) { return v.IsUint(); }
static unsigned Get(const ValueType& v) { return v.GetUint(); }
Expand Down Expand Up @@ -562,39 +567,39 @@ struct TypeHelper<ValueType, unsigned long> {
};
#endif

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, int64_t> {
static bool Is(const ValueType& v) { return v.IsInt64(); }
static int64_t Get(const ValueType& v) { return v.GetInt64(); }
static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, uint64_t> {
static bool Is(const ValueType& v) { return v.IsUint64(); }
static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, double> {
static bool Is(const ValueType& v) { return v.IsDouble(); }
static double Get(const ValueType& v) { return v.GetDouble(); }
static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, float> {
static bool Is(const ValueType& v) { return v.IsFloat(); }
static float Get(const ValueType& v) { return v.GetFloat(); }
static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, const typename ValueType::Ch*> {
typedef const typename ValueType::Ch* StringType;
static bool Is(const ValueType& v) { return v.IsString(); }
Expand All @@ -604,7 +609,7 @@ struct TypeHelper<ValueType, const typename ValueType::Ch*> {
};

#if RAPIDJSON_HAS_STDSTRING
template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
typedef std::basic_string<typename ValueType::Ch> StringType;
static bool Is(const ValueType& v) { return v.IsString(); }
Expand All @@ -613,7 +618,7 @@ struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
};
#endif

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, typename ValueType::Array> {
typedef typename ValueType::Array ArrayType;
static bool Is(const ValueType& v) { return v.IsArray(); }
Expand All @@ -622,14 +627,14 @@ struct TypeHelper<ValueType, typename ValueType::Array> {
static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, typename ValueType::ConstArray> {
typedef typename ValueType::ConstArray ArrayType;
static bool Is(const ValueType& v) { return v.IsArray(); }
static ArrayType Get(const ValueType& v) { return v.GetArray(); }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, typename ValueType::Object> {
typedef typename ValueType::Object ObjectType;
static bool Is(const ValueType& v) { return v.IsObject(); }
Expand All @@ -638,7 +643,7 @@ struct TypeHelper<ValueType, typename ValueType::Object> {
static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
};

template<typename ValueType>
template<typename ValueType>
struct TypeHelper<ValueType, typename ValueType::ConstObject> {
typedef typename ValueType::ConstObject ObjectType;
static bool Is(const ValueType& v) { return v.IsObject(); }
Expand Down Expand Up @@ -796,7 +801,7 @@ class GenericValue {

//! Constructor for unsigned value.
explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
data_.n.u64 = u;
data_.n.u64 = u;
data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
}

Expand Down Expand Up @@ -1030,14 +1035,14 @@ class GenericValue {
switch (GetType()) {
case kObjectType: // Warning: O(n^2) inner-loop
if (data_.o.size != rhs.data_.o.size)
return false;
return false;
for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
return false;
}
return true;

case kArrayType:
if (data_.a.size != rhs.data_.a.size)
return false;
Expand Down Expand Up @@ -1261,6 +1266,9 @@ class GenericValue {
//! Get a value from an object associated with name (string object).
GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }

GenericValue& operator[](std::string_view name) { return (*this)[GenericValue(StringRef(name))]; }
const GenericValue& operator[](std::string_view name) const { return (*this)[GenericValue(StringRef(name))]; }
#endif

//! Const member iterator
Expand Down Expand Up @@ -1308,6 +1316,7 @@ class GenericValue {
\note Linear time complexity.
*/
bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
bool HasMember(std::string_view name) const { return FindMember(name) != MemberEnd(); }
#endif

//! Check whether a member exists in the object with GenericValue name.
Expand Down Expand Up @@ -1372,6 +1381,9 @@ class GenericValue {
*/
MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }

MemberIterator FindMember(std::string_view name) { return FindMember(GenericValue(StringRef(name))); }
ConstMemberIterator FindMember(std::string_view name) const { return FindMember(GenericValue(StringRef(name))); }
#endif

//! Add a member (name-value pair) to the object.
Expand Down Expand Up @@ -1520,7 +1532,7 @@ class GenericValue {
\note Linear time complexity.
*/
void RemoveAllMembers() {
RAPIDJSON_ASSERT(IsObject());
RAPIDJSON_ASSERT(IsObject());
DoClearMembers();
}

Expand Down Expand Up @@ -1653,7 +1665,7 @@ class GenericValue {
\note Linear time complexity.
*/
void Clear() {
RAPIDJSON_ASSERT(IsArray());
RAPIDJSON_ASSERT(IsArray());
GenericValue* e = GetElementsPointer();
for (GenericValue* v = e; v != e + data_.a.size; ++v)
v->~GenericValue();
Expand Down Expand Up @@ -1859,7 +1871,7 @@ class GenericValue {

//! Set this value as a string without copying source string.
/*! This version has better performance with supplied length, and also support string containing null character.
\param s source string pointer.
\param s source string pointer.
\param length The length of source string, excluding the trailing null terminator.
\return The value itself for fluent API.
\post IsString() == true && GetString() == s && GetStringLength() == length
Expand All @@ -1876,7 +1888,7 @@ class GenericValue {

//! Set this value as a string by copying from source string.
/*! This version has better performance with supplied length, and also support string containing null character.
\param s source string.
\param s source string.
\param length The length of source string, excluding the trailing null terminator.
\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
\return The value itself for fluent API.
Expand All @@ -1885,7 +1897,7 @@ class GenericValue {
GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }

//! Set this value as a string by copying from source string.
/*! \param s source string.
/*! \param s source string.
\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
\return The value itself for fluent API.
\post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
Expand Down Expand Up @@ -1970,10 +1982,10 @@ class GenericValue {
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
return false;
return handler.EndArray(data_.a.size);

case kStringType:
return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);

default:
RAPIDJSON_ASSERT(GetType() == kNumberType);
if (IsDouble()) return handler.Double(data_.n.d);
Expand Down Expand Up @@ -2518,12 +2530,12 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
}

//! Constructor
/*! Creates an empty document which type is Null.
/*! Creates an empty document which type is Null.
\param allocator Optional allocator for allocating memory.
\param stackCapacity Optional initial capacity of stack in bytes.
\param stackAllocator Optional allocator for allocating memory for stack.
*/
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
{
if (!allocator_)
Expand Down Expand Up @@ -2740,7 +2752,7 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
GenericDocument& Parse(const Ch* str, size_t length) {
return Parse<parseFlags, Encoding>(str, length);
}

GenericDocument& Parse(const Ch* str, size_t length) {
return Parse<kParseDefaultFlags>(str, length);
}
Expand Down Expand Up @@ -2825,24 +2837,24 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }

bool RawNumber(const Ch* str, SizeType length, bool copy) {
if (copy)
bool RawNumber(const Ch* str, SizeType length, bool copy) {
if (copy)
new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
else
new (stack_.template Push<ValueType>()) ValueType(str, length);
return true;
}

bool String(const Ch* str, SizeType length, bool copy) {
if (copy)
bool String(const Ch* str, SizeType length, bool copy) {
if (copy)
new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
else
new (stack_.template Push<ValueType>()) ValueType(str, length);
return true;
}

bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }

bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }

bool EndObject(SizeType memberCount) {
Expand All @@ -2852,7 +2864,7 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
}

bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }

bool EndArray(SizeType elementCount) {
ValueType* elements = stack_.template Pop<ValueType>(elementCount);
stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
Expand Down
1 change: 1 addition & 0 deletions include/rapidjson/rapidjson.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@

#if RAPIDJSON_HAS_STDSTRING
#include <string>
#include <string_view>
#endif // RAPIDJSON_HAS_STDSTRING

///////////////////////////////////////////////////////////////////////////////
Expand Down
17 changes: 17 additions & 0 deletions include/rapidjson/writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "internal/itoa.h"
#include "stringbuffer.h"
#include <new> // placement new
#include <string_view>

#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
#include <intrin.h>
Expand Down Expand Up @@ -207,6 +208,10 @@ class Writer {
return EndValue(WriteString(str, length));
}

bool String(std::string_view strv) {
return String(strv.data(), SizeType(strv.size()));
}

#if RAPIDJSON_HAS_STDSTRING
bool String(const std::basic_string<Ch>& str) {
return String(str.data(), SizeType(str.size()));
Expand All @@ -220,6 +225,18 @@ class Writer {
}

bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
Writer& Key2(const Ch* str, SizeType length, bool copy = false) { String(str, length, copy); return *this; }

bool Key(std::string_view strv)
{
return Key(strv.data(), SizeType(strv.size()));
}

Writer& Key2(std::string_view strv)
{
Key(strv.data(), SizeType(strv.size()));
return *this;
}

#if RAPIDJSON_HAS_STDSTRING
bool Key(const std::basic_string<Ch>& str)
Expand Down

0 comments on commit 2034422

Please sign in to comment.