/*
 * Copyright (c) 2016, 2017 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_VALIDATE_H__
#define __ARM_COMPUTE_VALIDATE_H__

#include "arm_compute/core/Error.h"
#include "arm_compute/core/HOGInfo.h"
#include "arm_compute/core/IKernel.h"
#include "arm_compute/core/IMultiHOG.h"
#include "arm_compute/core/IMultiImage.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/MultiImageInfo.h"
#include "arm_compute/core/Window.h"

#include <algorithm>

namespace arm_compute
{
namespace detail
{
/* Check whether two dimension objects differ.
 *
 * @param[in] dim1      First object to be compared.
 * @param[in] dim2      Second object to be compared.
 * @param[in] upper_dim The dimension from which to check.
 *
 * @return Return true if the two objects are different.
 */
template <typename T>
inline bool have_different_dimensions(const Dimensions<T> &dim1, const Dimensions<T> &dim2, unsigned int upper_dim)
{
    for(unsigned int i = upper_dim; i < arm_compute::Dimensions<T>::num_max_dimensions; ++i)
    {
        if(dim1[i] != dim2[i])
        {
            return true;
        }
    }

    return false;
}

/** Functor to compare two @ref Dimensions objects and throw an error on mismatch.
 *
 * @param[in] dim      Object to compare against.
 * @param[in] function Function in which the error occured.
 * @param[in] file     File in which the error occured.
 * @param[in] line     Line in which the error occured.
 */
template <typename T>
class compare_dimension
{
public:
    compare_dimension(const Dimensions<T> &dim, const char *function, const char *file, int line)
        : _dim{ dim }, _function{ function }, _file{ file }, _line{ line }
    {
    }

    /** Compare the given object against the stored one.
     *
     * @param[in] dim To be compared object.
     */
    void operator()(const Dimensions<T> &dim)
    {
        ARM_COMPUTE_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
                                     "Objects have different dimensions");
    }

private:
    const Dimensions<T> &_dim;
    const char *const    _function;
    const char *const    _file;
    const int            _line;
};
} // namespace detail
/** Throw an error if one of the pointers is a nullptr.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] pointers Pointers to check against nullptr.
 */
template <typename... Ts>
void error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
{
    auto is_nullptr = [&](const void *ptr)
    {
        ARM_COMPUTE_ERROR_ON_LOC(ptr == nullptr, function, file, line);
    };

    for_each(is_nullptr, std::forward<Ts>(pointers)...);
}
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...) ::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the passed window is invalid.
 *
 * The subwindow is invalid if:
 * - It is not a valid window.
 * - Its dimensions don't match the full window's ones
 * - The step for each of its dimension is not identical to the corresponding one of the full window.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] full     Full size window
 *  @param[in] win      Window to validate.
 */
void error_on_mismatching_windows(const char *function, const char *file, const int line,
                                  const Window &full, const Window &win);
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) ::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w)

/** Throw an error if the passed subwindow is invalid.
 *
 * The subwindow is invalid if:
 * - It is not a valid window.
 * - It is not fully contained inside the full window
 * - The step for each of its dimension is not identical to the corresponding one of the full window.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] full     Full size window
 *  @param[in] sub      Sub-window to validate.
 */
void error_on_invalid_subwindow(const char *function, const char *file, const int line,
                                const Window &full, const Window &sub);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) ::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s)

/** Throw an error if the window can't be collapsed at the given dimension.
 *
 * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] full     Full size window
 *  @param[in] window   Window to be collapsed.
 *  @param[in] dim      Dimension need to be checked.
 */
void error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
                                                  const Window &full, const Window &window, const int dim);
#define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) ::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d)

/** Throw an error if the passed coordinates have too many dimensions.
 *
 * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] pos      Coordinates to validate
 *  @param[in] max_dim  Maximum number of dimensions allowed.
 */
void error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
                                         const Coordinates &pos, unsigned int max_dim);
#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) ::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md)

/** Throw an error if the passed window has too many dimensions.
 *
 * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] win      Window to validate
 *  @param[in] max_dim  Maximum number of dimensions allowed.
 */
void error_on_window_dimensions_gte(const char *function, const char *file, const int line,
                                    const Window &win, unsigned int max_dim);
#define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) ::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md)

/** Throw an error if the passed dimension objects differ.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] dim1     The first object to be compared.
 *  @param[in] dim2     The second object to be compared.
 *  @param[in] dims     (Optional) Further allowed objects.
 */
template <typename T, typename... Ts>
void error_on_mismatching_dimensions(const char *function, const char *file, int line,
                                     const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);

    for_each(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...);
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) ::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the passed two tensors have different shapes from the given dimension
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor_1 The first tensor to be compared.
 *  @param[in] tensor_2 The second tensor to be compared.
 *  @param[in] tensors  (Optional) Further allowed tensors.
 */
template <typename... Ts>
void error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                 const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
}

/** Throw an error if the passed two tensors have different shapes from the given dimension
 *
 *  @param[in] function  Function in which the error occurred.
 *  @param[in] file      Name of the file where the error occurred.
 *  @param[in] line      Line on which the error occurred.
 *  @param[in] upper_dim The dimension from which to check.
 *  @param[in] tensor_1  The first tensor to be compared.
 *  @param[in] tensor_2  The second tensor to be compared.
 *  @param[in] tensors   (Optional) Further allowed tensors.
 */
template <typename... Ts>
void error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                 unsigned int upper_dim, const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);

    const std::array < const ITensor *, 2 + sizeof...(Ts) > tensors_array{ { tensor_1, tensor_2, std::forward<Ts>(tensors)... } };
    ARM_COMPUTE_UNUSED(tensors_array);

    ARM_COMPUTE_ERROR_ON_LOC(tensors_array.cbegin() == nullptr, function, file, line);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_array.cbegin()), tensors_array.cend(), [&](const ITensor * tensor)
    {
        ARM_COMPUTE_ERROR_ON_LOC(tensor == nullptr, function, file, line);
        return detail::have_different_dimensions((*tensors_array.cbegin())->info()->tensor_shape(), tensor->info()->tensor_shape(), upper_dim);
    }),
    function, file, line, "Tensors have different shapes");
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) ::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the passed two tensors have different data types
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor   The first tensor to be compared.
 *  @param[in] tensors  (Optional) Further allowed tensors.
 */
template <typename... Ts>
void error_on_mismatching_data_types(const char *function, const char *file, const int line,
                                     const ITensor *tensor, Ts... tensors)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(tensor);

    ARM_COMPUTE_ERROR_ON_LOC(tensor == nullptr, function, file, line);

    DataType &&tensor_data_type = tensor->info()->data_type();
    ARM_COMPUTE_UNUSED(tensor_data_type);

    const std::array<const ITensor *, sizeof...(Ts)> tensors_array{ { std::forward<Ts>(tensors)... } };
    ARM_COMPUTE_UNUSED(tensors_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(std::any_of(tensors_array.begin(), tensors_array.end(), [&](const ITensor * tensor_obj)
    {
        ARM_COMPUTE_ERROR_ON_LOC(tensor_obj == nullptr, function, file, line);
        return tensor_obj->info()->data_type() != tensor_data_type;
    }),
    function, file, line, "Tensors have different data types");
}

#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) ::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the passed tensors have different fixed point data types or different fixed point positions
 *
 * @note: If the first tensor doesn't have fixed point data type, the function returns without throwing an error
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor_1 The first tensor to be compared.
 *  @param[in] tensor_2 The second tensor to be compared.
 *  @param[in] tensors  (Optional) Further allowed tensors.
 */
template <typename... Ts>
void error_on_mismatching_fixed_point(const char *function, const char *file, const int line,
                                      const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(tensor_1);
    ARM_COMPUTE_UNUSED(tensor_2);

    DataType &&first_data_type            = tensor_1->info()->data_type();
    const int  first_fixed_point_position = tensor_1->info()->fixed_point_position();
    ARM_COMPUTE_UNUSED(first_data_type);
    ARM_COMPUTE_UNUSED(first_fixed_point_position);

    if((first_data_type != DataType::QS8) && (first_data_type != DataType::QS16))
    {
        return;
    }

    const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_array{ { tensor_2, std::forward<Ts>(tensors)... } };
    ARM_COMPUTE_UNUSED(tensors_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(std::any_of(tensors_array.begin(), tensors_array.end(), [&](const ITensor * tensor)
    {
        return tensor->info()->data_type() != first_data_type;
    }),
    function, file, line, "Tensors have different fixed point data types");

    ARM_COMPUTE_ERROR_ON_LOC_MSG(std::any_of(tensors_array.begin(), tensors_array.end(), [&](const ITensor * tensor)
    {
        return tensor->info()->fixed_point_position() != first_fixed_point_position;
    }),
    function, file, line, "Tensors have different fixed point positions");
}

#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT(...) ::arm_compute::error_on_mismatching_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] object   Tensor/multi-image to validate.
 *  @param[in] format   First format allowed.
 *  @param[in] formats  (Optional) Further allowed formats.
 */
template <typename T, typename F, typename... Fs>
void error_on_format_not_in(const char *function, const char *file, const int line,
                            const T *object, F &&format, Fs &&... formats)
{
    ARM_COMPUTE_ERROR_ON_LOC(object == nullptr, function, file, line);

    Format &&object_format = object->info()->format();
    ARM_COMPUTE_UNUSED(object_format);

    ARM_COMPUTE_ERROR_ON_LOC(object_format == Format::UNKNOWN, function, file, line);

    const std::array<F, sizeof...(Fs)> formats_array{ { std::forward<Fs>(formats)... } };
    ARM_COMPUTE_UNUSED(formats_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(object_format != format && std::none_of(formats_array.begin(), formats_array.end(), [&](const F & f)
    {
        return f == object_format;
    }),
    function, file, line, "Format %s not supported by this kernel", string_from_format(object_format).c_str());
}
#define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)

/** Throw an error if the data type of the passed tensor does not match any of the data types provided.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor   Tensor to validate.
 *  @param[in] dt       First data type allowed.
 *  @param[in] dts      (Optional) Further allowed data types.
 */
template <typename T, typename... Ts>
void error_on_data_type_not_in(const char *function, const char *file, const int line,
                               const ITensor *tensor, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_ERROR_ON_LOC(tensor == nullptr, function, file, line);

    const DataType &tensor_dt = tensor->info()->data_type(); //NOLINT
    ARM_COMPUTE_UNUSED(tensor_dt);

    ARM_COMPUTE_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);

    const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
    ARM_COMPUTE_UNUSED(dts_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(tensor_dt != dt && std::none_of(dts_array.begin(), dts_array.end(), [&](const T & d)
    {
        return d == tensor_dt;
    }),
    function, file, line, "ITensor data type %s not supported by this kernel", string_from_data_type(tensor_dt).c_str());
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) ::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)

/** Throw an error if the data type or the number of channels of the passed tensor does not match any of the data types and number of channels provided.
 *
 *  @param[in] function     Function in which the error occurred.
 *  @param[in] file         Name of the file where the error occurred.
 *  @param[in] line         Line on which the error occurred.
 *  @param[in] tensor       Tensor to validate.
 *  @param[in] num_channels Number of channels to check
 *  @param[in] dt           First data type allowed.
 *  @param[in] dts          (Optional) Further allowed data types.
 */
template <typename T, typename... Ts>
void error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
                                       const ITensor *tensor, size_t num_channels, T &&dt, Ts &&... dts)
{
    error_on_data_type_not_in(function, file, line, tensor, std::forward<T>(dt), std::forward<Ts>(dts)...);

    const size_t tensor_nc = tensor->info()->num_channels();
    ARM_COMPUTE_UNUSED(tensor_nc);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(tensor_nc != num_channels, function, file, line, "Number of channels %d. Required number of channels %d", tensor_nc, num_channels);
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) ::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__)

/** Throw an error if the tensor is not 2D.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor   Tensor to validate.
 */
void error_on_tensor_not_2d(const char *function, const char *file, const int line,
                            const ITensor *tensor);
#define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) ::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t)

/** Throw an error if the channel is not in channels.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] cn       Input channel
 *  @param[in] channel  First channel allowed.
 *  @param[in] channels (Optional) Further allowed channels.
 */
template <typename T, typename... Ts>
void error_on_channel_not_in(const char *function, const char *file, const int line,
                             T cn, T &&channel, Ts &&... channels)
{
    ARM_COMPUTE_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);

    const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
    ARM_COMPUTE_UNUSED(channels_array);
    ARM_COMPUTE_ERROR_ON_LOC(channel != cn && std::none_of(channels_array.begin(), channels_array.end(), [&](const T & f)
    {
        return f == cn;
    }),
    function, file, line);
}
#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) ::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__)

/** Throw an error if the channel is not in format.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] fmt      Input channel
 *  @param[in] cn       First channel allowed.
 */
void error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
                                          Format fmt, Channel cn);
#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) ::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c)

/** Throw an error if the @ref IMultiHOG container is invalid
 *
 * An @ref IMultiHOG container is invalid if:
 *
 * -# it is a nullptr
 * -# it doesn't contain models
 * -# it doesn't have the HOG data objects with the same phase_type, normalization_type and l2_hyst_threshold (if normalization_type == L2HYS_NORM)
 *
 *  @param[in] function  Function in which the error occurred.
 *  @param[in] file      Name of the file where the error occurred.
 *  @param[in] line      Line on which the error occurred.
 *  @param[in] multi_hog IMultiHOG container to validate
 */
void error_on_invalid_multi_hog(const char *function, const char *file, const int line,
                                const IMultiHOG *multi_hog);
#define ARM_COMPUTE_ERROR_ON_INVALID_MULTI_HOG(m) ::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m)

/** Throw an error if the kernel is not configured.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] kernel   Kernel to validate.
 */
void error_on_unconfigured_kernel(const char *function, const char *file, const int line,
                                  const IKernel *kernel);
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) ::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k)

/** Throw an error if if the coordinates and shape of the subtensor are within the parent tensor.
 *
 * @param[in] function     Function in which the error occurred.
 * @param[in] file         Name of the file where the error occurred.
 * @param[in] line         Line on which the error occurred.
 * @param[in] parent_shape Parent tensor shape
 * @param[in] coords       Coordinates inside the parent tensor where the first element of the subtensor is
 * @param[in] shape        Shape of the subtensor
 */
void error_on_invalid_subtensor(const char *function, const char *file, const int line,
                                const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) ::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s)

/** Throw an error if the valid region of a subtensor is not inside the valid region of the parent tensor.
 *
 * @param[in] function            Function in which the error occurred.
 * @param[in] file                Name of the file where the error occurred.
 * @param[in] line                Line on which the error occurred.
 * @param[in] parent_valid_region Parent valid region.
 * @param[in] valid_region        Valid region of subtensor.
 */
void error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
                                             const ValidRegion &parent_valid_region, const ValidRegion &valid_region);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) ::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv)

/** Throw an error if the input fixed-point positions are different.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] tensor_1 The first tensor to be compared.
 *  @param[in] tensor_2 The second tensor to be compared.
 *  @param[in] tensors  (Optional) Further allowed tensors.
 */
template <typename... Ts>
void error_on_mismatching_fixed_point_position(const char *function, const char *file, const int line,
                                               const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_array{ { tensor_2, std::forward<Ts>(tensors)... } };
    ARM_COMPUTE_UNUSED(tensors_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(std::any_of(tensors_array.begin(), tensors_array.end(), [&](const ITensor * tensor)
    {
        return tensor->info()->fixed_point_position() != tensor_1->info()->fixed_point_position();
    }),
    function, file, line, "Tensors have different fixed-point positions");
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT_POSITION(...) ::arm_compute::error_on_mismatching_fixed_point_position(__func__, __FILE__, __LINE__, __VA_ARGS__)

/** Throw an error if the fixed-point value is not representable in the specified Q format.
 *
 *  @param[in] function Function in which the error occurred.
 *  @param[in] file     Name of the file where the error occurred.
 *  @param[in] line     Line on which the error occurred.
 *  @param[in] value    The floating point value to be checked.
 *  @param[in] tensor   Input tensor that has information on data type and fixed-point position.
 */
template <typename... Ts>
void error_on_value_not_representable_in_fixed_point(const char *function, const char *file, int line,
                                                     float value, const ITensor *tensor)
{
    const int          fixed_point_position = tensor->info()->fixed_point_position();
    const DataType     dt                   = tensor->info()->data_type();
    const unsigned int q_max_range          = 0xFFFFFFFFu >> (((sizeof(unsigned int) - element_size_from_data_type(dt)) * 8) + 1);
    const float        max_range            = q_max_range / (static_cast<float>(1 << fixed_point_position));
    ARM_COMPUTE_UNUSED(max_range);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(value > max_range, function, file, line,
                                 "Value %f is not representable in %s with fixed-point position %d", value, string_from_data_type(dt).c_str(), fixed_point_position);
}
#define ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(...) ::arm_compute::error_on_value_not_representable_in_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__)
}
#endif /* __ARM_COMPUTE_VALIDATE_H__*/
