1
+ //
2
+ // This is a derivative work. originally part of the LLVM Project.
3
+ // Licensed under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ // Copyright (c) 2023 Vinnie Falco ([email protected] )
8
+ //
9
+ // Official repository: https://github.com/cppalliance/mrdox
10
+ //
11
+
12
+ #ifndef MRDOX_SUPPORT_RANGEFOR_HPP
13
+ #define MRDOX_SUPPORT_RANGEFOR_HPP
14
+
15
+ #include < mrdox/Platform.hpp>
16
+
17
+ namespace clang {
18
+ namespace mrdox {
19
+
20
+ /* * Range to help range-for loops identify first and last.
21
+ */
22
+ template <class Container >
23
+ class RangeFor
24
+ {
25
+ Container const & C_;
26
+
27
+ public:
28
+ struct value_type ;
29
+ using size_type = std::size_t ;
30
+ using difference_type = std::ptrdiff_t ;
31
+ using pointer = value_type*;
32
+ using reference = value_type&;
33
+ using const_pointer = value_type const *;
34
+ using const_reference = value_type const &;
35
+
36
+ class iterator ;
37
+
38
+ explicit
39
+ RangeFor (Container const & C) noexcept
40
+ : C_(C)
41
+ {
42
+ }
43
+
44
+ iterator begin () const noexcept ;
45
+ iterator end () const noexcept ;
46
+ };
47
+
48
+ // ------------------------------------------------
49
+
50
+ template <class Container >
51
+ struct RangeFor <Container>::value_type
52
+ {
53
+ typename Container::value_type const & value;
54
+ bool const first;
55
+ bool const last;
56
+
57
+ value_type const * operator ->() const noexcept
58
+ {
59
+ return this ;
60
+ }
61
+ };
62
+
63
+ // ------------------------------------------------
64
+
65
+ template <class Container >
66
+ class RangeFor <Container>::iterator
67
+ {
68
+ using const_iterator =
69
+ typename Container::const_iterator;
70
+
71
+ const_iterator it_{};
72
+ const_iterator begin_;
73
+ const_iterator last_;
74
+ const_iterator end_;
75
+
76
+ friend class RangeFor ;
77
+ friend struct value_type ;
78
+
79
+ iterator (
80
+ Container const & C,
81
+ const_iterator it) noexcept
82
+ : it_(it)
83
+ , begin_(C.begin())
84
+ , last_(C.begin() != C.end() ?
85
+ std::prev (C.end()) : C.end())
86
+ , end_(C.end())
87
+ {
88
+ }
89
+
90
+ public:
91
+ using value_type = typename RangeFor<Container>::value_type;
92
+ using pointer = void ;
93
+ using reference = value_type;
94
+ using size_type = std::size_t ;
95
+ using iterator_category = typename
96
+ std::iterator_traits<typename Container::iterator>::iterator_category;
97
+
98
+ iterator () = default;
99
+ iterator (iterator const &) = default;
100
+ iterator& operator =(
101
+ iterator const &) = default ;
102
+
103
+ iterator& operator ++() noexcept
104
+ {
105
+ ++it_;
106
+ return *this ;
107
+ }
108
+
109
+ iterator operator ++(int ) noexcept
110
+ {
111
+ auto temp = *this ;
112
+ ++temp;
113
+ return temp;
114
+ }
115
+
116
+ reference operator ->() const noexcept
117
+ {
118
+ return value_type{
119
+ *it_,
120
+ it_ == begin_,
121
+ it_ == last_ };
122
+ }
123
+
124
+ reference operator *() const noexcept
125
+ {
126
+ return value_type{
127
+ *it_,
128
+ it_ == begin_,
129
+ it_ == last_ };
130
+ }
131
+
132
+ bool operator ==(iterator const & it) const noexcept
133
+ {
134
+ return it_ == it.it_ ;
135
+ }
136
+
137
+ bool operator !=(iterator const & it) const noexcept
138
+ {
139
+ return it_ != it.it_ ;
140
+ }
141
+ };
142
+
143
+ // ------------------------------------------------
144
+
145
+ template <class Container >
146
+ RangeFor (Container const &) -> RangeFor<Container>;
147
+
148
+ template <class Container >
149
+ auto RangeFor<Container>::begin() const noexcept ->
150
+ iterator
151
+ {
152
+ return iterator (C_, C_.begin ());
153
+ }
154
+
155
+ template <class Container >
156
+ auto RangeFor<Container>::end() const noexcept ->
157
+ iterator
158
+ {
159
+ return iterator (C_, C_.end ());
160
+ }
161
+
162
+ } // mrdox
163
+ } // clang
164
+
165
+ #endif
0 commit comments