/* * 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 #include namespace android { namespace vintf { template struct MapIterTypes { using K = typename Map::key_type; using V = typename Map::mapped_type; // Iterator over all values of a Map template struct IteratorImpl : public std::iterator < std::bidirectional_iterator_tag, /* Category */ V, ptrdiff_t, /* Distance */ typename std::conditional::type /* Pointer */, typename std::conditional::type /* Reference */ > { using traits = std::iterator_traits; 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::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; using ConstValueIterator = IteratorImpl; template struct IterableImpl { using map_ref = typename std::conditional::type; IterableImpl(map_ref map) : mMap(map) {} IteratorImpl begin() const { return IteratorImpl(mMap.begin()); } IteratorImpl end() const { return IteratorImpl(mMap.end()); } bool empty() const { return begin() == end(); } private: map_ref mMap; }; template struct RangeImpl { using iter_type = typename std::conditional::type; using range_type = std::pair; RangeImpl(range_type r) : mRange(r) {} IteratorImpl begin() const { return mRange.first; } IteratorImpl end() const { return mRange.second; } bool empty() const { return begin() == end(); } private: range_type mRange; }; using ValueIterable = IterableImpl; using ConstValueIterable = IterableImpl; }; template using ConstMapValueIterable = typename MapIterTypes>::ConstValueIterable; template using ConstMultiMapValueIterable = typename MapIterTypes>::ConstValueIterable; template using MapValueIterable = typename MapIterTypes>::ValueIterable; template using MultiMapValueIterable = typename MapIterTypes>::ValueIterable; template ConstMapValueIterable iterateValues(const std::map &map) { return map; } template ConstMultiMapValueIterable iterateValues(const std::multimap &map) { return map; } template MapValueIterable iterateValues(std::map& map) { return map; } template MultiMapValueIterable iterateValues(std::multimap& map) { return map; } template typename MapIterTypes>::template RangeImpl iterateValues( const std::multimap& map, const K& key) { return map.equal_range(key); } } // namespace vintf } // namespace android #endif // ANDROID_VINTF_MAP_VALUE_ITERATOR_H