dune-common 2.12-git
Loading...
Searching...
No Matches
layout_left_padded.hh
Go to the documentation of this file.
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_PADDED_HH
6#define DUNE_COMMON_STD_LAYOUT_LEFT_PADDED_HH
7
8#include <cassert>
9#include <span>
10#include <type_traits>
11
17
18namespace Dune::Std {
19namespace Impl {
20
21template <class Layout>
22struct IsLayoutLeftPadded : std::false_type {};
23
24template <std::size_t PaddingValue>
25struct IsLayoutLeftPadded<layout_left_padded<PaddingValue>> : std::true_type {};
26
27template <class Layout>
28inline constexpr bool is_layout_left_padded_v = IsLayoutLeftPadded<Layout>::value;
29
30} // end namespace Impl
31
49template <std::size_t PaddingValue>
50template <class Extents>
51class layout_left_padded<PaddingValue>::mapping
52{
53public:
54 using extents_type = Extents;
55 using index_type = typename extents_type::index_type;
56 using size_type = typename extents_type::size_type;
57 using rank_type = typename extents_type::rank_type;
59
60 static constexpr std::size_t padding_value = PaddingValue;
61
62 constexpr mapping () noexcept = default;
63 constexpr mapping (const mapping&) noexcept = default;
64
65 constexpr mapping (const extents_type& e) noexcept
66 : extents_(e)
67 , stride1_(default_stride1(e))
68 {}
69
70 template <class OtherIndexType,
73 constexpr mapping (const extents_type& e, OtherIndexType padding) noexcept
74 : extents_(e)
75 , stride1_(index_type(padding))
76 {
77 assert(Extents::rank() <= 1 || index_type(padding) >= e.extent(0));
78 if constexpr(PaddingValue != std::dynamic_extent)
79 assert(index_type(PaddingValue) == index_type(padding));
80 }
81
82 template <class OtherExtents,
84 constexpr mapping (const layout_left::mapping<OtherExtents>& m) noexcept
85 : mapping(extents_type(m.extents()))
86 {}
87
88 template <class OtherExtents, class E = extents_type,
89 std::enable_if_t<(E::rank() <= 1), int> = 0,
90 std::enable_if_t<std::is_constructible_v<extents_type, OtherExtents>, int> = 0>
91 constexpr mapping (const layout_right::mapping<OtherExtents>& m) noexcept
93 {}
94
95 template <class OtherExtents,
97 constexpr mapping (const layout_stride::mapping<OtherExtents>& m) noexcept
98 : extents_(m.extents())
99 , stride1_(Extents::rank() > 1 ? m.stride(1) : index_type(0))
100 {
101#ifndef NDEBUG
102 if constexpr(Extents::rank() > 0)
103 assert(m.stride(0) == 1);
104 for (rank_type r = 2; r < Extents::rank(); ++r)
105 assert(m.stride(r) == stride1_ * fwd_product(r));
106#endif
107 }
108
109 template <class OtherMapping,
112 constexpr mapping (const OtherMapping& m) noexcept
113 : extents_(m.extents())
114 , stride1_(Extents::rank() > 1 ? m.stride(1) : index_type(0))
115 {}
116
117 constexpr mapping& operator= (const mapping&) noexcept = default;
118
119 constexpr const extents_type& extents () const noexcept { return extents_; }
120
121 constexpr index_type required_span_size () const noexcept
122 {
123 if constexpr(Extents::rank() == 0)
124 return 1;
125 else {
126 if (product() == 0)
127 return 0;
128 index_type result = 1;
129 for (rank_type r = 0; r < Extents::rank(); ++r)
130 result += (extents_.extent(r)-1) * stride(r);
131 return result;
132 }
133 }
134
135 template <class... Indices,
136 std::enable_if_t<(sizeof...(Indices) == Extents::rank()), int> = 0,
137 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0>
138 constexpr index_type operator() (Indices... indices) const noexcept
139 {
140 const index_type ii[] = {index_type(indices)...};
141 index_type result = 0;
142 for (rank_type r = 0; r < Extents::rank(); ++r)
143 result += ii[r] * stride(r);
144 return result;
145 }
146
147 constexpr index_type operator() () const noexcept { return 0; }
148
149 static constexpr bool is_always_unique () noexcept { return true; }
150 static constexpr bool is_always_exhaustive () noexcept { return PaddingValue == std::dynamic_extent; }
151 static constexpr bool is_always_strided () noexcept { return true; }
152
153 constexpr bool is_unique () const noexcept { return true; }
154 constexpr bool is_strided () const noexcept { return true; }
155 constexpr bool is_exhaustive () const noexcept
156 {
157 return Extents::rank() <= 1 || stride1_ == extents_.extent(0);
158 }
159
160 template <class E = extents_type,
161 std::enable_if_t<(E::rank() > 0), int> = 0>
162 constexpr index_type stride (rank_type r) const noexcept
163 {
164 assert(r < Extents::rank());
165 if (r == 0)
166 return 1;
167 if (r == 1)
168 return stride1_;
169 return stride1_ * fwd_product(r);
170 }
171
172 template <class OtherMapping,
173 std::enable_if_t<(OtherMapping::extents_type::rank() == Extents::rank()), int> = 0,
174 std::enable_if_t<(OtherMapping::is_always_strided()), int> = 0>
175 friend constexpr bool operator== (const mapping& a, const OtherMapping& b) noexcept
176 {
177 if (a.extents_ != b.extents())
178 return false;
179 for (rank_type r = 0; r < Extents::rank(); ++r)
180 if (a.stride(r) != b.stride(r))
181 return false;
182 return true;
183 }
184
185private:
186 static constexpr index_type padded_stride (index_type padding, index_type extent) noexcept
187 {
188 assert(padding >= extent);
189 return padding;
190 }
191
192 static constexpr index_type default_stride1 (const extents_type& e) noexcept
193 {
194 if constexpr(Extents::rank() <= 1)
195 return 0;
196 else if constexpr(PaddingValue == std::dynamic_extent)
197 return e.extent(0);
198 else
199 return padded_stride(index_type(PaddingValue), e.extent(0));
200 }
201
202 constexpr index_type fwd_product (rank_type r) const noexcept
203 {
204 index_type prod = 1;
205 for (rank_type k = 1; k < r; ++k)
206 prod *= extents_.extent(k);
207 return prod;
208 }
209
210 constexpr size_type product () const noexcept
211 {
212 size_type prod = 1;
213 for (rank_type r = 0; r < Extents::rank(); ++r)
214 prod *= extents_.extent(r);
215 return prod;
216 }
217
218private:
219 DUNE_NO_UNIQUE_ADDRESS extents_type extents_;
220 index_type stride1_ = 0;
221};
222
223} // end namespace Dune::Std
224
225#endif // DUNE_COMMON_STD_LAYOUT_LEFT_PADDED_HH
#define DUNE_NO_UNIQUE_ADDRESS
Definition no_unique_address.hh:24
Namespace for features backported from new C++ standards.
Definition algorithm.hh:19
A layout mapping where the leftmost extent has stride 1.
Definition layout_left.hh:20
A layout mapping where the rightmost extent has stride 1.
Definition layout_right.hh:20
constexpr const extents_type & extents() const noexcept
Definition layout_right.hh:86
constexpr index_type stride(rank_type i) const noexcept
The stride is the product of the extents E(n)*E(n-1)*...*E(i+1)
Definition layout_right.hh:121
A layout mapping where the strides are user-defined.
Definition layout_stride.hh:21
A layout mapping where the leftmost extent has stride 1 and the second stride may be padded.
Definition fwd_layouts.hh:54
A left layout mapping with optional padding of the stride of dimension 1.
Definition layout_left_padded.hh:52
constexpr bool is_unique() const noexcept
Definition layout_left_padded.hh:153
constexpr mapping() noexcept=default
Extents extents_type
Definition layout_left_padded.hh:54
constexpr index_type required_span_size() const noexcept
Definition layout_left_padded.hh:121
static constexpr bool is_always_exhaustive() noexcept
Definition layout_left_padded.hh:150
constexpr mapping(const extents_type &e, OtherIndexType padding) noexcept
Definition layout_left_padded.hh:73
static constexpr bool is_always_strided() noexcept
Definition layout_left_padded.hh:151
typename extents_type::index_type index_type
Definition layout_left_padded.hh:55
constexpr mapping(const OtherMapping &m) noexcept
Definition layout_left_padded.hh:112
constexpr mapping(const layout_stride::mapping< OtherExtents > &m) noexcept
Definition layout_left_padded.hh:97
static constexpr bool is_always_unique() noexcept
Definition layout_left_padded.hh:149
constexpr const extents_type & extents() const noexcept
Definition layout_left_padded.hh:119
typename extents_type::rank_type rank_type
Definition layout_left_padded.hh:57
constexpr bool is_exhaustive() const noexcept
Definition layout_left_padded.hh:155
constexpr mapping(const layout_left::mapping< OtherExtents > &m) noexcept
Definition layout_left_padded.hh:84
constexpr bool is_strided() const noexcept
Definition layout_left_padded.hh:154
typename extents_type::size_type size_type
Definition layout_left_padded.hh:56
constexpr index_type stride(rank_type r) const noexcept
Definition layout_left_padded.hh:162