/*
 * Copyright (c) 2020-2021 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_ITENSORPACK_H
#define ARM_COMPUTE_ITENSORPACK_H

#include <cstddef>
#include <cstdint>
#include <map>

namespace arm_compute
{
// Forward declaration
class ITensor;

/** Tensor packing service */
class ITensorPack
{
private:
    struct PackElement
    {
        PackElement() = default;
        PackElement(ITensor *tensor)
            : tensor(tensor), ctensor(nullptr)
        {
        }
        PackElement(const ITensor *ctensor)
            : tensor(nullptr), ctensor(ctensor)
        {
        }

        ITensor       *tensor{ nullptr };
        const ITensor *ctensor{ nullptr };
    };

public:
    /** Default Constructor */
    ITensorPack() = default;
    /** Add tensor to the pack
     *
     * @param[in] id     ID/type of the tensor to add
     * @param[in] tensor Tensor to add
     */
    void add_tensor(int id, ITensor *tensor);

    /** Add const tensor to the pack
     *
     * @param[in] id     ID/type of the tensor to add
     * @param[in] tensor Tensor to add
     */
    void add_tensor(int id, const ITensor *tensor);

    /** Add const tensor to the pack
     *
     * @param[in] id     ID/type of the tensor to add
     * @param[in] tensor Tensor to add
     */
    void add_const_tensor(int id, const ITensor *tensor);
    /** Get tensor of a given id from the pac
     *
     * @param[in] id ID of tensor to extract
     *
     * @return The pointer to the tensor if exist and is non-const else nullptr
     */
    ITensor *get_tensor(int id);
    /** Get constant tensor of a given id
     *
     * @param[in] id ID of tensor to extract
     *
     * @return The pointer to the tensor if exist and is const else nullptr
     */
    const ITensor *get_const_tensor(int id) const;
    /** Pack size accessor
     *
     * @return Number of tensors registered to the pack
     */
    size_t size() const;
    /** Checks if pack is empty
     *
     * @return True if empty else false
     */
    bool empty() const;

private:
    std::map<unsigned int, PackElement> _pack{}; /**< Container with the packed tensors */
};
} // namespace arm_compute
#endif /*ARM_COMPUTE_ITENSORPACK_H */
