Alexandria  2.18
Please provide a description of the project.
GridIndexHelper.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 
19 /**
20  * @file GridContainer/_impl/GridIndexHelper.icpp
21  * @date July 4, 2014
22  * @author Nikolaos Apostolakos
23  */
24 
25 #include "ElementsKernel/Exception.h"
26 
27 namespace Euclid {
28 namespace GridContainer {
29 
30 template <typename... AxesTypes>
31 GridIndexHelper<AxesTypes...>::GridIndexHelper(const std::tuple<GridAxis<AxesTypes>...>& axes_tuple)
32  : m_axes_sizes{GridConstructionHelper<AxesTypes...>::createAxesSizesVector(axes_tuple,
33  TemplateLoopCounter<sizeof...(AxesTypes)>{})}
34  , m_axes_index_factors{GridConstructionHelper<AxesTypes...>::createAxisIndexFactorVector(
35  axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})}
36  , m_axes_names{
37  GridConstructionHelper<AxesTypes...>::createAxesNamesVector(axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})} {}
38 
39 template <typename... AxesTypes>
40 size_t GridIndexHelper<AxesTypes...>::axisIndex(size_t axis, size_t array_index) const {
41  size_t index = array_index % m_axes_index_factors[axis + 1];
42  index = index / m_axes_index_factors[axis];
43  return index;
44 }
45 
46 template <typename Coord>
47 size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord) {
48  return coord * factors[factors.size() - 2];
49 }
50 
51 template <typename Coord, typename... RestCoords>
52 size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord, RestCoords... rest_coords) {
53  return coord * factors[factors.size() - sizeof...(RestCoords) - 2] + calculateTotalIndex(factors, rest_coords...);
54 }
55 
56 template <typename... AxesTypes>
57 size_t GridIndexHelper<AxesTypes...>::totalIndex(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
58  return calculateTotalIndex(m_axes_index_factors, coords...);
59 }
60 
61 template <typename Coord>
62 void checkBounds(const std::vector<std::string>& axes_names, const std::vector<size_t>& axes_sizes, Coord coord) {
63  if (coord >= axes_sizes[axes_sizes.size() - 1]) {
64  throw Elements::Exception() << "Coordinate " << coord << " for axis " << axes_names[axes_sizes.size() - 1] << " (size "
65  << axes_sizes[axes_sizes.size() - 1] << ") is out of bound";
66  }
67 }
68 
69 template <typename Coord, typename... RestCoords>
70 void checkBounds(const std::vector<std::string>& axes_names, const std::vector<size_t>& axes_sizes, Coord coord,
71  RestCoords... rest_coords) {
72  if (coord >= axes_sizes[axes_sizes.size() - sizeof...(RestCoords) - 1]) {
73  throw Elements::Exception() << "Coordinate " << coord << " for axis "
74  << axes_names[axes_sizes.size() - sizeof...(RestCoords) - 1] << " (size "
75  << axes_sizes[axes_sizes.size() - sizeof...(RestCoords) - 1] << ") is out of bound";
76  }
77  checkBounds(axes_names, axes_sizes, rest_coords...);
78 }
79 
80 template <typename... AxesTypes>
81 size_t GridIndexHelper<AxesTypes...>::totalIndexChecked(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
82  checkBounds(m_axes_names, m_axes_sizes, coords...);
83  return calculateTotalIndex(m_axes_index_factors, coords...);
84 }
85 
86 template <typename... AxesTypes>
87 template <typename Coord>
88 void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord) const {
89  if (coord != 0) {
90  if (fixed_indices.find(m_axes_sizes.size() - 1) != fixed_indices.end()) {
91  throw Elements::Exception() << "Coordinate " << coord << " for axis " << m_axes_names[m_axes_sizes.size() - 1]
92  << " (size 1) is out of bound";
93  }
94  }
95 }
96 
97 template <typename... AxesTypes>
98 template <typename Coord, typename... RestCoords>
99 void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord,
100  RestCoords... rest_coords) const {
101  if (coord != 0) {
102  size_t axis_index = m_axes_sizes.size() - sizeof...(RestCoords) - 1;
103  if (fixed_indices.find(axis_index) != fixed_indices.end()) {
104  throw Elements::Exception() << "Coordinate " << coord << " for axis " << m_axes_names[axis_index]
105  << " (size 1) is out of bound";
106  }
107  }
108  checkAllFixedAreZero(fixed_indices, rest_coords...);
109 }
110 
111 } // namespace GridContainer
112 } // end of namespace Euclid