/**
 *
 * @file src/trace/Serializer.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Augustin Degomme
 * @author Thibault Soucarre
 *
 * @date 2024-07-17
 */
#ifndef SERIALIZER_HPP
#define SERIALIZER_HPP

#include <boost/bimap.hpp>
#include <QMutex>

template <typename T>
class Singleton
{
public:
    static T &Instance() {
        static T me;
        return me;
    }
};

// the Serializer assigns a unique id to an instance of a type and keep its track to return it if asked.
//  This allows to serialize pointed members in different files, when boost can't keep its track.
//  Containers and types are serialized in a.vite file separated from other data files which use them, so we need to correlate them when saving or restoring.
//  for each type there is only one global instance of Serializer, so we use a Singleton for that
//  in order to be thread safe, a lock is needed

template <typename T>
class Serializer : public Singleton<Serializer<T>>
{

private:
    boost::bimap<int, const T *> _map;
    QMutex _lock;

public:
    /*!
     * \fn setUid
     * \brief add a value to the set, marked by its unique id
     * \brief returns false if the id is not unique and operation failed, true else
     */

    bool setUid(int n, const T *c);

    /*!
     * \fn setUid
     * \brief add a value to the set, and set an uid for him
     * \brief returns false if the id is not unique and operation failed, true else
     */

    int setUid(const T *c);

    /*!
     * \fn getValue
     * \brief get the value's address in the current representation
     */
    const T *getValue(int n);

    /*!
     * \fn getUid
     * \brief get the value's uid in the current representation
     */
    int getUid(const T *c);

    /*!
     * \fn clear
     * \brief Clear all data in the serializer
     */
    void clear();
};

// check if this is necessary for the compiler
#include "trace/Serializer.cpp"

#endif
