Dune Core Modules (unstable)

layout_left.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_STD_LAYOUT_LEFT_HH
6#define DUNE_COMMON_STD_LAYOUT_LEFT_HH
7
8#include <array>
9#include <type_traits>
10
11#include <dune/common/indices.hh>
12#include <dune/common/std/no_unique_address.hh>
13#include <dune/common/std/impl/fwd_layouts.hh>
14
15namespace Dune::Std {
16
18template <class Extents>
20{
21 template <class> friend class mapping;
22
23public:
24 using extents_type = Extents;
25 using size_type = typename extents_type::size_type;
26 using rank_type = typename extents_type::rank_type;
27 using index_type = typename extents_type::index_type;
29
31 constexpr mapping () noexcept = default;
32
34 constexpr mapping (const mapping&) noexcept = default;
35
37 constexpr mapping (const extents_type& e) noexcept
38 : extents_(e)
39 {}
40
42 template <class OtherExtents,
43 std::enable_if_t<std::is_constructible_v<extents_type, OtherExtents>, int> = 0>
44 #if __cpp_conditional_explicit >= 201806L
45 explicit(!std::is_convertible_v<OtherExtents, extents_type>)
46 #endif
47 constexpr mapping (const mapping<OtherExtents>& m) noexcept
48 : extents_(m.extents())
49 {}
50
52 template <class OtherExtents, class E = extents_type,
53 std::enable_if_t<(E::rank() <= 1), int> = 0,
54 std::enable_if_t<std::is_constructible_v<extents_type, OtherExtents>, int> = 0>
55 #if __cpp_conditional_explicit >= 201806L
56 explicit(!std::is_convertible_v<OtherExtents, extents_type>)
57 #endif
58 constexpr mapping (const layout_right::mapping<OtherExtents>& m) noexcept
59 : extents_(m.extents())
60 {}
61
63 template <class OtherExtents,
64 std::enable_if_t<std::is_constructible_v<extents_type, OtherExtents>, int> = 0>
65 #if __cpp_conditional_explicit >= 201806L
66 explicit(extents_type::rank() > 0)
67 #endif
69 : extents_(m.extents())
70 {
71#ifndef NDEBUG
72 if constexpr(extents_type::rank() > 0) {
73 index_type prod = 1;
74 for (rank_type r = 0; r < extents_type::rank()-1; ++r) {
75 assert(m.strides(r) == prod);
76 prod *= m.extents().extent(r);
77 }
78 assert(m.strides(extents_type::rank()-1) == prod);
79 }
80#endif
81 }
82
84 constexpr mapping& operator= (const mapping&) noexcept = default;
85
86 constexpr const extents_type& extents () const noexcept { return extents_; }
87 constexpr index_type required_span_size () const noexcept { return extents_.product(); }
88
90 template <class... Indices,
91 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
92 std::enable_if_t<(... && std::is_convertible_v<Indices, index_type>), int> = 0,
93 std::enable_if_t<(... && std::is_nothrow_constructible_v<Indices, index_type>), int> = 0>
94 constexpr index_type operator() (Indices... ii) const noexcept
95 {
96 const std::array indices{index_type(std::move(ii))...};
97 index_type value = indices.back();
98 for (rank_type r = 1; r < extents_type::rank(); ++r) {
99 const rank_type j = extents_type::rank()-r;
100 value = indices[j-1] + extents_.extent(j-1) * value;
101 }
102 return value;
103 }
104
106 constexpr index_type operator() () const noexcept
107 {
108 return 0;
109 }
110
111 static constexpr bool is_always_unique () noexcept { return true; }
112 static constexpr bool is_always_exhaustive () noexcept { return true; }
113 static constexpr bool is_always_strided () noexcept { return true; }
114
115 static constexpr bool is_unique () noexcept { return true; }
116 static constexpr bool is_exhaustive () noexcept { return true; }
117 static constexpr bool is_strided () noexcept { return true; }
118
120 template <class E = extents_type,
121 std::enable_if_t<(E::rank() > 0), int> = 0>
122 constexpr index_type stride (rank_type i) const noexcept
123 {
124 assert(i < extents_type::rank());
125 index_type prod = 1;
126 for (rank_type r = 0; r < i; ++r)
127 prod *= extents().extent(r);
128 return prod;
129 }
130
131 template <class OtherExtents,
132 std::enable_if_t<(Extents::rank() == OtherExtents::rank()), int> = 0>
133 friend constexpr bool operator== (const mapping& a, const mapping<OtherExtents>& b) noexcept
134 {
135 return a.extents_ == b.extents_;
136 }
137
138private:
139 DUNE_NO_UNIQUE_ADDRESS extents_type extents_;
140};
141
142} // end namespace Dune::Std
143
144#endif // DUNE_COMMON_STD_LAYOUT_LEFT_HH
Multidimensional index space with dynamic and static extents.
Definition: extents.hh:55
constexpr index_type extent(rank_type r) const noexcept
Return the extent of dimension i
Definition: extents.hh:101
A layout mapping where the leftmost extent has stride 1.
Definition: layout_left.hh:20
constexpr index_type stride(rank_type i) const noexcept
The stride is the product of the extents E(0)*E(1)*...*E(i-1)
Definition: layout_left.hh:122
constexpr mapping & operator=(const mapping &) noexcept=default
Copy-assignment for the mapping.
constexpr mapping() noexcept=default
The default construction is possible for default constructible extents.
constexpr index_type operator()() const noexcept
The default offset for rank-0 tensors is 0.
Definition: layout_left.hh:106
constexpr mapping(const layout_right::mapping< OtherExtents > &m) noexcept
Construct the mapping from a layout_right.
Definition: layout_left.hh:58
A layout mapping where the rightmost extent has stride 1.
Definition: layout_right.hh:20
A layout mapping where the strides are user-defined.
Definition: layout_stride.hh:20
constexpr const strides_type & strides() const noexcept
Get the array of all strides.
Definition: layout_stride.hh:128
Namespace for features backported from new C++ standards.
Definition: default_accessor.hh:10
A layout where the leftmost extent has stride 1.
Definition: fwd_layouts.hh:17
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)