Commit 5672d246 authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

GenericValue: add RAPIDJSON_NOEXCEPT

Added basic detection of `noexcept` support for some compilers, added
corresponding RAPIDJSON_NOEXCEPT annotations to
 * non-allocating constructors
 * (move) assignment
 * Swap
parent 36031b1b
...@@ -2004,7 +2004,8 @@ PREDEFINED = \ ...@@ -2004,7 +2004,8 @@ PREDEFINED = \
# definition found in the source code. # definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # 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 # 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 # remove all references to function-like macros that are alone on a line, have
......
...@@ -416,11 +416,11 @@ public: ...@@ -416,11 +416,11 @@ public:
//@{ //@{
//! Default constructor creates a null value. //! Default constructor creates a null value.
GenericValue() : data_(), flags_(kNullFlag) {} GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
//! Move constructor in C++11 //! Move constructor in C++11
GenericValue(GenericValue&& rhs) : data_(rhs.data_), flags_(rhs.flags_) { GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) {
rhs.flags_ = kNullFlag; // give up contents rhs.flags_ = kNullFlag; // give up contents
} }
#endif #endif
...@@ -436,7 +436,7 @@ public: ...@@ -436,7 +436,7 @@ public:
\param type Type of the value. \param type Type of the value.
\note Default content for number is zero. \note Default content for number is zero.
*/ */
GenericValue(Type type) : data_(), flags_() { GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
static const unsigned defaultFlags[7] = { static const unsigned defaultFlags[7] = {
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
kNumberAnyFlag kNumberAnyFlag
...@@ -463,9 +463,9 @@ public: ...@@ -463,9 +463,9 @@ public:
*/ */
#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
template <typename T> 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 #else
explicit GenericValue(bool b) explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
#endif #endif
: data_(), flags_(b ? kTrueFlag : kFalseFlag) { : data_(), flags_(b ? kTrueFlag : kFalseFlag) {
// safe-guard against failing SFINAE // safe-guard against failing SFINAE
...@@ -473,21 +473,21 @@ public: ...@@ -473,21 +473,21 @@ public:
} }
//! Constructor for int value. //! Constructor for int value.
explicit GenericValue(int i) : data_(), flags_(kNumberIntFlag) { explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) {
data_.n.i64 = i; data_.n.i64 = i;
if (i >= 0) if (i >= 0)
flags_ |= kUintFlag | kUint64Flag; flags_ |= kUintFlag | kUint64Flag;
} }
//! Constructor for unsigned value. //! Constructor for unsigned value.
explicit GenericValue(unsigned u) : data_(), flags_(kNumberUintFlag) { explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) {
data_.n.u64 = u; data_.n.u64 = u;
if (!(u & 0x80000000)) if (!(u & 0x80000000))
flags_ |= kIntFlag | kInt64Flag; flags_ |= kIntFlag | kInt64Flag;
} }
//! Constructor for int64_t value. //! 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; data_.n.i64 = i64;
if (i64 >= 0) { if (i64 >= 0) {
flags_ |= kNumberUint64Flag; flags_ |= kNumberUint64Flag;
...@@ -501,7 +501,7 @@ public: ...@@ -501,7 +501,7 @@ public:
} }
//! Constructor for uint64_t value. //! 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; data_.n.u64 = u64;
if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
flags_ |= kInt64Flag; flags_ |= kInt64Flag;
...@@ -512,13 +512,13 @@ public: ...@@ -512,13 +512,13 @@ public:
} }
//! Constructor for double value. //! 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) //! 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) //! 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) //! 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); } GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); }
...@@ -569,7 +569,7 @@ public: ...@@ -569,7 +569,7 @@ public:
//! Assignment with move semantics. //! Assignment with move semantics.
/*! \param rhs Source of the assignment. It will become a null value after assignment. /*! \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); RAPIDJSON_ASSERT(this != &rhs);
this->~GenericValue(); this->~GenericValue();
RawAssign(rhs); RawAssign(rhs);
...@@ -578,7 +578,7 @@ public: ...@@ -578,7 +578,7 @@ public:
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
//! Move assignment in C++11 //! Move assignment in C++11
GenericValue& operator=(GenericValue&& rhs) { GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
return *this = rhs.Move(); return *this = rhs.Move();
} }
#endif #endif
...@@ -588,7 +588,7 @@ public: ...@@ -588,7 +588,7 @@ public:
\note This overload is needed to avoid clashes with the generic primitive type assignment overload below. \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
\see GenericStringRef, operator=(T) \see GenericStringRef, operator=(T)
*/ */
GenericValue& operator=(StringRefType str) { GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
GenericValue s(str); GenericValue s(str);
return *this = s; return *this = s;
} }
...@@ -631,7 +631,7 @@ public: ...@@ -631,7 +631,7 @@ public:
\param other Another value. \param other Another value.
\note Constant complexity. \note Constant complexity.
*/ */
GenericValue& Swap(GenericValue& other) { GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
GenericValue temp; GenericValue temp;
temp.RawAssign(*this); temp.RawAssign(*this);
RawAssign(other); RawAssign(other);
......
...@@ -372,6 +372,22 @@ template<int x> struct StaticAssertTest {}; ...@@ -372,6 +372,22 @@ template<int x> struct StaticAssertTest {};
#endif #endif
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS #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 // no automatic detection, yet
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment