Alexandria  2.27.0
SDC-CH common library for the Euclid project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GridContainer.icpp
Go to the documentation of this file.
1 
26 #include "GridConstructionHelper.h"
27 
28 namespace Euclid {
29 namespace GridContainer {
30 
31 template <typename GridCellManager, typename... AxesTypes>
35  m_axes, TemplateLoopCounter<sizeof...(AxesTypes) - 1>{}));
36 }
37 
38 template <typename GridCellManager, typename... AxesTypes>
40  : m_axes{std::move(axes_tuple)} {
43  m_axes, TemplateLoopCounter<sizeof...(AxesTypes) - 1>{}));
44 }
45 
46 template <typename GridCellManager, typename... AxesTypes>
47 template <typename... Args>
49  Args&&... args)
50  : m_axes{std::move(axes_tuple)} {
53  std::forward<Args>(args)...);
54 }
55 
56 template <typename... AxesTypes>
58  size_t index) {
59  std::tuple<GridAxis<AxesTypes>...> result{original};
60  GridConstructionHelper<AxesTypes...>::template findAndFixAxis(result, axis, index, TemplateLoopCounter<0>{});
61  return result;
62 }
63 
64 template <typename GridCellManager, typename... AxesTypes>
68  m_axes, TemplateLoopCounter<sizeof...(AxesTypes) - 1>{}))} {}
69 
70 template <typename GridCellManager, typename... AxesTypes>
71 GridContainer<GridCellManager, AxesTypes...>::GridContainer(const GridContainer<GridCellManager, AxesTypes...>& other,
72  size_t axis, size_t index)
73  : m_axes{other.m_axes}
74  , m_axes_fixed{fixAxis(other.m_axes, axis, index)}
75  , m_fixed_indices{other.m_fixed_indices}
76  , m_cell_manager{other.m_cell_manager} {
77  // Update the fixed indices
78  if (m_fixed_indices.find(axis) != m_fixed_indices.end()) {
79  throw Elements::Exception() << "Axis " << axis << " is already fixed";
80  }
81  m_fixed_indices[axis] = index;
82 }
83 
84 template <typename GridCellManager, typename... AxesTypes>
85 auto GridContainer<GridCellManager, AxesTypes...>::copy() const -> GridContainer {
86  GridContainer clone{m_axes};
87  std::copy(begin(), end(), std::begin(clone));
88  return clone;
89 }
90 
91 template <typename GridCellManager, typename... AxesTypes>
92 template <int I>
93 auto GridContainer<GridCellManager, AxesTypes...>::getOriginalAxis() const -> const GridAxis<axis_type<I>>& {
94  return std::get<I>(m_axes);
95 }
96 
97 template <typename GridCellManager, typename... AxesTypes>
99  return std::tuple_size<decltype(m_axes_fixed)>::value;
100 }
101 
102 template <typename GridCellManager, typename... AxesTypes>
103 template <int I>
104 auto GridContainer<GridCellManager, AxesTypes...>::getAxis() const -> const GridAxis<axis_type<I>>& {
105  return std::get<I>(m_axes_fixed);
106 }
107 
108 template <typename GridCellManager, typename... AxesTypes>
110  return m_axes_fixed;
111 }
112 
113 template <typename GridCellManager, typename... AxesTypes>
115  iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
116  GridConstructionHelper<AxesTypes...>::fixIteratorAxes(result, m_fixed_indices, TemplateLoopCounter<0>{});
117  return result;
118 }
119 
120 template <typename GridCellManager, typename... AxesTypes>
121 auto GridContainer<GridCellManager, AxesTypes...>::begin() const -> const_iterator {
122  const_iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
123  GridConstructionHelper<AxesTypes...>::fixIteratorAxes(result, m_fixed_indices, TemplateLoopCounter<0>{});
124  return result;
125 }
126 
127 template <typename GridCellManager, typename... AxesTypes>
129  const_iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
130  GridConstructionHelper<AxesTypes...>::fixIteratorAxes(result, m_fixed_indices, TemplateLoopCounter<0>{});
131  return result;
132 }
133 
134 template <typename GridCellManager, typename... AxesTypes>
136  return iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
137 }
138 
139 template <typename GridCellManager, typename... AxesTypes>
140 auto GridContainer<GridCellManager, AxesTypes...>::end() const -> const_iterator {
141  return const_iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
142 }
143 
144 template <typename GridCellManager, typename... AxesTypes>
146  return const_iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
147 }
148 
149 template <typename GridCellManager, typename... AxesTypes>
151  return m_index_helper_fixed.m_axes_index_factors.back();
152 }
153 
154 template <typename GridCellManager, typename... AxesTypes>
156  decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) const -> const reference_type {
157  size_t total_index = m_index_helper.totalIndex(indices...);
158  // If we have fixed axes we need to move the index accordingly
159  for (auto& pair : m_fixed_indices) {
160  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
161  }
162  return (*m_cell_manager)[total_index];
163 }
164 
165 template <typename GridCellManager, typename... AxesTypes>
167  decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) -> reference_type {
168  size_t total_index = m_index_helper.totalIndex(indices...);
169  // If we have fixed axes we need to move the index accordingly
170  for (auto& pair : m_fixed_indices) {
171  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
172  }
173  return (*m_cell_manager)[total_index];
174 }
175 
176 template <typename GridCellManager, typename... AxesTypes>
178  decltype(std::declval<GridAxis<AxesTypes>>().size())... indices) const -> const reference_type {
179  return const_cast<GridContainer*>(this)->at(indices...);
180 }
181 
182 template <typename GridCellManager, typename... AxesTypes>
183 auto GridContainer<GridCellManager, AxesTypes...>::at(decltype(std::declval<GridAxis<AxesTypes>>().size())... indices)
184  -> reference_type {
185  // First make a check that all the fixed axes are zero
186  m_index_helper.checkAllFixedAreZero(m_fixed_indices, indices...);
187  size_t total_index = m_index_helper.totalIndexChecked(indices...);
188  // If we have fixed axes we need to move the index accordingly
189  for (auto& pair : m_fixed_indices) {
190  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
191  }
192  return (*m_cell_manager)[total_index];
193 }
194 
195 template <std::size_t I>
196 struct InfimumHelper {
197  template <typename>
198  using Index = std::size_t;
199 
200  template <typename... AxesType>
201  static std::tuple<Index<AxesType>...> getIndex(const std::tuple<AxesType...>& coords,
202  const std::tuple<GridAxis<AxesType>...>& axes) {
203  std::tuple<Index<AxesType>...> index;
204  getIndex(coords, axes, index);
205  return index;
206  }
207 
208  template <typename IndexTuple, typename... AxesType>
209  static void getIndex(const std::tuple<AxesType...>& coords, const std::tuple<GridAxis<AxesType>...>& axes,
210  IndexTuple& index) {
211  auto& axn = std::get<I>(axes);
212  std::get<I>(index) = axn.infimum(std::get<I>(coords)) - axn.begin();
213  InfimumHelper<I - 1>::getIndex(coords, axes, index);
214  }
215 };
216 
217 template <>
218 struct InfimumHelper<0> {
219  template <typename>
221 
222  template <typename... AxesType>
224  const std::tuple<GridAxis<AxesType>...>& axes) {
225  auto i0 = std::get<0>(axes).infimum(std::get<0>(coords));
226  return std::make_tuple(i0);
227  }
228 
229  template <typename IndexTuple, typename... AxesType>
230  static void getIndex(const std::tuple<AxesType...>& coords, const std::tuple<GridAxis<AxesType>...>& axes,
231  IndexTuple& index) {
232  auto& ax0 = std::get<0>(axes);
233  std::get<0>(index) = ax0.infimum(std::get<0>(coords)) - ax0.begin();
234  }
235 };
236 
237 template <typename GridCellManager, typename... AxesTypes>
238 auto GridContainer<GridCellManager, AxesTypes...>::infimum(const AxesTypes... coordinates) const
239  -> std::tuple<decltype(std::declval<GridAxis<AxesTypes>>().size())...> {
240  return infimum(std::make_tuple(coordinates...));
241 }
242 
243 template <typename GridCellManager, typename... AxesTypes>
246  return InfimumHelper<sizeof...(AxesTypes) - 1>::getIndex(coords, m_axes);
247 }
248 
249 template <typename GridCellManager, typename... AxesTypes>
250 template <int I>
251 GridContainer<GridCellManager, AxesTypes...>
253  if (index >= getOriginalAxis<I>().size()) {
254  throw Elements::Exception() << "Index (" << index << ") out of axis " << getOriginalAxis<I>().name() << " size ("
255  << getOriginalAxis<I>().size() << ")";
256  }
257  return GridContainer<GridCellManager, AxesTypes...>(*this, I, index);
258 }
259 
260 template <typename GridCellManager, typename... AxesTypes>
261 template <int I>
262 const GridContainer<GridCellManager, AxesTypes...>
264  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByIndex<I>(index);
265 }
266 
267 template <typename GridCellManager, typename... AxesTypes>
268 template <int I>
269 GridContainer<GridCellManager, AxesTypes...>
271  auto& axis = getOriginalAxis<I>();
272  auto found_axis = std::find(axis.begin(), axis.end(), value);
273  if (found_axis == axis.end()) {
274  throw Elements::Exception() << "Failed to fix axis " << getOriginalAxis<I>().name() << " (given value not found)";
275  }
276  return GridContainer<GridCellManager, AxesTypes...>(*this, I, found_axis - axis.begin());
277 }
278 
279 template <typename GridCellManager, typename... AxesTypes>
280 template <int I>
281 const GridContainer<GridCellManager, AxesTypes...>
283  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByValue<I>(value);
284 }
285 
286 } // end of namespace GridContainer
287 } // end of namespace Euclid
size_t size() const
Returns the total number of cells of the grid.
T copy(T...args)
GridContainer copy() const
But if needed be, allow explicit copies.
std::tuple< GridAxis< AxesTypes >...> m_axes
A tuple containing the axes of the grid.
static void getIndex(const std::tuple< AxesType...> &coords, const std::tuple< GridAxis< AxesType >...> &axes, IndexTuple &index)
const reference_type at(decltype(std::declval< GridAxis< AxesTypes >>().size())...indices) const
const_iterator cbegin()
Returns a constant iterator to the first cell of the grid.
const_iterator cend()
Returns a constant iterator to the cell after the last of the grid.
T make_tuple(T...args)
Representation of a multi-dimensional grid which contains axis information.
Definition: GridContainer.h:97
T end(T...args)
const GridAxis< axis_type< I > > & getOriginalAxis() const
const reference_type operator()(decltype(std::declval< GridAxis< AxesTypes >>().size())...indices) const
static std::unique_ptr< GridCellManager > factory(size_t size)
Provides information related with an axis of a GridContainer.
Definition: GridAxis.h:49
T declval(T...args)
T move(T...args)
T find(T...args)
GridContainer construction helper class.
T begin(T...args)
typename std::tuple_element< I, std::tuple< AxesTypes...>>::type axis_type
static constexpr size_t axisNumber()
Returns the number of axes of the grid (dimensionality)
iterator end()
Returns an iterator to the cell after the last of the grid.
iterator begin()
Returns an iterator to the first cell of the grid.
static std::tuple< std::size_t > getIndex(const std::tuple< AxesType...> &coords, const std::tuple< GridAxis< AxesType >...> &axes)
std::tuple< GridAxis< AxesTypes >...> fixAxis(const std::tuple< GridAxis< AxesTypes >...> &original, size_t axis, size_t index)
const std::tuple< GridAxis< AxesTypes >...> & getAxesTuple() const
Returns a tuple containing the information of all the grid axes.