Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
iterator.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstddef>
5#include <type_traits>
6
7namespace gaia {
8 namespace core {
11
17
19 namespace detail {
20 template <typename, typename = void>
21 struct iterator_traits_base {}; // empty for non-iterators
22
23 template <typename It>
24 struct iterator_traits_base<
25 It, std::void_t<
26 typename It::iterator_category, typename It::value_type, typename It::difference_type,
27 typename It::pointer, typename It::reference>> {
28 using iterator_category = typename It::iterator_category;
29 using value_type = typename It::value_type;
30 using difference_type = typename It::difference_type;
31 using pointer = typename It::pointer;
32 using reference = typename It::reference;
33 };
34
35 template <typename T, bool = std::is_object_v<T>>
36 struct iterator_traits_pointer_base {
37 using iterator_category = random_access_iterator_tag;
38 using value_type = std::remove_cv_t<T>;
39 using difference_type = std::ptrdiff_t;
40 using pointer = T*;
41 using reference = T&;
42 };
43
45 template <typename T>
46 struct iterator_traits_pointer_base<T, false> {};
47
49 template <typename It>
50 struct iterator_traits: iterator_traits_base<It> {};
51
52 // Iterator traits for pointers
53 template <typename T>
54 struct iterator_traits<T*>: iterator_traits_pointer_base<T> {};
55
56 template <typename It>
57 using iterator_cat_t = typename iterator_traits<It>::iterator_category;
58 } // namespace detail
60
63 template <typename T, typename = void>
64 [[maybe_unused]] constexpr bool is_iterator_v = false;
65
68 template <typename T>
69 [[maybe_unused]] constexpr bool is_iterator_v<T, std::void_t<detail::iterator_cat_t<T>>> = true;
70
71 template <typename T>
72 struct is_iterator: std::bool_constant<is_iterator_v<T>> {};
73
76 template <typename It>
77 [[maybe_unused]] constexpr bool is_input_iter_v =
78 std::is_convertible_v<detail::iterator_cat_t<It>, input_iterator_tag>;
79
82 template <typename It>
83 [[maybe_unused]] constexpr bool is_fwd_iter_v =
84 std::is_convertible_v<detail::iterator_cat_t<It>, forward_iterator_tag>;
85
88 template <typename It>
89 [[maybe_unused]] constexpr bool is_rev_iter_v =
90 std::is_convertible_v<detail::iterator_cat_t<It>, reverse_iterator_tag>;
91
94 template <typename It>
95 [[maybe_unused]] constexpr bool is_bidi_iter_v =
96 std::is_convertible_v<detail::iterator_cat_t<It>, bidirectional_iterator_tag>;
97
100 template <typename It>
101 [[maybe_unused]] constexpr bool is_random_iter_v =
102 std::is_convertible_v<detail::iterator_cat_t<It>, random_access_iterator_tag>;
103
106 template <typename It>
107 using iterator_ref_t = typename detail::iterator_traits<It>::reference;
108
111 template <typename It>
112 using iterator_value_t = typename detail::iterator_traits<It>::value_type;
113
116 template <typename It>
117 using iterator_diff_t = typename detail::iterator_traits<It>::difference_type;
118
121 template <typename... It>
122 using common_diff_t = std::common_type_t<iterator_diff_t<It>...>;
123
129 template <typename It>
130 constexpr iterator_diff_t<It> distance(It first, It last) {
131 if constexpr (std::is_pointer_v<It> || is_random_iter_v<It>)
132 return last - first;
133 else {
134 iterator_diff_t<It> offset{};
135 while (first != last) {
136 ++first;
137 ++offset;
138 }
139 return offset;
140 }
141 }
142 } // namespace core
143} // namespace gaia
Definition iterator.h:16
Definition iterator.h:12
Definition iterator.h:9
Definition iterator.h:72
Definition iterator.h:10
Definition iterator.h:13