/*
 * 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 occurred.
 * @param[in] file     File in which the error occurred.
 * @param[in] line     Line in which the error occurred.
 */
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.
     */
    arm_compute::Error operator()(const Dimensions<T> &dim)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
                                            "Objects have different dimensions");
        return arm_compute::Error{};
    }

private:
    const Dimensions<T> &_dim;
    const char *const    _function;
    const char *const    _file;
    const int            _line;
};

template <typename F>
inline arm_compute::Error for_each_error(F &&)
{
    return arm_compute::Error{};
}

template <typename F, typename T, typename... Ts>
inline arm_compute::Error for_each_error(F &&func, T &&arg, Ts &&... args)
{
    ARM_COMPUTE_RETURN_ON_ERROR(func(arg));
    ARM_COMPUTE_RETURN_ON_ERROR(for_each_error(func, args...));
    return arm_compute::Error{};
}

template <typename T>
struct get_tensor_info_t;
template <>
struct get_tensor_info_t<ITensorInfo *>
{
    ITensorInfo *operator()(const ITensor *tensor)
    {
        return tensor->info();
    }
};
} // namespace detail

/** Create 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
{
    const std::array<const void *, sizeof...(Ts)> pointers_array{ { std::forward<Ts>(pointers)... } };
    bool has_nullptr = std::any_of(pointers_array.begin(), pointers_array.end(), [&](const void *ptr)
    {
        return (ptr == nullptr);
    });
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBWINDOW(f, s) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
#define ARM_COMPUTE_RETURN_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))

/** Return 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.
 *
 * @return Error
 */
template <typename T, typename... Ts>
arm_compute::Error error_on_mismatching_dimensions(const char *function, const char *file, int line,
                                                   const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
{
    ARM_COMPUTE_RETURN_ON_ERROR(detail::for_each_error(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed two tensor infos 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_info_1 The first tensor info to be compared.
 *  @param[in] tensor_info_2 The second tensor info to be compared.
 *  @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                      const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    return error_on_mismatching_shapes(function, file, line, 0U, tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)...);
}
/** Return 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                      const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
}
/** Return 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_info_1 The first tensor info to be compared.
 *  @param[in] tensor_info_2 The second tensor info to be compared.
 *  @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                      unsigned int upper_dim, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_1 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_2 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));

    const std::array < const ITensorInfo *, 2 + sizeof...(Ts) > tensors_info_array{ { tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_info_array.cbegin()), tensors_info_array.cend(), [&](const ITensorInfo * tensor_info)
    {
        return detail::have_different_dimensions((*tensors_info_array.cbegin())->tensor_shape(), tensor_info->tensor_shape(), upper_dim);
    }),
    function, file, line, "Tensors have different shapes");
    return arm_compute::Error{};
}
/** Return 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error 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_RETURN_ERROR_ON_LOC(tensor_1 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_2 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(function, file, line, upper_dim, tensor_1->info(), tensor_2->info(),
                                                                           detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed two tensor infos 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_info  The first tensor info to be compared.
 *  @param[in] tensor_infos (Optional) Further allowed tensor infos.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_data_types(const char *function, const char *file, const int line,
                                                          const ITensorInfo *tensor_info, Ts... tensor_infos)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));

    DataType &&tensor_data_type = tensor_info->data_type();
    const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
    {
        return tensor_info_obj->data_type() != tensor_data_type;
    }),
    function, file, line, "Tensors have different data types");
    return arm_compute::Error{};
}
/** Return 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_data_types(const char *function, const char *file, const int line,
                                                          const ITensor *tensor, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(function, file, line, tensor->info(),
                                                                               detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed tensor infos 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_info_1 The first tensor info to be compared.
 *  @param[in] tensor_info_2 The second tensor info to be compared.
 *  @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_fixed_point(const char *function, const char *file, const int line,
                                                           const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    DataType &&first_data_type            = tensor_info_1->data_type();
    const int  first_fixed_point_position = tensor_info_1->fixed_point_position();

    if(!is_data_type_fixed_point(first_data_type))
    {
        return arm_compute::Error{};
    }

    const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->data_type() != first_data_type;
    }),
    function, file, line, "Tensors have different fixed point data types");
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->fixed_point_position() != first_fixed_point_position;
    }),
    function, file, line, "Tensors have different fixed point positions");

    return arm_compute::Error{};
}
/** Return an error if the passed tensor 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error 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_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point(function, file, line, tensor_1->info(), tensor_2->info(),
                                                                                detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_FIXED_POINT(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::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__)

/** Return an error if the data type of the passed tensor info 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_info Tensor info to validate.
 *  @param[in] dt          First data type allowed.
 *  @param[in] dts         (Optional) Further allowed data types.
 *
 * @return Error
 */
template <typename T, typename... Ts>
inline arm_compute::Error error_on_data_type_not_in(const char *function, const char *file, const int line,
                                                    const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);

    const DataType &tensor_dt = tensor_info->data_type(); //NOLINT
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);

    const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
    ARM_COMPUTE_RETURN_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());
    return arm_compute::Error{};
}
/** Return 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.
 *
 * @return Error
 */
template <typename T, typename... Ts>
inline arm_compute::Error error_on_data_type_not_in(const char *function, const char *file, const int line,
                                                    const ITensor *tensor, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor->info(), std::forward<T>(dt), std::forward<Ts>(dts)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))

/** Return an error if the data type or the number of channels of the passed tensor info 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_info  Tensor info 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.
 *
 * @return Error
 */
template <typename T, typename... Ts>
inline arm_compute::Error error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
                                                            const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor_info, std::forward<T>(dt), std::forward<Ts>(dts)...));
    const size_t tensor_nc = tensor_info->num_channels();
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(tensor_nc != num_channels, function, file, line, "Number of channels %d. Required number of channels %d", tensor_nc, num_channels);
    return arm_compute::Error{};
}
/** Return 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.
 *
 * @return Error
 */
template <typename T, typename... Ts>
inline arm_compute::Error 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)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(error_on_data_type_channel_not_in(function, file, line, tensor->info(), num_channels, std::forward<T>(dt), std::forward<Ts>(dts)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
#define ARM_COMPUTE_RETURN_ERROR_ON_TENSOR_NOT_2D(t) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))

/** Return 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.
 *
 * @return Error
 */
template <typename T, typename... Ts>
inline arm_compute::Error error_on_channel_not_in(const char *function, const char *file, const int line,
                                                  T cn, T &&channel, Ts &&... channels)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);

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

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))

/** Return 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
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_MULTI_HOG(m) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))

/** Return 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.
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
#define ARM_COMPUTE_RETURN_ERROR_ON_UNCONFIGURED_KERNEL(k) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))

/** Return 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
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))

/** Return 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.
 *
 * @return Error
 */
arm_compute::Error 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_THROW_ON(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))

/** Return 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_info_1 The first tensor info to be compared.
 *  @param[in] tensor_info_2 The second tensor info to be compared.
 *  @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error error_on_mismatching_fixed_point_position(const char *function, const char *file, const int line,
                                                                    const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_info_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_info_array.begin(), tensor_info_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->fixed_point_position() != tensor_info_1->fixed_point_position();
    }),
    function, file, line, "Tensors have different fixed-point positions");
    return arm_compute::Error{};
}
/** Return 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.
 *
 * @return Error
 */
template <typename... Ts>
inline arm_compute::Error 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)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point_position(function, file, line, tensor_1->info(), tensor_2->info(),
                                                                                         detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT_POSITION(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_fixed_point_position(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_FIXED_POINT_POSITION(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point_position(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return 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_info Input tensor info that has information on data type and fixed-point position.
 *
 * @return Error
 */
inline arm_compute::Error error_on_value_not_representable_in_fixed_point(const char *function, const char *file, int line,
                                                                          float value, const ITensorInfo *tensor_info)
{
    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_RETURN_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);
    return arm_compute::Error{};
}
/** Return an error 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.
 *
 * @return Error
 */
inline arm_compute::Error error_on_value_not_representable_in_fixed_point(const char *function, const char *file, int line,
                                                                          float value, const ITensor *tensor)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_value_not_representable_in_fixed_point(function, file, line, value, tensor->info()));
    return arm_compute::Error{};
}
#define ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_value_not_representable_in_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_value_not_representable_in_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
}
#endif /* __ARM_COMPUTE_VALIDATE_H__*/
