/** This file is a part of rexy's matrix client Copyright (C) 2019-2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifndef RJP_ITERATOR_HPP #define RJP_ITERATOR_HPP #include #include //exchange namespace raii{ class rjp_object_iterator { public: using iterator = RJP_object_iterator; using const_iterator = const iterator; private: RJP_value* m_root; RJP_object_iterator m_obj = {}; public: rjp_object_iterator(RJP_value* v):m_root(v){ if(m_root) rjp_init_object_iterator(&m_obj, m_root); } rjp_object_iterator(const rjp_object_iterator& e): rjp_object_iterator(e.m_root){} rjp_object_iterator(rjp_object_iterator&& e): m_root(std::exchange(e.m_root, nullptr)), m_obj(e.m_obj) { e.m_obj = {}; } rjp_object_iterator& operator=(rjp_object_iterator&& e){ std::swap(m_root, e.m_root); std::swap(m_obj, e.m_obj); return *this; } rjp_object_iterator& operator=(const rjp_object_iterator& e){ rjp_object_iterator it(e); *this = std::move(it); return *this; } ~rjp_object_iterator(void){ if(m_root) rjp_delete_object_iterator(&m_obj); } constexpr bool operator==(const rjp_object_iterator& e)const{ RJP_value* l = m_root, *r = e.m_root; if(l) l = rjp_object_iterator_current(&m_obj); if(r) r = rjp_object_iterator_current(&e.m_obj); return l == r; } constexpr bool operator!=(const rjp_object_iterator& e)const{ return !(*this == e); } rjp_object_iterator& operator++(void); RJP_value* operator*(void){ return rjp_object_iterator_current(&m_obj); } const RJP_value* operator*(void)const{ return rjp_object_iterator_current(&m_obj); } }; class rjp_array_iterator { public: using iterator = RJP_array_iterator*; using const_iterator = const iterator; private: RJP_value* m_root; RJP_array_iterator m_arr; public: rjp_array_iterator(RJP_value* v):m_root(v){ if(m_root) rjp_init_array_iterator(&m_arr, m_root); } rjp_array_iterator(rjp_array_iterator&& e): m_root(std::exchange(e.m_root, nullptr)) { m_arr = RJP_array_iterator{0}; } rjp_array_iterator(const rjp_array_iterator& e): rjp_array_iterator(e.m_root){} rjp_array_iterator& operator=(rjp_array_iterator&& e){ std::swap(m_root, e.m_root); std::swap(m_arr, e.m_arr); return *this; } rjp_array_iterator& operator=(const rjp_array_iterator& e){ rjp_array_iterator it(e); *this = std::move(it); return *this; } ~rjp_array_iterator(void){ if(m_root) rjp_delete_array_iterator(&m_arr); } constexpr bool operator==(const rjp_array_iterator& e)const{ RJP_value* l = m_root, *r = e.m_root; if(l) l = rjp_array_iterator_current(&m_arr); if(r) r = rjp_array_iterator_current(&e.m_arr); return l == r; } constexpr bool operator!=(const rjp_array_iterator& e)const{ return !(*this == e); } rjp_array_iterator& operator++(void); RJP_value* operator*(void){ return rjp_array_iterator_current(&m_arr); } const RJP_value* operator*(void)const{ return rjp_array_iterator_current(&m_arr); } }; } #endif