Index.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class template Index.
6 
7 #pragma once
8 
9 #include <array>
10 #include <cstddef>
11 #include <limits>
12 #include <ostream>
13 
14 #include "ErrorHandling/Assert.hpp"
15 #include "Utilities/Gsl.hpp"
16 #include "Utilities/MakeArray.hpp"
17 #include "Utilities/Requires.hpp"
18 #include "Utilities/TypeTraits.hpp" // IWYU pragma: keep
19 namespace PUP {
20 class er;
21 } // namespace PUP
22 
23 /// \ingroup DataStructuresGroup
24 /// An integer multi-index.
25 ///
26 /// \tparam Dim the number of integers in the Index.
27 template <size_t Dim>
28 class Index {
29  public:
30  /// Construct with each element set to the same value.
31  explicit Index(const size_t i0 = std::numeric_limits<size_t>::max()) noexcept
32  : indices_(make_array<Dim>(i0)) {}
33 
34  /// Construct specifying value in each dimension
35  template <typename... I, Requires<(sizeof...(I) > 1)> = nullptr>
36  explicit Index(I... i) noexcept
37  : indices_(make_array(static_cast<size_t>(i)...)) {
38  static_assert(cpp17::conjunction_v<tt::is_integer<I>...>,
39  "You must pass in a set of size_t's to Index.");
40  static_assert(Dim == sizeof...(I),
41  "The number of indices given to Index must be the same as "
42  "the dimensionality of the Index.");
43  }
44 
45  explicit Index(std::array<size_t, Dim> i) noexcept : indices_(std::move(i)) {}
46 
47  size_t operator[](const size_t d) const noexcept {
48  return gsl::at(indices_, d);
49  }
50  size_t& operator[](const size_t d) noexcept { return gsl::at(indices_, d); }
51 
52  typename std::array<size_t, Dim>::iterator begin() {
53  return indices_.begin();
54  }
55  typename std::array<size_t, Dim>::const_iterator begin() const {
56  return indices_.begin();
57  }
58 
59  typename std::array<size_t, Dim>::iterator end() { return indices_.end(); }
60  typename std::array<size_t, Dim>::const_iterator end() const {
61  return indices_.end();
62  }
63 
64  size_t size() const noexcept { return Dim; }
65 
66  /// The product of the indices.
67  /// If Dim = 0, the product is defined as 1.
68  template <int N = Dim, Requires<(N > 0)> = nullptr>
69  constexpr size_t product() const noexcept {
70  return indices_[N - 1] * product<N - 1>();
71  }
72  /// \cond
73  // Specialization for N = 0 to stop recursion
74  template <int N = Dim, Requires<(N == 0)> = nullptr>
75  constexpr size_t product() const noexcept {
76  return 1;
77  }
78  /// \endcond
79 
80  /// Return a smaller Index with the d-th element removed.
81  ///
82  /// \param d the element to remove.
83  template <size_t N = Dim, Requires<(N > 0)> = nullptr>
84  Index<Dim - 1> slice_away(const size_t d) const noexcept {
85  ASSERT(d < Dim,
86  "Can't slice dimension " << d << " from an Index<" << Dim << ">");
87  std::array<size_t, Dim - 1> t{};
88  for (size_t i = 0; i < Dim; ++i) {
89  if (i < d) {
90  gsl::at(t, i) = gsl::at(indices_, i);
91  } else if (i > d) {
92  gsl::at(t, i - 1) = gsl::at(indices_, i);
93  }
94  }
95  return Index<Dim - 1>(t);
96  }
97 
98  /// \cond
99  // clang-tidy: runtime-references
100  void pup(PUP::er& p) noexcept; // NOLINT
101  /// \endcond
102 
103  template <size_t N>
104  friend std::ostream& operator<<(std::ostream& os, // NOLINT
105  const Index<N>& i);
106 
107  const size_t* data() const noexcept { return indices_.data(); }
108  size_t* data() noexcept { return indices_.data(); }
109 
110  const std::array<size_t, Dim>& indices() const noexcept { return indices_; }
111 
112  private:
113  std::array<size_t, Dim> indices_;
114 };
115 
116 /// \ingroup DataStructuresGroup
117 /// Get the collapsed index into a 1D array of the data corresponding to this
118 /// Index. Note that the first dimension of the Index varies fastest when
119 /// computing the collapsed index.
120 template <size_t N>
121 size_t collapsed_index(const Index<N>& index, const Index<N>& extents) noexcept;
122 
123 template <size_t N>
124 std::ostream& operator<<(std::ostream& os, const Index<N>& i);
125 
126 /// \cond HIDDEN_SYMBOLS
127 template <size_t N>
128 bool operator==(const Index<N>& lhs, const Index<N>& rhs) noexcept;
129 
130 template <size_t N>
131 bool operator!=(const Index<N>& lhs, const Index<N>& rhs) noexcept;
132 /// \endcond
Index< Dim - 1 > slice_away(const size_t d) const noexcept
Return a smaller Index with the d-th element removed.
Definition: Index.hpp:84
Definition: Strahlkorper.hpp:14
size_t collapsed_index(const Index< N > &index, const Index< N > &extents) noexcept
Get the collapsed index into a 1D array of the data corresponding to this Index. Note that the first ...
Defines function make_array.
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
Defines the type alias Requires.
Index(const size_t i0=std::numeric_limits< size_t >::max()) noexcept
Construct with each element set to the same value.
Definition: Index.hpp:31
Index(I... i) noexcept
Construct specifying value in each dimension.
Definition: Index.hpp:36
constexpr std::array< T, Size > make_array(Args &&... args) noexcept(noexcept(MakeArray_detail::MakeArray< Size==0 >::template apply< T >(std::make_index_sequence<(Size==0 ? Size :Size - 1)>{}, std::forward< Args >(args)...)))
Create a std::array<T, Size>{{T(args...), T(args...), ...}}
Definition: MakeArray.hpp:68
constexpr bool conjunction_v
Definition: TypeTraits.hpp:108
Defines macro ASSERT.
An integer multi-index.
Definition: Index.hpp:28
Defines functions and classes from the GSL.
constexpr size_t product() const noexcept
The product of the indices. If Dim = 0, the product is defined as 1.
Definition: Index.hpp:69
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
Defines type traits, some of which are future STL type_traits header.
Check if I is an integer type (non-bool, non-character), unlike std::is_integral. ...
Definition: TypeTraits.hpp:1281
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid...
Definition: Gsl.hpp:124