matrix_thing/include/raii/rjp_iterator.hpp
2020-02-24 14:29:46 -08:00

140 lines
3.7 KiB
C++

/**
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 <http://www.gnu.org/licenses/>.
*/
#ifndef RJP_ITERATOR_HPP
#define RJP_ITERATOR_HPP
#include <rjp.h>
#include <utility> //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{0};
}
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