/*
 * 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;
    };

    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;
}

} // namespace vintf
} // namespace android

#endif // ANDROID_VINTF_MAP_VALUE_ITERATOR_H
