Alexandria  2.16
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GridIndexHelper.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 
27 namespace Euclid {
28 namespace GridContainer {
29 
30 template<typename... AxesTypes>
32  : m_axes_sizes {
34  axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
37  axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
38  }, m_axes_names {
40  axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
41  } { }
42 
43 template<typename... AxesTypes>
44 size_t GridIndexHelper<AxesTypes...>::axisIndex(size_t axis, size_t array_index) const {
45  size_t index = array_index % m_axes_index_factors[axis + 1];
46  index = index / m_axes_index_factors[axis];
47  return index;
48 }
49 
50 template <typename Coord>
51 size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord) {
52  return coord * factors[factors.size() - 2];
53 }
54 
55 template <typename Coord, typename... RestCoords>
56 size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord, RestCoords... rest_coords) {
57  return coord * factors[factors.size()-sizeof...(RestCoords)-2] + calculateTotalIndex(factors, rest_coords...);
58 }
59 
60 template<typename... AxesTypes>
61 size_t GridIndexHelper<AxesTypes...>::totalIndex(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
62  return calculateTotalIndex(m_axes_index_factors, coords...);
63 }
64 
65 template <typename Coord>
66 void checkBounds(const std::vector<std::string>& axes_names,
67  const std::vector<size_t>& axes_sizes, Coord coord) {
68  if (coord >= axes_sizes[axes_sizes.size()-1]) {
69  throw Elements::Exception() << "Coordinate " << coord << " for axis "
70  << axes_names[axes_sizes.size()-1] << " (size "
71  << axes_sizes[axes_sizes.size()-1]
72  << ") is out of bound";
73  }
74 }
75 
76 template <typename Coord, typename... RestCoords>
77 void checkBounds(const std::vector<std::string>& axes_names,
78  const std::vector<size_t>& axes_sizes, Coord coord, RestCoords... rest_coords) {
79  if (coord >= axes_sizes[axes_sizes.size()-sizeof...(RestCoords)-1]) {
80  throw Elements::Exception() << "Coordinate " << coord << " for axis "
81  << axes_names[axes_sizes.size()-sizeof...(RestCoords)-1] << " (size "
82  << axes_sizes[axes_sizes.size()-sizeof...(RestCoords)-1]
83  << ") is out of bound";
84  }
85  checkBounds(axes_names, axes_sizes, rest_coords...);
86 }
87 
88 template<typename... AxesTypes>
89 size_t GridIndexHelper<AxesTypes...>::totalIndexChecked(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
90  checkBounds(m_axes_names, m_axes_sizes, coords...);
91  return calculateTotalIndex(m_axes_index_factors, coords...);
92 }
93 
94 template<typename... AxesTypes>
95 template <typename Coord>
96 void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord) const {
97  if (coord != 0) {
98  if (fixed_indices.find(m_axes_sizes.size()-1) != fixed_indices.end()) {
99  throw Elements::Exception() << "Coordinate " << coord << " for axis "
100  << m_axes_names[m_axes_sizes.size()-1] << " (size 1) is out of bound";
101  }
102  }
103 }
104 
105 template<typename... AxesTypes>
106 template <typename Coord, typename... RestCoords>
108  Coord coord, RestCoords... rest_coords) const {
109  if (coord != 0) {
110  size_t axis_index = m_axes_sizes.size() - sizeof...(RestCoords) - 1;
111  if (fixed_indices.find(axis_index) != fixed_indices.end()) {
112  throw Elements::Exception() << "Coordinate " << coord << " for axis "
113  << m_axes_names[axis_index] << " (size 1) is out of bound";
114  }
115  }
116  checkAllFixedAreZero(fixed_indices, rest_coords...);
117 }
118 
119 }
120 } // end of namespace Euclid
std::vector< size_t > m_axes_index_factors
size_t totalIndex(decltype(std::declval< GridAxis< AxesTypes >>().size())...coords) const
T end(T...args)
GridIndexHelper(const std::tuple< GridAxis< AxesTypes >...> &axes_tuple)
static std::vector< std::string > createAxesNamesVector(const std::tuple< GridAxis< Axes >...> &axes, const TemplateLoopCounter< I > &)
Creates a vector which contains the names of the given axes.
Provides information related with an axis of a GridContainer.
Definition: GridAxis.h:49
std::vector< std::string > m_axes_names
T declval(T...args)
static std::vector< size_t > createAxisIndexFactorVector(const std::tuple< GridAxis< Axes >...> &axes, const TemplateLoopCounter< I > &)
Creates a vector which contains the index factors of the given axes.
static std::vector< size_t > createAxesSizesVector(const std::tuple< GridAxis< Axes >...> &axes, const TemplateLoopCounter< I > &)
Creates a vector which contains the sizes of the given axes.
T find(T...args)
T size(T...args)
void checkAllFixedAreZero(const std::map< size_t, size_t > &fixed_indices, Coord coord) const
Checks if any of the given coordinates is fixed and not zero.
size_t totalIndexChecked(decltype(std::declval< GridAxis< AxesTypes >>().size())...coords) const
size_t axisIndex(size_t axis, size_t array_index) const