1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ART_LIBARTBASE_BASE_ITERATION_RANGE_H_
18 #define ART_LIBARTBASE_BASE_ITERATION_RANGE_H_
19
20 #include <iterator>
21 #include <type_traits>
22
23 namespace art {
24
25 // Helper class that acts as a container for range-based loops, given an iteration
26 // range [first, last) defined by two iterators.
27 template <typename Iter>
28 class IterationRange {
29 public:
30 using iterator = Iter;
31 using difference_type = typename std::iterator_traits<Iter>::difference_type;
32 using value_type = typename std::iterator_traits<Iter>::value_type;
33 using pointer = typename std::iterator_traits<Iter>::pointer;
34 using reference = typename std::iterator_traits<Iter>::reference;
35
IterationRange(iterator first,iterator last)36 IterationRange(iterator first, iterator last) : first_(first), last_(last) { }
37
begin()38 iterator begin() const { return first_; }
end()39 iterator end() const { return last_; }
cbegin()40 iterator cbegin() const { return first_; }
cend()41 iterator cend() const { return last_; }
42
43 protected:
44 iterator first_;
45 iterator last_;
46 };
47
48 template <typename Iter>
MakeIterationRange(const Iter & begin_it,const Iter & end_it)49 inline IterationRange<Iter> MakeIterationRange(const Iter& begin_it, const Iter& end_it) {
50 return IterationRange<Iter>(begin_it, end_it);
51 }
52
53 template <typename List>
54 inline auto MakeIterationRange(List& list) -> IterationRange<decltype(list.begin())> {
55 static_assert(std::is_same_v<decltype(list.begin()), decltype(list.end())>,
56 "Different iterator types");
57 return MakeIterationRange(list.begin(), list.end());
58 }
59
60 template <typename Iter>
MakeEmptyIterationRange(const Iter & it)61 inline IterationRange<Iter> MakeEmptyIterationRange(const Iter& it) {
62 return IterationRange<Iter>(it, it);
63 }
64
65 template <typename Container>
ReverseRange(Container && c)66 inline auto ReverseRange(Container&& c) {
67 using riter = typename std::reverse_iterator<decltype(c.begin())>;
68 return MakeIterationRange(riter(c.end()), riter(c.begin()));
69 }
70
71 template <typename T, size_t size>
ReverseRange(T (& array)[size])72 inline auto ReverseRange(T (&array)[size]) {
73 return ReverseRange(MakeIterationRange<T*>(array, array+size));
74 }
75
76 } // namespace art
77
78 #endif // ART_LIBARTBASE_BASE_ITERATION_RANGE_H_
79