Merge pull request #128 from pah/feature/cxx11-move
Initial C++11 move support
This commit is contained in:
commit
bc9d7866be
@ -2004,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
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*! \file document.h */
|
||||
|
||||
#include "reader.h"
|
||||
#include "internal/meta.h"
|
||||
#include "internal/strfunc.h"
|
||||
#include <new> // placement new
|
||||
|
||||
@ -38,15 +39,17 @@ RAPIDJSON_DIAG_OFF(effc++)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
#ifndef RAPIDJSON_HAS_STDSTRING
|
||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
||||
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
|
||||
#else
|
||||
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
|
||||
#endif
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
/*! \def RAPIDJSON_HAS_STDSTRING
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\brief Enable RapidJSON support for \c std::string
|
||||
|
||||
By defining this preprocessor symbol, several convenience functions for using
|
||||
By defining this preprocessor symbol to \c 1, several convenience functions for using
|
||||
\ref rapidjson::GenericValue with \c std::string are enabled, especially
|
||||
for construction and comparison.
|
||||
|
||||
@ -56,7 +59,6 @@ RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif // RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||
#include "internal/meta.h"
|
||||
#include <iterator> // std::iterator, std::random_access_iterator_tag
|
||||
#endif
|
||||
|
||||
@ -277,7 +279,7 @@ struct GenericStringRef {
|
||||
GenericValue instead.
|
||||
*/
|
||||
template<SizeType N>
|
||||
GenericStringRef(const CharType (&str)[N])
|
||||
GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
|
||||
: s(str), length(N-1) {}
|
||||
|
||||
//! Explicitly create string reference from \c const character pointer
|
||||
@ -300,7 +302,7 @@ struct GenericStringRef {
|
||||
GenericValue instead.
|
||||
*/
|
||||
explicit GenericStringRef(const CharType* str)
|
||||
: s(str), length(internal::StrLen(str)){}
|
||||
: s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
|
||||
|
||||
//! Create constant string reference from pointer and length
|
||||
/*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
|
||||
@ -363,7 +365,7 @@ inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length)
|
||||
return GenericStringRef<CharType>(str, SizeType(length));
|
||||
}
|
||||
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
//! Mark a string object as constant string
|
||||
/*! Mark a string object (e.g. \c std::string) as a "string literal".
|
||||
This function can be used to avoid copying a string to be referenced as a
|
||||
@ -430,7 +432,14 @@ public:
|
||||
//@{
|
||||
|
||||
//! Default constructor creates a null value.
|
||||
GenericValue() : data_(), flags_(kNullFlag) {}
|
||||
GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
//! Move constructor in C++11
|
||||
GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) {
|
||||
rhs.flags_ = kNullFlag; // give up contents
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
//! Copy constructor is not permitted.
|
||||
@ -443,7 +452,7 @@ public:
|
||||
\param type Type of the value.
|
||||
\note Default content for number is zero.
|
||||
*/
|
||||
GenericValue(Type type) : data_(), flags_() {
|
||||
GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
|
||||
static const unsigned defaultFlags[7] = {
|
||||
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
|
||||
kNumberAnyFlag
|
||||
@ -470,9 +479,9 @@ public:
|
||||
*/
|
||||
#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
|
||||
template <typename T>
|
||||
explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>)))
|
||||
explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT
|
||||
#else
|
||||
explicit GenericValue(bool b)
|
||||
explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
|
||||
#endif
|
||||
: data_(), flags_(b ? kTrueFlag : kFalseFlag) {
|
||||
// safe-guard against failing SFINAE
|
||||
@ -480,21 +489,21 @@ public:
|
||||
}
|
||||
|
||||
//! Constructor for int value.
|
||||
explicit GenericValue(int i) : data_(), flags_(kNumberIntFlag) {
|
||||
explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) {
|
||||
data_.n.i64 = i;
|
||||
if (i >= 0)
|
||||
flags_ |= kUintFlag | kUint64Flag;
|
||||
}
|
||||
|
||||
//! Constructor for unsigned value.
|
||||
explicit GenericValue(unsigned u) : data_(), flags_(kNumberUintFlag) {
|
||||
explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) {
|
||||
data_.n.u64 = u;
|
||||
if (!(u & 0x80000000))
|
||||
flags_ |= kIntFlag | kInt64Flag;
|
||||
}
|
||||
|
||||
//! Constructor for int64_t value.
|
||||
explicit GenericValue(int64_t i64) : data_(), flags_(kNumberInt64Flag) {
|
||||
explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) {
|
||||
data_.n.i64 = i64;
|
||||
if (i64 >= 0) {
|
||||
flags_ |= kNumberUint64Flag;
|
||||
@ -508,7 +517,7 @@ public:
|
||||
}
|
||||
|
||||
//! Constructor for uint64_t value.
|
||||
explicit GenericValue(uint64_t u64) : data_(), flags_(kNumberUint64Flag) {
|
||||
explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) {
|
||||
data_.n.u64 = u64;
|
||||
if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
|
||||
flags_ |= kInt64Flag;
|
||||
@ -519,13 +528,13 @@ public:
|
||||
}
|
||||
|
||||
//! Constructor for double value.
|
||||
explicit GenericValue(double d) : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; }
|
||||
explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : 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(StringRef(s, length)); }
|
||||
GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); }
|
||||
|
||||
//! Constructor for constant string (i.e. do not make a copy of string)
|
||||
explicit GenericValue(StringRefType s) : data_(), flags_() { SetStringRaw(s); }
|
||||
explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : 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(StringRef(s, length), allocator); }
|
||||
@ -533,7 +542,7 @@ public:
|
||||
//! Constructor for copy-string (i.e. do make a copy of string)
|
||||
GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
|
||||
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
//! Constructor for copy-string from a string object (i.e. do make a copy of string)
|
||||
/*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
|
||||
*/
|
||||
@ -576,19 +585,26 @@ public:
|
||||
//! Assignment with move semantics.
|
||||
/*! \param rhs Source of the assignment. It will become a null value after assignment.
|
||||
*/
|
||||
GenericValue& operator=(GenericValue& rhs) {
|
||||
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_ASSERT(this != &rhs);
|
||||
this->~GenericValue();
|
||||
RawAssign(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
//! Move assignment in C++11
|
||||
GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
|
||||
return *this = rhs.Move();
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Assignment of constant string reference (no copy)
|
||||
/*! \param str Constant string reference to be assigned
|
||||
\note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
|
||||
\see GenericStringRef, operator=(T)
|
||||
*/
|
||||
GenericValue& operator=(StringRefType str) {
|
||||
GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
|
||||
GenericValue s(str);
|
||||
return *this = s;
|
||||
}
|
||||
@ -631,7 +647,7 @@ public:
|
||||
\param other Another value.
|
||||
\note Constant complexity.
|
||||
*/
|
||||
GenericValue& Swap(GenericValue& other) {
|
||||
GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
|
||||
GenericValue temp;
|
||||
temp.RawAssign(*this);
|
||||
RawAssign(other);
|
||||
@ -641,7 +657,7 @@ public:
|
||||
|
||||
//! Prepare Value for move semantics
|
||||
/*! \return *this */
|
||||
GenericValue& Move() { return *this; }
|
||||
GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
|
||||
//@}
|
||||
|
||||
//!@name Equal-to and not-equal-to operators
|
||||
@ -693,7 +709,7 @@ public:
|
||||
//! Equal-to operator with const C-string pointer
|
||||
bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
|
||||
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
//! Equal-to operator with string object
|
||||
/*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
|
||||
*/
|
||||
@ -921,6 +937,23 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
|
||||
return AddMember(name, value, allocator);
|
||||
}
|
||||
GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
|
||||
return AddMember(name, value, allocator);
|
||||
}
|
||||
GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
|
||||
return AddMember(name, value, allocator);
|
||||
}
|
||||
GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
|
||||
GenericValue n(name);
|
||||
return AddMember(n, value, allocator);
|
||||
}
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
|
||||
//! Add a member (name-value pair) to the object.
|
||||
/*! \param name A constant string reference as name of member.
|
||||
\param value Value of any type.
|
||||
@ -1162,6 +1195,12 @@ int z = a[0u].GetInt(); // This works too.
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
|
||||
return PushBack(value, allocator);
|
||||
}
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
//! Append a constant string reference at the end of the array.
|
||||
/*! \param value Constant string reference to be appended.
|
||||
\param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
|
||||
@ -1316,7 +1355,7 @@ int z = a[0u].GetInt(); // This works too.
|
||||
*/
|
||||
GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
|
||||
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
//! Set this value as a string by copying from source string.
|
||||
/*! \param s source string.
|
||||
\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
|
||||
@ -1502,7 +1541,7 @@ private:
|
||||
}
|
||||
|
||||
//! Initialize this value as constant string, without calling destructor.
|
||||
void SetStringRaw(StringRefType s) {
|
||||
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
|
||||
flags_ = kConstStringFlag;
|
||||
data_.s.str = s;
|
||||
data_.s.length = s.length;
|
||||
@ -1526,7 +1565,7 @@ private:
|
||||
}
|
||||
|
||||
//! Assignment without calling destructor
|
||||
void RawAssign(GenericValue& rhs) {
|
||||
void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||
data_ = rhs.data_;
|
||||
flags_ = rhs.flags_;
|
||||
rhs.flags_ = kNullFlag;
|
||||
|
@ -21,6 +21,10 @@
|
||||
#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++)
|
||||
@ -30,7 +34,7 @@ RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(6334)
|
||||
#endif
|
||||
|
||||
#ifdef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
@ -100,7 +104,7 @@ template <typename T> struct IsPointer<T*> : TrueType {};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// IsBaseOf
|
||||
//
|
||||
#ifdef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
|
||||
template <typename B, typename D> struct IsBaseOf
|
||||
: BoolType< ::std::is_base_of<B,D>::value> {};
|
||||
|
@ -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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
TEST(Value, default_constructor) {
|
||||
TEST(Value, DefaultConstructor) {
|
||||
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_operator) {
|
||||
TEST(Value, EqualtoOperator) {
|
||||
Value::AllocatorType allocator;
|
||||
Value x(kObjectType);
|
||||
x.AddMember("hello", "world", allocator)
|
||||
@ -555,7 +596,7 @@ TEST(Value, String) {
|
||||
EXPECT_STREQ("World", w.GetString());
|
||||
EXPECT_EQ(5u, w.GetStringLength());
|
||||
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
{
|
||||
std::string str = "Hello World";
|
||||
str[5] = '\0';
|
||||
@ -643,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());
|
||||
@ -751,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++)
|
||||
@ -760,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;
|
||||
@ -818,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\0D", 3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user