2 * Copyright (C) 2012-2020 Euclid Science Ground Segment
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)
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
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
20 * @file GridContainer/_impl/GridIndexHelper.icpp
22 * @author Nikolaos Apostolakos
25 #include "ElementsKernel/Exception.h"
28 namespace GridContainer {
30 template<typename... AxesTypes>
31 GridIndexHelper<AxesTypes...>::GridIndexHelper(const std::tuple<GridAxis<AxesTypes>...>& axes_tuple)
33 GridConstructionHelper<AxesTypes...>::createAxesSizesVector(
34 axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
35 }, m_axes_index_factors {
36 GridConstructionHelper<AxesTypes...>::createAxisIndexFactorVector(
37 axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
39 GridConstructionHelper<AxesTypes...>::createAxesNamesVector(
40 axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})
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];
50 template <typename Coord>
51 size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord) {
52 return coord * factors[factors.size() - 2];
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...);
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...);
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";
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";
85 checkBounds(axes_names, axes_sizes, rest_coords...);
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...);
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 {
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";
105 template<typename... AxesTypes>
106 template <typename Coord, typename... RestCoords>
107 void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices,
108 Coord coord, RestCoords... rest_coords) const {
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";
116 checkAllFixedAreZero(fixed_indices, rest_coords...);
120 } // end of namespace Euclid