/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright 2010-2018 Danny Robson <danny@nerdcruft.net>
 */

#pragma once

namespace cruft::iterator {
    ///////////////////////////////////////////////////////////////////////////
    template <typename ContainerT>
    class indices {
    public:
        using value_type = std::size_t;

        indices (const ContainerT &_container):
            m_target (_container.size ())
        { ; }

        class iterator {
        public:
            using iterator_category = std::forward_iterator_tag;

            iterator (value_type _index):
                m_index (_index)
            { ; }

            bool
            operator!= (const iterator &rhs) const
            {
                return m_index != rhs.m_index;
            }

            bool
            operator== (const iterator &rhs) const
            {
                return m_index == rhs.m_index;
            }

            iterator&
            operator++ (void) &
            {
                ++m_index;
                return *this;
            };

            const value_type&
            operator* (void) const&
            {
                return m_index;
            }

        private:
            value_type m_index;
        };

        iterator begin (void) const { return iterator {       0u }; }
        iterator end   (void) const { return iterator { m_target }; }

        constexpr auto size (void) const noexcept
        {
            return m_target;
        }

    private:
        std::size_t m_target;
    };


    template <typename ContainerT>
    indices (ContainerT const&) -> indices<ContainerT>;
}