|
|
- #pragma once
-
- #include <gp/utils/iterators/iterator_properties.hpp>
-
- #include <cstddef>
- #include <cstdint>
-
- namespace gp {
-
- struct index_to_1 {
- size_t value;
-
- index_to_1(size_t v) : value{v + 1}
- {}
-
- void left() {
- value <<= 1;
- }
-
- void right() {
- value = (value << 1) + 1;
- }
-
- void up() {
- value >>= 1;
- }
-
- bool is_right() const {
- return value & 1;
- }
-
- bool is_left() const {
- return !(value & 1);
- }
-
- bool is_root() const {
- return value == 1;
- }
-
- operator size_t() {
- return value - 1;
- }
- };
-
- template<typename reflect, typename T, int sign = 1>
- struct flat_tree_iterator {
- reflect& tree;
- size_t index;
-
- bool has_right(index_to_1 v) const {
- v.right();
- return (v < tree.data().size()) && (tree.data()[v].has_value());
- }
-
- bool has_left(index_to_1 v) const {
- v.left();
- return (v < tree.data().size()) && (tree.data()[v].has_value());
- }
-
- flat_tree_iterator& operator++() {
- index = next();
- return *this;
- }
-
- flat_tree_iterator operator++(int) {
- auto cpy = *this;
- index = next();
- return cpy;
- }
-
- size_t next() const {
- index_to_1 it{index};
-
- enum class cases {
- right_climber,
- left_climber,
- descender,
- starter
- };
-
- const cases current_case = [&](){
- if(index == (size_t)-1) {
- return cases::starter;
- } else if(has_right(it)) {
- return cases::descender;
- } else if(it.is_left()) {
- return cases::left_climber;
- } else {
- return cases::right_climber;
- }
- }();
-
- switch(current_case) {
- case cases::starter: {
- it = index_to_1{0};
- while(has_left(it)) {
- it.left();
- }
- } break;
- case cases::descender: {
- it.right();
- while(has_left(it)) {
- it.left();
- }
- } break;
- case cases::left_climber: {
- it.up();
- } break;
- case cases::right_climber: {
- while(it.is_right()) {
- it.up();
- }
- if(it.is_root()) {
- it.value = -1;
- }
- } break;
- }
- return it;
- }
-
- bool operator!=(flat_tree_iterator rhs) {
- return index != rhs.index;
- }
-
- T& operator*() {
- return tree.data_[index].value();
- }
- };
- }
|