diff --git a/src/core/include/scene/unit.hpp b/src/core/include/scene/unit.hpp index 289c0bd..41ad459 100644 --- a/src/core/include/scene/unit.hpp +++ b/src/core/include/scene/unit.hpp @@ -207,7 +207,87 @@ namespace gkit::scene { private: std::atomic process_enabled = true; // process enabled flag - std::atomic ready_to_drop = false; // drop flag(mark as dead) + std::atomic ready_to_drop = false; // drop flag(mark as dead) + + public: + // iterator + class iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = Unit; + using difference_type = std::ptrdiff_t; + using pointer = Unit*; + using reference = Unit&; + + public: + iterator(Unit* owner, size_t pos); + auto operator*() -> reference const; + auto operator->() -> pointer const; + auto operator++() -> iterator&; + auto operator++(int) -> iterator; + auto operator--() -> iterator&; + auto operator--(int) -> iterator; + auto operator==(const iterator& other) const -> bool; + auto operator!=(const iterator& other) const -> bool; + + private: + Unit* m_owner; + size_t m_pos; + friend class Unit; + }; + + // Why this part didn't use auto, because it need to have a const_iterator use + // but auto could not allow two same function but with different return + // but begin() and end() need those two return + // So I will not change it + auto begin() -> iterator; + auto end() -> iterator; + + public: + // Next, we are going to write the const implementation of the iterator. + class const_iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = const Unit; + using difference_type = std::ptrdiff_t; + using pointer = const Unit*; + using reference = const Unit&; + + const_iterator(const Unit* owner, size_t pos); + auto operator*() -> reference const; + auto operator->() -> pointer const; + auto operator++() -> const_iterator&; + auto operator++(int) -> const_iterator; + auto operator--() -> const_iterator&; + auto operator--(int) -> const_iterator; + auto operator==(const const_iterator& other) const -> bool; + auto operator!=(const const_iterator& other) const -> bool; + + private: + const Unit* m_owner; + size_t m_pos; + }; + + auto begin() const -> const_iterator; + auto end() const -> const_iterator; + + auto cbegin() const -> const_iterator; + auto cend() const -> const_iterator; + + public: + // This is a reverse iterator, implemented using std::reverse_iterator. + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + auto rbegin() -> reverse_iterator; + auto rend() -> reverse_iterator; + + auto rbegin() const -> const_reverse_iterator; + auto rend() const -> const_reverse_iterator; + + auto crbegin() const -> const_reverse_iterator; + auto crend() const -> const_reverse_iterator; + }; // class Unit template diff --git a/src/core/scene/unit.cpp b/src/core/scene/unit.cpp index 63ba2c7..2c21eaa 100644 --- a/src/core/scene/unit.cpp +++ b/src/core/scene/unit.cpp @@ -184,3 +184,101 @@ auto gkit::scene::Unit::get_parent() noexcept -> std::optiona if (parent == nullptr) return std::nullopt; return std::ref(*parent); } + + +// iterator part use +gkit::scene::Unit::iterator::iterator(Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {} +auto gkit::scene::Unit::iterator::operator*() -> reference const { +auto child_opt = m_owner->get_available_child(static_cast(m_pos)); + return **child_opt; +} +auto gkit::scene::Unit::iterator::operator->() -> pointer const { + auto child_opt = m_owner->get_available_child(static_cast(m_pos)); + return *child_opt; +} +auto gkit::scene::Unit::iterator::operator++() -> iterator& { + ++m_pos; + return *this; +} +auto gkit::scene::Unit::iterator::operator++(int) -> iterator { + iterator tmp = *this; + ++(*this); + return tmp; +} +auto gkit::scene::Unit::iterator::operator--() -> iterator& { + --m_pos; + return *this; +} +auto gkit::scene::Unit::iterator::operator--(int) -> iterator { + iterator tmp = *this; + --(*this); + return tmp; +} +auto gkit::scene::Unit::iterator::operator==(const iterator& other) const -> bool { return m_owner == other.m_owner && m_pos == other.m_pos; } +auto gkit::scene::Unit::iterator::operator!=(const iterator& other) const -> bool { return !(*this == other); } + +auto gkit::scene::Unit::begin() -> iterator{ + return iterator(this, 0); +} + +auto gkit::scene::Unit::end() -> iterator{ + return iterator(this, active_index_cache.size()); +} + +// now is const_iterator use +gkit::scene::Unit::const_iterator::const_iterator(const Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {} + +auto gkit::scene::Unit::const_iterator::operator*() -> reference const { + auto child_opt = const_cast(m_owner)->get_available_child(static_cast(m_pos)); + return **child_opt; +} + +auto gkit::scene::Unit::const_iterator::operator->() -> pointer const { + auto child_opt = const_cast(m_owner)->get_available_child(static_cast(m_pos)); + return *child_opt; +} + +auto gkit::scene::Unit::const_iterator::operator++() -> const_iterator& { + ++m_pos; + return *this; +} +auto gkit::scene::Unit::const_iterator::operator++(int) -> const_iterator { + const_iterator tmp = *this; + ++(*this); + return tmp; +} +auto gkit::scene::Unit::const_iterator::operator--() -> const_iterator& { + --m_pos; + return *this; +} +auto gkit::scene::Unit::const_iterator::operator--(int) -> const_iterator { + const_iterator tmp = *this; + --(*this); + return tmp; +} + +auto gkit::scene::Unit::const_iterator::operator==(const const_iterator& other) const -> bool { return m_owner == other.m_owner && m_pos == other.m_pos; } +auto gkit::scene::Unit::const_iterator::operator!=(const const_iterator& other) const -> bool { return !(*this == other); } + +auto gkit::scene::Unit::begin() const -> const_iterator { + const_cast(this); + return const_iterator(this, 0); +} + +auto gkit::scene::Unit::end() const -> const_iterator { + const_cast(this); + return const_iterator(this, active_index_cache.size()); +} + +auto gkit::scene::Unit::cbegin() const -> const_iterator { return begin(); } +auto gkit::scene::Unit::cend() const -> const_iterator { return end(); } + +// This is a reverse iterator, implemented using std::reverse_iterator. +using reverse_iterator = std::reverse_iterator; +using const_reverse_iterator = std::reverse_iterator; +auto gkit::scene::Unit::rbegin() -> reverse_iterator { return reverse_iterator(end()); } +auto gkit::scene::Unit::rend() -> reverse_iterator { return reverse_iterator(begin()); } +auto gkit::scene::Unit::rbegin() const -> const_reverse_iterator { return const_reverse_iterator(end()); } +auto gkit::scene::Unit::rend() const -> const_reverse_iterator { return const_reverse_iterator(begin()); } +auto gkit::scene::Unit::crbegin() const -> const_reverse_iterator { return rbegin(); } +auto gkit::scene::Unit::crend() const -> const_reverse_iterator { return rend(); } \ No newline at end of file