Iterators are now implemented via const_iterators and reverse_iterator and const_reverse_iterator now share a template class. Thanks a lot!
This commit is contained in:
parent
1c8d5dc211
commit
5c813b614f
3 changed files with 297 additions and 1287 deletions
|
@ -54,7 +54,7 @@ doxygen: create_output create_links
|
||||||
gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
||||||
gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
||||||
|
|
||||||
upload: doxygen check_output
|
upload: clean doxygen check_output
|
||||||
cd html ; ../git-update-ghpages nlohmann/json
|
cd html ; ../git-update-ghpages nlohmann/json
|
||||||
rm -fr html
|
rm -fr html
|
||||||
open http://nlohmann.github.io/json/
|
open http://nlohmann.github.io/json/
|
||||||
|
|
791
src/json.hpp
791
src/json.hpp
|
@ -172,14 +172,17 @@ class basic_json
|
||||||
/// the type of an element const pointer
|
/// the type of an element const pointer
|
||||||
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
|
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
|
||||||
|
|
||||||
|
// forward declaration
|
||||||
|
template<typename Base> class json_reverse_iterator;
|
||||||
|
|
||||||
/// an iterator for a basic_json container
|
/// an iterator for a basic_json container
|
||||||
class iterator;
|
class iterator;
|
||||||
/// a const iterator for a basic_json container
|
/// a const iterator for a basic_json container
|
||||||
class const_iterator;
|
class const_iterator;
|
||||||
/// a reverse iterator for a basic_json container
|
/// a reverse iterator for a basic_json container
|
||||||
class reverse_iterator;
|
using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
|
||||||
/// a const reverse iterator for a basic_json container
|
/// a const reverse iterator for a basic_json container
|
||||||
class const_reverse_iterator;
|
using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
@ -4863,522 +4866,6 @@ class basic_json
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// a random access iterator for the basic_json class
|
|
||||||
class iterator : public std::iterator<std::random_access_iterator_tag, basic_json>
|
|
||||||
{
|
|
||||||
// allow basic_json class to access m_it
|
|
||||||
friend class basic_json;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// the type of the values when the iterator is dereferenced
|
|
||||||
using value_type = typename basic_json::value_type;
|
|
||||||
/// a type to represent differences between iterators
|
|
||||||
using difference_type = typename basic_json::difference_type;
|
|
||||||
/// defines a pointer to the type iterated over (value_type)
|
|
||||||
using pointer = typename basic_json::pointer;
|
|
||||||
/// defines a reference to the type iterated over (value_type)
|
|
||||||
using reference = typename basic_json::reference;
|
|
||||||
/// the category of the iterator
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
|
|
||||||
/// default constructor
|
|
||||||
iterator() = default;
|
|
||||||
|
|
||||||
/// constructor for a given JSON instance
|
|
||||||
iterator(pointer object) : m_object(object)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = typename object_t::iterator();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = typename array_t::iterator();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator = primitive_iterator_t();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// copy constructor
|
|
||||||
iterator(const iterator& other) noexcept
|
|
||||||
: m_object(other.m_object), m_it(other.m_it)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// copy assignment
|
|
||||||
iterator& operator=(iterator other) noexcept (
|
|
||||||
std::is_nothrow_move_constructible<pointer>::value and
|
|
||||||
std::is_nothrow_move_assignable<pointer>::value and
|
|
||||||
std::is_nothrow_move_constructible<internal_iterator>::value and
|
|
||||||
std::is_nothrow_move_assignable<internal_iterator>::value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::swap(m_object, other.m_object);
|
|
||||||
std::swap(m_it, other.m_it);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// set the iterator to the first value
|
|
||||||
void set_begin()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = m_object->m_value.object->begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = m_object->m_value.array->begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
// set to end so begin()==end() is true: null is empty
|
|
||||||
m_it.primitive_iterator.set_end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator.set_begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// set the iterator past the last value
|
|
||||||
void set_end()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = m_object->m_value.object->end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = m_object->m_value.array->end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator.set_end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// return a reference to the value pointed to by the iterator
|
|
||||||
reference operator*()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return m_it.object_iterator->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return *m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator.is_begin())
|
|
||||||
{
|
|
||||||
return *m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// dereference the iterator
|
|
||||||
pointer operator->()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return &(m_it.object_iterator->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return &*m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator.is_begin())
|
|
||||||
{
|
|
||||||
return m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-increment (it++)
|
|
||||||
iterator operator++(int)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-increment (++it)
|
|
||||||
iterator& operator++()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
++m_it.object_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
++m_it.array_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
++m_it.primitive_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-decrement (it--)
|
|
||||||
iterator operator--(int)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
|
||||||
iterator& operator--()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
--m_it.object_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
--m_it.array_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
--m_it.primitive_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: equal
|
|
||||||
bool operator==(const iterator& other) const
|
|
||||||
{
|
|
||||||
// if objects are not the same, the comparison is undefined
|
|
||||||
if (m_object != other.m_object)
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot compare iterators of different containers");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return (m_it.object_iterator == other.m_it.object_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return (m_it.array_iterator == other.m_it.array_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: not equal
|
|
||||||
bool operator!=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: smaller
|
|
||||||
bool operator<(const iterator& other) const
|
|
||||||
{
|
|
||||||
// if objects are not the same, the comparison is undefined
|
|
||||||
if (m_object != other.m_object)
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot compare iterators of different containers");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator< for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return (m_it.array_iterator < other.m_it.array_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: less than or equal
|
|
||||||
bool operator<=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not other.operator < (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: greater than
|
|
||||||
bool operator>(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator<=(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: greater than or equal
|
|
||||||
bool operator>=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator<(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
iterator& operator+=(difference_type i)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator+= for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
iterator& operator-=(difference_type i)
|
|
||||||
{
|
|
||||||
return operator+=(-i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
iterator operator+(difference_type i)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result += i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
iterator operator-(difference_type i)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result -= i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return difference
|
|
||||||
difference_type operator-(const iterator& other) const
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator- for object iterators");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return m_it.array_iterator - other.m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return m_it.primitive_iterator - other.m_it.primitive_iterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// access to successor
|
|
||||||
reference operator[](difference_type n)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator[] for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return *(m_it.array_iterator + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator == -n)
|
|
||||||
{
|
|
||||||
return *m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an object iterator
|
|
||||||
typename object_t::key_type key() const
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return m_it.object_iterator->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use key() for non-object iterators");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an iterator
|
|
||||||
reference value()
|
|
||||||
{
|
|
||||||
return operator*();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// associated JSON instance
|
|
||||||
pointer m_object = nullptr;
|
|
||||||
/// the actual iterator of the associated instance
|
|
||||||
internal_iterator m_it = internal_iterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// a const random access iterator for the basic_json class
|
/// a const random access iterator for the basic_json class
|
||||||
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
|
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
|
||||||
{
|
{
|
||||||
|
@ -5874,70 +5361,96 @@ class basic_json
|
||||||
internal_iterator m_it = internal_iterator();
|
internal_iterator m_it = internal_iterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/// a random access iterator for the basic_json class
|
||||||
@brief a reverse random access iterator for the basic_json class
|
class iterator : public const_iterator
|
||||||
|
|
||||||
The reverse iterator is realized with the `std::reverse_iterator` adaptor.
|
|
||||||
This adaptor does not automatically inherit all functionality from the
|
|
||||||
base iterator class, so some functions need to be explicitly implemented
|
|
||||||
by either delegating them to the base class or by using the `base()`
|
|
||||||
function to access the underlying base iterator.
|
|
||||||
|
|
||||||
The following operators are implicitly inherited:
|
|
||||||
|
|
||||||
- `operator==`, `operator!=`, `operator<`, `operator<=`, `operator>`,
|
|
||||||
`operator>=`
|
|
||||||
- `operator-=`
|
|
||||||
- `operator->`, `operator*`
|
|
||||||
*/
|
|
||||||
class reverse_iterator : public std::reverse_iterator<typename basic_json::iterator>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// shortcut to the reverse iterator adaptor
|
using base_iterator = const_iterator;
|
||||||
using base_iterator = std::reverse_iterator<typename basic_json::iterator>;
|
using pointer = typename basic_json::pointer;
|
||||||
|
using reference = typename basic_json::reference;
|
||||||
|
|
||||||
/// create reverse iterator from iterator
|
/// default constructor
|
||||||
reverse_iterator(const typename base_iterator::iterator_type& it)
|
iterator() = default;
|
||||||
: base_iterator(it) {}
|
|
||||||
|
|
||||||
/// create reverse iterator from base class
|
/// constructor for a given JSON instance
|
||||||
reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
iterator(pointer object) noexcept : base_iterator(object)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// copy constructor
|
||||||
|
iterator(const iterator& other) noexcept
|
||||||
|
: base_iterator(other)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// copy assignment
|
||||||
|
iterator& operator=(iterator other) noexcept(
|
||||||
|
std::is_nothrow_move_constructible<pointer>::value and
|
||||||
|
std::is_nothrow_move_assignable<pointer>::value and
|
||||||
|
std::is_nothrow_move_constructible<internal_iterator>::value and
|
||||||
|
std::is_nothrow_move_assignable<internal_iterator>::value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
base_iterator::operator=(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return a reference to the value pointed to by the iterator
|
||||||
|
reference operator*()
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::operator*());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// dereference the iterator
|
||||||
|
pointer operator->()
|
||||||
|
{
|
||||||
|
return const_cast<pointer>(base_iterator::operator->());
|
||||||
|
}
|
||||||
|
|
||||||
/// post-increment (it++)
|
/// post-increment (it++)
|
||||||
reverse_iterator operator++(int)
|
iterator operator++(int)
|
||||||
{
|
{
|
||||||
return base_iterator::operator++(1);
|
iterator result = *this;
|
||||||
|
base_iterator::operator++();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pre-increment (++it)
|
/// pre-increment (++it)
|
||||||
reverse_iterator& operator++()
|
iterator& operator++()
|
||||||
{
|
{
|
||||||
base_iterator::operator++();
|
base_iterator::operator++();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// post-decrement (it--)
|
/// post-decrement (it--)
|
||||||
reverse_iterator operator--(int)
|
iterator operator--(int)
|
||||||
{
|
{
|
||||||
return base_iterator::operator--(1);
|
iterator result = *this;
|
||||||
|
base_iterator::operator--();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
/// pre-decrement (--it)
|
||||||
reverse_iterator& operator--()
|
iterator& operator--()
|
||||||
{
|
{
|
||||||
base_iterator::operator--();
|
base_iterator::operator--();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add to iterator
|
/// add to iterator
|
||||||
reverse_iterator& operator+=(difference_type i)
|
iterator& operator+=(difference_type i)
|
||||||
{
|
{
|
||||||
base_iterator::operator+=(i);
|
base_iterator::operator+=(i);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// subtract from iterator
|
||||||
|
iterator& operator-=(difference_type i)
|
||||||
|
{
|
||||||
|
base_iterator::operator-=(i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/// add to iterator
|
/// add to iterator
|
||||||
reverse_iterator operator+(difference_type i) const
|
iterator operator+(difference_type i)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
result += i;
|
result += i;
|
||||||
|
@ -5945,7 +5458,90 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/// subtract from iterator
|
/// subtract from iterator
|
||||||
reverse_iterator operator-(difference_type i) const
|
iterator operator-(difference_type i)
|
||||||
|
{
|
||||||
|
auto result = *this;
|
||||||
|
result -= i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type operator-(const iterator& other) const
|
||||||
|
{
|
||||||
|
return base_iterator::operator-(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// access to successor
|
||||||
|
reference operator[](difference_type n) const
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::operator[](n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the value of an iterator
|
||||||
|
reference value() const
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// a template for a reverse iterator class
|
||||||
|
template<typename Base>
|
||||||
|
class json_reverse_iterator : public std::reverse_iterator<Base>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// shortcut to the reverse iterator adaptor
|
||||||
|
using base_iterator = std::reverse_iterator<Base>;
|
||||||
|
using reference = typename Base::reference;
|
||||||
|
|
||||||
|
/// create reverse iterator from iterator
|
||||||
|
json_reverse_iterator(const typename base_iterator::iterator_type& it)
|
||||||
|
: base_iterator(it) {}
|
||||||
|
|
||||||
|
/// create reverse iterator from base class
|
||||||
|
json_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
||||||
|
|
||||||
|
/// post-increment (it++)
|
||||||
|
json_reverse_iterator operator++(int)
|
||||||
|
{
|
||||||
|
return base_iterator::operator++(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// pre-increment (++it)
|
||||||
|
json_reverse_iterator& operator++()
|
||||||
|
{
|
||||||
|
base_iterator::operator++();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// post-decrement (it--)
|
||||||
|
json_reverse_iterator operator--(int)
|
||||||
|
{
|
||||||
|
return base_iterator::operator--(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// pre-decrement (--it)
|
||||||
|
json_reverse_iterator& operator--()
|
||||||
|
{
|
||||||
|
base_iterator::operator--();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// add to iterator
|
||||||
|
json_reverse_iterator& operator+=(difference_type i)
|
||||||
|
{
|
||||||
|
base_iterator::operator+=(i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// add to iterator
|
||||||
|
json_reverse_iterator operator+(difference_type i) const
|
||||||
|
{
|
||||||
|
auto result = *this;
|
||||||
|
result += i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// subtract from iterator
|
||||||
|
json_reverse_iterator operator-(difference_type i) const
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
result -= i;
|
result -= i;
|
||||||
|
@ -5953,7 +5549,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return difference
|
/// return difference
|
||||||
difference_type operator-(const reverse_iterator& other) const
|
difference_type operator-(const json_reverse_iterator& other) const
|
||||||
{
|
{
|
||||||
return this->base() - other.base();
|
return this->base() - other.base();
|
||||||
}
|
}
|
||||||
|
@ -5979,97 +5575,6 @@ class basic_json
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// a const reverse random access iterator for the basic_json class
|
|
||||||
class const_reverse_iterator : public std::reverse_iterator<typename basic_json::const_iterator>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// shortcut to the reverse iterator adaptor
|
|
||||||
using base_iterator = std::reverse_iterator<typename basic_json::const_iterator>;
|
|
||||||
|
|
||||||
/// create reverse iterator from iterator
|
|
||||||
const_reverse_iterator(const typename base_iterator::iterator_type& it)
|
|
||||||
: base_iterator(it) {}
|
|
||||||
|
|
||||||
/// create reverse iterator from base class
|
|
||||||
const_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
|
||||||
|
|
||||||
/// post-increment (it++)
|
|
||||||
const_reverse_iterator operator++(int)
|
|
||||||
{
|
|
||||||
return base_iterator::operator++(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-increment (++it)
|
|
||||||
const_reverse_iterator& operator++()
|
|
||||||
{
|
|
||||||
base_iterator::operator++();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-decrement (it--)
|
|
||||||
const_reverse_iterator operator--(int)
|
|
||||||
{
|
|
||||||
return base_iterator::operator--(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
|
||||||
const_reverse_iterator& operator--()
|
|
||||||
{
|
|
||||||
base_iterator::operator--();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
const_reverse_iterator& operator+=(difference_type i)
|
|
||||||
{
|
|
||||||
base_iterator::operator+=(i);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
const_reverse_iterator operator+(difference_type i) const
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result += i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
const_reverse_iterator operator-(difference_type i) const
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result -= i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return difference
|
|
||||||
difference_type operator-(const const_reverse_iterator& other) const
|
|
||||||
{
|
|
||||||
return this->base() - other.base();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// access to successor
|
|
||||||
const_reference operator[](difference_type n) const
|
|
||||||
{
|
|
||||||
return *(this->operator+(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an object iterator
|
|
||||||
typename object_t::key_type key() const
|
|
||||||
{
|
|
||||||
auto it = --this->base();
|
|
||||||
return it.key();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the value of an iterator
|
|
||||||
const_reference value() const
|
|
||||||
{
|
|
||||||
auto it = --this->base();
|
|
||||||
return it.operator * ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// lexer and parser //
|
// lexer and parser //
|
||||||
|
|
|
@ -172,14 +172,17 @@ class basic_json
|
||||||
/// the type of an element const pointer
|
/// the type of an element const pointer
|
||||||
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
|
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
|
||||||
|
|
||||||
|
// forward declaration
|
||||||
|
template<typename Base> class json_reverse_iterator;
|
||||||
|
|
||||||
/// an iterator for a basic_json container
|
/// an iterator for a basic_json container
|
||||||
class iterator;
|
class iterator;
|
||||||
/// a const iterator for a basic_json container
|
/// a const iterator for a basic_json container
|
||||||
class const_iterator;
|
class const_iterator;
|
||||||
/// a reverse iterator for a basic_json container
|
/// a reverse iterator for a basic_json container
|
||||||
class reverse_iterator;
|
using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
|
||||||
/// a const reverse iterator for a basic_json container
|
/// a const reverse iterator for a basic_json container
|
||||||
class const_reverse_iterator;
|
using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
@ -4863,522 +4866,6 @@ class basic_json
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// a random access iterator for the basic_json class
|
|
||||||
class iterator : public std::iterator<std::random_access_iterator_tag, basic_json>
|
|
||||||
{
|
|
||||||
// allow basic_json class to access m_it
|
|
||||||
friend class basic_json;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// the type of the values when the iterator is dereferenced
|
|
||||||
using value_type = typename basic_json::value_type;
|
|
||||||
/// a type to represent differences between iterators
|
|
||||||
using difference_type = typename basic_json::difference_type;
|
|
||||||
/// defines a pointer to the type iterated over (value_type)
|
|
||||||
using pointer = typename basic_json::pointer;
|
|
||||||
/// defines a reference to the type iterated over (value_type)
|
|
||||||
using reference = typename basic_json::reference;
|
|
||||||
/// the category of the iterator
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
|
|
||||||
/// default constructor
|
|
||||||
iterator() = default;
|
|
||||||
|
|
||||||
/// constructor for a given JSON instance
|
|
||||||
iterator(pointer object) : m_object(object)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = typename object_t::iterator();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = typename array_t::iterator();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator = primitive_iterator_t();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// copy constructor
|
|
||||||
iterator(const iterator& other) noexcept
|
|
||||||
: m_object(other.m_object), m_it(other.m_it)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// copy assignment
|
|
||||||
iterator& operator=(iterator other) noexcept (
|
|
||||||
std::is_nothrow_move_constructible<pointer>::value and
|
|
||||||
std::is_nothrow_move_assignable<pointer>::value and
|
|
||||||
std::is_nothrow_move_constructible<internal_iterator>::value and
|
|
||||||
std::is_nothrow_move_assignable<internal_iterator>::value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::swap(m_object, other.m_object);
|
|
||||||
std::swap(m_it, other.m_it);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// set the iterator to the first value
|
|
||||||
void set_begin()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = m_object->m_value.object->begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = m_object->m_value.array->begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
// set to end so begin()==end() is true: null is empty
|
|
||||||
m_it.primitive_iterator.set_end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator.set_begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// set the iterator past the last value
|
|
||||||
void set_end()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator = m_object->m_value.object->end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator = m_object->m_value.array->end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator.set_end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// return a reference to the value pointed to by the iterator
|
|
||||||
reference operator*()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return m_it.object_iterator->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return *m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator.is_begin())
|
|
||||||
{
|
|
||||||
return *m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// dereference the iterator
|
|
||||||
pointer operator->()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return &(m_it.object_iterator->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return &*m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator.is_begin())
|
|
||||||
{
|
|
||||||
return m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-increment (it++)
|
|
||||||
iterator operator++(int)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-increment (++it)
|
|
||||||
iterator& operator++()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
++m_it.object_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
++m_it.array_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
++m_it.primitive_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-decrement (it--)
|
|
||||||
iterator operator--(int)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
m_it.object_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
|
||||||
iterator& operator--()
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
--m_it.object_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
--m_it.array_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
--m_it.primitive_iterator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: equal
|
|
||||||
bool operator==(const iterator& other) const
|
|
||||||
{
|
|
||||||
// if objects are not the same, the comparison is undefined
|
|
||||||
if (m_object != other.m_object)
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot compare iterators of different containers");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return (m_it.object_iterator == other.m_it.object_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return (m_it.array_iterator == other.m_it.array_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: not equal
|
|
||||||
bool operator!=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: smaller
|
|
||||||
bool operator<(const iterator& other) const
|
|
||||||
{
|
|
||||||
// if objects are not the same, the comparison is undefined
|
|
||||||
if (m_object != other.m_object)
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot compare iterators of different containers");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator< for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return (m_it.array_iterator < other.m_it.array_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: less than or equal
|
|
||||||
bool operator<=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not other.operator < (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: greater than
|
|
||||||
bool operator>(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator<=(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// comparison: greater than or equal
|
|
||||||
bool operator>=(const iterator& other) const
|
|
||||||
{
|
|
||||||
return not operator<(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
iterator& operator+=(difference_type i)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator+= for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
m_it.array_iterator += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
m_it.primitive_iterator += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
iterator& operator-=(difference_type i)
|
|
||||||
{
|
|
||||||
return operator+=(-i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
iterator operator+(difference_type i)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result += i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
iterator operator-(difference_type i)
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result -= i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return difference
|
|
||||||
difference_type operator-(const iterator& other) const
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator- for object iterators");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return m_it.array_iterator - other.m_it.array_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return m_it.primitive_iterator - other.m_it.primitive_iterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// access to successor
|
|
||||||
reference operator[](difference_type n)
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use operator[] for object iterators");
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::array):
|
|
||||||
{
|
|
||||||
return *(m_it.array_iterator + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
case (basic_json::value_t::null):
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (m_it.primitive_iterator == -n)
|
|
||||||
{
|
|
||||||
return *m_object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::out_of_range("cannot get value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an object iterator
|
|
||||||
typename object_t::key_type key() const
|
|
||||||
{
|
|
||||||
switch (m_object->m_type)
|
|
||||||
{
|
|
||||||
case (basic_json::value_t::object):
|
|
||||||
{
|
|
||||||
return m_it.object_iterator->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw std::domain_error("cannot use key() for non-object iterators");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an iterator
|
|
||||||
reference value()
|
|
||||||
{
|
|
||||||
return operator*();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// associated JSON instance
|
|
||||||
pointer m_object = nullptr;
|
|
||||||
/// the actual iterator of the associated instance
|
|
||||||
internal_iterator m_it = internal_iterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// a const random access iterator for the basic_json class
|
/// a const random access iterator for the basic_json class
|
||||||
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
|
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
|
||||||
{
|
{
|
||||||
|
@ -5874,70 +5361,96 @@ class basic_json
|
||||||
internal_iterator m_it = internal_iterator();
|
internal_iterator m_it = internal_iterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/// a random access iterator for the basic_json class
|
||||||
@brief a reverse random access iterator for the basic_json class
|
class iterator : public const_iterator
|
||||||
|
|
||||||
The reverse iterator is realized with the `std::reverse_iterator` adaptor.
|
|
||||||
This adaptor does not automatically inherit all functionality from the
|
|
||||||
base iterator class, so some functions need to be explicitly implemented
|
|
||||||
by either delegating them to the base class or by using the `base()`
|
|
||||||
function to access the underlying base iterator.
|
|
||||||
|
|
||||||
The following operators are implicitly inherited:
|
|
||||||
|
|
||||||
- `operator==`, `operator!=`, `operator<`, `operator<=`, `operator>`,
|
|
||||||
`operator>=`
|
|
||||||
- `operator-=`
|
|
||||||
- `operator->`, `operator*`
|
|
||||||
*/
|
|
||||||
class reverse_iterator : public std::reverse_iterator<typename basic_json::iterator>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// shortcut to the reverse iterator adaptor
|
using base_iterator = const_iterator;
|
||||||
using base_iterator = std::reverse_iterator<typename basic_json::iterator>;
|
using pointer = typename basic_json::pointer;
|
||||||
|
using reference = typename basic_json::reference;
|
||||||
|
|
||||||
/// create reverse iterator from iterator
|
/// default constructor
|
||||||
reverse_iterator(const typename base_iterator::iterator_type& it)
|
iterator() = default;
|
||||||
: base_iterator(it) {}
|
|
||||||
|
|
||||||
/// create reverse iterator from base class
|
/// constructor for a given JSON instance
|
||||||
reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
iterator(pointer object) noexcept : base_iterator(object)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// copy constructor
|
||||||
|
iterator(const iterator& other) noexcept
|
||||||
|
: base_iterator(other)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// copy assignment
|
||||||
|
iterator& operator=(iterator other) noexcept(
|
||||||
|
std::is_nothrow_move_constructible<pointer>::value and
|
||||||
|
std::is_nothrow_move_assignable<pointer>::value and
|
||||||
|
std::is_nothrow_move_constructible<internal_iterator>::value and
|
||||||
|
std::is_nothrow_move_assignable<internal_iterator>::value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
base_iterator::operator=(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return a reference to the value pointed to by the iterator
|
||||||
|
reference operator*()
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::operator*());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// dereference the iterator
|
||||||
|
pointer operator->()
|
||||||
|
{
|
||||||
|
return const_cast<pointer>(base_iterator::operator->());
|
||||||
|
}
|
||||||
|
|
||||||
/// post-increment (it++)
|
/// post-increment (it++)
|
||||||
reverse_iterator operator++(int)
|
iterator operator++(int)
|
||||||
{
|
{
|
||||||
return base_iterator::operator++(1);
|
iterator result = *this;
|
||||||
|
base_iterator::operator++();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pre-increment (++it)
|
/// pre-increment (++it)
|
||||||
reverse_iterator& operator++()
|
iterator& operator++()
|
||||||
{
|
{
|
||||||
base_iterator::operator++();
|
base_iterator::operator++();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// post-decrement (it--)
|
/// post-decrement (it--)
|
||||||
reverse_iterator operator--(int)
|
iterator operator--(int)
|
||||||
{
|
{
|
||||||
return base_iterator::operator--(1);
|
iterator result = *this;
|
||||||
|
base_iterator::operator--();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
/// pre-decrement (--it)
|
||||||
reverse_iterator& operator--()
|
iterator& operator--()
|
||||||
{
|
{
|
||||||
base_iterator::operator--();
|
base_iterator::operator--();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add to iterator
|
/// add to iterator
|
||||||
reverse_iterator& operator+=(difference_type i)
|
iterator& operator+=(difference_type i)
|
||||||
{
|
{
|
||||||
base_iterator::operator+=(i);
|
base_iterator::operator+=(i);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// subtract from iterator
|
||||||
|
iterator& operator-=(difference_type i)
|
||||||
|
{
|
||||||
|
base_iterator::operator-=(i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/// add to iterator
|
/// add to iterator
|
||||||
reverse_iterator operator+(difference_type i) const
|
iterator operator+(difference_type i)
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
result += i;
|
result += i;
|
||||||
|
@ -5945,7 +5458,90 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/// subtract from iterator
|
/// subtract from iterator
|
||||||
reverse_iterator operator-(difference_type i) const
|
iterator operator-(difference_type i)
|
||||||
|
{
|
||||||
|
auto result = *this;
|
||||||
|
result -= i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type operator-(const iterator& other) const
|
||||||
|
{
|
||||||
|
return base_iterator::operator-(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// access to successor
|
||||||
|
reference operator[](difference_type n) const
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::operator[](n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the value of an iterator
|
||||||
|
reference value() const
|
||||||
|
{
|
||||||
|
return const_cast<reference>(base_iterator::value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// a template for a reverse iterator class
|
||||||
|
template<typename Base>
|
||||||
|
class json_reverse_iterator : public std::reverse_iterator<Base>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// shortcut to the reverse iterator adaptor
|
||||||
|
using base_iterator = std::reverse_iterator<Base>;
|
||||||
|
using reference = typename Base::reference;
|
||||||
|
|
||||||
|
/// create reverse iterator from iterator
|
||||||
|
json_reverse_iterator(const typename base_iterator::iterator_type& it)
|
||||||
|
: base_iterator(it) {}
|
||||||
|
|
||||||
|
/// create reverse iterator from base class
|
||||||
|
json_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
||||||
|
|
||||||
|
/// post-increment (it++)
|
||||||
|
json_reverse_iterator operator++(int)
|
||||||
|
{
|
||||||
|
return base_iterator::operator++(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// pre-increment (++it)
|
||||||
|
json_reverse_iterator& operator++()
|
||||||
|
{
|
||||||
|
base_iterator::operator++();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// post-decrement (it--)
|
||||||
|
json_reverse_iterator operator--(int)
|
||||||
|
{
|
||||||
|
return base_iterator::operator--(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// pre-decrement (--it)
|
||||||
|
json_reverse_iterator& operator--()
|
||||||
|
{
|
||||||
|
base_iterator::operator--();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// add to iterator
|
||||||
|
json_reverse_iterator& operator+=(difference_type i)
|
||||||
|
{
|
||||||
|
base_iterator::operator+=(i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// add to iterator
|
||||||
|
json_reverse_iterator operator+(difference_type i) const
|
||||||
|
{
|
||||||
|
auto result = *this;
|
||||||
|
result += i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// subtract from iterator
|
||||||
|
json_reverse_iterator operator-(difference_type i) const
|
||||||
{
|
{
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
result -= i;
|
result -= i;
|
||||||
|
@ -5953,7 +5549,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return difference
|
/// return difference
|
||||||
difference_type operator-(const reverse_iterator& other) const
|
difference_type operator-(const json_reverse_iterator& other) const
|
||||||
{
|
{
|
||||||
return this->base() - other.base();
|
return this->base() - other.base();
|
||||||
}
|
}
|
||||||
|
@ -5979,97 +5575,6 @@ class basic_json
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// a const reverse random access iterator for the basic_json class
|
|
||||||
class const_reverse_iterator : public std::reverse_iterator<typename basic_json::const_iterator>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// shortcut to the reverse iterator adaptor
|
|
||||||
using base_iterator = std::reverse_iterator<typename basic_json::const_iterator>;
|
|
||||||
|
|
||||||
/// create reverse iterator from iterator
|
|
||||||
const_reverse_iterator(const typename base_iterator::iterator_type& it)
|
|
||||||
: base_iterator(it) {}
|
|
||||||
|
|
||||||
/// create reverse iterator from base class
|
|
||||||
const_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
|
|
||||||
|
|
||||||
/// post-increment (it++)
|
|
||||||
const_reverse_iterator operator++(int)
|
|
||||||
{
|
|
||||||
return base_iterator::operator++(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-increment (++it)
|
|
||||||
const_reverse_iterator& operator++()
|
|
||||||
{
|
|
||||||
base_iterator::operator++();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// post-decrement (it--)
|
|
||||||
const_reverse_iterator operator--(int)
|
|
||||||
{
|
|
||||||
return base_iterator::operator--(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pre-decrement (--it)
|
|
||||||
const_reverse_iterator& operator--()
|
|
||||||
{
|
|
||||||
base_iterator::operator--();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
const_reverse_iterator& operator+=(difference_type i)
|
|
||||||
{
|
|
||||||
base_iterator::operator+=(i);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add to iterator
|
|
||||||
const_reverse_iterator operator+(difference_type i) const
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result += i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// subtract from iterator
|
|
||||||
const_reverse_iterator operator-(difference_type i) const
|
|
||||||
{
|
|
||||||
auto result = *this;
|
|
||||||
result -= i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return difference
|
|
||||||
difference_type operator-(const const_reverse_iterator& other) const
|
|
||||||
{
|
|
||||||
return this->base() - other.base();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// access to successor
|
|
||||||
const_reference operator[](difference_type n) const
|
|
||||||
{
|
|
||||||
return *(this->operator+(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the key of an object iterator
|
|
||||||
typename object_t::key_type key() const
|
|
||||||
{
|
|
||||||
auto it = --this->base();
|
|
||||||
return it.key();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return the value of an iterator
|
|
||||||
const_reference value() const
|
|
||||||
{
|
|
||||||
auto it = --this->base();
|
|
||||||
return it.operator * ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// lexer and parser //
|
// lexer and parser //
|
||||||
|
|
Loading…
Reference in a new issue