Currently the for(auto item& : myValue) loop is not supported by rapidjson. I guess this is because the case of Begin and End does not match what the standard expects.
I'd like to use this for array iteration, though I suspect it could also be useful over members as well.
This can be achieved by simply adding the following four functions to the rapidjson namespace:
namespace rapidjson {
template <typename Encoding, typename Allocator>
typename GenericValue<Encoding,Allocator>::ValueIterator begin(GenericValue<Encoding,Allocator>& v) { return v.Begin(); }
template <typename Encoding, typename Allocator>
typename GenericValue<Encoding,Allocator>::ConstValueIterator begin(const GenericValue<Encoding,Allocator>& v) { return v.Begin(); }
template <typename Encoding, typename Allocator>
typename GenericValue<Encoding,Allocator>::ValueIterator end(GenericValue<Encoding,Allocator>& v) { return v.End(); }
template <typename Encoding, typename Allocator>
typename GenericValue<Encoding,Allocator>::ConstValueIterator end(const GenericValue<Encoding,Allocator>& v) { return v.End(); }
} // namespace rapidjson
I'm not sure, if adding this to the core library is sufficient, though. GenericValue is a variant type, which should at least allow you to select the "iteration type" you want to use: array element vs. object members.
Thanks @pah, this is great.
Would there be any overhead of confusion from the following new API?
for (auto& item : doc.ArrayItems()) {}
for (auto& member : doc.Members()) {}
Yes, something like this could be an option.
I thought of shallow wrapper objects returned by functions GetArray()/ GetObject() (symmetric to GetInt, etc.), restricting access to a GenericValue to the specific type and adding additional convenience APIs like range-loop support.
boost::make_iterator_range(doc.Begin(), doc.End())
boost::make_iterator_range(doc.MemberBegin(), doc.MemberEnd())
So that you can do it even with free functions.
+1
+1
@pah Your idea of GetArray()/GetObject has been implemented in PR #542 .
Please review the PR when you have time. Thank you.
Merged #542
As mentioned in the first post, the capitalization of B and E on Begin() and End() functions are preventing auto ranged based for looping. for (auto Val : Doc).
I've attempted to change them to lowercase myself however at that point the compiler starts telling you you're trying to access private/protected member functions when you shouldn't be..
Two things to note here:
GetArray()/GetObject() functions to use range-based for over arrays or objects: Document doc;
// ... fill the array
for( const auto& e : doc.GetArray() ) // loop over array
std::cout << e.GetInt() << std::endl;
// ... fill an object
for( auto& m : doc.GetObject() ) // loop over object (non-const)
m.value.SetNull(); // modify entry
Most helpful comment
Two things to note here:
GetArray()/GetObject()functions to use range-basedforover arrays or objects: