#pragma once #include "container/stl_alias.hpp" #include "iterator/counting_iterator.hpp" struct flat_index_group { stl_vector_mp index_group{}; /// a list of indices in the group stl_vector_mp start_indices{}; /// a list of start indices for each group in the flat index group inline size_t size() const { return start_indices.size() - 1; } struct group_index_looper { auto begin() const { return counting_iterator{0}; } auto end() const { return counting_iterator{static_cast(parent_group.size())}; } const flat_index_group& parent_group{}; }; auto group_indices() const { return group_index_looper{*this}; } struct group_looper { auto begin() const { return std::next(parent_group.index_group.begin(), *(parent_group.start_indices.begin() + group_idx)); } auto end() const { return std::next(parent_group.index_group.begin(), *(parent_group.start_indices.begin() + group_idx + 1)); } const flat_index_group& parent_group{}; const uint32_t group_idx{}; }; auto group(uint32_t group_idx) const { return group_looper{*this, group_idx}; } inline auto group_index_iter_begin() const { return counting_iterator{0}; } inline auto group_index_iter_end() const { return counting_iterator{static_cast(size())}; } inline auto group_begin(uint32_t group_idx) const { return std::next(index_group.begin(), *(start_indices.begin() + group_idx)); } inline auto group_end(uint32_t group_idx) const { return std::next(index_group.begin(), *(start_indices.begin() + group_idx + 1)); } };