EnTT 4.0.0
Loading...
Searching...
No Matches
iterator.hpp
1#ifndef ENTT_STL_ITERATOR_HPP
2#define ENTT_STL_ITERATOR_HPP
3
5#if __has_include(<entt/ext/stl/iterator.hpp>)
6# include <entt/ext/stl/iterator.hpp>
7#else
8# include <iterator>
9# include <version>
10# include "../config/config.h"
11
12namespace entt::stl {
13
14using std::advance;
15using std::bidirectional_iterator_tag;
16using std::distance;
17using std::forward_iterator_tag;
18using std::input_iterator_tag;
19using std::iterator_traits;
20using std::make_reverse_iterator;
21using std::random_access_iterator_tag;
22using std::reverse_iterator;
23
24# ifndef ENTT_FORCE_STL
25# if defined(__cpp_lib_ranges)
26# define ENTT_HAS_ITERATOR_CONCEPTS
27
28using std::bidirectional_iterator;
29using std::forward_iterator;
30using std::input_iterator;
31using std::input_or_output_iterator;
32using std::output_iterator;
33using std::random_access_iterator;
34using std::sentinel_for;
35
36# endif
37# endif
38
39# ifndef ENTT_HAS_ITERATOR_CONCEPTS
40# include <concepts>
41# include <utility>
42
43namespace internal {
44
45template<typename It>
46concept has_iterator_category = requires {
47 typename std::iterator_traits<It>::iterator_category;
48};
49
50template<typename It>
51concept has_iterator_concept = has_iterator_category<It> && requires {
52 typename It::iterator_concept;
53};
54
55template<has_iterator_category It>
56struct iterator_tag {
57 using type = typename std::iterator_traits<It>::iterator_category;
58};
59
60template<has_iterator_concept It>
61struct iterator_tag<It> {
62 using type = typename It::iterator_concept;
63};
64
65template<typename It, typename Tag>
66concept has_iterator_tag = std::derived_from<typename iterator_tag<It>::type, Tag>;
67
68} // namespace internal
69
70// Bare minimum definitions to support broken platforms like PS4.
71// EnTT does not provide full featured definitions for iterator concepts.
72
73template<typename It>
74concept input_or_output_iterator = requires(It it) {
75 *it;
76 { ++it } -> std::same_as<It &>;
77 it++;
78};
79
80template<typename It>
81concept input_iterator = input_or_output_iterator<It> && internal::has_iterator_tag<It, std::input_iterator_tag>;
82
83template<typename It, typename Type>
84concept output_iterator = input_or_output_iterator<It> && requires(It it, Type &&value) {
85 *it++ = std::forward<Type>(value);
86};
87
88template<typename It>
89concept forward_iterator = input_iterator<It> && internal::has_iterator_tag<It, std::forward_iterator_tag>;
90
91template<typename It>
92concept bidirectional_iterator = forward_iterator<It> && internal::has_iterator_tag<It, std::bidirectional_iterator_tag>;
93
94template<typename It>
95concept random_access_iterator = bidirectional_iterator<It> && internal::has_iterator_tag<It, std::random_access_iterator_tag>;
96
97template<class Sentinel, typename It>
98concept sentinel_for = input_or_output_iterator<It> && requires(Sentinel sentinel, It it) {
99 { it == sentinel } -> std::same_as<bool>;
100};
101
102# endif
103
104} // namespace entt::stl
105#endif
107
108#undef ENTT_HAS_ITERATOR_CONCEPTS
109
110#endif
Custom EnTT namespace for the standard template library.
Definition entt.hpp:5