| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| #ifndef ANDROID_VINTF_MAP_VALUE_ITERATOR_H |
| #define ANDROID_VINTF_MAP_VALUE_ITERATOR_H |
| |
| #include <iterator> |
| #include <map> |
| |
| namespace android { |
| namespace vintf { |
| |
| template<typename Map> |
| struct MapIterTypes { |
| using K = typename Map::key_type; |
| using V = typename Map::mapped_type; |
| |
| // Iterator over all values of a Map |
| template<bool is_const> |
| struct IteratorImpl : public std::iterator < |
| std::bidirectional_iterator_tag, /* Category */ |
| V, |
| ptrdiff_t, /* Distance */ |
| typename std::conditional<is_const, const V *, V *>::type /* Pointer */, |
| typename std::conditional<is_const, const V &, V &>::type /* Reference */ |
| > |
| { |
| using traits = std::iterator_traits<IteratorImpl>; |
| using ptr_type = typename traits::pointer; |
| using ref_type = typename traits::reference; |
| using diff_type = typename traits::difference_type; |
| |
| using map_iter = typename std::conditional<is_const, |
| typename Map::const_iterator, typename Map::iterator>::type; |
| |
| IteratorImpl(map_iter i) : mIter(i) {} |
| |
| inline IteratorImpl &operator++() { |
| mIter++; |
| return *this; |
| }; |
| inline IteratorImpl operator++(int) { |
| IteratorImpl i = *this; |
| mIter++; |
| return i; |
| } |
| inline IteratorImpl &operator--() { |
| mIter--; |
| return *this; |
| } |
| inline IteratorImpl operator--(int) { |
| IteratorImpl i = *this; |
| mIter--; |
| return i; |
| } |
| inline ref_type operator*() const { return mIter->second; } |
| inline ptr_type operator->() const { return &(mIter->second); } |
| inline bool operator==(const IteratorImpl &rhs) const { return mIter == rhs.mIter; } |
| inline bool operator!=(const IteratorImpl &rhs) const { return mIter != rhs.mIter; } |
| |
| private: |
| map_iter mIter; |
| }; |
| |
| using ValueIterator = IteratorImpl<false>; |
| using ConstValueIterator = IteratorImpl<true>; |
| |
| template<bool is_const> |
| struct IterableImpl { |
| using map_ref = typename std::conditional<is_const, const Map &, Map &>::type; |
| IterableImpl(map_ref map) : mMap(map) {} |
| |
| IteratorImpl<is_const> begin() const { |
| return IteratorImpl<is_const>(mMap.begin()); |
| } |
| |
| IteratorImpl<is_const> end() const { |
| return IteratorImpl<is_const>(mMap.end()); |
| } |
| |
| bool empty() const { return begin() == end(); } |
| |
| private: |
| map_ref mMap; |
| }; |
| |
| template <bool is_const> |
| struct RangeImpl { |
| using iter_type = typename std::conditional<is_const, typename Map::const_iterator, |
| typename Map::iterator>::type; |
| using range_type = std::pair<iter_type, iter_type>; |
| RangeImpl(range_type r) : mRange(r) {} |
| IteratorImpl<is_const> begin() const { return mRange.first; } |
| IteratorImpl<is_const> end() const { return mRange.second; } |
| bool empty() const { return begin() == end(); } |
| |
| private: |
| range_type mRange; |
| }; |
| |
| using ValueIterable = IterableImpl<false>; |
| using ConstValueIterable = IterableImpl<true>; |
| }; |
| |
| template<typename K, typename V> |
| using ConstMapValueIterable = typename MapIterTypes<std::map<K, V>>::ConstValueIterable; |
| template<typename K, typename V> |
| using ConstMultiMapValueIterable = typename MapIterTypes<std::multimap<K, V>>::ConstValueIterable; |
| |
| template<typename K, typename V> |
| ConstMapValueIterable<K, V> iterateValues(const std::map<K, V> &map) { |
| return map; |
| } |
| template<typename K, typename V> |
| ConstMultiMapValueIterable<K, V> iterateValues(const std::multimap<K, V> &map) { |
| return map; |
| } |
| |
| template <typename K, typename V> |
| typename MapIterTypes<std::multimap<K, V>>::template RangeImpl<true> iterateValues( |
| const std::multimap<K, V>& map, const K& key) { |
| return map.equal_range(key); |
| } |
| |
| } // namespace vintf |
| } // namespace android |
| |
| #endif // ANDROID_VINTF_MAP_VALUE_ITERATOR_H |