// SPDX-License-Identifier: 0BSD
/*!
 * @file
 * @license{
 * BSD Zero Clause License
 *
 * Copyright (c) 2022 by Raphael Bach
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 * }
 */
/*==============================================================================
    GUARD
==============================================================================*/
#ifndef FMPI_FUTHARK_INTERNAL_H_20211219235241
#define FMPI_FUTHARK_INTERNAL_H_20211219235241
/*==============================================================================
    INCLUDE
==============================================================================*/
// C Standard Library
#include <stddef.h> // size_t
// External
#include "../../../external/cpl/cpl_map.h"
// Internal
#include "../fmpi_common.h"
#include "fmpi_generic.h"
#include "fmpi_type_generic.h"
/*==============================================================================
    MACRO
==============================================================================*/
struct fmpi_futhark_ctx;

#define FMPI_FUTHARK_TYPES \
    FMPI_TYPE_REAL

#define FMPI_PRIV_FUTHARK_FUNC_IDX(d, t) \
    (((t) * FMPI_DIM_MAX) + (d) - 1)

#define FMPI_PRIV_FUTHARK_ARRAY_ENTRY(D, T) \
    [FMPI_PRIV_FUTHARK_FUNC_IDX(D, FMPI_TYPE_##T)] = fmpi_futhark_new_##D##d_##T

#define FMPI_FUTHARK_ARRAY_ENTRY_LIST(D) \
    CPL_MAP_FIXED(FMPI_PRIV_FUTHARK_ARRAY_ENTRY, CPL_COMMA, (D), FMPI_FUTHARK_TYPES)

// In a comma separeted list of expressions contained in a pair of parentheses
// only the last one is returned, allowing to silence warnings about unused
// parameters by putting them first.
#define FMPI_FUTHARK_NEW_1(T, ctx, array, x, y, z) \
    ((void)(y), (void)(z), futhark_new_##T##_1d(ctx, array, (int64_t)(x)))

#define FMPI_FUTHARK_NEW_2(T, ctx, array, x, y, z) \
    ((void)(z), futhark_new_##T##_2d(ctx, array, (int64_t)(x), (int64_t)(y)))

#define FMPI_FUTHARK_NEW_3(T, ctx, array, x, y, z) \
    futhark_new_##T##_3d(ctx, array, (int64_t)(x), (int64_t)(y), (int64_t)(z))

#define FMPI_FUTHARK_DECLARATION(D, T) \
void * fmpi_futhark_new_##D##d_##T( \
    const struct fmpi_futhark_ctx * ctx, const void * array, size_t x, size_t y, size_t z \
); \
void fmpi_futhark_free_##D##d_##T( \
    const struct fmpi_futhark_ctx * ctx, void * array \
)

FMPI_DECLARE_FUNCS_DT(FMPI_FUTHARK_DECLARATION, 1, FMPI_FUTHARK_TYPES);
FMPI_DECLARE_FUNCS_DT(FMPI_FUTHARK_DECLARATION, 2, FMPI_FUTHARK_TYPES);
FMPI_DECLARE_FUNCS_DT(FMPI_FUTHARK_DECLARATION, 3, FMPI_FUTHARK_TYPES);
/*==============================================================================
    GUARD
==============================================================================*/
#endif // FMPI_FUTHARK_INTERNAL_H_20211219235241