dune-common  2.11
layout_left.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_HH
6 #define DUNE_COMMON_STD_LAYOUT_LEFT_HH
7 
8 #include <array>
9 #include <type_traits>
10 
11 #include <dune/common/indices.hh>
14 
15 namespace Dune::Std {
16 
18 template <class Extents>
19 class layout_left::mapping
20 {
21  template <class> friend class mapping;
22 
23 public:
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 
138 private:
140 };
141 
142 } // end namespace Dune::Std
143 
144 #endif // DUNE_COMMON_STD_LAYOUT_LEFT_HH
A layout mapping where the strides are user-defined.
Definition: fwd_layouts.hh:42
Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19
constexpr index_type operator()() const noexcept
The default offset for rank-0 tensors is 0.
Definition: layout_left.hh:106
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
typename extents_type::index_type index_type
Definition: layout_left.hh:27
friend constexpr bool operator==(const mapping &a, const mapping< OtherExtents > &b) noexcept
Definition: layout_left.hh:133
#define DUNE_NO_UNIQUE_ADDRESS
Definition: no_unique_address.hh:24
Extents extents_type
Definition: layout_left.hh:24
static constexpr bool is_exhaustive() noexcept
Definition: layout_left.hh:116
constexpr const extents_type & extents() const noexcept
Definition: layout_left.hh:86
constexpr mapping() noexcept=default
The default construction is possible for default constructible extents.
static constexpr bool is_always_exhaustive() noexcept
Definition: layout_left.hh:112
constexpr const extents_type & extents() const noexcept
Definition: layout_stride.hh:87
I i
Definition: hybridmultiindex.hh:328
static constexpr bool is_strided() noexcept
Definition: layout_left.hh:117
constexpr index_type required_span_size() const noexcept
Definition: layout_left.hh:87
constexpr const extents_type & extents() const noexcept
Definition: layout_right.hh:86
static constexpr bool is_always_unique() noexcept
Definition: layout_left.hh:111
constexpr mapping & operator=(const mapping &) noexcept=default
Copy-assignment for the mapping.
static constexpr bool is_unique() noexcept
Definition: layout_left.hh:115
constexpr const strides_type & strides() const noexcept
Get the array of all strides.
Definition: layout_stride.hh:129
typename extents_type::size_type size_type
Definition: layout_left.hh:25
static constexpr bool is_always_strided() noexcept
Definition: layout_left.hh:113
A layout mapping where the leftmost extent has stride 1.
Definition: fwd_layouts.hh:19
A layout mapping where the rightmost extent has stride 1.
Definition: fwd_layouts.hh:32
A layout where the leftmost extent has stride 1.For two-dimensional tensors this corresponds to colum...
Definition: fwd_layouts.hh:16
typename extents_type::rank_type rank_type
Definition: layout_left.hh:26