Skip to content

Iteration

Oskari Rauta edited this page Mar 11, 2024 · 13 revisions

Iteration is done through a wrapper that encapsulates JSON element, this is because of multiple available types in different containers; for this reason, same iterator could not return JSON element, without a wrapper - actually I've have heard that Boost libraries do have this possibility through something called any_iterator - but I am not using Boost.

There are 2 of these wrappers, one is for const and on is for non-const iteration.
Not much of container functions are made available on JSON variable; just the basics

  • begin()
  • end()
  • empty()
  • contains()

These usually are enough in most cases where user is not supposed to control the container through iterator, instead value in wrapper inside iterator. Both kind of wrappers have same functions, but using mutating functions on a const wrapper will result in thrown exception warning that function is not available for const.

Note about iterators

Iterators are available only for object and array types, trying to use them on other types does not harm, but it won't work; for example, if you have a JSON variable that holds type of string or int, and you try to

for ( const auto& j : json["my_string"] )
	std::cout << j.to_string() << std::endl;

std::cout... will never be executed.

Result Wrapper

Wrappers have a set of functions that are available for normal JSON variable as well; not all, but for most people, enough. Through value() member, full access to JSON value of iterator though is available. On const wrapper it is copy of variable, and on non-const, it's reference to variable.

  • JSON::TYPE type()
  • bool indexed()
  • bool named()
  • size_t length()
  • size_t index()
  • std::string name()
  • JSON value()
  • size_t size()
  • bool empty()
  • std::string to_string()
  • double to_float()
  • double to_double()
  • long long to int()
  • bool to_bool()

Most of these types are known from JSON variable and they do exactly the same. It's to prevent need to type

std::string str = it.value().to_string()

instead, you can use this to access to_string:

std::string str = it.to_string()
  • bool named() and bool indexed() are used to determine if container being iterated is object or array (or neither)
  • size_t size() and size_t length() expose size of container being iterated, such as size of json object or array
  • size_t index() and std::string name() return indexes of containers

If .index() is used on other type than array, -1 is returned. Or if .name() is used on other type than object type, result is empty string.

Operators

  • std::string()
  • double()
  • long long()
  • int()
  • bool()

These operators work exactly the same as they do when used with JSON() variable.

Comparators

  • bool operator ==(const JSON::TYPE type)
  • bool operator !=(const JSON::TYPE type)

Also types can be compared across iterators, without needing to go through JSON value()

Output streams

Both result types and iterators support output streams, so you just do this

for ( const auto& j : json["my_string"] )
	std::cout << j << std::endl;

instead of using std::cout << j.to_string() << std::endl;

Clone this wiki locally