document.h: add GenericMemberIterator
Add dedicated class-based member iterator to prepare the switch to a (safe) API change to return MemberEnd() from FindMember(). Pointer-based iterator can be kept by defining RAPIDJSON_NOMEMBERITERATORCLASS. This may be useful for platforms without a working <iterator> header.
This commit is contained in:
parent
05179e2891
commit
17a8804cf3
@ -5,6 +5,11 @@
|
|||||||
#include "internal/strfunc.h"
|
#include "internal/strfunc.h"
|
||||||
#include <new> // placement new
|
#include <new> // placement new
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
|
#include "internal/meta.h"
|
||||||
|
#include <iterator> // std::iterator, std::random_access_iterator_tag
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
@ -21,7 +26,7 @@ namespace rapidjson {
|
|||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
class GenericValue;
|
class GenericValue;
|
||||||
|
|
||||||
//! Name-value pair in an object.
|
//! Name-value pair in a JSON object value.
|
||||||
/*!
|
/*!
|
||||||
This class was internal to GenericValue. It used to be a inner struct.
|
This class was internal to GenericValue. It used to be a inner struct.
|
||||||
But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
|
But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
|
||||||
@ -33,6 +38,145 @@ struct GenericMember {
|
|||||||
GenericValue<Encoding, Allocator> value; //!< value of member.
|
GenericValue<Encoding, Allocator> value; //!< value of member.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
|
|
||||||
|
//! (Const) member iterator for a JSON object value
|
||||||
|
/*!
|
||||||
|
\tparam Const Is this a const iterator?
|
||||||
|
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
|
||||||
|
\tparam Allocator Allocator type for allocating memory of object, array and string.
|
||||||
|
|
||||||
|
This class implements a Random Access Iterator for GenericMember elements
|
||||||
|
of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
|
||||||
|
|
||||||
|
\note This iterator implementation is mainly intended to avoid implicit
|
||||||
|
conversions from iterator values to \c NULL,
|
||||||
|
e.g. from GenericValue::FindMember.
|
||||||
|
|
||||||
|
\note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
|
||||||
|
pointer-based implementation, if your platform doesn't provide
|
||||||
|
the C++ <iterator> header.
|
||||||
|
|
||||||
|
\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
|
||||||
|
*/
|
||||||
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
|
class GenericMemberIterator
|
||||||
|
: public std::iterator<std::random_access_iterator_tag
|
||||||
|
, typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
|
||||||
|
|
||||||
|
friend class GenericValue<Encoding,Allocator>;
|
||||||
|
template <bool, typename, typename> friend class GenericMemberIterator;
|
||||||
|
|
||||||
|
typedef GenericMember<Encoding,Allocator> PlainType;
|
||||||
|
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
|
||||||
|
typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Iterator type itself
|
||||||
|
typedef GenericMemberIterator Type;
|
||||||
|
//! Const iterator type
|
||||||
|
typedef GenericMemberIterator<true,Encoding,Allocator> ConstType;
|
||||||
|
//! Non-const iterator type
|
||||||
|
typedef GenericMemberIterator<false,Encoding,Allocator> NonConstType;
|
||||||
|
|
||||||
|
//! Pointer to (const) GenericMember
|
||||||
|
typedef typename BaseType::pointer Pointer;
|
||||||
|
//! Reference to (const) GenericMember
|
||||||
|
typedef typename BaseType::reference Reference;
|
||||||
|
//! Signed integer type (e.g. \c ptrdiff_t)
|
||||||
|
typedef typename BaseType::difference_type DifferenceType;
|
||||||
|
|
||||||
|
//! Default constructor (singular value)
|
||||||
|
/*! Creates an iterator pointing to no element.
|
||||||
|
\note All operations, except for comparisons, are undefined on such values.
|
||||||
|
*/
|
||||||
|
GenericMemberIterator() : ptr_() {}
|
||||||
|
|
||||||
|
//! Iterator conversions to more const
|
||||||
|
/*!
|
||||||
|
\param it (Non-const) iterator to copy from
|
||||||
|
|
||||||
|
Allows the creation of an iterator from another GenericMemberIterator
|
||||||
|
that is "less const". Especially, creating a non-const iterator from
|
||||||
|
a const iterator are disabled:
|
||||||
|
\li const -> non-const (not ok)
|
||||||
|
\li const -> const (ok)
|
||||||
|
\li non-const -> const (ok)
|
||||||
|
\li non-const -> non-const (ok)
|
||||||
|
|
||||||
|
\note If the \c Const template parameter is already \c false, this
|
||||||
|
constructor effectively defines a regular copy-constructor.
|
||||||
|
Otherwise, the copy constructor is implicitly defined.
|
||||||
|
*/
|
||||||
|
GenericMemberIterator(const NonConstType & it)
|
||||||
|
: ptr_( it.ptr_ ) {}
|
||||||
|
|
||||||
|
//! @name stepping
|
||||||
|
//@{
|
||||||
|
Type& operator++(){ ++ptr_; return *this; }
|
||||||
|
Type& operator--(){ --ptr_; return *this; }
|
||||||
|
Type operator++(int){ Type old(*this); ++ptr_; return old; }
|
||||||
|
Type operator--(int){ Type old(*this); --ptr_; return old; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! @name increment/decrement
|
||||||
|
//@{
|
||||||
|
Type operator+(DifferenceType n) const { return Type(ptr_+n); }
|
||||||
|
Type operator-(DifferenceType n) const { return Type(ptr_-n); }
|
||||||
|
|
||||||
|
Type& operator+=(DifferenceType n) { ptr_+=n; return *this; }
|
||||||
|
Type& operator-=(DifferenceType n) { ptr_-=n; return *this; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! @name relations
|
||||||
|
//@{
|
||||||
|
bool operator==(Type that) const { return ptr_ == that.ptr_; }
|
||||||
|
bool operator!=(Type that) const { return ptr_ != that.ptr_; }
|
||||||
|
bool operator<=(Type that) const { return ptr_ <= that.ptr_; }
|
||||||
|
bool operator>=(Type that) const { return ptr_ >= that.ptr_; }
|
||||||
|
bool operator< (Type that) const { return ptr_ < that.ptr_; }
|
||||||
|
bool operator> (Type that) const { return ptr_ > that.ptr_; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! @name dereference
|
||||||
|
//@{
|
||||||
|
Reference operator*() const { return *ptr_; }
|
||||||
|
Pointer operator->() const { return ptr_; }
|
||||||
|
Reference operator[](DifferenceType n) const { return ptr_[n]; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! Distance
|
||||||
|
DifferenceType operator-(Type that) const { return ptr_-that.ptr_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//!< Internal constructor from plain pointer
|
||||||
|
explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
|
||||||
|
|
||||||
|
Pointer ptr_; //!< raw pointer
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
|
|
||||||
|
// class-based member iterator implementation disabled, use plain pointers
|
||||||
|
|
||||||
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
|
struct GenericMemberIterator;
|
||||||
|
|
||||||
|
//! non-const GenericMemberIterator
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
struct GenericMemberIterator<false,Encoding,Allocator> {
|
||||||
|
//! use plain pointer as iterator type
|
||||||
|
typedef GenericMember<Encoding,Allocator>* Type;
|
||||||
|
};
|
||||||
|
//! const GenericMemberIterator
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
struct GenericMemberIterator<true,Encoding,Allocator> {
|
||||||
|
//! use plain const pointer as iterator type
|
||||||
|
typedef const GenericMember<Encoding,Allocator>* Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// GenericValue
|
// GenericValue
|
||||||
|
|
||||||
@ -55,8 +199,8 @@ public:
|
|||||||
typedef Encoding EncodingType; //!< Encoding type from template parameter.
|
typedef Encoding EncodingType; //!< Encoding type from template parameter.
|
||||||
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
||||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||||
typedef Member* MemberIterator; //!< Member iterator for iterating in object.
|
typedef typename GenericMemberIterator<false,Encoding,Allocator>::Type MemberIterator; //!< Member iterator for iterating in object.
|
||||||
typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object.
|
typedef typename GenericMemberIterator<true,Encoding,Allocator>::Type ConstMemberIterator; //!< Constant member iterator for iterating in object.
|
||||||
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
|
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
|
||||||
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
|
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user