Commit 22ce1e4c authored by Dennis Gläser's avatar Dennis Gläser
Browse files

[common] add helpers for iterator ranges

parent 4f0b09cd
install(FILES
id.hh
idpair.hh
iteratorfacades.hh
iteratorrange.hh
math.hh
promotedtype.hh
typetraits.hh
......
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Base class for stl conformant forward iterators.
* The implementations are strongly inspired by Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorfacades.hh
*
*/
#ifndef FRACKIT_COMMON_ITERATORFACADES_HH
#define FRACKIT_COMMON_ITERATORFACADES_HH
#include <cstddef>
#include <iterator>
#include <type_traits>
namespace Frackit {
/*!
* \ingroup Common
* \brief Base class for stl conformant forward iterators.
* The implementation is strongly inspired by the one in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorfacades.hh
*
* Implementations must define following functions:
*
* \code
*
* // Access the value referred to.
* reference dereference() const;
*
* // Compare for equality with iterator j
* bool equals(j);
*
* // position the iterator at the next element.
* void increment()
*
* \endcode
*
* See the above link to dune-common for more information.
*
* \tparam IT Iterator implementation
* \tparam VT The value type
* \tparam RT The reference type
* \tparam DT The type for differences between two iterators
*/
template<class IT, class VT, class RT = VT&, class DT = std::ptrdiff_t>
class ForwardIteratorFacade
{
using Implementation = IT;
template<class OtherIt>
static constexpr bool isInteroperable = std::is_convertible_v<Implementation, OtherIt>
|| std::is_convertible_v<OtherIt, Implementation>;
public:
// type aliases required by C++ for iterators
using iterator_category = std::forward_iterator_tag;
using value_type = typename std::remove_const<VT>::type;
using difference_type = DT;
using pointer = VT*;
using reference = RT;
//! dereferencing operator
reference operator*() const
{ return static_cast<Implementation const*>(this)->dereference(); }
//! dereferencing operator
pointer operator->() const
{ return &(static_cast<const Implementation *>(this)->dereference()); }
//! Preincrement operator
Implementation& operator++()
{
static_cast<Implementation *>(this)->increment();
return *static_cast<Implementation *>(this);
}
//! Postincrement operator
Implementation operator++(int)
{
Implementation tmp(static_cast<Implementation const&>(*this));
this->operator++();
return tmp;
}
//! equality operator
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>, int> = 0>
friend inline bool operator==(const Implementation& it, const OtherIt& otherIt)
{ return it.equals(otherIt); }
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>
&& !std::is_same_v<OtherIt, Implementation>, int> = 0>
friend inline bool operator==(const OtherIt& otherIt, const Implementation& it)
{ return it.equals(otherIt); }
//! inequality operator
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>, int> = 0>
friend inline bool operator!=(const Implementation& it, const OtherIt& otherIt)
{ return !it.equals(otherIt); }
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>
&& !std::is_same_v<OtherIt, Implementation>, int> = 0>
friend inline bool operator!=(const OtherIt& otherIt, const Implementation& it)
{ return !it.equals(otherIt); }
};
/*!
* \brief Iterator facade for a random-access container, of which
* one wants to iterate over a set of elements by means of
* a list of indices.
*/
template<class Container, class IndexList>
class RandomAccessContainerIndexedIterator
: public ForwardIteratorFacade< RandomAccessContainerIndexedIterator<Container, IndexList>,
typename Container::value_type,
const typename Container::value_type& >
{
using ThisType = RandomAccessContainerIndexedIterator<Container, IndexList>;
using IndexIterator = typename IndexList::const_iterator;
using ValueType = typename Container::value_type;
public:
RandomAccessContainerIndexedIterator()
: it_(IndexIterator())
, c_(nullptr)
{}
RandomAccessContainerIndexedIterator(const IndexIterator& it,
const Container& c)
: it_(it)
, c_(&c)
{}
const ValueType& dereference() const { return (*c_)[*it_]; }
bool equals(const ThisType& other) const { return it_ == other.it_; }
void increment() { ++it_; }
private:
IndexIterator it_;
const Container* c_;
};
} // end namespace Frackit
#endif // FRACKIT_COMMON_ITERATORFACADES_HH
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Simple range between begin and end iterators
* that can be used to support range-based for loops.
* The implementation is strongly inspired by the one provided in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorrange.hh
*/
#ifndef FRACKIT_COMMON_ITERATORRANGE_HH
#define FRACKIT_COMMON_ITERATORRANGE_HH
namespace Frackit {
/*!
* \ingroup Common
* \brief Simple range between begin and end iterators
* that can be used to support range-based for loops.
* The implementation is strongly inspired by the one provided in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorrange.hh
*
* \tparam Iterator The type of iterator
*/
template<typename Iterator>
class IteratorRange
{
public:
///@{
//! The iterators belonging to this range.
using iterator = Iterator;
using const_iterator = Iterator;
///@}
//! Constructs an iterator range on [begin, end).
IteratorRange(const Iterator& begin, const Iterator& end)
: begin_(begin)
, end_(end)
{}
//! Default constructor
IteratorRange() = default;
//! Returns an iterator pointing to the begin of the range.
Iterator begin() const { return begin_; }
//! Returns an iterator pointing past the end of the range.
Iterator end() const { return end_; }
private:
Iterator begin_;
Iterator end_;
};
} // end namespace Frackit
#endif // FRACKIT_COMMON_ITERATORRANGE_HH
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment