Commit 5c813b61 by Niels

closes #104 and integrates code from #93

Iterators are now implemented via const_iterators and reverse_iterator and const_reverse_iterator now share a template class. Thanks a lot!
parent 1c8d5dc2
...@@ -54,7 +54,7 @@ doxygen: create_output create_links ...@@ -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/
......
...@@ -172,14 +172,17 @@ class basic_json ...@@ -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,8 +4866,8 @@ class basic_json ...@@ -4863,8 +4866,8 @@ class basic_json
}; };
public: public:
/// a random access iterator for the basic_json class /// a const random access iterator for the basic_json class
class iterator : public std::iterator<std::random_access_iterator_tag, basic_json> class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
{ {
// allow basic_json class to access m_it // allow basic_json class to access m_it
friend class basic_json; friend class basic_json;
...@@ -4875,17 +4878,17 @@ class basic_json ...@@ -4875,17 +4878,17 @@ class basic_json
/// a type to represent differences between iterators /// a type to represent differences between iterators
using difference_type = typename basic_json::difference_type; using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type) /// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::pointer; using pointer = typename basic_json::const_pointer;
/// defines a reference to the type iterated over (value_type) /// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::reference; using reference = typename basic_json::const_reference;
/// the category of the iterator /// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag; using iterator_category = std::bidirectional_iterator_tag;
/// default constructor /// default constructor
iterator() = default; const_iterator() = default;
/// constructor for a given JSON instance /// constructor for a given JSON instance
iterator(pointer object) : m_object(object) const_iterator(pointer object) : m_object(object)
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -4907,13 +4910,38 @@ class basic_json ...@@ -4907,13 +4910,38 @@ class basic_json
} }
} }
/// copy constructor given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor /// copy constructor
iterator(const iterator& other) noexcept const_iterator(const const_iterator& other) noexcept
: m_object(other.m_object), m_it(other.m_it) : m_object(other.m_object), m_it(other.m_it)
{} {}
/// copy assignment /// copy assignment
iterator& operator=(iterator other) noexcept ( const_iterator& operator=(const_iterator other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and std::is_nothrow_move_constructible<internal_iterator>::value and
...@@ -4985,7 +5013,7 @@ class basic_json ...@@ -4985,7 +5013,7 @@ class basic_json
public: public:
/// return a reference to the value pointed to by the iterator /// return a reference to the value pointed to by the iterator
reference operator*() reference operator*() const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5019,7 +5047,7 @@ class basic_json ...@@ -5019,7 +5047,7 @@ class basic_json
} }
/// dereference the iterator /// dereference the iterator
pointer operator->() pointer operator->() const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5033,11 +5061,6 @@ class basic_json ...@@ -5033,11 +5061,6 @@ class basic_json
return &*m_it.array_iterator; return &*m_it.array_iterator;
} }
case (basic_json::value_t::null):
{
throw std::out_of_range("cannot get value");
}
default: default:
{ {
if (m_it.primitive_iterator.is_begin()) if (m_it.primitive_iterator.is_begin())
...@@ -5053,36 +5076,16 @@ class basic_json ...@@ -5053,36 +5076,16 @@ class basic_json
} }
/// post-increment (it++) /// post-increment (it++)
iterator operator++(int) const_iterator operator++(int)
{ {
auto result = *this; auto result = *this;
++(*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; return result;
} }
/// pre-increment (++it) /// pre-increment (++it)
iterator& operator++() const_iterator& operator++()
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5109,36 +5112,16 @@ class basic_json ...@@ -5109,36 +5112,16 @@ class basic_json
} }
/// post-decrement (it--) /// post-decrement (it--)
iterator operator--(int) const_iterator operator--(int)
{ {
auto result = *this; auto result = *this;
--(*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; return result;
} }
/// pre-decrement (--it) /// pre-decrement (--it)
iterator& operator--() const_iterator& operator--()
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5165,7 +5148,7 @@ class basic_json ...@@ -5165,7 +5148,7 @@ class basic_json
} }
/// comparison: equal /// comparison: equal
bool operator==(const iterator& other) const bool operator==(const const_iterator& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
...@@ -5193,13 +5176,13 @@ class basic_json ...@@ -5193,13 +5176,13 @@ class basic_json
} }
/// comparison: not equal /// comparison: not equal
bool operator!=(const iterator& other) const bool operator!=(const const_iterator& other) const
{ {
return not operator==(other); return not operator==(other);
} }
/// comparison: smaller /// comparison: smaller
bool operator<(const iterator& other) const bool operator<(const const_iterator& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
...@@ -5227,25 +5210,25 @@ class basic_json ...@@ -5227,25 +5210,25 @@ class basic_json
} }
/// comparison: less than or equal /// comparison: less than or equal
bool operator<=(const iterator& other) const bool operator<=(const const_iterator& other) const
{ {
return not other.operator < (*this); return not other.operator < (*this);
} }
/// comparison: greater than /// comparison: greater than
bool operator>(const iterator& other) const bool operator>(const const_iterator& other) const
{ {
return not operator<=(other); return not operator<=(other);
} }
/// comparison: greater than or equal /// comparison: greater than or equal
bool operator>=(const iterator& other) const bool operator>=(const const_iterator& other) const
{ {
return not operator<(other); return not operator<(other);
} }
/// add to iterator /// add to iterator
iterator& operator+=(difference_type i) const_iterator& operator+=(difference_type i)
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5271,13 +5254,13 @@ class basic_json ...@@ -5271,13 +5254,13 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
iterator& operator-=(difference_type i) const_iterator& operator-=(difference_type i)
{ {
return operator+=(-i); return operator+=(-i);
} }
/// add to iterator /// add to iterator
iterator operator+(difference_type i) const_iterator operator+(difference_type i)
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5285,7 +5268,7 @@ class basic_json ...@@ -5285,7 +5268,7 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
iterator operator-(difference_type i) const_iterator operator-(difference_type i)
{ {
auto result = *this; auto result = *this;
result -= i; result -= i;
...@@ -5293,14 +5276,13 @@ class basic_json ...@@ -5293,14 +5276,13 @@ class basic_json
} }
/// return difference /// return difference
difference_type operator-(const iterator& other) const difference_type operator-(const const_iterator& other) const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
case (basic_json::value_t::object): case (basic_json::value_t::object):
{ {
throw std::domain_error("cannot use operator- for object iterators"); throw std::domain_error("cannot use operator- for object iterators");
return 0;
} }
case (basic_json::value_t::array): case (basic_json::value_t::array):
...@@ -5316,7 +5298,7 @@ class basic_json ...@@ -5316,7 +5298,7 @@ class basic_json
} }
/// access to successor /// access to successor
reference operator[](difference_type n) reference operator[](difference_type n) const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5366,8 +5348,8 @@ class basic_json ...@@ -5366,8 +5348,8 @@ class basic_json
} }
} }
/// return the key of an iterator /// return the value of an iterator
reference value() reference value() const
{ {
return operator*(); return operator*();
} }
...@@ -5379,401 +5361,96 @@ class basic_json ...@@ -5379,401 +5361,96 @@ class basic_json
internal_iterator m_it = internal_iterator(); internal_iterator m_it = internal_iterator();
}; };
/// a const random access iterator for the basic_json class /// a random access iterator for the basic_json class
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json> class iterator : public const_iterator
{ {
// allow basic_json class to access m_it
friend class basic_json;
public: public:
/// the type of the values when the iterator is dereferenced using base_iterator = const_iterator;
using value_type = typename basic_json::value_type; using pointer = typename basic_json::pointer;
/// a type to represent differences between iterators using reference = typename basic_json::reference;
using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::const_pointer;
/// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::const_reference;
/// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag;
/// default constructor /// default constructor
const_iterator() = default; iterator() = default;
/// constructor for a given JSON instance /// constructor for a given JSON instance
const_iterator(pointer object) : m_object(object) iterator(pointer object) noexcept : base_iterator(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 given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor /// copy constructor
const_iterator(const const_iterator& other) noexcept iterator(const iterator& other) noexcept
: m_object(other.m_object), m_it(other.m_it) : base_iterator(other)
{} {}
/// copy assignment /// copy assignment
const_iterator& operator=(const_iterator other) noexcept( iterator& operator=(iterator other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_assignable<internal_iterator>::value std::is_nothrow_move_assignable<internal_iterator>::value
) )
{ {
std::swap(m_object, other.m_object); base_iterator::operator=(other);
std::swap(m_it, other.m_it);
return *this; return *this;
} }
private: /// return a reference to the value pointed to by the iterator
/// set the iterator to the first value reference operator*()
void set_begin()
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{ {
m_it.object_iterator = m_object->m_value.object->begin(); return const_cast<reference>(base_iterator::operator*());
break;
} }
case (basic_json::value_t::array): /// dereference the iterator
pointer operator->()
{ {
m_it.array_iterator = m_object->m_value.array->begin(); return const_cast<pointer>(base_iterator::operator->());
break;
} }
case (basic_json::value_t::null): /// post-increment (it++)
iterator operator++(int)
{ {
// set to end so begin()==end() is true: null is empty iterator result = *this;
m_it.primitive_iterator.set_end(); base_iterator::operator++();
break; return result;
} }
default: /// pre-increment (++it)
iterator& operator++()
{ {
m_it.primitive_iterator.set_begin(); base_iterator::operator++();
break; return *this;
}
}
} }
/// set the iterator past the last value /// post-decrement (it--)
void set_end() iterator operator--(int)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{ {
m_it.object_iterator = m_object->m_value.object->end(); iterator result = *this;
break; base_iterator::operator--();
return result;
} }
case (basic_json::value_t::array): /// pre-decrement (--it)
iterator& operator--()
{ {
m_it.array_iterator = m_object->m_value.array->end(); base_iterator::operator--();
break; return *this;
} }
default: /// add to iterator
iterator& operator+=(difference_type i)
{ {
m_it.primitive_iterator.set_end(); base_iterator::operator+=(i);
break; return *this;
}
}
} }
public: /// subtract from iterator
/// return a reference to the value pointed to by the iterator iterator& operator-=(difference_type i)
reference operator*() const
{
switch (m_object->m_type)
{ {
case (basic_json::value_t::object): base_iterator::operator-=(i);
{
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->() const
{
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;
}
default:
{
if (m_it.primitive_iterator.is_begin())
{
return m_object;
}
else
{
throw std::out_of_range("cannot get value");
}
}
}
}
/// post-increment (it++)
const_iterator operator++(int)
{
auto result = *this;
++(*this);
return result;
}
/// pre-increment (++it)
const_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--)
const_iterator operator--(int)
{
auto result = *this;
--(*this);
return result;
}
/// pre-decrement (--it)
const_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 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 const_iterator& other) const
{
return not operator==(other);
}
/// comparison: smaller
bool operator<(const 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 const_iterator& other) const
{
return not other.operator < (*this);
}
/// comparison: greater than
bool operator>(const const_iterator& other) const
{
return not operator<=(other);
}
/// comparison: greater than or equal
bool operator>=(const const_iterator& other) const
{
return not operator<(other);
}
/// add to iterator
const_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; return *this;
} }
/// subtract from iterator
const_iterator& operator-=(difference_type i)
{
return operator+=(-i);
}
/// add to iterator /// add to iterator
const_iterator operator+(difference_type i) iterator operator+(difference_type i)
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5781,163 +5458,82 @@ class basic_json ...@@ -5781,163 +5458,82 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
const_iterator operator-(difference_type i) iterator operator-(difference_type i)
{ {
auto result = *this; auto result = *this;
result -= i; result -= i;
return result; return result;
} }
/// return difference difference_type operator-(const iterator& other) const
difference_type operator-(const 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");
}
case (basic_json::value_t::array):
{ {
return m_it.array_iterator - other.m_it.array_iterator; return base_iterator::operator-(other);
}
default:
{
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
}
} }
/// access to successor /// access to successor
reference operator[](difference_type n) const reference operator[](difference_type n) const
{ {
switch (m_object->m_type) return const_cast<reference>(base_iterator::operator[](n));
{
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 value of an iterator /// return the value of an iterator
reference value() const reference value() const
{ {
return operator*(); return const_cast<reference>(base_iterator::value());
} }
private:
/// associated JSON instance
pointer m_object = nullptr;
/// the actual iterator of the associated instance
internal_iterator m_it = internal_iterator();
}; };
/*! /// a template for a reverse iterator class
@brief a reverse random access iterator for the basic_json class template<typename Base>
class json_reverse_iterator : public std::reverse_iterator<Base>
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 /// shortcut to the reverse iterator adaptor
using base_iterator = std::reverse_iterator<typename basic_json::iterator>; using base_iterator = std::reverse_iterator<Base>;
using reference = typename Base::reference;
/// create reverse iterator from iterator /// create reverse iterator from iterator
reverse_iterator(const typename base_iterator::iterator_type& it) json_reverse_iterator(const typename base_iterator::iterator_type& it)
: base_iterator(it) {} : base_iterator(it) {}
/// create reverse iterator from base class /// create reverse iterator from base class
reverse_iterator(const base_iterator& it) : base_iterator(it) {} json_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
/// post-increment (it++) /// post-increment (it++)
reverse_iterator operator++(int) json_reverse_iterator operator++(int)
{ {
return base_iterator::operator++(1); return base_iterator::operator++(1);
} }
/// pre-increment (++it) /// pre-increment (++it)
reverse_iterator& operator++() json_reverse_iterator& operator++()
{ {
base_iterator::operator++(); base_iterator::operator++();
return *this; return *this;
} }
/// post-decrement (it--) /// post-decrement (it--)
reverse_iterator operator--(int) json_reverse_iterator operator--(int)
{ {
return base_iterator::operator--(1); return base_iterator::operator--(1);
} }
/// pre-decrement (--it) /// pre-decrement (--it)
reverse_iterator& operator--() json_reverse_iterator& operator--()
{ {
base_iterator::operator--(); base_iterator::operator--();
return *this; return *this;
} }
/// add to iterator /// add to iterator
reverse_iterator& operator+=(difference_type i) json_reverse_iterator& operator+=(difference_type i)
{ {
base_iterator::operator+=(i); base_iterator::operator+=(i);
return *this; return *this;
} }
/// add to iterator /// add to iterator
reverse_iterator operator+(difference_type i) const json_reverse_iterator operator+(difference_type i) const
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5945,7 +5541,7 @@ class basic_json ...@@ -5945,7 +5541,7 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
reverse_iterator operator-(difference_type i) const 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 ...@@ -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 ...@@ -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 ...@@ -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,8 +4866,8 @@ class basic_json ...@@ -4863,8 +4866,8 @@ class basic_json
}; };
public: public:
/// a random access iterator for the basic_json class /// a const random access iterator for the basic_json class
class iterator : public std::iterator<std::random_access_iterator_tag, basic_json> class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
{ {
// allow basic_json class to access m_it // allow basic_json class to access m_it
friend class basic_json; friend class basic_json;
...@@ -4875,17 +4878,17 @@ class basic_json ...@@ -4875,17 +4878,17 @@ class basic_json
/// a type to represent differences between iterators /// a type to represent differences between iterators
using difference_type = typename basic_json::difference_type; using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type) /// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::pointer; using pointer = typename basic_json::const_pointer;
/// defines a reference to the type iterated over (value_type) /// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::reference; using reference = typename basic_json::const_reference;
/// the category of the iterator /// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag; using iterator_category = std::bidirectional_iterator_tag;
/// default constructor /// default constructor
iterator() = default; const_iterator() = default;
/// constructor for a given JSON instance /// constructor for a given JSON instance
iterator(pointer object) : m_object(object) const_iterator(pointer object) : m_object(object)
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -4907,13 +4910,38 @@ class basic_json ...@@ -4907,13 +4910,38 @@ class basic_json
} }
} }
/// copy constructor given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor /// copy constructor
iterator(const iterator& other) noexcept const_iterator(const const_iterator& other) noexcept
: m_object(other.m_object), m_it(other.m_it) : m_object(other.m_object), m_it(other.m_it)
{} {}
/// copy assignment /// copy assignment
iterator& operator=(iterator other) noexcept ( const_iterator& operator=(const_iterator other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and std::is_nothrow_move_constructible<internal_iterator>::value and
...@@ -4985,7 +5013,7 @@ class basic_json ...@@ -4985,7 +5013,7 @@ class basic_json
public: public:
/// return a reference to the value pointed to by the iterator /// return a reference to the value pointed to by the iterator
reference operator*() reference operator*() const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5019,7 +5047,7 @@ class basic_json ...@@ -5019,7 +5047,7 @@ class basic_json
} }
/// dereference the iterator /// dereference the iterator
pointer operator->() pointer operator->() const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5033,11 +5061,6 @@ class basic_json ...@@ -5033,11 +5061,6 @@ class basic_json
return &*m_it.array_iterator; return &*m_it.array_iterator;
} }
case (basic_json::value_t::null):
{
throw std::out_of_range("cannot get value");
}
default: default:
{ {
if (m_it.primitive_iterator.is_begin()) if (m_it.primitive_iterator.is_begin())
...@@ -5053,36 +5076,16 @@ class basic_json ...@@ -5053,36 +5076,16 @@ class basic_json
} }
/// post-increment (it++) /// post-increment (it++)
iterator operator++(int) const_iterator operator++(int)
{ {
auto result = *this; auto result = *this;
++(*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; return result;
} }
/// pre-increment (++it) /// pre-increment (++it)
iterator& operator++() const_iterator& operator++()
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5109,36 +5112,16 @@ class basic_json ...@@ -5109,36 +5112,16 @@ class basic_json
} }
/// post-decrement (it--) /// post-decrement (it--)
iterator operator--(int) const_iterator operator--(int)
{ {
auto result = *this; auto result = *this;
--(*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; return result;
} }
/// pre-decrement (--it) /// pre-decrement (--it)
iterator& operator--() const_iterator& operator--()
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5165,7 +5148,7 @@ class basic_json ...@@ -5165,7 +5148,7 @@ class basic_json
} }
/// comparison: equal /// comparison: equal
bool operator==(const iterator& other) const bool operator==(const const_iterator& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
...@@ -5193,13 +5176,13 @@ class basic_json ...@@ -5193,13 +5176,13 @@ class basic_json
} }
/// comparison: not equal /// comparison: not equal
bool operator!=(const iterator& other) const bool operator!=(const const_iterator& other) const
{ {
return not operator==(other); return not operator==(other);
} }
/// comparison: smaller /// comparison: smaller
bool operator<(const iterator& other) const bool operator<(const const_iterator& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
...@@ -5227,25 +5210,25 @@ class basic_json ...@@ -5227,25 +5210,25 @@ class basic_json
} }
/// comparison: less than or equal /// comparison: less than or equal
bool operator<=(const iterator& other) const bool operator<=(const const_iterator& other) const
{ {
return not other.operator < (*this); return not other.operator < (*this);
} }
/// comparison: greater than /// comparison: greater than
bool operator>(const iterator& other) const bool operator>(const const_iterator& other) const
{ {
return not operator<=(other); return not operator<=(other);
} }
/// comparison: greater than or equal /// comparison: greater than or equal
bool operator>=(const iterator& other) const bool operator>=(const const_iterator& other) const
{ {
return not operator<(other); return not operator<(other);
} }
/// add to iterator /// add to iterator
iterator& operator+=(difference_type i) const_iterator& operator+=(difference_type i)
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5271,13 +5254,13 @@ class basic_json ...@@ -5271,13 +5254,13 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
iterator& operator-=(difference_type i) const_iterator& operator-=(difference_type i)
{ {
return operator+=(-i); return operator+=(-i);
} }
/// add to iterator /// add to iterator
iterator operator+(difference_type i) const_iterator operator+(difference_type i)
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5285,7 +5268,7 @@ class basic_json ...@@ -5285,7 +5268,7 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
iterator operator-(difference_type i) const_iterator operator-(difference_type i)
{ {
auto result = *this; auto result = *this;
result -= i; result -= i;
...@@ -5293,14 +5276,13 @@ class basic_json ...@@ -5293,14 +5276,13 @@ class basic_json
} }
/// return difference /// return difference
difference_type operator-(const iterator& other) const difference_type operator-(const const_iterator& other) const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
case (basic_json::value_t::object): case (basic_json::value_t::object):
{ {
throw std::domain_error("cannot use operator- for object iterators"); throw std::domain_error("cannot use operator- for object iterators");
return 0;
} }
case (basic_json::value_t::array): case (basic_json::value_t::array):
...@@ -5316,7 +5298,7 @@ class basic_json ...@@ -5316,7 +5298,7 @@ class basic_json
} }
/// access to successor /// access to successor
reference operator[](difference_type n) reference operator[](difference_type n) const
{ {
switch (m_object->m_type) switch (m_object->m_type)
{ {
...@@ -5366,8 +5348,8 @@ class basic_json ...@@ -5366,8 +5348,8 @@ class basic_json
} }
} }
/// return the key of an iterator /// return the value of an iterator
reference value() reference value() const
{ {
return operator*(); return operator*();
} }
...@@ -5379,401 +5361,96 @@ class basic_json ...@@ -5379,401 +5361,96 @@ class basic_json
internal_iterator m_it = internal_iterator(); internal_iterator m_it = internal_iterator();
}; };
/// a const random access iterator for the basic_json class /// a random access iterator for the basic_json class
class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json> class iterator : public const_iterator
{ {
// allow basic_json class to access m_it
friend class basic_json;
public: public:
/// the type of the values when the iterator is dereferenced using base_iterator = const_iterator;
using value_type = typename basic_json::value_type; using pointer = typename basic_json::pointer;
/// a type to represent differences between iterators using reference = typename basic_json::reference;
using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::const_pointer;
/// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::const_reference;
/// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag;
/// default constructor /// default constructor
const_iterator() = default; iterator() = default;
/// constructor for a given JSON instance /// constructor for a given JSON instance
const_iterator(pointer object) : m_object(object) iterator(pointer object) noexcept : base_iterator(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 given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor /// copy constructor
const_iterator(const const_iterator& other) noexcept iterator(const iterator& other) noexcept
: m_object(other.m_object), m_it(other.m_it) : base_iterator(other)
{} {}
/// copy assignment /// copy assignment
const_iterator& operator=(const_iterator other) noexcept( iterator& operator=(iterator other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_assignable<internal_iterator>::value std::is_nothrow_move_assignable<internal_iterator>::value
) )
{ {
std::swap(m_object, other.m_object); base_iterator::operator=(other);
std::swap(m_it, other.m_it);
return *this; return *this;
} }
private: /// return a reference to the value pointed to by the iterator
/// set the iterator to the first value reference operator*()
void set_begin()
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{ {
m_it.object_iterator = m_object->m_value.object->begin(); return const_cast<reference>(base_iterator::operator*());
break;
} }
case (basic_json::value_t::array): /// dereference the iterator
pointer operator->()
{ {
m_it.array_iterator = m_object->m_value.array->begin(); return const_cast<pointer>(base_iterator::operator->());
break;
} }
case (basic_json::value_t::null): /// post-increment (it++)
iterator operator++(int)
{ {
// set to end so begin()==end() is true: null is empty iterator result = *this;
m_it.primitive_iterator.set_end(); base_iterator::operator++();
break; return result;
} }
default: /// pre-increment (++it)
iterator& operator++()
{ {
m_it.primitive_iterator.set_begin(); base_iterator::operator++();
break; return *this;
}
}
} }
/// set the iterator past the last value /// post-decrement (it--)
void set_end() iterator operator--(int)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{ {
m_it.object_iterator = m_object->m_value.object->end(); iterator result = *this;
break; base_iterator::operator--();
return result;
} }
case (basic_json::value_t::array): /// pre-decrement (--it)
iterator& operator--()
{ {
m_it.array_iterator = m_object->m_value.array->end(); base_iterator::operator--();
break; return *this;
} }
default: /// add to iterator
iterator& operator+=(difference_type i)
{ {
m_it.primitive_iterator.set_end(); base_iterator::operator+=(i);
break; return *this;
}
}
} }
public: /// subtract from iterator
/// return a reference to the value pointed to by the iterator iterator& operator-=(difference_type i)
reference operator*() const
{
switch (m_object->m_type)
{ {
case (basic_json::value_t::object): base_iterator::operator-=(i);
{
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->() const
{
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;
}
default:
{
if (m_it.primitive_iterator.is_begin())
{
return m_object;
}
else
{
throw std::out_of_range("cannot get value");
}
}
}
}
/// post-increment (it++)
const_iterator operator++(int)
{
auto result = *this;
++(*this);
return result;
}
/// pre-increment (++it)
const_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--)
const_iterator operator--(int)
{
auto result = *this;
--(*this);
return result;
}
/// pre-decrement (--it)
const_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 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 const_iterator& other) const
{
return not operator==(other);
}
/// comparison: smaller
bool operator<(const 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 const_iterator& other) const
{
return not other.operator < (*this);
}
/// comparison: greater than
bool operator>(const const_iterator& other) const
{
return not operator<=(other);
}
/// comparison: greater than or equal
bool operator>=(const const_iterator& other) const
{
return not operator<(other);
}
/// add to iterator
const_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; return *this;
} }
/// subtract from iterator
const_iterator& operator-=(difference_type i)
{
return operator+=(-i);
}
/// add to iterator /// add to iterator
const_iterator operator+(difference_type i) iterator operator+(difference_type i)
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5781,163 +5458,82 @@ class basic_json ...@@ -5781,163 +5458,82 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
const_iterator operator-(difference_type i) iterator operator-(difference_type i)
{ {
auto result = *this; auto result = *this;
result -= i; result -= i;
return result; return result;
} }
/// return difference difference_type operator-(const iterator& other) const
difference_type operator-(const 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");
}
case (basic_json::value_t::array):
{ {
return m_it.array_iterator - other.m_it.array_iterator; return base_iterator::operator-(other);
}
default:
{
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
}
} }
/// access to successor /// access to successor
reference operator[](difference_type n) const reference operator[](difference_type n) const
{ {
switch (m_object->m_type) return const_cast<reference>(base_iterator::operator[](n));
{
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 value of an iterator /// return the value of an iterator
reference value() const reference value() const
{ {
return operator*(); return const_cast<reference>(base_iterator::value());
} }
private:
/// associated JSON instance
pointer m_object = nullptr;
/// the actual iterator of the associated instance
internal_iterator m_it = internal_iterator();
}; };
/*! /// a template for a reverse iterator class
@brief a reverse random access iterator for the basic_json class template<typename Base>
class json_reverse_iterator : public std::reverse_iterator<Base>
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 /// shortcut to the reverse iterator adaptor
using base_iterator = std::reverse_iterator<typename basic_json::iterator>; using base_iterator = std::reverse_iterator<Base>;
using reference = typename Base::reference;
/// create reverse iterator from iterator /// create reverse iterator from iterator
reverse_iterator(const typename base_iterator::iterator_type& it) json_reverse_iterator(const typename base_iterator::iterator_type& it)
: base_iterator(it) {} : base_iterator(it) {}
/// create reverse iterator from base class /// create reverse iterator from base class
reverse_iterator(const base_iterator& it) : base_iterator(it) {} json_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
/// post-increment (it++) /// post-increment (it++)
reverse_iterator operator++(int) json_reverse_iterator operator++(int)
{ {
return base_iterator::operator++(1); return base_iterator::operator++(1);
} }
/// pre-increment (++it) /// pre-increment (++it)
reverse_iterator& operator++() json_reverse_iterator& operator++()
{ {
base_iterator::operator++(); base_iterator::operator++();
return *this; return *this;
} }
/// post-decrement (it--) /// post-decrement (it--)
reverse_iterator operator--(int) json_reverse_iterator operator--(int)
{ {
return base_iterator::operator--(1); return base_iterator::operator--(1);
} }
/// pre-decrement (--it) /// pre-decrement (--it)
reverse_iterator& operator--() json_reverse_iterator& operator--()
{ {
base_iterator::operator--(); base_iterator::operator--();
return *this; return *this;
} }
/// add to iterator /// add to iterator
reverse_iterator& operator+=(difference_type i) json_reverse_iterator& operator+=(difference_type i)
{ {
base_iterator::operator+=(i); base_iterator::operator+=(i);
return *this; return *this;
} }
/// add to iterator /// add to iterator
reverse_iterator operator+(difference_type i) const json_reverse_iterator operator+(difference_type i) const
{ {
auto result = *this; auto result = *this;
result += i; result += i;
...@@ -5945,7 +5541,7 @@ class basic_json ...@@ -5945,7 +5541,7 @@ class basic_json
} }
/// subtract from iterator /// subtract from iterator
reverse_iterator operator-(difference_type i) const 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 ...@@ -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 ...@@ -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 //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment