Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
4007301e
Commit
4007301e
authored
Jul 04, 2014
by
Philipp A. Hartmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a wrapper for constant string references
parent
3bfffa3c
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
101 additions
and
33 deletions
+101
-33
document.h
include/rapidjson/document.h
+95
-33
meta.h
include/rapidjson/internal/meta.h
+6
-0
No files found.
include/rapidjson/document.h
View file @
4007301e
...
...
@@ -174,6 +174,51 @@ struct GenericMemberIterator<true,Encoding,Allocator> {
#endif // RAPIDJSON_NOMEMBERITERATORCLASS
///////////////////////////////////////////////////////////////////////////////
// GenericStringRef
//! Reference to a constant string (not taking a copy)
template
<
typename
CharType
>
struct
GenericStringRef
{
typedef
CharType
Ch
;
//!< character type of the string
//! Create string reference from \c const character array
template
<
SizeType
N
>
GenericStringRef
(
const
CharType
(
&
str
)[
N
])
:
s
(
str
),
length
(
N
-
1
)
{}
//! Explicitly create string reference from \c const character pointer
explicit
GenericStringRef
(
const
CharType
*
str
)
:
s
(
str
),
length
(
internal
::
StrLen
(
str
)){}
//! Create constant string reference from pointer and length
GenericStringRef
(
const
CharType
*
str
,
SizeType
len
)
:
s
(
str
),
length
(
len
)
{
RAPIDJSON_ASSERT
(
s
!=
NULL
);
}
//! implicit conversion to plain CharType pointer
operator
const
Ch
*
()
const
{
return
s
;
}
const
Ch
*
s
;
//!< plain CharType pointer
const
SizeType
length
;
//!< length of the string (excluding the trailing NULL terminator)
private
:
//! Disallow construction from non-const array
template
<
SizeType
N
>
GenericStringRef
(
CharType
(
&
str
)[
N
])
/* = delete */
;
};
//! Mark a character pointer as constant string
template
<
typename
CharType
>
inline
GenericStringRef
<
CharType
>
StringRef
(
const
CharType
*
str
)
{
return
GenericStringRef
<
CharType
>
(
str
,
internal
::
StrLen
(
str
));
}
//! Mark a character pointer as constant string
template
<
typename
CharType
>
inline
GenericStringRef
<
CharType
>
StringRef
(
const
CharType
*
str
,
size_t
length
)
{
return
GenericStringRef
<
CharType
>
(
str
,
SizeType
(
length
));
}
///////////////////////////////////////////////////////////////////////////////
// GenericValue
...
...
@@ -196,6 +241,7 @@ public:
typedef
Encoding
EncodingType
;
//!< Encoding type from template parameter.
typedef
Allocator
AllocatorType
;
//!< Allocator type from template parameter.
typedef
typename
Encoding
::
Ch
Ch
;
//!< Character type derived from Encoding.
typedef
GenericStringRef
<
Ch
>
StringRefType
;
//!< Reference to a constant string
typedef
typename
GenericMemberIterator
<
false
,
Encoding
,
Allocator
>::
Iterator
MemberIterator
;
//!< Member iterator for iterating in object.
typedef
typename
GenericMemberIterator
<
true
,
Encoding
,
Allocator
>::
Iterator
ConstMemberIterator
;
//!< Constant member iterator for iterating in object.
typedef
GenericValue
*
ValueIterator
;
//!< Value iterator for iterating in array.
...
...
@@ -207,9 +253,11 @@ public:
//! Default constructor creates a null value.
GenericValue
()
:
data_
(),
flags_
(
kNullFlag
)
{}
//! Copy constructor is not permitted.
private
:
//! Copy constructor is not permitted.
GenericValue
(
const
GenericValue
&
rhs
);
//! Disabled constructor for arbitrary pointers.
template
<
typename
T
>
explicit
GenericValue
(
T
*
);
public
:
...
...
@@ -283,16 +331,16 @@ public:
explicit
GenericValue
(
double
d
)
:
data_
(),
flags_
(
kNumberDoubleFlag
)
{
data_
.
n
.
d
=
d
;
}
//! Constructor for constant string (i.e. do not make a copy of string)
GenericValue
(
const
Ch
*
s
,
SizeType
length
)
:
data_
(),
flags_
()
{
SetStringRaw
(
s
,
length
);
}
GenericValue
(
const
Ch
*
s
,
SizeType
length
)
:
data_
(),
flags_
()
{
SetStringRaw
(
StringRef
(
s
,
length
)
);
}
//! Constructor for constant string (i.e. do not make a copy of string)
explicit
GenericValue
(
const
Ch
*
s
)
:
data_
(),
flags_
()
{
SetStringRaw
(
s
,
internal
::
StrLen
(
s
)
);
}
explicit
GenericValue
(
StringRefType
s
)
:
data_
(),
flags_
()
{
SetStringRaw
(
s
);
}
//! Constructor for copy-string (i.e. do make a copy of string)
GenericValue
(
const
Ch
*
s
,
SizeType
length
,
Allocator
&
allocator
)
:
data_
(),
flags_
()
{
SetStringRaw
(
s
,
length
,
allocator
);
}
GenericValue
(
const
Ch
*
s
,
SizeType
length
,
Allocator
&
allocator
)
:
data_
(),
flags_
()
{
SetStringRaw
(
StringRef
(
s
,
length
)
,
allocator
);
}
//! Constructor for copy-string (i.e. do make a copy of string)
GenericValue
(
const
Ch
*
s
,
Allocator
&
allocator
)
:
data_
(),
flags_
()
{
SetStringRaw
(
s
,
internal
::
StrLen
(
s
),
allocator
);
}
GenericValue
(
const
Ch
*
s
,
Allocator
&
allocator
)
:
data_
(),
flags_
()
{
SetStringRaw
(
StringRef
(
s
),
allocator
);
}
//! Destructor.
/*! Need to destruct elements of array, members of object, or copy-string.
...
...
@@ -339,12 +387,17 @@ public:
return
*
this
;
}
//! Assignment of constant string reference (no copy)
GenericValue
&
operator
=
(
StringRefType
str
)
{
return
(
*
this
).
template
operator
=<
StringRefType
>
(
str
);
}
//! Assignment with primitive types.
/*! \tparam T Either
Type, int, unsigned, int64_t, uint64_t, const Ch*
/*! \tparam T Either
\ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
\param value The value to be assigned.
*/
template
<
typename
T
>
GenericValue
&
operator
=
(
T
value
)
{
RAPIDJSON_DISABLEIF_RETURN
(
internal
::
IsPointer
<
T
>
,
GenericValue
&
)
operator
=
(
T
value
)
{
this
->~
GenericValue
();
new
(
this
)
GenericValue
(
value
);
return
*
this
;
...
...
@@ -428,7 +481,7 @@ public:
A better approach is to use the now public FindMember().
*/
GenericValue
&
operator
[](
const
Ch
*
name
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
));
GenericValue
n
(
StringRef
(
name
));
return
(
*
this
)[
n
];
}
const
GenericValue
&
operator
[](
const
Ch
*
name
)
const
{
return
const_cast
<
GenericValue
&>
(
*
this
)[
name
];
}
...
...
@@ -481,7 +534,7 @@ public:
\c std::map, this has been changed to MemberEnd() now.
*/
MemberIterator
FindMember
(
const
Ch
*
name
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
));
GenericValue
n
(
StringRef
(
name
));
return
FindMember
(
n
);
}
...
...
@@ -530,19 +583,23 @@ public:
return
*
this
;
}
GenericValue
&
AddMember
(
const
Ch
*
name
,
Allocator
&
nameAllocator
,
GenericValue
&
value
,
Allocator
&
allocator
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
),
nameAllocator
);
//! Add a member (name-value pair) to the object.
GenericValue
&
AddMember
(
StringRefType
name
,
GenericValue
&
value
,
Allocator
&
allocator
)
{
GenericValue
n
(
name
);
return
AddMember
(
n
,
value
,
allocator
);
}
GenericValue
&
AddMember
(
const
Ch
*
name
,
GenericValue
&
value
,
Allocator
&
allocator
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
));
return
AddMember
(
n
,
value
,
allocator
);
//! Add a constant string value as member (name-value pair) to the object.
GenericValue
&
AddMember
(
StringRefType
name
,
StringRefType
value
,
Allocator
&
allocator
)
{
GenericValue
v
(
value
);
return
AddMember
(
name
,
v
,
allocator
);
}
//! Add any primitive value as member (name-value pair) to the object.
template
<
typename
T
>
GenericValue
&
AddMember
(
const
Ch
*
name
,
T
value
,
Allocator
&
allocator
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
));
RAPIDJSON_DISABLEIF_RETURN
(
internal
::
IsPointer
<
T
>
,
GenericValue
&
)
AddMember
(
StringRefType
name
,
T
value
,
Allocator
&
allocator
)
{
GenericValue
n
(
name
);
GenericValue
v
(
value
);
return
AddMember
(
n
,
v
,
allocator
);
}
...
...
@@ -553,7 +610,7 @@ public:
\note Removing member is implemented by moving the last member. So the ordering of members is changed.
*/
bool
RemoveMember
(
const
Ch
*
name
)
{
GenericValue
n
(
name
,
internal
::
StrLen
(
name
));
GenericValue
n
(
StringRef
(
name
));
return
RemoveMember
(
n
);
}
...
...
@@ -657,7 +714,7 @@ int z = a[0u].GetInt(); // This works too.
return
*
this
;
}
//! Append a
v
alue at the end of the array.
//! Append a
GenericV
alue at the end of the array.
/*! \param value The value to be appended.
\param allocator The allocator for allocating memory. It must be the same one use previously.
\return The value itself for fluent API.
...
...
@@ -672,8 +729,15 @@ int z = a[0u].GetInt(); // This works too.
return
*
this
;
}
//! Append a constant string reference at the end of the array.
GenericValue
&
PushBack
(
StringRefType
value
,
Allocator
&
allocator
)
{
return
(
*
this
).
template
PushBack
<
StringRefType
>
(
value
,
allocator
);
}
//! Append a primitive value at the end of the array.
template
<
typename
T
>
GenericValue
&
PushBack
(
T
value
,
Allocator
&
allocator
)
{
RAPIDJSON_DISABLEIF_RETURN
(
internal
::
IsPointer
<
T
>
,
GenericValue
&
)
PushBack
(
T
value
,
Allocator
&
allocator
)
{
GenericValue
v
(
value
);
return
PushBack
(
v
,
allocator
);
}
...
...
@@ -728,13 +792,13 @@ int z = a[0u].GetInt(); // This works too.
\param length The length of source string, excluding the trailing null terminator.
\return The value itself for fluent API.
*/
GenericValue
&
SetString
(
const
Ch
*
s
,
SizeType
length
)
{
this
->~
GenericValue
();
SetStringRaw
(
s
,
length
);
return
*
this
;
}
GenericValue
&
SetString
(
const
Ch
*
s
,
SizeType
length
)
{
return
SetString
(
StringRef
(
s
,
length
))
;
}
//! Set this value as a string without copying source string.
/*! \param s source string
pointer.
/*! \param s source string
reference
\return The value itself for fluent API.
*/
GenericValue
&
SetString
(
const
Ch
*
s
)
{
return
SetString
(
s
,
internal
::
StrLen
(
s
))
;
}
GenericValue
&
SetString
(
StringRefType
s
)
{
this
->~
GenericValue
();
SetStringRaw
(
s
);
return
*
this
;
}
//! 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.
...
...
@@ -743,14 +807,14 @@ int z = a[0u].GetInt(); // This works too.
\param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().
\return The value itself for fluent API.
*/
GenericValue
&
SetString
(
const
Ch
*
s
,
SizeType
length
,
Allocator
&
allocator
)
{
this
->~
GenericValue
();
SetStringRaw
(
s
,
length
,
allocator
);
return
*
this
;
}
GenericValue
&
SetString
(
const
Ch
*
s
,
SizeType
length
,
Allocator
&
allocator
)
{
this
->~
GenericValue
();
SetStringRaw
(
StringRef
(
s
,
length
)
,
allocator
);
return
*
this
;
}
//! Set this value as a string by copying from source string.
/*! \param s source string.
\param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().
\return The value itself for fluent API.
*/
GenericValue
&
SetString
(
const
Ch
*
s
,
Allocator
&
allocator
)
{
SetString
(
s
,
internal
::
StrLen
(
s
),
allocator
);
return
*
this
;
}
GenericValue
&
SetString
(
const
Ch
*
s
,
Allocator
&
allocator
)
{
return
SetString
(
s
,
internal
::
StrLen
(
s
),
allocator
)
;
}
//@}
...
...
@@ -906,21 +970,19 @@ private:
}
//! Initialize this value as constant string, without calling destructor.
void
SetStringRaw
(
const
Ch
*
s
,
SizeType
length
)
{
RAPIDJSON_ASSERT
(
s
!=
NULL
);
void
SetStringRaw
(
StringRefType
s
)
{
flags_
=
kConstStringFlag
;
data_
.
s
.
str
=
s
;
data_
.
s
.
length
=
length
;
data_
.
s
.
length
=
s
.
length
;
}
//! Initialize this value as copy string with initial data, without calling destructor.
void
SetStringRaw
(
const
Ch
*
s
,
SizeType
length
,
Allocator
&
allocator
)
{
RAPIDJSON_ASSERT
(
s
!=
NULL
);
void
SetStringRaw
(
StringRefType
s
,
Allocator
&
allocator
)
{
flags_
=
kCopyStringFlag
;
data_
.
s
.
str
=
(
Ch
*
)
allocator
.
Malloc
((
length
+
1
)
*
sizeof
(
Ch
));
data_
.
s
.
length
=
length
;
memcpy
(
const_cast
<
Ch
*>
(
data_
.
s
.
str
),
s
,
length
*
sizeof
(
Ch
));
const_cast
<
Ch
*>
(
data_
.
s
.
str
)[
length
]
=
'\0'
;
data_
.
s
.
str
=
(
Ch
*
)
allocator
.
Malloc
((
s
.
length
+
1
)
*
sizeof
(
Ch
));
data_
.
s
.
length
=
s
.
length
;
memcpy
(
const_cast
<
Ch
*>
(
data_
.
s
.
str
),
s
,
s
.
length
*
sizeof
(
Ch
));
const_cast
<
Ch
*>
(
data_
.
s
.
str
)[
s
.
length
]
=
'\0'
;
}
//! Assignment without calling destructor
...
...
include/rapidjson/internal/meta.h
View file @
4007301e
...
...
@@ -30,6 +30,9 @@ template <typename T> struct IsSame<T,T> : TrueType {};
template
<
typename
T
>
struct
IsConst
:
FalseType
{};
template
<
typename
T
>
struct
IsConst
<
const
T
>
:
TrueType
{};
template
<
typename
T
>
struct
IsPointer
:
FalseType
{};
template
<
typename
T
>
struct
IsPointer
<
T
*>
:
TrueType
{};
template
<
typename
CT
,
typename
T
>
struct
IsMoreConst
{
enum
{
Value
=
...
...
@@ -64,6 +67,9 @@ template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef
typename
::
rapidjson
::
internal
::
EnableIf
\
<
RAPIDJSON_REMOVEFPTR_
(
cond
)
>::
Type
*
=
NULL
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
typename
::
rapidjson
::
internal
::
DisableIf
<
cond
,
returntype
>::
Type
}
// namespace internal
}
// namespace rapidjson
//@endcond
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment