range.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #ifndef ENTT_META_RANGE_HPP
  2. #define ENTT_META_RANGE_HPP
  3. #include <compare>
  4. #include <concepts>
  5. #include <cstddef>
  6. #include "../core/fwd.hpp"
  7. #include "../core/iterator.hpp"
  8. #include "../stl/iterator.hpp"
  9. #include "../stl/utility.hpp"
  10. #include "context.hpp"
  11. namespace entt {
  12. /*! @cond ENTT_INTERNAL */
  13. namespace internal {
  14. struct meta_base_node;
  15. template<typename Type, typename It>
  16. struct meta_range_iterator final {
  17. using value_type = stl::pair<id_type, Type>;
  18. using pointer = input_iterator_pointer<value_type>;
  19. using reference = value_type;
  20. using difference_type = std::ptrdiff_t;
  21. using iterator_category = stl::input_iterator_tag;
  22. using iterator_concept = stl::random_access_iterator_tag;
  23. constexpr meta_range_iterator() noexcept
  24. : it{},
  25. ctx{} {}
  26. constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept
  27. : it{iter},
  28. ctx{&area} {}
  29. constexpr meta_range_iterator &operator++() noexcept {
  30. return ++it, *this;
  31. }
  32. constexpr meta_range_iterator operator++(int) noexcept {
  33. const meta_range_iterator orig = *this;
  34. return ++(*this), orig;
  35. }
  36. constexpr meta_range_iterator &operator--() noexcept {
  37. return --it, *this;
  38. }
  39. constexpr meta_range_iterator operator--(int) noexcept {
  40. const meta_range_iterator orig = *this;
  41. return operator--(), orig;
  42. }
  43. constexpr meta_range_iterator &operator+=(const difference_type value) noexcept {
  44. it += value;
  45. return *this;
  46. }
  47. constexpr meta_range_iterator operator+(const difference_type value) const noexcept {
  48. meta_range_iterator copy = *this;
  49. return (copy += value);
  50. }
  51. constexpr meta_range_iterator &operator-=(const difference_type value) noexcept {
  52. return (*this += -value);
  53. }
  54. constexpr meta_range_iterator operator-(const difference_type value) const noexcept {
  55. return (*this + -value);
  56. }
  57. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  58. if constexpr(stl::is_same_v<It, typename meta_context::container_type::const_iterator>) {
  59. return {it[value].first, Type{*ctx, *it[value].second}};
  60. } else {
  61. return {it[value].id, Type{*ctx, it[value]}};
  62. }
  63. }
  64. [[nodiscard]] constexpr pointer operator->() const noexcept {
  65. return operator*();
  66. }
  67. [[nodiscard]] constexpr reference operator*() const noexcept {
  68. return operator[](0);
  69. }
  70. [[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator &other) const noexcept {
  71. return it - other.it;
  72. }
  73. [[nodiscard]] constexpr bool operator==(const meta_range_iterator &other) const noexcept {
  74. return it == other.it;
  75. }
  76. [[nodiscard]] constexpr auto operator<=>(const meta_range_iterator &other) const noexcept {
  77. return it <=> other.it;
  78. }
  79. private:
  80. It it;
  81. const meta_ctx *ctx;
  82. };
  83. } // namespace internal
  84. /*! @endcond */
  85. /**
  86. * @brief Iterable range to use to iterate all types of meta objects.
  87. * @tparam Type Type of meta objects returned.
  88. * @tparam It Type of forward iterator.
  89. */
  90. template<typename Type, stl::forward_iterator It>
  91. using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
  92. } // namespace entt
  93. #endif