range.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #ifndef ENTT_META_RANGE_HPP
  2. #define ENTT_META_RANGE_HPP
  3. #include <cstddef>
  4. #include <iterator>
  5. #include "internal.hpp"
  6. namespace entt {
  7. /**
  8. * @brief Iterable range to use to iterate all types of meta objects.
  9. * @tparam Type Type of meta objects iterated.
  10. */
  11. template<typename Type>
  12. class meta_range {
  13. struct range_iterator {
  14. using difference_type = std::ptrdiff_t;
  15. using value_type = Type;
  16. using pointer = void;
  17. using reference = value_type;
  18. using iterator_category = std::input_iterator_tag;
  19. using node_type = typename Type::node_type;
  20. range_iterator() ENTT_NOEXCEPT = default;
  21. range_iterator(node_type *head) ENTT_NOEXCEPT
  22. : it{head}
  23. {}
  24. range_iterator & operator++() ENTT_NOEXCEPT {
  25. return ++it, *this;
  26. }
  27. range_iterator operator++(int) ENTT_NOEXCEPT {
  28. range_iterator orig = *this;
  29. return ++(*this), orig;
  30. }
  31. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  32. return it.operator->();
  33. }
  34. [[nodiscard]] bool operator==(const range_iterator &other) const ENTT_NOEXCEPT {
  35. return other.it == it;
  36. }
  37. [[nodiscard]] bool operator!=(const range_iterator &other) const ENTT_NOEXCEPT {
  38. return !(*this == other);
  39. }
  40. private:
  41. typename internal::meta_range<node_type>::iterator it{};
  42. };
  43. public:
  44. /*! @brief Node type. */
  45. using node_type = typename Type::node_type;
  46. /*! @brief Input iterator type. */
  47. using iterator = range_iterator;
  48. /*! @brief Default constructor. */
  49. meta_range() ENTT_NOEXCEPT = default;
  50. /**
  51. * @brief Constructs a meta range from a given node.
  52. * @param head The underlying node with which to construct the range.
  53. */
  54. meta_range(node_type *head)
  55. : node{head}
  56. {}
  57. /**
  58. * @brief Returns an iterator to the beginning.
  59. * @return An iterator to the first meta object of the range.
  60. */
  61. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  62. return iterator{node};
  63. }
  64. /**
  65. * @brief Returns an iterator to the end.
  66. * @return An iterator to the element following the last meta object of the
  67. * range.
  68. */
  69. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  70. return iterator{};
  71. }
  72. private:
  73. node_type *node{nullptr};
  74. };
  75. }
  76. #endif