From 744b4852ff40ad33a0408882a04c5ef121bc9a48 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Tue, 19 Aug 2014 19:38:34 +0200 Subject: [PATCH] GenericValue: add (optional) support for std::string Some users may want to use RapidJSON with std::string objects. This commits adds an (opt-in) feature to include some basic support. The implementation uses std::basic_string as generic string type. Support currently covers: * construction * comparison No special APIs for AddMember or PushBack have been added, as std::string most probably requires copying (or an explicit StringRef() call). --- include/rapidjson/document.h | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 5322076..f14717e 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -21,6 +21,8 @@ #ifndef RAPIDJSON_DOCUMENT_H_ #define RAPIDJSON_DOCUMENT_H_ +/*! \file document.h */ + #include "reader.h" #include "internal/strfunc.h" #include // placement new @@ -33,6 +35,26 @@ RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(effc++) #endif +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#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 + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#include +#endif // RAPIDJSON_HAS_STDSTRING + #ifndef RAPIDJSON_NOMEMBERITERATORCLASS #include "internal/meta.h" #include // std::iterator, std::random_access_iterator_tag @@ -56,6 +78,9 @@ struct GenericMember { GenericValue value; //!< value of member. }; +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + #ifndef RAPIDJSON_NOMEMBERITERATORCLASS //! (Constant) member iterator for a JSON object value @@ -338,6 +363,25 @@ inline GenericStringRef StringRef(const CharType* str, size_t length) return GenericStringRef(str, SizeType(length)); } +#ifdef 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 + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + /////////////////////////////////////////////////////////////////////////////// // GenericValue @@ -470,6 +514,13 @@ 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 + //! 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. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } +#endif + //! Destructor. /*! Need to destruct elements of array, members of object, or copy-string. */ @@ -622,6 +673,13 @@ public: //! Equal-to operator with const C-string pointer bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } +#ifdef RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + //! Equal-to operator with primitive types /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false */ @@ -1207,6 +1265,17 @@ int z = a[0u].GetInt(); // This works too. */ GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } +#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(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(s.data(), s.size(), allocator); } +#endif + //@} //! Generate events of this value to a Handler.