xref: /aosp_15_r20/system/libvintf/include/vintf/MapValueIterator.h (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
1 /*
2  * Copyright (C) 2017 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 
18 #ifndef ANDROID_VINTF_MAP_VALUE_ITERATOR_H
19 #define ANDROID_VINTF_MAP_VALUE_ITERATOR_H
20 
21 #include <iterator>
22 #include <map>
23 
24 namespace android {
25 namespace vintf {
26 
27 template<typename Map>
28 struct MapIterTypes {
29     using K = typename Map::key_type;
30     using V = typename Map::mapped_type;
31 
32     // Iterator over all values of a Map
33     template<bool is_const>
34     struct IteratorImpl
35     {
36         using iterator_category = std::bidirectional_iterator_tag;
37         using value_type = V;
38         using difference_type = ptrdiff_t;
39         using pointer = typename std::conditional<is_const, const V *, V *>::type;
40         using reference = typename std::conditional<is_const, const V &, V &>::type;
41 
42         using map_iter = typename std::conditional<is_const,
43                 typename Map::const_iterator, typename Map::iterator>::type;
44 
IteratorImplMapIterTypes::IteratorImpl45         IteratorImpl(map_iter i) : mIter(i) {}
46 
47         inline IteratorImpl &operator++()    {
48             mIter++;
49             return *this;
50         }
51         inline IteratorImpl  operator++(int) {
52             IteratorImpl i = *this;
53             mIter++;
54             return i;
55         }
56         inline IteratorImpl &operator--()    {
57             mIter--;
58             return *this;
59         }
60         inline IteratorImpl  operator--(int) {
61             IteratorImpl i = *this;
62             mIter--;
63             return i;
64         }
65         inline reference operator*() const  { return mIter->second; }
66         inline pointer operator->() const { return &(mIter->second); }
67         inline bool operator==(const IteratorImpl &rhs) const { return mIter == rhs.mIter; }
68         inline bool operator!=(const IteratorImpl &rhs) const { return mIter != rhs.mIter; }
69 
70     private:
71         map_iter mIter;
72     };
73 
74     using ValueIterator = IteratorImpl<false>;
75     using ConstValueIterator = IteratorImpl<true>;
76 
77     template<bool is_const>
78     struct IterableImpl {
79         using map_ref = typename std::conditional<is_const, const Map &, Map &>::type;
IterableImplMapIterTypes::IterableImpl80         IterableImpl(map_ref map) : mMap(map) {}
81 
beginMapIterTypes::IterableImpl82         IteratorImpl<is_const> begin() const {
83             return IteratorImpl<is_const>(mMap.begin());
84         }
85 
endMapIterTypes::IterableImpl86         IteratorImpl<is_const> end() const {
87             return IteratorImpl<is_const>(mMap.end());
88         }
89 
emptyMapIterTypes::IterableImpl90         bool empty() const { return begin() == end(); }
91 
92        private:
93         map_ref mMap;
94     };
95 
96     template <bool is_const>
97     struct RangeImpl {
98         using iter_type = typename std::conditional<is_const, typename Map::const_iterator,
99                                                     typename Map::iterator>::type;
100         using range_type = std::pair<iter_type, iter_type>;
RangeImplMapIterTypes::RangeImpl101         RangeImpl(range_type r) : mRange(r) {}
beginMapIterTypes::RangeImpl102         IteratorImpl<is_const> begin() const { return mRange.first; }
endMapIterTypes::RangeImpl103         IteratorImpl<is_const> end() const { return mRange.second; }
emptyMapIterTypes::RangeImpl104         bool empty() const { return begin() == end(); }
105 
106        private:
107         range_type mRange;
108     };
109 
110     using ValueIterable = IterableImpl<false>;
111     using ConstValueIterable = IterableImpl<true>;
112 };
113 
114 template<typename K, typename V>
115 using ConstMapValueIterable = typename MapIterTypes<std::map<K, V>>::ConstValueIterable;
116 template<typename K, typename V>
117 using ConstMultiMapValueIterable = typename MapIterTypes<std::multimap<K, V>>::ConstValueIterable;
118 template <typename K, typename V>
119 using MapValueIterable = typename MapIterTypes<std::map<K, V>>::ValueIterable;
120 template <typename K, typename V>
121 using MultiMapValueIterable = typename MapIterTypes<std::multimap<K, V>>::ValueIterable;
122 
123 template<typename K, typename V>
iterateValues(const std::map<K,V> & map)124 ConstMapValueIterable<K, V> iterateValues(const std::map<K, V> &map) {
125     return map;
126 }
127 template<typename K, typename V>
iterateValues(const std::multimap<K,V> & map)128 ConstMultiMapValueIterable<K, V> iterateValues(const std::multimap<K, V> &map) {
129     return map;
130 }
131 template <typename K, typename V>
iterateValues(std::map<K,V> & map)132 MapValueIterable<K, V> iterateValues(std::map<K, V>& map) {
133     return map;
134 }
135 template <typename K, typename V>
iterateValues(std::multimap<K,V> & map)136 MultiMapValueIterable<K, V> iterateValues(std::multimap<K, V>& map) {
137     return map;
138 }
139 
140 template <typename K, typename V>
iterateValues(const std::multimap<K,V> & map,const K & key)141 typename MapIterTypes<std::multimap<K, V>>::template RangeImpl<true> iterateValues(
142     const std::multimap<K, V>& map, const K& key) {
143     return map.equal_range(key);
144 }
145 
146 } // namespace vintf
147 } // namespace android
148 
149 #endif // ANDROID_VINTF_MAP_VALUE_ITERATOR_H
150