2 * Copyright (C) 2012-2021 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"
28namespace GridContainer {
30template <typename... AxesTypes>
31GridIndexHelper<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)>{})}
37 GridConstructionHelper<AxesTypes...>::createAxesNamesVector(axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})} {}
39template <typename... AxesTypes>
40size_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];
46template <typename Coord>
47size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord) {
48 return coord * factors[factors.size() - 2];
51template <typename Coord, typename... RestCoords>
52size_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...);
56template <typename... AxesTypes>
57size_t GridIndexHelper<AxesTypes...>::totalIndex(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
58 return calculateTotalIndex(m_axes_index_factors, coords...);
61template <typename Coord>
62void 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";
69template <typename Coord, typename... RestCoords>
70void 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";
77 checkBounds(axes_names, axes_sizes, rest_coords...);
80template <typename... AxesTypes>
81size_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...);
86template <typename... AxesTypes>
87template <typename Coord>
88void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord) const {
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";
97template <typename... AxesTypes>
98template <typename Coord, typename... RestCoords>
99void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord,
100 RestCoords... rest_coords) const {
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";
108 checkAllFixedAreZero(fixed_indices, rest_coords...);
111} // namespace GridContainer
112} // end of namespace Euclid