added schema node iterator

This commit is contained in:
Sascha Kühl 2025-02-03 22:29:47 +01:00
parent 89fb7e8a8d
commit 6a5974337d
6 changed files with 268 additions and 2 deletions

View File

@ -3,6 +3,7 @@
#include "matador/object/error_code.hpp"
#include "matador/object/schema_node.hpp"
#include "matador/object/schema_node_iterator.hpp"
#include "matador/utils/result.hpp"
#include "matador/utils/error.hpp"
@ -15,6 +16,8 @@ namespace matador::object {
class schema {
public:
typedef const_schema_node_iterator const_iterator; /**< Shortcut for the list const iterator. */
schema();
template <typename Type>
@ -36,6 +39,20 @@ public:
return utils::ok<void>();
}
/**
* Return the first schema node.
*
* @return The first schema node iterator.
*/
[[nodiscard]] const_iterator begin() const;
/**
* Return the last schema node.
*
* @return The last schema node iterator.
*/
[[nodiscard]] const_iterator end() const;
[[nodiscard]] bool empty() const;
[[nodiscard]] size_t size() const;

View File

@ -56,7 +56,8 @@ private:
private:
friend schema;
friend class schema;
friend class const_schema_node_iterator;
schema &schema_;
std::unique_ptr<basic_object_info> info_;

View File

@ -0,0 +1,130 @@
#ifndef SCHEMA_NODE_ITERATOR_HPP
#define SCHEMA_NODE_ITERATOR_HPP
#include "matador/object/schema_node.hpp"
#include <iterator>
namespace matador::object {
class const_schema_node_iterator {
public:
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = schema_node;
using pointer = value_type*;
using reference = value_type&;
/**
* Creates an empty iterator
*/
const_schema_node_iterator() = default;
/**
* @brief Creates an iterator for a concrete type.
*
* This constructor creates an iterator for a concrete
* type and a concrete object.
*
* @param node The schema node of the object
*/
explicit const_schema_node_iterator(std::shared_ptr<value_type> node);
/**
* Copy from a given const_object_view_iterator.
*
* @param x The prototype_iterator to copy from.
*/
const_schema_node_iterator(const const_schema_node_iterator &x) = default;
/**
* Assign from a given prototype_iterator.
*
* @param x The prototype_iterator to assign from.
* @return The assigned prototype_iterator.
*/
const_schema_node_iterator& operator=(const const_schema_node_iterator &x) = default;
~const_schema_node_iterator() = default;
/**
* @brief Compares this with another iterators.
*
* Compares this with another iterators. Returns true
* if the iterators node prototype_type are the same.
*
* @param i The iterator to compare with.
* @return True if the iterators are the same.
*/
bool operator==(const const_schema_node_iterator &i) const;
/**
* @brief Compares this with another iterators.
*
* Compares this with another iterators. Returns true
* if the iterators node prototype_node are not the same.
*
* @param i The iterator to compare with.
* @return True if the iterators are not the same.
*/
bool operator!=(const const_schema_node_iterator &i) const;
/**
* Pre increments the iterator
*
* @return Returns iterators successor.
*/
const_schema_node_iterator& operator++();
/**
* Post increments the iterator
*
* @return Returns iterator before incrementing.
*/
const_schema_node_iterator operator++(int);
/**
* Pre increments the iterator
*
* @return Returns iterators predecessor.
*/
const_schema_node_iterator& operator--();
/**
* Post decrements the iterator
*
* @return Returns iterator before decrementing.
*/
const_schema_node_iterator operator--(int);
/**
* Returns the pointer to the node.
*
* @return The pointer to the node.
*/
pointer operator->() const;
/**
* Returns the node.
*
* @return The iterators underlying node.
*/
const reference operator*() const;
/**
* Returns the pointer to the node.
*
* @return The pointer to the node.
*/
[[nodiscard]] pointer get() const;
private:
void increment();
void decrement();
private:
std::shared_ptr<value_type> node_;
};
}
#endif //SCHEMA_NODE_ITERATOR_HPP

View File

@ -47,6 +47,8 @@ add_library(matador-core STATIC
object/schema.cpp
object/schema_node.cpp
object/basic_object_info.cpp
../../include/matador/object/schema_node_iterator.hpp
object/schema_node_iterator.cpp
)
target_link_libraries(matador-core ${CMAKE_DL_LIBS})

View File

@ -14,11 +14,21 @@ schema::schema()
root_->last_child_->previous_sibling_ = root_->first_child_;
}
schema::const_iterator schema::begin() const {
return const_iterator(root_->first_child_->next_sibling_);
}
schema::const_iterator schema::end() const {
return const_iterator(root_->last_child_);
}
bool schema::empty() const {
return root_->first_child_ == root_->last_child_->previous_sibling_;
}
size_t schema::size() const { return 0; }
size_t schema::size() const {
return static_cast<size_t>(std::distance(begin(), end()));
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::string &parent) {

View File

@ -0,0 +1,106 @@
#include <utility>
#include "matador/object/schema_node_iterator.hpp"
namespace matador::object {
const_schema_node_iterator::const_schema_node_iterator(std::shared_ptr<value_type> node)
: node_(std::move(node))
{}
bool const_schema_node_iterator::operator==(const const_schema_node_iterator &i) const
{
return (node_ == i.node_);
}
bool const_schema_node_iterator::operator!=(const const_schema_node_iterator &i) const
{
return !operator==(i);
}
const_schema_node_iterator& const_schema_node_iterator::operator++()
{
increment();
return *this;
}
const_schema_node_iterator const_schema_node_iterator::operator++(int)
{
const std::shared_ptr<value_type> tmp = node_;
increment();
return const_schema_node_iterator(tmp);
}
const_schema_node_iterator& const_schema_node_iterator::operator--()
{
decrement();
return *this;
}
const_schema_node_iterator const_schema_node_iterator::operator--(int)
{
const std::shared_ptr<value_type> tmp = node_;
decrement();
return const_schema_node_iterator(tmp);
}
const_schema_node_iterator::pointer const_schema_node_iterator::operator->() const
{
return node_.get();
}
const_schema_node_iterator::reference const_schema_node_iterator::operator*() const
{
return *node_;
}
const_schema_node_iterator::pointer const_schema_node_iterator::get() const
{
return node_.get();
}
void const_schema_node_iterator::increment()
{
if (!node_) {
return;
}
// if we have a child, child is the next iterator to return
// (if we don't do iterate over the siblings)
if (node_->first_child_ && node_->first_child_->next_sibling_ != node_->last_child_) {
node_ = node_->first_child_->next_sibling_;
} else {
// if there is no child, we check for sibling
// if there is a sibling, this is our next iterator to return
// if not, we go back to the parent
std::shared_ptr<value_type> node = node_;
while (node_->parent_ && node_->next_sibling_ == node_->parent_->last_child_) {
node = node->parent_;
}
node_ = node_->next_sibling_;
}
}
void const_schema_node_iterator::decrement()
{
if (!node_) {
return;
}
// if node has a previous sibling, we set it
// as our next iterator. then we check if there
// are last children. if so, we set the last-last
// child as our iterator
if (node_->previous_sibling_ && node_->previous_sibling_->previous_sibling_) {
std::shared_ptr<value_type> node = node_->previous_sibling_;
while (node_->last_child_ && node_->first_child_->next_sibling_ != node_->last_child_) {
node = node->last_child_->previous_sibling_;
}
node_ = node;
// if there is no previous sibling, our next iterator
// is the parent of the node
} else {
node_ = node_->parent_;
}
}
}