15 #ifndef RAPIDJSON_POINTER_H_
16 #define RAPIDJSON_POINTER_H_
19 #include "internal/itoa.h"
23 RAPIDJSON_DIAG_OFF(
switch-
enum)
28 RAPIDJSON_DIAG_OFF(4512)
31 RAPIDJSON_NAMESPACE_BEGIN
80 template <
typename ValueType,
typename Allocator = CrtAllocator>
81 class GenericPointer {
84 typedef typename ValueType::Ch
Ch;
117 Parse(source, internal::StrLen(source));
120 #if RAPIDJSON_HAS_STDSTRING
128 Parse(source.c_str(), source.size());
140 Parse(source, length);
175 Allocator::Free(tokens_);
184 Allocator::Free(tokens_);
186 tokenCount_ = rhs.tokenCount_;
187 parseErrorOffset_ = rhs.parseErrorOffset_;
188 parseErrorCode_ = rhs.parseErrorCode_;
193 tokens_ = rhs.tokens_;
213 r.allocator_ = allocator;
214 Ch *p = r.CopyFromRaw(*
this, 1, token.
length + 1);
215 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(
Ch));
216 r.tokens_[tokenCount_].name = p;
217 r.tokens_[tokenCount_].length = token.
length;
218 r.tokens_[tokenCount_].index = token.
index;
230 Token token = { name, length, kPointerInvalidIndex };
231 return Append(token, allocator);
240 template <
typename T>
242 Append(T* name,
Allocator* allocator = 0)
const {
243 return Append(name, StrLen(name), allocator);
246 #if RAPIDJSON_HAS_STDSTRING
253 GenericPointer Append(
const std::basic_string<Ch>& name,
Allocator* allocator = 0)
const {
254 return Append(name.c_str(),
static_cast<SizeType>(name.size()), allocator);
266 char* end =
sizeof(
SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
268 buffer[length] =
'\0';
270 if (
sizeof(Ch) == 1) {
271 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
272 return Append(token, allocator);
276 for (
size_t i = 0; i <= length; i++)
278 Token token = { name, length, index };
279 return Append(token, allocator);
289 GenericPointer Append(
const ValueType& token,
Allocator* allocator = 0)
const {
290 if (token.IsString())
291 return Append(token.GetString(), token.GetStringLength(), allocator);
295 return Append(
static_cast<SizeType>(token.GetUint64()), allocator);
306 size_t GetParseErrorOffset()
const {
return parseErrorOffset_; }
314 Allocator& GetAllocator() {
return *allocator_; }
320 const Token* GetTokens()
const {
return tokens_; }
323 size_t GetTokenCount()
const {
return tokenCount_; }
334 bool operator==(
const GenericPointer& rhs)
const {
335 if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
338 for (
size_t i = 0; i < tokenCount_; i++) {
339 if (tokens_[i].index != rhs.tokens_[i].index ||
340 tokens_[i].length != rhs.tokens_[i].length ||
341 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name,
sizeof(Ch)* tokens_[i].length) != 0))
354 bool operator!=(
const GenericPointer& rhs)
const {
return !(*
this == rhs); }
366 template<
typename OutputStream>
367 bool Stringify(OutputStream& os)
const {
368 return Stringify<false, OutputStream>(os);
376 template<
typename OutputStream>
377 bool StringifyUriFragment(OutputStream& os)
const {
378 return Stringify<true, OutputStream>(os);
401 ValueType& Create(ValueType& root,
typename ValueType::AllocatorType& allocator,
bool* alreadyExist = 0)
const {
403 ValueType* v = &root;
405 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
406 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1) {
407 v->PushBack(ValueType().Move(), allocator);
408 v = &((*v)[v->Size() - 1]);
412 if (t->index == kPointerInvalidIndex) {
417 if (!v->IsArray() && !v->IsObject())
422 if (t->index >= v->Size()) {
423 v->Reserve(t->index + 1, allocator);
424 while (t->index >= v->Size())
425 v->PushBack(ValueType().Move(), allocator);
428 v = &((*v)[t->index]);
431 typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
432 if (m == v->MemberEnd()) {
433 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
434 v = &(--v->MemberEnd())->value;
444 *alreadyExist = exist;
455 template <
typename stackAllocator>
456 ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
bool* alreadyExist = 0)
const {
457 return Create(document, document.GetAllocator(), alreadyExist);
479 ValueType* Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
481 ValueType* v = &root;
482 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
483 switch (v->GetType()) {
486 typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
487 if (m == v->MemberEnd())
493 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
495 v = &((*v)[t->index]);
502 if (unresolvedTokenIndex)
503 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
514 const ValueType* Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
515 return Get(
const_cast<ValueType&
>(root), unresolvedTokenIndex);
533 ValueType& GetWithDefault(ValueType& root,
const ValueType& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
535 Value& v = Create(root, allocator, &alreadyExist);
536 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
540 ValueType& GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const {
542 Value& v = Create(root, allocator, &alreadyExist);
543 return alreadyExist ? v : v.SetString(defaultValue, allocator);
546 #if RAPIDJSON_HAS_STDSTRING
548 ValueType& GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
550 Value& v = Create(root, allocator, &alreadyExist);
551 return alreadyExist ? v : v.SetString(defaultValue, allocator);
559 template <
typename T>
560 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
561 GetWithDefault(ValueType& root, T defaultValue,
typename ValueType::AllocatorType& allocator)
const {
562 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
566 template <
typename stackAllocator>
567 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
const ValueType& defaultValue)
const {
568 return GetWithDefault(document, defaultValue, document.GetAllocator());
572 template <
typename stackAllocator>
573 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
const Ch* defaultValue)
const {
574 return GetWithDefault(document, defaultValue, document.GetAllocator());
577 #if RAPIDJSON_HAS_STDSTRING
579 template <
typename stackAllocator>
580 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
const std::basic_string<Ch>& defaultValue)
const {
581 return GetWithDefault(document, defaultValue, document.GetAllocator());
589 template <
typename T,
typename stackAllocator>
590 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
591 GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue)
const {
592 return GetWithDefault(document, defaultValue, document.GetAllocator());
610 ValueType&
Set(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
611 return Create(root, allocator) = value;
615 ValueType&
Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
616 return Create(root, allocator).CopyFrom(value, allocator);
620 ValueType&
Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const {
621 return Create(root, allocator) = ValueType(value, allocator).Move();
624 #if RAPIDJSON_HAS_STDSTRING
626 ValueType&
Set(ValueType& root,
const std::basic_string<Ch>& value,
typename ValueType::AllocatorType& allocator)
const {
627 return Create(root, allocator) = ValueType(value, allocator).Move();
635 template <
typename T>
636 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
637 Set(ValueType& root, T value,
typename ValueType::AllocatorType& allocator)
const {
638 return Create(root, allocator) = ValueType(value).Move();
642 template <
typename stackAllocator>
644 return Create(document) = value;
648 template <
typename stackAllocator>
650 return Create(document).CopyFrom(value, document.
GetAllocator());
654 template <
typename stackAllocator>
656 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
659 #if RAPIDJSON_HAS_STDSTRING
661 template <
typename stackAllocator>
663 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
671 template <
typename T,
typename stackAllocator>
672 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
674 return Create(document) = value;
692 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
693 return Create(root, allocator).Swap(value);
697 template <
typename stackAllocator>
699 return Create(document).Swap(value);
713 if (tokenCount_ == 0)
716 ValueType* v = &root;
717 const Token* last = tokens_ + (tokenCount_ - 1);
718 for (
const Token *t = tokens_; t != last; ++t) {
719 switch (v->GetType()) {
723 if (m == v->MemberEnd())
729 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
731 v = &((*v)[t->index]);
738 switch (v->GetType()) {
742 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
744 v->Erase(v->Begin() + last->
index);
759 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
763 size_t nameBufferSize = rhs.tokenCount_;
764 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
765 nameBufferSize += t->length;
767 tokenCount_ = rhs.tokenCount_ + extraToken;
768 tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + (nameBufferSize + extraNameBufferSize) *
sizeof(Ch)));
769 nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
770 if (rhs.tokenCount_ > 0) {
771 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ *
sizeof(Token));
773 if (nameBufferSize > 0) {
774 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize *
sizeof(Ch));
778 std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
779 for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
782 return nameBuffer_ + nameBufferSize;
790 bool NeedPercentEncode(Ch c)
const {
791 return !((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~');
795 #ifndef __clang__ // -Wdocumentation
802 void Parse(
const Ch* source,
size_t length) {
813 for (
const Ch* s = source; s != source + length; s++)
817 Token* token = tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + length *
sizeof(Ch)));
818 Ch* name = nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
822 bool uriFragment =
false;
823 if (source[i] ==
'#') {
828 if (i != length && source[i] !=
'/') {
838 bool isNumber =
true;
840 while (i < length && source[i] !=
'/') {
845 PercentDecodeStream is(&source[i], source + length);
846 GenericInsituStringStream<EncodingType> os(name);
847 Ch* begin = os.PutBegin();
848 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
852 size_t len = os.PutEnd(begin);
863 else if (NeedPercentEncode(c)) {
875 if (c ==
'0') c =
'~';
876 else if (c ==
'1') c =
'/';
890 if (c < '0' || c >
'9')
895 token->length =
static_cast<SizeType>(name - token->name);
896 if (token->length == 0)
901 if (isNumber && token->length > 1 && token->name[0] ==
'0')
907 for (
size_t j = 0; j < token->length; j++) {
917 token->index = isNumber ? n : kPointerInvalidIndex;
926 Allocator::Free(tokens_);
930 parseErrorOffset_ = i;
940 template<
bool uriFragment,
typename OutputStream>
941 bool Stringify(OutputStream& os)
const {
947 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
949 for (
size_t j = 0; j < t->length; j++) {
959 else if (uriFragment && NeedPercentEncode(c)) {
961 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
962 PercentEncodeStream<OutputStream> target(os);
963 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
965 j += source.Tell() - 1;
980 class PercentDecodeStream {
982 typedef typename ValueType::Ch Ch;
989 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
992 if (*src_ !=
'%' || src_ + 3 > end_) {
998 for (
int j = 0; j < 2; j++) {
999 c =
static_cast<Ch
>(c << 4);
1001 if (h >=
'0' && h <=
'9') c =
static_cast<Ch
>(c + h -
'0');
1002 else if (h >=
'A' && h <=
'F') c =
static_cast<Ch
>(c + h -
'A' + 10);
1003 else if (h >=
'a' && h <=
'f') c =
static_cast<Ch
>(c + h -
'a' + 10);
1013 size_t Tell()
const {
return static_cast<size_t>(src_ - head_); }
1014 bool IsValid()
const {
return valid_; }
1024 template <
typename OutputStream>
1025 class PercentEncodeStream {
1027 PercentEncodeStream(OutputStream& os) : os_(os) {}
1029 unsigned char u =
static_cast<unsigned char>(c);
1030 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
1032 os_.Put(hexDigits[u >> 4]);
1033 os_.Put(hexDigits[u & 15]);
1044 size_t parseErrorOffset_;
1049 typedef GenericPointer<Value>
Pointer;
1056 template <
typename T>
1057 typename T::ValueType& CreateValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::AllocatorType& a) {
1058 return pointer.Create(root, a);
1061 template <
typename T,
typename CharType,
size_t N>
1062 typename T::ValueType& CreateValueByPointer(T& root,
const CharType(&source)[N],
typename T::AllocatorType& a) {
1063 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1068 template <
typename DocumentType>
1069 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer) {
1070 return pointer.Create(document);
1073 template <
typename DocumentType,
typename CharType,
size_t N>
1074 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const CharType(&source)[N]) {
1075 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1080 template <
typename T>
1081 typename T::ValueType* GetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1082 return pointer.Get(root, unresolvedTokenIndex);
1085 template <
typename T>
1086 const typename T::ValueType* GetValueByPointer(
const T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1087 return pointer.Get(root, unresolvedTokenIndex);
1090 template <
typename T,
typename CharType,
size_t N>
1091 typename T::ValueType* GetValueByPointer(T& root,
const CharType (&source)[N],
size_t* unresolvedTokenIndex = 0) {
1092 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1095 template <
typename T,
typename CharType,
size_t N>
1096 const typename T::ValueType* GetValueByPointer(
const T& root,
const CharType(&source)[N],
size_t* unresolvedTokenIndex = 0) {
1097 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1102 template <
typename T>
1103 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1104 return pointer.GetWithDefault(root, defaultValue, a);
1107 template <
typename T>
1108 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1109 return pointer.GetWithDefault(root, defaultValue, a);
1112 #if RAPIDJSON_HAS_STDSTRING
1113 template <
typename T>
1114 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1115 return pointer.GetWithDefault(root, defaultValue, a);
1119 template <
typename T,
typename T2>
1120 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1121 GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue,
typename T::AllocatorType& a) {
1122 return pointer.GetWithDefault(root, defaultValue, a);
1125 template <
typename T,
typename CharType,
size_t N>
1126 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1127 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1130 template <
typename T,
typename CharType,
size_t N>
1131 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1132 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1135 #if RAPIDJSON_HAS_STDSTRING
1136 template <
typename T,
typename CharType,
size_t N>
1137 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1138 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1142 template <
typename T,
typename CharType,
size_t N,
typename T2>
1143 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1144 GetValueByPointerWithDefault(T& root,
const CharType(&source)[N], T2 defaultValue,
typename T::AllocatorType& a) {
1145 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1150 template <
typename DocumentType>
1151 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& defaultValue) {
1152 return pointer.GetWithDefault(document, defaultValue);
1155 template <
typename DocumentType>
1156 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* defaultValue) {
1157 return pointer.GetWithDefault(document, defaultValue);
1160 #if RAPIDJSON_HAS_STDSTRING
1161 template <
typename DocumentType>
1162 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1163 return pointer.GetWithDefault(document, defaultValue);
1167 template <
typename DocumentType,
typename T2>
1168 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1169 GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1170 return pointer.GetWithDefault(document, defaultValue);
1173 template <
typename DocumentType,
typename CharType,
size_t N>
1174 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& defaultValue) {
1175 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1178 template <
typename DocumentType,
typename CharType,
size_t N>
1179 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* defaultValue) {
1180 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1183 #if RAPIDJSON_HAS_STDSTRING
1184 template <
typename DocumentType,
typename CharType,
size_t N>
1185 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1186 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1190 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1191 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1192 GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N], T2 defaultValue) {
1193 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1198 template <
typename T>
1199 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1200 return pointer.Set(root, value, a);
1203 template <
typename T>
1204 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1205 return pointer.Set(root, value, a);
1208 template <
typename T>
1209 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* value,
typename T::AllocatorType& a) {
1210 return pointer.Set(root, value, a);
1213 #if RAPIDJSON_HAS_STDSTRING
1214 template <
typename T>
1215 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1216 return pointer.Set(root, value, a);
1220 template <
typename T,
typename T2>
1221 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1222 SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 value,
typename T::AllocatorType& a) {
1223 return pointer.Set(root, value, a);
1226 template <
typename T,
typename CharType,
size_t N>
1227 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1228 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1231 template <
typename T,
typename CharType,
size_t N>
1232 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1233 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1236 template <
typename T,
typename CharType,
size_t N>
1237 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::Ch* value,
typename T::AllocatorType& a) {
1238 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1241 #if RAPIDJSON_HAS_STDSTRING
1242 template <
typename T,
typename CharType,
size_t N>
1243 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1244 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1248 template <
typename T,
typename CharType,
size_t N,
typename T2>
1249 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1250 SetValueByPointer(T& root,
const CharType(&source)[N], T2 value,
typename T::AllocatorType& a) {
1251 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1256 template <
typename DocumentType>
1257 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1258 return pointer.Set(document, value);
1261 template <
typename DocumentType>
1262 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& value) {
1263 return pointer.Set(document, value);
1266 template <
typename DocumentType>
1267 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* value) {
1268 return pointer.Set(document, value);
1271 #if RAPIDJSON_HAS_STDSTRING
1272 template <
typename DocumentType>
1273 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& value) {
1274 return pointer.Set(document, value);
1278 template <
typename DocumentType,
typename T2>
1279 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1280 SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1281 return pointer.Set(document, value);
1284 template <
typename DocumentType,
typename CharType,
size_t N>
1285 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1286 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1289 template <
typename DocumentType,
typename CharType,
size_t N>
1290 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& value) {
1291 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1294 template <
typename DocumentType,
typename CharType,
size_t N>
1295 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* value) {
1296 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1299 #if RAPIDJSON_HAS_STDSTRING
1300 template <
typename DocumentType,
typename CharType,
size_t N>
1301 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1302 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1306 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1307 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1308 SetValueByPointer(DocumentType& document,
const CharType(&source)[N], T2 value) {
1309 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1314 template <
typename T>
1315 typename T::ValueType& SwapValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1316 return pointer.Swap(root, value, a);
1319 template <
typename T,
typename CharType,
size_t N>
1320 typename T::ValueType& SwapValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1321 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1324 template <
typename DocumentType>
1325 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1326 return pointer.Swap(document, value);
1329 template <
typename DocumentType,
typename CharType,
size_t N>
1330 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1331 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1336 template <
typename T>
1337 bool EraseValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1338 return pointer.Erase(root);
1341 template <
typename T,
typename CharType,
size_t N>
1342 bool EraseValueByPointer(T& root,
const CharType(&source)[N]) {
1343 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1348 RAPIDJSON_NAMESPACE_END
1358 #endif // RAPIDJSON_POINTER_H_