From 420c8ce2f8df1e1dbd61b551a3027d8af22eb039 Mon Sep 17 00:00:00 2001 From: Alexander Nevskiy Date: Fri, 12 Jun 2015 23:56:49 +0300 Subject: [PATCH] Reimplement iterator via const_iterator. --- src/json.hpp | 669 ++++++++++----------------------------------------- 1 file changed, 128 insertions(+), 541 deletions(-) mode change 100644 => 100755 src/json.hpp diff --git a/src/json.hpp b/src/json.hpp old mode 100644 new mode 100755 index 25521bbe8..e85d704fb --- a/src/json.hpp +++ b/src/json.hpp @@ -2392,522 +2392,6 @@ class basic_json }; public: - /// a random access iterator for the basic_json class - class iterator : public std::iterator - { - // 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) noexcept : 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.generic_iterator = -1; - 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::value and - std::is_nothrow_move_assignable::value and - std::is_nothrow_move_constructible::value and - std::is_nothrow_move_assignable::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() noexcept - { - 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.generic_iterator = 1; - break; - } - - default: - { - m_it.generic_iterator = 0; - break; - } - } - } - - /// set the iterator past the last value - void set_end() noexcept - { - 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.generic_iterator = 1; - 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.generic_iterator == 0) - { - 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.generic_iterator == 0) - { - 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.generic_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.generic_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.generic_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.generic_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.generic_iterator == other.m_it.generic_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.generic_iterator < other.m_it.generic_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.generic_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.generic_iterator - other.m_it.generic_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.generic_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; - }; - /// a const random access iterator for the basic_json class class const_iterator : public std::iterator { @@ -2952,31 +2436,6 @@ class basic_json } } - /// copy constructor given a nonconst iterator - const_iterator(const iterator& other) noexcept : 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.generic_iterator = other.m_it.generic_iterator; - break; - } - } - } - /// copy constructor const_iterator(const const_iterator& other) noexcept : m_object(other.m_object), m_it(other.m_it) @@ -3103,6 +2562,11 @@ class basic_json return &*m_it.array_iterator; } + case (basic_json::value_t::null): + { + throw std::out_of_range("cannot get value"); + } + default: { if (m_it.generic_iterator == 0) @@ -3443,6 +2907,129 @@ class basic_json internal_iterator m_it; }; + /// a random access iterator for the basic_json class + class iterator : public const_iterator + { + public: + typedef const_iterator MyBase; + typedef basic_json* pointer; + typedef basic_json& reference; + + /// default constructor + iterator() = default; + + /// constructor for a given JSON instance + iterator(pointer object) noexcept : MyBase(object) + { + } + + /// copy constructor + iterator(const iterator& other) noexcept + : MyBase(other) + {} + + /// copy assignment + iterator& operator=(iterator other) noexcept( + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value and + std::is_nothrow_move_constructible::value and + std::is_nothrow_move_assignable::value + ) + { + MyBase::operator=(other); + return *this; + } + + /// return a reference to the value pointed to by the iterator + reference operator*() + { + return ((reference) MyBase::operator*()); + } + + /// dereference the iterator + pointer operator->() + { + return ((pointer) MyBase::operator->()); + } + + /// post-increment (it++) + iterator operator++(int) + { + iterator result = *this; + MyBase::operator++(); + return result; + } + + /// pre-increment (++it) + iterator& operator++() + { + MyBase::operator++(); + return *this; + } + + /// post-decrement (it--) + iterator operator--(int) + { + iterator result = *this; + MyBase::operator--(); + return result; + } + + /// pre-decrement (--it) + iterator& operator--() + { + MyBase::operator--(); + return *this; + } + + /// add to iterator + iterator& operator+=(difference_type i) + { + MyBase::operator+=(i); + return *this; + } + + /// subtract from iterator + iterator& operator-=(difference_type i) + { + MyBase::operator-=(i); + return *this; + } + + /// 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; + } + + difference_type operator-(const iterator& other) const + { + return MyBase::operator-(other); + } + + /// access to successor + reference operator[](difference_type n) const + { + return ((reference) MyBase::operator[](n)); + } + + /// return the value of an iterator + reference value() const + { + return ((reference) MyBase::value()); + } + }; + /// a reverse random access iterator for the basic_json class class reverse_iterator : private std::reverse_iterator {