Skip to content
Snippets Groups Projects
Commit 90baaddf authored by Simon Praetorius's avatar Simon Praetorius
Browse files

Add mixin class for an indexed iterator

parent 1b79c9e4
No related branches found
No related tags found
1 merge request!1366Add mixin class for an indexed iterator
Pipeline #70051 passed
Pipeline: Dune Nightly Test

#70059

    ......@@ -62,6 +62,7 @@ install(FILES
    hash.hh
    hybridutilities.hh
    indent.hh
    indexediterator.hh
    indices.hh
    integersequence.hh
    interfaces.hh
    ......
    // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    // vi: set et ts=4 sw=2 sts=2:
    // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
    // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    #ifndef DUNE_COMMON_INDEXEDITERATOR_HH
    #define DUNE_COMMON_INDEXEDITERATOR_HH
    #include <iterator>
    #include <type_traits>
    namespace Dune
    {
    /**
    * \brief An iterator mixin that adds an `index()` method returning an
    * enumeration index for the traversal.
    *
    * This is a mixin class that derives from its template parameter `Iter` and
    * adds the method `index()` to retrieve an enumeration index during traversal.
    * Only the increment and decrement operators are adapted to also increment
    * (decrement) the accompanying index in the same way the iterator is incremented
    * or decremented. Especially the dereference and comparison operators are not
    * modified by this mixin class.
    *
    * \tparam Iter An iterator type the `IndexedIterator` will inherit from.
    */
    template<class Iter>
    class IndexedIterator
    : public Iter
    {
    using Traits = std::iterator_traits<Iter>;
    static_assert(std::is_base_of_v<std::forward_iterator_tag, typename Traits::iterator_category>);
    public:
    using size_type = typename Traits::difference_type;
    //! Default constructor default-constructs the `Iter` base type and the index by 0.
    IndexedIterator () = default;
    //! Construct the `Iter` base type by `it` and the index by the given starting index.
    IndexedIterator (Iter it, size_type index = 0)
    : Iter(it)
    , index_(index)
    {}
    //! Return the enumeration index.
    size_type index () const
    {
    return index_;
    }
    //! Increment the iterator and the index.
    IndexedIterator& operator++ ()
    {
    Iter::operator++();
    ++index_;
    return *this;
    }
    //! Increment the iterator and the index.
    IndexedIterator operator++ (int)
    {
    IndexedIterator tmp(*this);
    this->operator++();
    return tmp;
    }
    //! Decrement the iterator and the index.
    template <class I = Iter,
    decltype(--std::declval<I&>(), bool{}) = true>
    IndexedIterator& operator-- ()
    {
    Iter::operator--();
    --index_;
    return *this;
    }
    //! Decrement the iterator and the index.
    template <class I = Iter,
    decltype(std::declval<I&>()--, bool{}) = true>
    IndexedIterator operator-- (int)
    {
    IndexedIterator tmp(*this);
    this->operator--();
    return tmp;
    }
    //! Increment the iterator and the index.
    template <class I = Iter,
    decltype(std::declval<I&>()+=1, bool{}) = true>
    IndexedIterator& operator+= (typename Iter::difference_type n)
    {
    Iter::operator+=(n);
    index_ += n;
    return *this;
    }
    //! Decrement the iterator and the index.
    template <class I = Iter,
    decltype(std::declval<I&>()-=1, bool{}) = true>
    IndexedIterator& operator-= (typename Iter::difference_type n)
    {
    Iter::operator-=(n);
    index_ -= n;
    return *this;
    }
    private:
    size_type index_ = 0;
    };
    } // end namespace Dune
    #endif // DUNE_COMMON_INDEXEDITERATOR_HH
    ......@@ -208,6 +208,9 @@ dune_add_test(SOURCES hybridutilitiestest.cc
    LINK_LIBRARIES dunecommon
    LABELS quick)
    dune_add_test(SOURCES indexediteratortest.cc
    LABELS quick)
    dune_add_test(SOURCES indicestest.cc
    LABELS quick)
    ......
    // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
    // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
    #include <config.h>
    #include <numeric>
    #include <vector>
    #include <dune/common/indexediterator.hh>
    #include <dune/common/iteratorrange.hh>
    #include <dune/common/rangeutilities.hh>
    #include <dune/common/test/testsuite.hh>
    auto testSparseRange()
    {
    using namespace Dune;
    TestSuite suite("Check sparseRange()");
    std::vector<int> vec(10);
    std::iota(vec.begin(), vec.end(), 0);
    auto indexedRange = IteratorRange{IndexedIterator{vec.begin()}, IndexedIterator{vec.end()}};
    for (auto&& [vi,i] : Dune::sparseRange(indexedRange))
    suite.check(vi == i);
    return suite;
    }
    int main()
    {
    Dune::TestSuite suite;
    suite.subTest(testSparseRange());
    return suite.exit();
    }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment