1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*70a7ec85SAndroid Build Coastguard Worker *
4*70a7ec85SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*70a7ec85SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*70a7ec85SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*70a7ec85SAndroid Build Coastguard Worker *
8*70a7ec85SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*70a7ec85SAndroid Build Coastguard Worker *
10*70a7ec85SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*70a7ec85SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*70a7ec85SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*70a7ec85SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*70a7ec85SAndroid Build Coastguard Worker * limitations under the License.
15*70a7ec85SAndroid Build Coastguard Worker */
16*70a7ec85SAndroid Build Coastguard Worker
17*70a7ec85SAndroid Build Coastguard Worker
18*70a7ec85SAndroid Build Coastguard Worker #ifndef ANDROID_VINTF_MAP_VALUE_ITERATOR_H
19*70a7ec85SAndroid Build Coastguard Worker #define ANDROID_VINTF_MAP_VALUE_ITERATOR_H
20*70a7ec85SAndroid Build Coastguard Worker
21*70a7ec85SAndroid Build Coastguard Worker #include <iterator>
22*70a7ec85SAndroid Build Coastguard Worker #include <map>
23*70a7ec85SAndroid Build Coastguard Worker
24*70a7ec85SAndroid Build Coastguard Worker namespace android {
25*70a7ec85SAndroid Build Coastguard Worker namespace vintf {
26*70a7ec85SAndroid Build Coastguard Worker
27*70a7ec85SAndroid Build Coastguard Worker template<typename Map>
28*70a7ec85SAndroid Build Coastguard Worker struct MapIterTypes {
29*70a7ec85SAndroid Build Coastguard Worker using K = typename Map::key_type;
30*70a7ec85SAndroid Build Coastguard Worker using V = typename Map::mapped_type;
31*70a7ec85SAndroid Build Coastguard Worker
32*70a7ec85SAndroid Build Coastguard Worker // Iterator over all values of a Map
33*70a7ec85SAndroid Build Coastguard Worker template<bool is_const>
34*70a7ec85SAndroid Build Coastguard Worker struct IteratorImpl
35*70a7ec85SAndroid Build Coastguard Worker {
36*70a7ec85SAndroid Build Coastguard Worker using iterator_category = std::bidirectional_iterator_tag;
37*70a7ec85SAndroid Build Coastguard Worker using value_type = V;
38*70a7ec85SAndroid Build Coastguard Worker using difference_type = ptrdiff_t;
39*70a7ec85SAndroid Build Coastguard Worker using pointer = typename std::conditional<is_const, const V *, V *>::type;
40*70a7ec85SAndroid Build Coastguard Worker using reference = typename std::conditional<is_const, const V &, V &>::type;
41*70a7ec85SAndroid Build Coastguard Worker
42*70a7ec85SAndroid Build Coastguard Worker using map_iter = typename std::conditional<is_const,
43*70a7ec85SAndroid Build Coastguard Worker typename Map::const_iterator, typename Map::iterator>::type;
44*70a7ec85SAndroid Build Coastguard Worker
IteratorImplMapIterTypes::IteratorImpl45*70a7ec85SAndroid Build Coastguard Worker IteratorImpl(map_iter i) : mIter(i) {}
46*70a7ec85SAndroid Build Coastguard Worker
47*70a7ec85SAndroid Build Coastguard Worker inline IteratorImpl &operator++() {
48*70a7ec85SAndroid Build Coastguard Worker mIter++;
49*70a7ec85SAndroid Build Coastguard Worker return *this;
50*70a7ec85SAndroid Build Coastguard Worker }
51*70a7ec85SAndroid Build Coastguard Worker inline IteratorImpl operator++(int) {
52*70a7ec85SAndroid Build Coastguard Worker IteratorImpl i = *this;
53*70a7ec85SAndroid Build Coastguard Worker mIter++;
54*70a7ec85SAndroid Build Coastguard Worker return i;
55*70a7ec85SAndroid Build Coastguard Worker }
56*70a7ec85SAndroid Build Coastguard Worker inline IteratorImpl &operator--() {
57*70a7ec85SAndroid Build Coastguard Worker mIter--;
58*70a7ec85SAndroid Build Coastguard Worker return *this;
59*70a7ec85SAndroid Build Coastguard Worker }
60*70a7ec85SAndroid Build Coastguard Worker inline IteratorImpl operator--(int) {
61*70a7ec85SAndroid Build Coastguard Worker IteratorImpl i = *this;
62*70a7ec85SAndroid Build Coastguard Worker mIter--;
63*70a7ec85SAndroid Build Coastguard Worker return i;
64*70a7ec85SAndroid Build Coastguard Worker }
65*70a7ec85SAndroid Build Coastguard Worker inline reference operator*() const { return mIter->second; }
66*70a7ec85SAndroid Build Coastguard Worker inline pointer operator->() const { return &(mIter->second); }
67*70a7ec85SAndroid Build Coastguard Worker inline bool operator==(const IteratorImpl &rhs) const { return mIter == rhs.mIter; }
68*70a7ec85SAndroid Build Coastguard Worker inline bool operator!=(const IteratorImpl &rhs) const { return mIter != rhs.mIter; }
69*70a7ec85SAndroid Build Coastguard Worker
70*70a7ec85SAndroid Build Coastguard Worker private:
71*70a7ec85SAndroid Build Coastguard Worker map_iter mIter;
72*70a7ec85SAndroid Build Coastguard Worker };
73*70a7ec85SAndroid Build Coastguard Worker
74*70a7ec85SAndroid Build Coastguard Worker using ValueIterator = IteratorImpl<false>;
75*70a7ec85SAndroid Build Coastguard Worker using ConstValueIterator = IteratorImpl<true>;
76*70a7ec85SAndroid Build Coastguard Worker
77*70a7ec85SAndroid Build Coastguard Worker template<bool is_const>
78*70a7ec85SAndroid Build Coastguard Worker struct IterableImpl {
79*70a7ec85SAndroid Build Coastguard Worker using map_ref = typename std::conditional<is_const, const Map &, Map &>::type;
IterableImplMapIterTypes::IterableImpl80*70a7ec85SAndroid Build Coastguard Worker IterableImpl(map_ref map) : mMap(map) {}
81*70a7ec85SAndroid Build Coastguard Worker
beginMapIterTypes::IterableImpl82*70a7ec85SAndroid Build Coastguard Worker IteratorImpl<is_const> begin() const {
83*70a7ec85SAndroid Build Coastguard Worker return IteratorImpl<is_const>(mMap.begin());
84*70a7ec85SAndroid Build Coastguard Worker }
85*70a7ec85SAndroid Build Coastguard Worker
endMapIterTypes::IterableImpl86*70a7ec85SAndroid Build Coastguard Worker IteratorImpl<is_const> end() const {
87*70a7ec85SAndroid Build Coastguard Worker return IteratorImpl<is_const>(mMap.end());
88*70a7ec85SAndroid Build Coastguard Worker }
89*70a7ec85SAndroid Build Coastguard Worker
emptyMapIterTypes::IterableImpl90*70a7ec85SAndroid Build Coastguard Worker bool empty() const { return begin() == end(); }
91*70a7ec85SAndroid Build Coastguard Worker
92*70a7ec85SAndroid Build Coastguard Worker private:
93*70a7ec85SAndroid Build Coastguard Worker map_ref mMap;
94*70a7ec85SAndroid Build Coastguard Worker };
95*70a7ec85SAndroid Build Coastguard Worker
96*70a7ec85SAndroid Build Coastguard Worker template <bool is_const>
97*70a7ec85SAndroid Build Coastguard Worker struct RangeImpl {
98*70a7ec85SAndroid Build Coastguard Worker using iter_type = typename std::conditional<is_const, typename Map::const_iterator,
99*70a7ec85SAndroid Build Coastguard Worker typename Map::iterator>::type;
100*70a7ec85SAndroid Build Coastguard Worker using range_type = std::pair<iter_type, iter_type>;
RangeImplMapIterTypes::RangeImpl101*70a7ec85SAndroid Build Coastguard Worker RangeImpl(range_type r) : mRange(r) {}
beginMapIterTypes::RangeImpl102*70a7ec85SAndroid Build Coastguard Worker IteratorImpl<is_const> begin() const { return mRange.first; }
endMapIterTypes::RangeImpl103*70a7ec85SAndroid Build Coastguard Worker IteratorImpl<is_const> end() const { return mRange.second; }
emptyMapIterTypes::RangeImpl104*70a7ec85SAndroid Build Coastguard Worker bool empty() const { return begin() == end(); }
105*70a7ec85SAndroid Build Coastguard Worker
106*70a7ec85SAndroid Build Coastguard Worker private:
107*70a7ec85SAndroid Build Coastguard Worker range_type mRange;
108*70a7ec85SAndroid Build Coastguard Worker };
109*70a7ec85SAndroid Build Coastguard Worker
110*70a7ec85SAndroid Build Coastguard Worker using ValueIterable = IterableImpl<false>;
111*70a7ec85SAndroid Build Coastguard Worker using ConstValueIterable = IterableImpl<true>;
112*70a7ec85SAndroid Build Coastguard Worker };
113*70a7ec85SAndroid Build Coastguard Worker
114*70a7ec85SAndroid Build Coastguard Worker template<typename K, typename V>
115*70a7ec85SAndroid Build Coastguard Worker using ConstMapValueIterable = typename MapIterTypes<std::map<K, V>>::ConstValueIterable;
116*70a7ec85SAndroid Build Coastguard Worker template<typename K, typename V>
117*70a7ec85SAndroid Build Coastguard Worker using ConstMultiMapValueIterable = typename MapIterTypes<std::multimap<K, V>>::ConstValueIterable;
118*70a7ec85SAndroid Build Coastguard Worker template <typename K, typename V>
119*70a7ec85SAndroid Build Coastguard Worker using MapValueIterable = typename MapIterTypes<std::map<K, V>>::ValueIterable;
120*70a7ec85SAndroid Build Coastguard Worker template <typename K, typename V>
121*70a7ec85SAndroid Build Coastguard Worker using MultiMapValueIterable = typename MapIterTypes<std::multimap<K, V>>::ValueIterable;
122*70a7ec85SAndroid Build Coastguard Worker
123*70a7ec85SAndroid Build Coastguard Worker template<typename K, typename V>
iterateValues(const std::map<K,V> & map)124*70a7ec85SAndroid Build Coastguard Worker ConstMapValueIterable<K, V> iterateValues(const std::map<K, V> &map) {
125*70a7ec85SAndroid Build Coastguard Worker return map;
126*70a7ec85SAndroid Build Coastguard Worker }
127*70a7ec85SAndroid Build Coastguard Worker template<typename K, typename V>
iterateValues(const std::multimap<K,V> & map)128*70a7ec85SAndroid Build Coastguard Worker ConstMultiMapValueIterable<K, V> iterateValues(const std::multimap<K, V> &map) {
129*70a7ec85SAndroid Build Coastguard Worker return map;
130*70a7ec85SAndroid Build Coastguard Worker }
131*70a7ec85SAndroid Build Coastguard Worker template <typename K, typename V>
iterateValues(std::map<K,V> & map)132*70a7ec85SAndroid Build Coastguard Worker MapValueIterable<K, V> iterateValues(std::map<K, V>& map) {
133*70a7ec85SAndroid Build Coastguard Worker return map;
134*70a7ec85SAndroid Build Coastguard Worker }
135*70a7ec85SAndroid Build Coastguard Worker template <typename K, typename V>
iterateValues(std::multimap<K,V> & map)136*70a7ec85SAndroid Build Coastguard Worker MultiMapValueIterable<K, V> iterateValues(std::multimap<K, V>& map) {
137*70a7ec85SAndroid Build Coastguard Worker return map;
138*70a7ec85SAndroid Build Coastguard Worker }
139*70a7ec85SAndroid Build Coastguard Worker
140*70a7ec85SAndroid Build Coastguard Worker template <typename K, typename V>
iterateValues(const std::multimap<K,V> & map,const K & key)141*70a7ec85SAndroid Build Coastguard Worker typename MapIterTypes<std::multimap<K, V>>::template RangeImpl<true> iterateValues(
142*70a7ec85SAndroid Build Coastguard Worker const std::multimap<K, V>& map, const K& key) {
143*70a7ec85SAndroid Build Coastguard Worker return map.equal_range(key);
144*70a7ec85SAndroid Build Coastguard Worker }
145*70a7ec85SAndroid Build Coastguard Worker
146*70a7ec85SAndroid Build Coastguard Worker } // namespace vintf
147*70a7ec85SAndroid Build Coastguard Worker } // namespace android
148*70a7ec85SAndroid Build Coastguard Worker
149*70a7ec85SAndroid Build Coastguard Worker #endif // ANDROID_VINTF_MAP_VALUE_ITERATOR_H
150