dune-common  2.11
layout_right.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_RIGHT_HH
6 #define DUNE_COMMON_STD_LAYOUT_RIGHT_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_right::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_left::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 = extents_type::rank()-1; r > 0; --r) {
75  assert(m.strides(r) == prod);
76  prod *= m.extents().extent(r);
77  }
78  assert(m.strides(0) == 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.front();
98  for (rank_type j = 0; j < extents_type::rank()-1; ++j) {
99  value = indices[j+1] + extents_.extent(j+1) * value;
100  }
101  return value;
102  }
103 
105  constexpr index_type operator() () const noexcept
106  {
107  return 0;
108  }
109 
110  static constexpr bool is_always_unique () noexcept { return true; }
111  static constexpr bool is_always_exhaustive () noexcept { return true; }
112  static constexpr bool is_always_strided () noexcept { return true; }
113 
114  static constexpr bool is_unique () noexcept { return true; }
115  static constexpr bool is_exhaustive () noexcept { return true; }
116  static constexpr bool is_strided () noexcept { return true; }
117 
119  template <class E = extents_type,
120  std::enable_if_t<(E::rank() > 0), int> = 0>
121  constexpr index_type stride (rank_type i) const noexcept
122  {
123  assert(i < extents_type::rank());
124  index_type prod = 1;
125  for (rank_type r = i+1; r < extents_type::rank(); ++r)
126  prod *= extents().extent(r);
127  return prod;
128  }
129 
130  template <class OtherExtents>
131  friend constexpr bool operator== (const mapping& a, const mapping<OtherExtents>& b) noexcept
132  {
133  return a.extents_ == b.extents_;
134  }
135 
136 private:
138 };
139 
140 } // end namespace Dune::Std
141 
142 #endif // DUNE_COMMON_STD_LAYOUT_RIGHT_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 mapping() noexcept=default
The default construction is possible for default constructible extents.
static constexpr bool is_unique() noexcept
Definition: layout_right.hh:114
typename extents_type::rank_type rank_type
Definition: layout_right.hh:26
#define DUNE_NO_UNIQUE_ADDRESS
Definition: no_unique_address.hh:24
typename extents_type::index_type index_type
Definition: layout_right.hh:27
constexpr const extents_type & extents() const noexcept
Definition: layout_left.hh:86
constexpr const extents_type & extents() const noexcept
Definition: layout_stride.hh:87
I i
Definition: hybridmultiindex.hh:328
static constexpr bool is_always_exhaustive() noexcept
Definition: layout_right.hh:111
A layout where the rightmost extent has stride 1, and strides increase right-to-left as the product o...
Definition: fwd_layouts.hh:29
static constexpr bool is_exhaustive() noexcept
Definition: layout_right.hh:115
constexpr mapping & operator=(const mapping &) noexcept=default
Copy-assignment for the mapping.
constexpr index_type operator()() const noexcept
The default offset for rank-0 tensors is 0.
Definition: layout_right.hh:105
typename extents_type::size_type size_type
Definition: layout_right.hh:25
constexpr const extents_type & extents() const noexcept
Definition: layout_right.hh:86
static constexpr bool is_always_unique() noexcept
Definition: layout_right.hh:110
constexpr index_type required_span_size() const noexcept
Definition: layout_right.hh:87
constexpr const strides_type & strides() const noexcept
Get the array of all strides.
Definition: layout_stride.hh:129
static constexpr bool is_strided() noexcept
Definition: layout_right.hh:116
A layout mapping where the leftmost extent has stride 1.
Definition: fwd_layouts.hh:19
friend constexpr bool operator==(const mapping &a, const mapping< OtherExtents > &b) noexcept
Definition: layout_right.hh:131
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
Extents extents_type
Definition: layout_right.hh:24
A layout mapping where the rightmost extent has stride 1.
Definition: fwd_layouts.hh:32
static constexpr bool is_always_strided() noexcept
Definition: layout_right.hh:112