range.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #ifndef ENTT_META_RANGE_HPP
  2. #define ENTT_META_RANGE_HPP
  3. #include <cstddef>
  4. #include <iterator>
  5. #include <utility>
  6. #include "../core/fwd.hpp"
  7. #include "../core/iterator.hpp"
  8. #include "context.hpp"
  9. namespace entt {
  10. /**
  11. * @cond TURN_OFF_DOXYGEN
  12. * Internal details not to be documented.
  13. */
  14. namespace internal {
  15. template<typename Type, typename It>
  16. struct meta_range_iterator final {
  17. using difference_type = std::ptrdiff_t;
  18. using value_type = std::pair<id_type, Type>;
  19. using pointer = input_iterator_pointer<value_type>;
  20. using reference = value_type;
  21. using iterator_category = std::input_iterator_tag;
  22. using iterator_concept = std::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. 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. 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. return {it[value].first, Type{*ctx, it[value].second}};
  59. }
  60. [[nodiscard]] constexpr pointer operator->() const noexcept {
  61. return operator*();
  62. }
  63. [[nodiscard]] constexpr reference operator*() const noexcept {
  64. return {it->first, Type{*ctx, it->second}};
  65. }
  66. template<typename... Args>
  67. friend constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  68. template<typename... Args>
  69. friend constexpr bool operator==(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  70. template<typename... Args>
  71. friend constexpr bool operator<(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  72. private:
  73. It it;
  74. const meta_ctx *ctx;
  75. };
  76. template<typename... Args>
  77. [[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  78. return lhs.it - rhs.it;
  79. }
  80. template<typename... Args>
  81. [[nodiscard]] constexpr bool operator==(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  82. return lhs.it == rhs.it;
  83. }
  84. template<typename... Args>
  85. [[nodiscard]] constexpr bool operator!=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  86. return !(lhs == rhs);
  87. }
  88. template<typename... Args>
  89. [[nodiscard]] constexpr bool operator<(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  90. return lhs.it < rhs.it;
  91. }
  92. template<typename... Args>
  93. [[nodiscard]] constexpr bool operator>(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  94. return rhs < lhs;
  95. }
  96. template<typename... Args>
  97. [[nodiscard]] constexpr bool operator<=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  98. return !(lhs > rhs);
  99. }
  100. template<typename... Args>
  101. [[nodiscard]] constexpr bool operator>=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  102. return !(lhs < rhs);
  103. }
  104. } // namespace internal
  105. /**
  106. * Internal details not to be documented.
  107. * @endcond
  108. */
  109. /**
  110. * @brief Iterable range to use to iterate all types of meta objects.
  111. * @tparam Type Type of meta objects returned.
  112. * @tparam It Type of forward iterator.
  113. */
  114. template<typename Type, typename It>
  115. using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
  116. } // namespace entt
  117. #endif