Alexandria  2.18
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GridContainer.icpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
26 #include "GridConstructionHelper.h"
27 
28 namespace Euclid {
29 namespace GridContainer {
30 
31 template <typename GridCellManager, typename... AxesTypes>
33 
34 template <typename GridCellManager, typename... AxesTypes>
36  : m_axes{std::move(axes_tuple)} {}
37 
38 template <typename... AxesTypes>
39 std::tuple<GridAxis<AxesTypes>...> fixAxis(const std::tuple<GridAxis<AxesTypes>...>& original, size_t axis, size_t index) {
40  std::tuple<GridAxis<AxesTypes>...> result{original};
41  GridConstructionHelper<AxesTypes...>::template findAndFixAxis(result, axis, index, TemplateLoopCounter<0>{});
42  return result;
43 }
44 
45 template <typename GridCellManager, typename... AxesTypes>
47  size_t index)
48  : m_axes{other.m_axes}
49  , m_axes_fixed{fixAxis(other.m_axes, axis, index)}
50  , m_fixed_indices{other.m_fixed_indices}
51  , m_cell_manager{other.m_cell_manager} {
52  // Update the fixed indices
53  if (m_fixed_indices.find(axis) != m_fixed_indices.end()) {
54  throw Elements::Exception() << "Axis " << axis << " is already fixed";
55  }
56  m_fixed_indices[axis] = index;
57 }
58 
59 template <typename GridCellManager, typename... AxesTypes>
60 template <int I>
62  return std::get<I>(m_axes);
63 }
64 
65 template <typename GridCellManager, typename... AxesTypes>
67  return std::tuple_size<decltype(m_axes_fixed)>::value;
68 }
69 
70 template <typename GridCellManager, typename... AxesTypes>
71 template <int I>
73  return std::get<I>(m_axes_fixed);
74 }
75 
76 template <typename GridCellManager, typename... AxesTypes>
78  return m_axes_fixed;
79 }
80 
81 template <typename GridCellManager, typename... AxesTypes>
83  iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
85  return result;
86 }
87 
88 template <typename GridCellManager, typename... AxesTypes>
90  const_iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
92  return result;
93 }
94 
95 template <typename GridCellManager, typename... AxesTypes>
97  const_iterator result{*this, GridCellManagerTraits<GridCellManager>::begin(*m_cell_manager)};
99  return result;
100 }
101 
102 template <typename GridCellManager, typename... AxesTypes>
104  return iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
105 }
106 
107 template <typename GridCellManager, typename... AxesTypes>
109  return const_iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
110 }
111 
112 template <typename GridCellManager, typename... AxesTypes>
114  return const_iterator{*this, GridCellManagerTraits<GridCellManager>::end(*m_cell_manager)};
115 }
116 
117 template <typename GridCellManager, typename... AxesTypes>
119  return m_index_helper_fixed.m_axes_index_factors.back();
120 }
121 
122 template <typename GridCellManager, typename... AxesTypes>
124  -> const cell_type& {
125  size_t total_index = m_index_helper.totalIndex(indices...);
126  // If we have fixed axes we need to move the index accordingly
127  for (auto& pair : m_fixed_indices) {
128  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
129  }
130  return (*m_cell_manager)[total_index];
131 }
132 
133 template <typename GridCellManager, typename... AxesTypes>
135  -> cell_type& {
136  return const_cast<cell_type&>(static_cast<const GridContainer&>(*this)(indices...));
137 }
138 
139 template <typename GridCellManager, typename... AxesTypes>
141  -> const cell_type& {
142  // First make a check that all the fixed axes are zero
143  m_index_helper.checkAllFixedAreZero(m_fixed_indices, indices...);
144  size_t total_index = m_index_helper.totalIndexChecked(indices...);
145  // If we have fixed axes we need to move the index accordingly
146  for (auto& pair : m_fixed_indices) {
147  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
148  }
149  return (*m_cell_manager)[total_index];
150 }
151 
152 template <typename GridCellManager, typename... AxesTypes>
154  -> cell_type& {
155  return const_cast<cell_type&>(static_cast<const GridContainer&>(*this).at(indices...));
156 }
157 
158 template <typename GridCellManager, typename... AxesTypes>
159 template <int I>
161  if (index >= getOriginalAxis<I>().size()) {
162  throw Elements::Exception() << "Index (" << index << ") out of axis " << getOriginalAxis<I>().name() << " size ("
163  << getOriginalAxis<I>().size() << ")";
164  }
165  return GridContainer<GridCellManager, AxesTypes...>(*this, I, index);
166 }
167 
168 template <typename GridCellManager, typename... AxesTypes>
169 template <int I>
170 const GridContainer<GridCellManager, AxesTypes...>
172  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByIndex<I>(index);
173 }
174 
175 template <typename GridCellManager, typename... AxesTypes>
176 template <int I>
177 GridContainer<GridCellManager, AxesTypes...>
179  auto& axis = getOriginalAxis<I>();
180  auto found_axis = std::find(axis.begin(), axis.end(), value);
181  if (found_axis == axis.end()) {
182  throw Elements::Exception() << "Failed to fix axis " << getOriginalAxis<I>().name() << " (given value not found)";
183  }
184  return GridContainer<GridCellManager, AxesTypes...>(*this, I, found_axis - axis.begin());
185 }
186 
187 template <typename GridCellManager, typename... AxesTypes>
188 template <int I>
189 const GridContainer<GridCellManager, AxesTypes...>
191  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByValue<I>(value);
192 }
193 
194 } // end of namespace GridContainer
195 } // end of namespace Euclid
std::tuple< GridAxis< AxesTypes >...> m_axes
A tuple containing the axes of the grid.
Class to iterate through the GridContainer cells.
Class used by the GridContainer to access the different CellManagers.
Representation of a multi-dimensional grid which contains axis information.
Definition: GridContainer.h:97
const cell_type & at(decltype(std::declval< GridAxis< AxesTypes >>().size())...indices) const
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.
typename std::tuple_element< I, std::tuple< AxesTypes...>>::type axis_type
GridCellManagerTraits< GridCellManager >::data_type cell_type
The type of the values stored in the grid cells.
std::tuple< GridAxis< AxesTypes >...> fixAxis(const std::tuple< GridAxis< AxesTypes >...> &original, size_t axis, size_t index)