Newer
Older
// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_ISTL_BASEARRAY_HH
#define DUNE_ISTL_BASEARRAY_HH
#include <cassert>
#include <cmath>
#include <cstddef>
#include <memory>
/** \file
\brief Implements several basic array containers.
/** \brief Everything in this namespace is internal to dune-istl, and may change without warning */
namespace Imp {
/** \brief A simple array container for objects of type B
Implement.
- iterator access
- const_iterator access
- random access
This container has *NO* memory management at all,
copy constructor, assignment and destructor are all default.
The constructor is made protected to emphasize that objects
Error checking: no error checking is provided normally.
Setting the compile time switch DUNE_ISTL_WITH_CHECKING
enables error checking.
\internal This class is an implementation detail, and should not be used outside of dune-istl.
template<class B, class ST=std::size_t >
class base_array_unmanaged
{
public:
//===== type definitions and constants
//! export the type representing the components
typedef B member_type;
//! the type for the index access
//! the type used for references
using reference = B&;
//! the type used for const references
using const_reference = const B&;
//===== access to components
//! random access to blocks
reference operator[] (size_type i)
if (i>=n) DUNE_THROW(ISTLError,"index out of range");
#endif
return p[i];
}
//! same for read only access
const_reference operator[] (size_type i) const
if (i>=n) DUNE_THROW(ISTLError,"index out of range");
: public RandomAccessIteratorFacade<RealIterator<T>, T>
typedef typename std::remove_const<T>::type ValueType;
friend class RandomAccessIteratorFacade<RealIterator<const ValueType>, const ValueType>;
friend class RandomAccessIteratorFacade<RealIterator<ValueType>, ValueType>;
friend class RealIterator<const ValueType>;
friend class RealIterator<ValueType>;
RealIterator (const B* _p, B* _i)
: p(_p), i(_i)
{}
template <class T_,
std::enable_if_t<std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T_>>, int> = 0>
RealIterator (const RealIterator<T_>& other)
: p(other.p), i(other.i)
template <class T_,
std::enable_if_t<std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T_>>, int> = 0>
RealIterator& operator= (const RealIterator<T_>& other)
{
p = other.p;
i = other.i;
return *this;
}
size_type index () const
bool equals (const RealIterator<ValueType>& other) const
//! equality
bool equals (const RealIterator<const ValueType>& other) const
std::ptrdiff_t distanceTo(const RealIterator& o) const
{
return o.i-i;
}
// Needed for operator[] of the iterator
reference elementAt (std::ptrdiff_t offset) const
reference dereference () const
return *i;
void advance(std::ptrdiff_t d)
{
i+=d;
}
const B* p = nullptr;
B* i = nullptr;
//! iterator type for sequential access
typedef RealIterator<B> iterator;
return iterator(p,p);
return iterator(p,p+n);
//! @returns an iterator that is positioned before
//! the end iterator of the vector, i.e. at the last entry.
iterator beforeEnd ()
return iterator(p,p+n-1);
//! @returns an iterator that is positioned before
//! the first entry of the vector.
iterator beforeBegin ()
return iterator(p,p-1);
}
//! random access returning iterator (end if not contained)
iterator find (size_type i)
//! iterator class for sequential access
typedef RealIterator<const B> const_iterator;
//! begin const_iterator
const_iterator begin () const
{
return const_iterator(p,p+0);
}
//! end const_iterator
const_iterator end () const
{
return const_iterator(p,p+n);
//! @returns an iterator that is positioned before
//! the end iterator of the vector. i.e. at the last element.
const_iterator beforeEnd () const
return const_iterator(p,p+n-1);
//! @returns an iterator that is positioned before
//! the first entry of the vector.
const_iterator beforeBegin () const
return const_iterator(p,p-1);
//! random access returning iterator (end if not contained)
const_iterator find (size_type i) const
//===== sizes
//! number of blocks in the array (are of size 1 here)
size_type size () const
//! Returns pointer to the underlying array
const B* data() const
{
return p;
}
//! Returns pointer to the underlying array
B* data()
{
return p;
}
protected:
//! makes empty array
base_array_unmanaged ()
: n(0), p(0)
{}
//! make an initialized array
base_array_unmanaged (size_type n_, B* p_)
: n(n_), p(p_)
{}
size_type n; // number of elements in array
B *p; // pointer to dynamically allocated built-in array
};
/** \brief A simple array container with non-consecutive index set.
Elements in the array are of type B. This class provides
- iterator access
- const_iterator access
- random access in log(n) steps using binary search
- find returning iterator
This container has *NO* memory management at all,
copy constructor, assignment and destructor are all default.
The constructor is made protected to emphasize that objects
are only usably in derived classes.
Error checking: no error checking is provided normally.
Setting the compile time switch DUNE_ISTL_WITH_CHECKING
enables error checking.
\internal This class is an implementation detail, and should not be used outside of dune-istl.
template<class B, class ST=std::size_t >
class compressed_base_array_unmanaged
{
public:
//===== type definitions and constants
//! export the type representing the components
typedef B member_type;
//! The type used for the index access
//! the type used for references
using reference = B&;
//! the type used for const references
using const_reference = const B&;
//===== access to components
//! random access to blocks, assumes ascending ordering
reference operator[] (size_type i)
Oliver Sander
committed
const size_type* lb = std::lower_bound(j, j+n, i);
DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
Oliver Sander
committed
return p[lb-j];
}
//! same for read only access, assumes ascending ordering
const_reference operator[] (size_type i) const
Oliver Sander
committed
const size_type* lb = std::lower_bound(j, j+n, i);
DUNE_THROW(ISTLError,"index "<<i<<" not in compressed array");
Oliver Sander
committed
return p[lb-j];
template<class T>
class RealIterator
: public BidirectionalIteratorFacade<RealIterator<T>, T>
typedef typename std::remove_const<T>::type ValueType;
friend class BidirectionalIteratorFacade<RealIterator<const ValueType>, const ValueType>;
friend class BidirectionalIteratorFacade<RealIterator<ValueType>, ValueType>;
friend class RealIterator<const ValueType>;
friend class RealIterator<ValueType>;
//! constructor
RealIterator (B* _p, size_type* _j, size_type _i)
: p(_p), j(_j), i(_i)
template <class T_,
std::enable_if_t<std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T_>>, int> = 0>
RealIterator (const RealIterator<T_>& other)
: p(other.p), j(other.j), i(other.i)
template <class T_,
std::enable_if_t<std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T_>>, int> = 0>
RealIterator& operator= (const RealIterator<T_>& other)
{
p = other.p;
j = other.j;
i = other.i;
return *this;
}
bool equals (const RealIterator<ValueType>& it) const
bool equals (const RealIterator<const ValueType>& it) const
//! return index corresponding to pointer
size_type index () const
//! Set index corresponding to pointer
void setindex (size_type k)
/**
* @brief offset from the first entry.
*
* An iterator positioned at the beginning
* has to be increment this amount of times to
* the same position.
*/
size_type offset () const
{
return i;
}
//! prefix increment
void increment()
{
++i;
}
//! prefix decrement
void decrement()
{
--i;
}
//! dereferencing
reference dereference () const
B* p = nullptr;
size_type* j = nullptr;
size_type i = 0;
/** @brief The iterator type. */
typedef RealIterator<B> iterator;
//! begin iterator
iterator begin ()
{
return iterator(p,j,0);
}
//! end iterator
iterator end ()
{
return iterator(p,j,n);
}
//! @returns an iterator that is positioned before
//! the end iterator of the vector, i.e. at the last entry.
iterator beforeEnd ()
//! @returns an iterator that is positioned before
//! the first entry of the vector.
iterator beforeBegin ()
//! random access returning iterator (end if not contained)
iterator find (size_type i)
const size_type* lb = std::lower_bound(j, j+n, i);
? iterator(p,j,lb-j)
//! begin const_iterator
const_iterator begin () const
{
return const_iterator(p,j,0);
}
//! end const_iterator
const_iterator end () const
{
return const_iterator(p,j,n);
}
//! @returns an iterator that is positioned before
//! the end iterator of the vector. i.e. at the last element.
const_iterator beforeEnd () const
//! @returns an iterator that is positioned before
//! the first entry of the vector.
const_iterator beforeBegin () const
{
return const_iterator(p,j,-1);
}
//! random access returning iterator (end if not contained)
const_iterator find (size_type i) const
const size_type* lb = std::lower_bound(j, j+n, i);
? const_iterator(p,j,lb-j)
}
//===== sizes
//! number of blocks in the array (are of size 1 here)
size_type size () const
{
return n;
}
protected:
//! makes empty array
compressed_base_array_unmanaged ()
size_type n; // number of elements in array
size_type* j; // the index set
} // end namespace Imp