Alexandria  2.14.1
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
GridContainer.icpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 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  : m_axes{std::move(axes)...} { }
34 
35 template<typename GridCellManager, typename... AxesTypes>
37  : m_axes{std::move(axes_tuple)} { }
38 
39 template<typename... AxesTypes>
40 std::tuple<GridAxis<AxesTypes>...> fixAxis(const std::tuple<GridAxis<AxesTypes>...>& original, size_t axis, size_t index) {
41  std::tuple<GridAxis<AxesTypes>...> result {original};
42  GridConstructionHelper<AxesTypes...>::template findAndFixAxis(result, axis, index, TemplateLoopCounter<0>{});
43  return result;
44 }
45 
46 template<typename GridCellManager, typename... AxesTypes>
49  size_t axis, size_t index)
50  : m_axes{other.m_axes}, m_axes_fixed{fixAxis(other.m_axes_fixed, axis, index)},
51  m_fixed_indices{other.m_fixed_indices}, 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  size_t total_index = m_index_helper.totalIndex(indices...);
125  // If we have fixed axes we need to move the index accordingly
126  for (auto& pair : m_fixed_indices) {
127  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
128  }
129  return (*m_cell_manager)[total_index];
130 }
131 
132 template<typename GridCellManager, typename... AxesTypes>
134  return const_cast<cell_type&>(static_cast<const GridContainer&>(*this)(indices...));
135 }
136 
137 template<typename GridCellManager, typename... AxesTypes>
139  // First make a check that all the fixed axes are zero
140  m_index_helper.checkAllFixedAreZero(m_fixed_indices, indices...);
141  size_t total_index = m_index_helper.totalIndexChecked(indices...);
142  // If we have fixed axes we need to move the index accordingly
143  for (auto& pair : m_fixed_indices) {
144  total_index += pair.second * m_index_helper.m_axes_index_factors[pair.first];
145  }
146  return (*m_cell_manager)[total_index];
147 }
148 
149 template<typename GridCellManager, typename... AxesTypes>
151  return const_cast<cell_type&>(static_cast<const GridContainer&>(*this).at(indices...));
152 }
153 
154 template<typename GridCellManager, typename... AxesTypes>
155 template<int I>
157  if (index >= getOriginalAxis<I>().size()) {
158  throw Elements::Exception() << "Index (" << index << ") out of axis "
159  << getOriginalAxis<I>().name() << " size ("
160  << getOriginalAxis<I>().size() << ")";
161  }
162  return GridContainer<GridCellManager, AxesTypes...>(*this, I, index);
163 }
164 
165 template<typename GridCellManager, typename... AxesTypes>
166 template<int I>
167 const GridContainer<GridCellManager, AxesTypes...> GridContainer<GridCellManager, AxesTypes...>::fixAxisByIndex(size_t index) const {
168  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByIndex<I>(index);
169 }
170 
171 template<typename GridCellManager, typename... AxesTypes>
172 template<int I>
174  auto& axis = getOriginalAxis<I>();
175  auto iter = std::find(axis.begin(), axis.end(), value);
176  if (iter == axis.end()) {
177  throw Elements::Exception() << "Failed to fix axis " << getOriginalAxis<I>().name()
178  << " (given value not found)";
179  }
180  return GridContainer<GridCellManager, AxesTypes...>(*this, I, iter-axis.begin());
181 }
182 
183 template<typename GridCellManager, typename... AxesTypes>
184 template<int I>
185 const GridContainer<GridCellManager, AxesTypes...> GridContainer<GridCellManager, AxesTypes...>::fixAxisByValue(const axis_type<I>& value) const {
186  return const_cast<GridContainer<GridCellManager, AxesTypes...>*>(this)->fixAxisByValue<I>(value);
187 }
188 
189 } // end of namespace GridContainer
190 } // 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)