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

Generalize the DenseVectorSpan for ranges

parent 3717983a
No related branches found
No related tags found
No related merge requests found
Pipeline #75751 waiting for manual action
......@@ -14,9 +14,23 @@
#include <dune/common/densevector.hh>
#include <dune/common/ftraits.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/std/default_accessor.hh>
#include <dune/common/std/iterator_accessor.hh>
#include <dune/common/std/layout_right.hh>
#include <dune/common/std/mdspan.hh>
namespace Dune {
namespace Impl {
template <class V>
concept IsVector = requires(V v)
{
v.data();
{ v.size() } -> std::integral;
};
} // end namespace Impl
/** @addtogroup DenseMatVec
* @{
......@@ -27,13 +41,13 @@ namespace Dune {
* \tparam K is the field type (use float, double, complex, etc)
* \tparam Extent The static size of the vector or `Std::dynamic_extent` if the size is dynamic
*/
template <class K, std::size_t Extent = Std::dynamic_extent>
template <class K, std::size_t Extent = Std::dynamic_extent, class Accessor = Std::default_accessor<K>>
class DenseVectorSpan
: private Std::mdspan< K, Std::extents<std::size_t,Extent> >
, public DenseVector< DenseVectorSpan<K, Extent> >
: private Std::mdspan< K, Std::extents<std::size_t,Extent>, Std::layout_right, Accessor >
, public DenseVector< DenseVectorSpan<K, Extent, Accessor> >
{
using Base = Std::mdspan< K, Std::extents<std::size_t,Extent> >;
using Interface = DenseVector< DenseVectorSpan<K, Extent> >;
using Base = Std::mdspan< K, Std::extents<std::size_t,Extent>, Std::layout_right, Accessor >;
using Interface = DenseVector< DenseVectorSpan<K, Extent, Accessor> >;
public:
// import all constructors from Std::mdspan
......@@ -54,6 +68,16 @@ public:
: Base(v.data(), v.size())
{}
//! Construct a span over an iterator range
template <class Range>
requires (not Impl::IsVector<Range>) && requires(Range&& r) {
{ r.begin() } -> std::convertible_to<typename Base::data_handle_type>;
{ r.end() } -> std::convertible_to<typename Base::data_handle_type>;
}
constexpr DenseVectorSpan (Range&& r) noexcept
: Base(r.begin(), std::distance(r.begin(), r.end()))
{}
// make assignment of other vectors possible
using Interface::operator=;
......@@ -134,17 +158,35 @@ template <class K, int N>
DenseVectorSpan (FieldVector<K,N> const&)
-> DenseVectorSpan<const K,std::size_t(N)>;
// span over an iterator range
template <class Range, class Iter = decltype(std::declval<Range>().begin())>
requires (not Impl::IsVector<Range>) && requires(Range& r) {
{ r.begin() } -> std::convertible_to<Iter>;
{ r.end() } -> std::convertible_to<Iter>;
}
DenseVectorSpan (Range&)
-> DenseVectorSpan<typename std::iterator_traits<Iter>::value_type, Std::dynamic_extent, Std::iterator_accessor<Iter>>;
template <class Range, class Iter = decltype(std::declval<Range>().cbegin())>
requires (not Impl::IsVector<Range>) && requires(const Range& r) {
{ r.begin() } -> std::convertible_to<Iter>;
{ r.end() } -> std::convertible_to<Iter>;
}
DenseVectorSpan (const Range&)
-> DenseVectorSpan<typename std::iterator_traits<Iter>::value_type, Std::dynamic_extent, Std::iterator_accessor<Iter>>;
template <class K, std::size_t Extent>
struct DenseMatVecTraits< DenseVectorSpan<K, Extent> >
template <class K, std::size_t Extent, class Accessor>
struct DenseMatVecTraits< DenseVectorSpan<K, Extent, Accessor> >
{
using derived_type = DenseVectorSpan<K, Extent>;
using derived_type = DenseVectorSpan<K, Extent, Accessor>;
using value_type = K;
using size_type = std::size_t;
};
template <class K, std::size_t Extent>
struct FieldTraits< DenseVectorSpan<K, Extent> >
template <class K, std::size_t Extent, class Accessor>
struct FieldTraits< DenseVectorSpan<K, Extent, Accessor> >
{
using field_type = typename FieldTraits<K>::field_type;
using real_type = typename FieldTraits<K>::real_type;
......
......@@ -5,6 +5,7 @@ install(FILES
default_accessor.hh
extents.hh
functional.hh
iterator_accessor.hh
layout_left.hh
layout_right.hh
layout_stride.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_STD_ITERATOR_ACCESSOR_HH
#define DUNE_COMMON_STD_ITERATOR_ACCESSOR_HH
#include <iterator>
namespace Dune::Std {
/**
* \brief A type for access to elements of mdspan using iterators as data handle.
* \ingroup CxxUtilities
*
* The `iterator_accessor` class template is an `AccessorPolicy` used by `mdspan`
* to provide access to elements in an iterator range [begin, end). The iterator
* thereby acts as a data handle.
*
* \tparam Iterator The iterator type should be conforming with the std iterator concept.
*/
template <class Iterator>
class iterator_accessor
{
public:
using element_type = typename std::iterator_traits<Iterator>::value_type;
using data_handle_type = Iterator;
using reference = typename std::iterator_traits<Iterator>::reference;
using offset_policy = iterator_accessor;
public:
/// \brief Default constructor
constexpr iterator_accessor () noexcept = default;
/// \brief Return a reference to the i'th element in the data range starting at `p`
constexpr reference access (data_handle_type p, std::size_t i) const noexcept
{
return *std::next(p,i);
}
/// \brief Return a data handle to the i'th element in the data range starting at `p`
constexpr data_handle_type offset (data_handle_type p, std::size_t i) const noexcept
{
return std::next(p,i);
}
};
} // end namespace Dune::Std
#endif // DUNE_COMMON_STD_ITERATOR_ACCESSOR_HH
......@@ -8,6 +8,7 @@
#include <dune/common/dynmatrix.hh>
#include <dune/common/densevectorspan.hh>
#include <dune/common/iteratorrange.hh>
#include <dune/common/test/testsuite.hh>
int main()
......@@ -45,5 +46,10 @@ int main()
[[maybe_unused]] auto x_span2 = Dune::DenseVectorSpan(data);
}
{
auto range = Dune::IteratorRange{x.begin(), x.end()};
[[maybe_unused]] auto x_span1 = Dune::DenseVectorSpan(range);
}
return test.exit();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment