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
881c91d6
Commit
881c91d6
authored
Sep 05, 2014
by
Milo Yip
Browse files
Options
Browse Files
Download
Plain Diff
Merge master and implement kParseFullPrecision
parents
d875f16a
5e03cbf1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
311 additions
and
60 deletions
+311
-60
Doxyfile
build/Doxyfile
+5
-2
capitalize.cpp
example/capitalize/capitalize.cpp
+1
-0
simplereader.cpp
example/simplereader/simplereader.cpp
+4
-0
document.h
include/rapidjson/document.h
+0
-0
meta.h
include/rapidjson/internal/meta.h
+114
-31
prettywriter.h
include/rapidjson/prettywriter.h
+3
-0
rapidjson.h
include/rapidjson/rapidjson.h
+43
-2
reader.h
include/rapidjson/reader.h
+0
-0
writer.h
include/rapidjson/writer.h
+3
-0
readertest.cpp
test/unittest/readertest.cpp
+0
-0
unittest.h
test/unittest/unittest.h
+2
-8
valuetest.cpp
test/unittest/valuetest.cpp
+136
-17
No files found.
build/Doxyfile
View file @
881c91d6
...
...
@@ -1993,7 +1993,9 @@ INCLUDE_FILE_PATTERNS =
PREDEFINED = \
RAPIDJSON_DOXYGEN_RUNNING \
RAPIDJSON_DISABLEIF_RETURN(cond,returntype)=returntype
RAPIDJSON_REMOVEFPTR_(x)=x \
RAPIDJSON_ENABLEIF_RETURN(cond,returntype)="RAPIDJSON_REMOVEFPTR_ returntype" \
RAPIDJSON_DISABLEIF_RETURN(cond,returntype)="RAPIDJSON_REMOVEFPTR_ returntype"
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
...
...
@@ -2002,7 +2004,8 @@ PREDEFINED = \
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED = \
RAPIDJSON_NOEXCEPT
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
...
...
example/capitalize/capitalize.cpp
View file @
881c91d6
...
...
@@ -31,6 +31,7 @@ struct CapitalizeFilter {
return
out_
.
String
(
&
buffer_
.
front
(),
length
,
true
);
// true = output handler need to copy the string
}
bool
StartObject
()
{
return
out_
.
StartObject
();
}
bool
Key
(
const
char
*
str
,
SizeType
length
,
bool
copy
)
{
return
String
(
str
,
length
,
copy
);
}
bool
EndObject
(
SizeType
memberCount
)
{
return
out_
.
EndObject
(
memberCount
);
}
bool
StartArray
()
{
return
out_
.
StartArray
();
}
bool
EndArray
(
SizeType
elementCount
)
{
return
out_
.
EndArray
(
elementCount
);
}
...
...
example/simplereader/simplereader.cpp
View file @
881c91d6
...
...
@@ -17,6 +17,10 @@ struct MyHandler {
return
true
;
}
bool
StartObject
()
{
cout
<<
"StartObject()"
<<
endl
;
return
true
;
}
bool
Key
(
const
char
*
str
,
SizeType
length
,
bool
copy
)
{
cout
<<
"Key("
<<
str
<<
", "
<<
length
<<
", "
<<
boolalpha
<<
copy
<<
")"
<<
endl
;
return
true
;
}
bool
EndObject
(
SizeType
memberCount
)
{
cout
<<
"EndObject("
<<
memberCount
<<
")"
<<
endl
;
return
true
;
}
bool
StartArray
()
{
cout
<<
"StartArray()"
<<
endl
;
return
true
;
}
bool
EndArray
(
SizeType
elementCount
)
{
cout
<<
"EndArray("
<<
elementCount
<<
")"
<<
endl
;
return
true
;
}
...
...
include/rapidjson/document.h
View file @
881c91d6
This diff is collapsed.
Click to expand it.
include/rapidjson/internal/meta.h
View file @
881c91d6
...
...
@@ -21,57 +21,129 @@
#ifndef RAPIDJSON_INTERNAL_META_H_
#define RAPIDJSON_INTERNAL_META_H_
#ifndef RAPIDJSON_RAPIDJSON_H_
#error <rapidjson.h> not yet included. Do not include this file directly.
#endif
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
effc
++
)
#endif
#if defined(_MSC_VER)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
6334
)
#endif
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
#include <type_traits>
#endif
//@cond RAPIDJSON_INTERNAL
namespace
rapidjson
{
namespace
internal
{
template
<
int
N
>
struct
IntegralC
{
enum
{
Value
=
N
};
};
template
<
bool
Cond
>
struct
BoolType
:
IntegralC
<
Cond
>
{};
struct
TrueType
:
BoolType
<
true
>
{};
struct
FalseType
:
BoolType
<
false
>
{};
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
template
<
typename
T
>
struct
Void
{
typedef
void
Type
;
};
///////////////////////////////////////////////////////////////////////////////
// BoolType, TrueType, FalseType
//
template
<
bool
Cond
>
struct
BoolType
{
static
const
bool
Value
=
Cond
;
typedef
BoolType
Type
;
};
typedef
BoolType
<
true
>
TrueType
;
typedef
BoolType
<
false
>
FalseType
;
///////////////////////////////////////////////////////////////////////////////
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
//
template
<
bool
C
>
struct
SelectIfImpl
{
template
<
typename
T1
,
typename
T2
>
struct
Apply
{
typedef
T1
Type
;
};
};
template
<>
struct
SelectIfImpl
<
false
>
{
template
<
typename
T1
,
typename
T2
>
struct
Apply
{
typedef
T2
Type
;
};
};
template
<
bool
C
,
typename
T1
,
typename
T2
>
struct
SelectIfCond
:
SelectIfImpl
<
C
>::
template
Apply
<
T1
,
T2
>
{};
template
<
typename
C
,
typename
T1
,
typename
T2
>
struct
SelectIf
:
SelectIfCond
<
C
::
Value
,
T1
,
T2
>
{};
template
<
bool
Cond1
,
bool
Cond2
>
struct
AndExprCond
:
FalseType
{};
template
<>
struct
AndExprCond
<
true
,
true
>
:
TrueType
{};
template
<
bool
Cond1
,
bool
Cond2
>
struct
OrExprCond
:
TrueType
{};
template
<>
struct
OrExprCond
<
false
,
false
>
:
FalseType
{};
template
<
typename
C
>
struct
BoolExpr
:
SelectIf
<
C
,
TrueType
,
FalseType
>::
Type
{};
template
<
typename
C
>
struct
NotExpr
:
SelectIf
<
C
,
FalseType
,
TrueType
>::
Type
{};
template
<
typename
C1
,
typename
C2
>
struct
AndExpr
:
AndExprCond
<
C1
::
Value
,
C2
::
Value
>::
Type
{};
template
<
typename
C1
,
typename
C2
>
struct
OrExpr
:
OrExprCond
<
C1
::
Value
,
C2
::
Value
>::
Type
{};
///////////////////////////////////////////////////////////////////////////////
// AddConst, MaybeAddConst, RemoveConst
template
<
typename
T
>
struct
AddConst
{
typedef
const
T
Type
;
};
template
<
bool
Constify
,
typename
T
>
struct
MaybeAddConst
:
SelectIfCond
<
Constify
,
const
T
,
T
>
{};
template
<
typename
T
>
struct
RemoveConst
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
RemoveConst
<
const
T
>
{
typedef
T
Type
;
};
template
<
bool
Condition
,
typename
T1
,
typename
T2
>
struct
SelectIfCond
;
template
<
typename
T1
,
typename
T2
>
struct
SelectIfCond
<
true
,
T1
,
T2
>
{
typedef
T1
Type
;
};
template
<
typename
T1
,
typename
T2
>
struct
SelectIfCond
<
false
,
T1
,
T2
>
{
typedef
T2
Type
;
};
template
<
typename
Condition
,
typename
T1
,
typename
T2
>
struct
SelectIf
:
SelectIfCond
<
Condition
::
Value
,
T1
,
T2
>
{};
template
<
bool
Constify
,
typename
T
>
struct
MaybeAddConst
:
SelectIfCond
<
Constify
,
const
T
,
T
>
{};
template
<
typename
T
,
typename
U
>
struct
IsSame
:
FalseType
{};
template
<
typename
T
>
struct
IsSame
<
T
,
T
>
:
TrueType
{};
///////////////////////////////////////////////////////////////////////////////
// IsSame, IsConst, IsMoreConst, IsPointer
//
template
<
typename
T
,
typename
U
>
struct
IsSame
:
FalseType
{};
template
<
typename
T
>
struct
IsSame
<
T
,
T
>
:
TrueType
{};
template
<
typename
T
>
struct
IsConst
:
FalseType
{};
template
<
typename
T
>
struct
IsConst
<
const
T
>
:
TrueType
{};
template
<
typename
CT
,
typename
T
>
struct
IsMoreConst
:
AndExpr
<
IsSame
<
typename
RemoveConst
<
CT
>::
Type
,
typename
RemoveConst
<
T
>::
Type
>
,
BoolType
<
IsConst
<
CT
>::
Value
>=
IsConst
<
T
>::
Value
>
>::
Type
{};
template
<
typename
T
>
struct
IsPointer
:
FalseType
{};
template
<
typename
T
>
struct
IsPointer
<
T
*>
:
TrueType
{};
template
<
typename
CT
,
typename
T
>
struct
IsMoreConst
{
enum
{
Value
=
(
IsSame
<
typename
RemoveConst
<
CT
>::
Type
,
typename
RemoveConst
<
T
>::
Type
>::
Value
&&
(
IsConst
<
CT
>::
Value
>=
IsConst
<
T
>::
Value
)
)
///////////////////////////////////////////////////////////////////////////////
// IsBaseOf
//
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
template
<
typename
B
,
typename
D
>
struct
IsBaseOf
:
BoolType
<
::
std
::
is_base_of
<
B
,
D
>::
value
>
{};
#else // simplified version adopted from Boost
template
<
typename
B
,
typename
D
>
struct
IsBaseOfImpl
{
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
B
)
!=
0
);
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
D
)
!=
0
);
typedef
char
(
&
Yes
)[
1
];
typedef
char
(
&
No
)
[
2
];
template
<
typename
T
>
static
Yes
Check
(
const
D
*
,
T
);
static
No
Check
(
const
B
*
,
int
);
struct
Host
{
operator
const
B
*
()
const
;
operator
const
D
*
();
};
enum
{
Value
=
(
sizeof
(
Check
(
Host
(),
0
))
==
sizeof
(
Yes
))
};
};
template
<
bool
Condition
,
typename
T
=
void
>
struct
EnableIfCond
;
template
<
typename
T
>
struct
EnableIfCond
<
true
,
T
>
{
typedef
T
Type
;
};
template
<
typename
B
,
typename
D
>
struct
IsBaseOf
:
OrExpr
<
IsSame
<
B
,
D
>
,
BoolExpr
<
IsBaseOfImpl
<
B
,
D
>
>
>::
Type
{};
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
//////////////////////////////////////////////////////////////////////////
// EnableIf / DisableIf
//
template
<
bool
Condition
,
typename
T
=
void
>
struct
EnableIfCond
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
EnableIfCond
<
false
,
T
>
{
/* empty */
};
template
<
bool
Condition
,
typename
T
=
void
>
struct
DisableIfCond
:
EnableIfCond
<!
Condition
,
T
>
{
};
template
<
bool
Condition
,
typename
T
=
void
>
struct
DisableIfCond
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
DisableIfCond
<
true
,
T
>
{
/* empty */
};
template
<
typename
Condition
,
typename
T
=
void
>
struct
EnableIf
:
EnableIfCond
<
Condition
::
Value
,
T
>
{};
...
...
@@ -80,26 +152,37 @@ template <typename Condition, typename T = void>
struct
DisableIf
:
DisableIfCond
<
Condition
::
Value
,
T
>
{};
// SFINAE helpers
struct
Sfinae
Result
Tag
{};
template
<
typename
T
>
struct
RemoveSfinae
Fptr
{}
;
template
<
typename
T
>
struct
RemoveSfinae
Fptr
<
SfinaeResult
Tag
&
(
*
)(
T
)
>
{
typedef
T
Type
;
};
struct
SfinaeTag
{};
template
<
typename
T
>
struct
RemoveSfinae
Tag
;
template
<
typename
T
>
struct
RemoveSfinae
Tag
<
Sfinae
Tag
&
(
*
)(
T
)
>
{
typedef
T
Type
;
};
#define RAPIDJSON_REMOVEFPTR_(type) \
typename
::
rapidjson
::
internal
::
RemoveSfinae
Fptr
\
<
::
rapidjson
::
internal
::
Sfinae
Result
Tag
&
(
*
)
type
>::
Type
typename
::
rapidjson
::
internal
::
RemoveSfinae
Tag
\
<
::
rapidjson
::
internal
::
SfinaeTag
&
(
*
)
type
>::
Type
#define RAPIDJSON_ENABLEIF(cond) \
typename
::
rapidjson
::
internal
::
EnableIf
\
<
RAPIDJSON_REMOVEFPTR_
(
cond
)
>::
Type
*
=
NULL
#define RAPIDJSON_DISABLEIF(cond) \
typename
::
rapidjson
::
internal
::
DisableIf
\
<
RAPIDJSON_REMOVEFPTR_
(
cond
)
>::
Type
*
=
NULL
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
typename
::
rapidjson
::
internal
::
EnableIf
\
<
RAPIDJSON_REMOVEFPTR_
(
cond
),
\
RAPIDJSON_REMOVEFPTR_
(
returntype
)
>::
Type
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
typename
::
rapidjson
::
internal
::
DisableIf
<
cond
,
returntype
>::
Type
typename
::
rapidjson
::
internal
::
DisableIf
\
<
RAPIDJSON_REMOVEFPTR_
(
cond
),
\
RAPIDJSON_REMOVEFPTR_
(
returntype
)
>::
Type
}
// namespace internal
}
// namespace rapidjson
//@endcond
#if
def __GNUC__
#if
defined(__GNUC__) || defined(_MSC_VER)
RAPIDJSON_DIAG_POP
#endif
...
...
include/rapidjson/prettywriter.h
View file @
881c91d6
...
...
@@ -88,6 +88,8 @@ public:
return
Base
::
WriteStartObject
();
}
bool
Key
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
return
String
(
str
,
length
,
copy
);
}
bool
EndObject
(
SizeType
memberCount
=
0
)
{
(
void
)
memberCount
;
RAPIDJSON_ASSERT
(
Base
::
level_stack_
.
GetSize
()
>=
sizeof
(
typename
Base
::
Level
));
...
...
@@ -135,6 +137,7 @@ public:
//! Simpler but slower overload.
bool
String
(
const
Ch
*
str
)
{
return
String
(
str
,
internal
::
StrLen
(
str
));
}
bool
Key
(
const
Ch
*
str
)
{
return
Key
(
str
,
internal
::
StrLen
(
str
));
}
//@}
protected
:
...
...
include/rapidjson/rapidjson.h
View file @
881c91d6
...
...
@@ -318,7 +318,12 @@ template<int x> struct StaticAssertTest {};
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
#if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= RAPIDJSON_VERSION_CODE(4,2,0))
#if defined(__GNUC__)
#define RAPIDJSON_GNUC \
RAPIDJSON_VERSION_CODE
(
__GNUC__
,
__GNUC_MINOR__
,
__GNUC_PATCHLEVEL__
)
#endif
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))
#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
...
...
@@ -326,7 +331,7 @@ template<int x> struct StaticAssertTest {};
RAPIDJSON_DIAG_PRAGMA
(
ignored
RAPIDJSON_STRINGIFY
(
RAPIDJSON_JOIN
(
-
W
,
x
)))
// push/pop support in Clang and GCC>=4.6
#if defined(__clang__) || (defined(
__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
>= RAPIDJSON_VERSION_CODE(4,6,0))
#if defined(__clang__) || (defined(
RAPIDJSON_GNUC) && RAPIDJSON_GNUC
>= RAPIDJSON_VERSION_CODE(4,6,0))
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
#else // GCC >= 4.2, < 4.6
...
...
@@ -352,6 +357,42 @@ template<int x> struct StaticAssertTest {};
#endif // RAPIDJSON_DIAG_*
///////////////////////////////////////////////////////////////////////////////
// C++11 features
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(
defined
(
_MSC_VER
)
&&
_MSC_VER
>=
1600
)
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
#else
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
#endif
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
#else
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
#endif
#endif
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
#define RAPIDJSON_NOEXCEPT noexcept
#else
#define RAPIDJSON_NOEXCEPT
/* noexcept */
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
// no automatic detection, yet
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
#endif
//!@endcond
///////////////////////////////////////////////////////////////////////////////
...
...
include/rapidjson/reader.h
View file @
881c91d6
This diff is collapsed.
Click to expand it.
include/rapidjson/writer.h
View file @
881c91d6
...
...
@@ -131,6 +131,8 @@ public:
return
WriteStartObject
();
}
bool
Key
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
=
false
)
{
return
String
(
str
,
length
,
copy
);
}
bool
EndObject
(
SizeType
memberCount
=
0
)
{
(
void
)
memberCount
;
RAPIDJSON_ASSERT
(
level_stack_
.
GetSize
()
>=
sizeof
(
Level
));
...
...
@@ -165,6 +167,7 @@ public:
//! Simpler but slower overload.
bool
String
(
const
Ch
*
str
)
{
return
String
(
str
,
internal
::
StrLen
(
str
));
}
bool
Key
(
const
Ch
*
str
)
{
return
Key
(
str
,
internal
::
StrLen
(
str
));
}
//@}
...
...
test/unittest/readertest.cpp
View file @
881c91d6
This diff is collapsed.
Click to expand it.
test/unittest/unittest.h
View file @
881c91d6
...
...
@@ -89,15 +89,9 @@ inline FILE* TempFile(char *filename) {
#pragma warning(disable : 4127)
#endif
class
AssertException
:
public
std
::
exception
{
class
AssertException
:
public
std
::
logic_error
{
public
:
AssertException
(
const
char
*
w
)
:
what_
(
w
)
{}
AssertException
(
const
AssertException
&
other
)
:
what_
(
other
.
what_
)
{}
AssertException
&
operator
=
(
const
AssertException
&
rhs
)
{
what_
=
rhs
.
what_
;
return
*
this
;
}
virtual
const
char
*
what
()
const
throw
()
{
return
what_
;
}
private
:
const
char
*
what_
;
AssertException
(
const
char
*
w
)
:
std
::
logic_error
(
w
)
{}
};
#define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x))
...
...
test/unittest/valuetest.cpp
View file @
881c91d6
...
...
@@ -24,7 +24,7 @@
using
namespace
rapidjson
;
TEST
(
Value
,
default_c
onstructor
)
{
TEST
(
Value
,
DefaultC
onstructor
)
{
Value
x
;
EXPECT_EQ
(
kNullType
,
x
.
GetType
());
EXPECT_TRUE
(
x
.
IsNull
());
...
...
@@ -38,7 +38,32 @@ TEST(Value, default_constructor) {
// Value y = x;
//}
TEST
(
Value
,
assignment_operator
)
{
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST
(
Value
,
MoveConstructor
)
{
typedef
GenericValue
<
UTF8
<>
,
CrtAllocator
>
Value
;
Value
::
AllocatorType
allocator
;
Value
x
((
Value
(
kArrayType
)));
x
.
Reserve
(
4u
,
allocator
);
x
.
PushBack
(
1
,
allocator
).
PushBack
(
2
,
allocator
).
PushBack
(
3
,
allocator
).
PushBack
(
4
,
allocator
);
EXPECT_TRUE
(
x
.
IsArray
());
EXPECT_EQ
(
4u
,
x
.
Size
());
// Value y(x); // should not compile
Value
y
(
std
::
move
(
x
));
EXPECT_TRUE
(
x
.
IsNull
());
EXPECT_TRUE
(
y
.
IsArray
());
EXPECT_EQ
(
4u
,
y
.
Size
());
// Value z = y; // should not compile
Value
z
=
std
::
move
(
y
);
EXPECT_TRUE
(
y
.
IsNull
());
EXPECT_TRUE
(
z
.
IsArray
());
EXPECT_EQ
(
4u
,
z
.
Size
());
}
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST
(
Value
,
AssignmentOperator
)
{
Value
x
(
1234
);
Value
y
;
y
=
x
;
...
...
@@ -63,6 +88,22 @@ TEST(Value, assignment_operator) {
y
=
StringRef
(
mstr
);
EXPECT_TRUE
(
y
.
IsString
());
EXPECT_EQ
(
y
.
GetString
(),
mstr
);
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// C++11 move assignment
x
=
Value
(
"World"
);
EXPECT_TRUE
(
x
.
IsString
());
EXPECT_STREQ
(
"World"
,
x
.
GetString
());
x
=
std
::
move
(
y
);
EXPECT_TRUE
(
y
.
IsNull
());
EXPECT_TRUE
(
x
.
IsString
());
EXPECT_EQ
(
x
.
GetString
(),
mstr
);
y
=
std
::
move
(
Value
().
SetInt
(
1234
));
EXPECT_TRUE
(
y
.
IsInt
());
EXPECT_EQ
(
1234
,
y
);
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
}
template
<
typename
A
,
typename
B
>
...
...
@@ -81,7 +122,7 @@ void TestUnequal(const A& a, const B& b) {
EXPECT_TRUE
(
b
!=
a
);
}
TEST
(
Value
,
equalto_o
perator
)
{
TEST
(
Value
,
EqualtoO
perator
)
{
Value
::
AllocatorType
allocator
;
Value
x
(
kObjectType
);
x
.
AddMember
(
"hello"
,
"world"
,
allocator
)
...
...
@@ -105,16 +146,33 @@ TEST(Value, equalto_operator) {
TestEqual
(
x
[
"i"
],
123
);
TestEqual
(
x
[
"pi"
],
3.14
);
// Test operator==()
Value
y
;
y
.
CopyFrom
(
x
,
allocator
);
// Test operator==() (including different allocators)
CrtAllocator
crtAllocator
;
GenericValue
<
UTF8
<>
,
CrtAllocator
>
y
;
GenericDocument
<
UTF8
<>
,
CrtAllocator
>
z
(
&
crtAllocator
);
y
.
CopyFrom
(
x
,
crtAllocator
);
z
.
CopyFrom
(
y
,
z
.
GetAllocator
());
TestEqual
(
x
,
y
);
TestEqual
(
y
,
z
);
TestEqual
(
z
,
x
);
// Swapping member order should be fine.
y
.
RemoveMember
(
"t"
);
EXPECT_TRUE
(
y
.
RemoveMember
(
"t"
)
);
TestUnequal
(
x
,
y
);
y
.
AddMember
(
"t"
,
Value
(
true
).
Move
(),
allocator
);
TestUnequal
(
z
,
y
);
EXPECT_TRUE
(
z
.
RemoveMember
(
"t"
));
TestUnequal
(
x
,
z
);
TestEqual
(
y
,
z
);
y
.
AddMember
(
"t"
,
true
,
crtAllocator
);
z
.
AddMember
(
"t"
,
true
,
z
.
GetAllocator
());
TestEqual
(
x
,
y
);
TestEqual
(
y
,
z
);
TestEqual
(
z
,
x
);
// Issue #129: compare Uint64
x
.
SetUint64
(
RAPIDJSON_UINT64_C2
(
0xFFFFFFFF
,
0xFFFFFFF0
));
y
.
SetUint64
(
RAPIDJSON_UINT64_C2
(
0xFFFFFFFF
,
0xFFFFFFFF
));
TestUnequal
(
x
,
y
);
}
template
<
typename
Value
>
...
...
@@ -538,7 +596,7 @@ TEST(Value, String) {
EXPECT_STREQ
(
"World"
,
w
.
GetString
());
EXPECT_EQ
(
5u
,
w
.
GetStringLength
());
#if
def
RAPIDJSON_HAS_STDSTRING
#if RAPIDJSON_HAS_STDSTRING
{
std
::
string
str
=
"Hello World"
;
str
[
5
]
=
'\0'
;
...
...
@@ -626,6 +684,21 @@ TEST(Value, Array) {
EXPECT_TRUE
(
y
[
4u
].
IsString
());
EXPECT_STREQ
(
"foo"
,
y
[
4u
].
GetString
());
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// PushBack(GenericValue&&, Allocator&);
{
Value
y
(
kArrayType
);
y
.
PushBack
(
Value
(
true
),
allocator
);
y
.
PushBack
(
std
::
move
(
Value
(
kArrayType
).
PushBack
(
Value
(
1
),
allocator
).
PushBack
(
"foo"
,
allocator
)),
allocator
);
EXPECT_EQ
(
2u
,
y
.
Size
());
EXPECT_TRUE
(
y
[
0u
].
IsTrue
());
EXPECT_TRUE
(
y
[
1u
].
IsArray
());
EXPECT_EQ
(
2u
,
y
[
1u
].
Size
());
EXPECT_TRUE
(
y
[
1u
][
0u
].
IsInt
());
EXPECT_TRUE
(
y
[
1u
][
1u
].
IsString
());
}
#endif
// iterator
Value
::
ValueIterator
itr
=
x
.
Begin
();
EXPECT_TRUE
(
itr
!=
x
.
End
());
...
...
@@ -734,7 +807,6 @@ TEST(Value, Array) {
}
// Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
#if 0
// http://en.wikipedia.org/wiki/Erase-remove_idiom
x
.
Clear
();
for
(
int
i
=
0
;
i
<
10
;
i
++
)
...
...
@@ -743,11 +815,11 @@ TEST(Value, Array) {
else
x
.
PushBack
(
Value
(
kNullType
).
Move
(),
allocator
);
x.Erase(std::remove(x.Begin(), x.End(), Value(kNullType)), x.End());
const
Value
null
(
kNullType
);
x
.
Erase
(
std
::
remove
(
x
.
Begin
(),
x
.
End
(),
null
),
x
.
End
());
EXPECT_EQ
(
5u
,
x
.
Size
());
for
(
int
i
=
0
;
i
<
5
;
i
++
)
EXPECT_EQ
(
i
*
2
,
x
[
i
]);
#endif
// SetArray()
Value
z
;
...
...
@@ -801,6 +873,22 @@ TEST(Value, Object) {
EXPECT_EQ
(
8u
,
o
.
MemberCount
());
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// AddMember(GenericValue&&, ...) variants
{
Value
o
(
kObjectType
);
o
.
AddMember
(
Value
(
"true"
),
Value
(
true
),
allocator
);
o
.
AddMember
(
Value
(
"false"
),
Value
(
false
).
Move
(),
allocator
);
// value is lvalue ref
o
.
AddMember
(
Value
(
"int"
).
Move
(),
Value
(
-
1
),
allocator
);
// name is lvalue ref
o
.
AddMember
(
"uint"
,
std
::
move
(
Value
().
SetUint
(
1u
)),
allocator
);
// name is literal, value is rvalue
EXPECT_TRUE
(
o
[
"true"
].
GetBool
());
EXPECT_FALSE
(
o
[
"false"
].
GetBool
());
EXPECT_EQ
(
-
1
,
o
[
"int"
].
GetInt
());
EXPECT_EQ
(
1u
,
o
[
"uint"
].
GetUint
());
EXPECT_EQ
(
4u
,
o
.
MemberCount
());
}
#endif
// Tests a member with null character
Value
name
;
const
Value
C0D
(
"C
\0
D"
,
3
);
...
...
@@ -818,10 +906,18 @@ TEST(Value, Object) {
EXPECT_TRUE
(
x
.
HasMember
(
name
));
EXPECT_TRUE
(
y
.
HasMember
(
name
));
GenericValue
<
UTF8
<>
,
CrtAllocator
>
othername
(
"A"
);
EXPECT_TRUE
(
x
.
HasMember
(
othername
));
EXPECT_TRUE
(
y
.
HasMember
(
othername
));
othername
.
SetString
(
"C
\0
D"
);
EXPECT_TRUE
(
x
.
HasMember
(
othername
));
EXPECT_TRUE
(
y
.
HasMember
(
othername
));
// operator[]
EXPECT_STREQ
(
"Apple"
,
x
[
"A"
].
GetString
());
EXPECT_STREQ
(
"Banana"
,
x
[
"B"
].
GetString
());
EXPECT_STREQ
(
"CherryD"
,
x
[
C0D
].
GetString
());
EXPECT_STREQ
(
"CherryD"
,
x
[
othername
].
GetString
());
// const operator[]
EXPECT_STREQ
(
"Apple"
,
y
[
"A"
].
GetString
());
...
...
@@ -892,7 +988,7 @@ TEST(Value, Object) {
x
.
RemoveMember
(
"B"
);
EXPECT_FALSE
(
x
.
HasMember
(
"B"
));
x
.
RemoveMember
(
name
);
x
.
RemoveMember
(
other
name
);
EXPECT_FALSE
(
x
.
HasMember
(
name
));
EXPECT_TRUE
(
x
.
MemberBegin
()
==
x
.
MemberEnd
());
...
...
@@ -905,11 +1001,14 @@ TEST(Value, Object) {
for
(
int
i
=
0
;
i
<
10
;
i
++
)
x
.
AddMember
(
keys
[
i
],
Value
(
kArrayType
).
PushBack
(
i
,
allocator
),
allocator
);
// MemberCount, iterator difference
EXPECT_EQ
(
x
.
MemberCount
(),
SizeType
(
x
.
MemberEnd
()
-
x
.
MemberBegin
()));
// Erase the first
itr
=
x
.
EraseMember
(
x
.
MemberBegin
());
EXPECT_FALSE
(
x
.
HasMember
(
keys
[
0
]));
EXPECT_EQ
(
x
.
MemberBegin
(),
itr
);
EXPECT_EQ
(
9
,
x
.
MemberEnd
()
-
x
.
MemberBegin
());
EXPECT_EQ
(
9
u
,
x
.
MemberCount
());
for
(;
itr
!=
x
.
MemberEnd
();
++
itr
)
{
int
i
=
(
itr
-
x
.
MemberBegin
())
+
1
;
EXPECT_STREQ
(
itr
->
name
.
GetString
(),
keys
[
i
]);
...
...
@@ -920,7 +1019,7 @@ TEST(Value, Object) {
itr
=
x
.
EraseMember
(
x
.
MemberEnd
()
-
1
);
EXPECT_FALSE
(
x
.
HasMember
(
keys
[
9
]));
EXPECT_EQ
(
x
.
MemberEnd
(),
itr
);
EXPECT_EQ
(
8
,
x
.
MemberEnd
()
-
x
.
MemberBegin
());
EXPECT_EQ
(
8
u
,
x
.
MemberCount
());
for
(;
itr
!=
x
.
MemberEnd
();
++
itr
)
{
int
i
=
(
itr
-
x
.
MemberBegin
())
+
1
;
EXPECT_STREQ
(
itr
->
name
.
GetString
(),
keys
[
i
]);
...
...
@@ -931,7 +1030,7 @@ TEST(Value, Object) {
itr
=
x
.
EraseMember
(
x
.
MemberBegin
()
+
4
);
EXPECT_FALSE
(
x
.
HasMember
(
keys
[
5
]));
EXPECT_EQ
(
x
.
MemberBegin
()
+
4
,
itr
);
EXPECT_EQ
(
7
,
x
.
MemberEnd
()
-
x
.
MemberBegin
());
EXPECT_EQ
(
7
u
,
x
.
MemberCount
());
for
(;
itr
!=
x
.
MemberEnd
();
++
itr
)
{
int
i
=
(
itr
-
x
.
MemberBegin
());
i
+=
(
i
<
4
)
?
1
:
2
;
...
...
@@ -955,7 +1054,7 @@ TEST(Value, Object) {
EXPECT_EQ
(
x
.
MemberBegin
()
+
first
,
itr
);
size_t
removeCount
=
last
-
first
;
EXPECT_EQ
(
n
-
removeCount
,
size_t
(
x
.
MemberEnd
()
-
x
.
MemberBegin
()
));
EXPECT_EQ
(
n
-
removeCount
,
x
.
MemberCount
(
));
for
(
unsigned
i
=
0
;
i
<
first
;
i
++
)
EXPECT_EQ
(
i
,
x
[
keys
[
i
]][
0u
].
GetUint
());
for
(
unsigned
i
=
first
;
i
<
n
-
removeCount
;
i
++
)
...
...
@@ -1059,3 +1158,23 @@ TEST(Document, CrtAllocator) {
V
a
(
kArrayType
);
a
.
PushBack
(
1
,
allocator
);
// Should not call destructor on uninitialized Value of newly allocated elements.
}
static
void
TestShortStringOptimization
(
const
char
*
str
)
{
const
rapidjson
::
SizeType
len
=
(
rapidjson
::
SizeType
)
strlen
(
str
);
rapidjson
::
Document
doc
;
rapidjson
::
Value
val
;
val
.
SetString
(
str
,
len
,
doc
.
GetAllocator
());
EXPECT_EQ
(
val
.
GetStringLength
(),
len
);
EXPECT_STREQ
(
val
.
GetString
(),
str
);
}
TEST
(
Value
,
AllocateShortString
)
{
TestShortStringOptimization
(
""
);
// edge case: empty string
TestShortStringOptimization
(
"12345678"
);
// regular case for short strings: 8 chars
TestShortStringOptimization
(
"12345678901"
);
// edge case: 11 chars in 32-bit mode (=> short string)
TestShortStringOptimization
(
"123456789012"
);
// edge case: 12 chars in 32-bit mode (=> regular string)
TestShortStringOptimization
(
"123456789012345"
);
// edge case: 15 chars in 64-bit mode (=> short string)
TestShortStringOptimization
(
"1234567890123456"
);
// edge case: 16 chars in 64-bit mode (=> regular string)
}
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