
//----------------------------------------------------
/**
    \brief		Sablona pro async-signal-safe vektor
*/
//----------------------------------------------------

template<class T>
class AsyncSafeVector
{
private:
    T * Data;
    int MaxSize;

public:
    int Size;

    AsyncSafeVector(T * _data,int _maxsize) : Data(_data),MaxSize(_maxsize),Size(0) {}
    ~AsyncSafeVector(void){}
    inline int PushBack(const T& data) { Data[Size++] = data; return 0; }
    inline T * At(int _index) { return Data+_index; }
    inline const T * At(int _index) const { return Data+_index; }
    inline T * Front(void) { return Data; }
    inline T * Back(void) { return Data+(Size-1); }
    inline int Erase(int _index)
    {
        if (Size == 1 && _index == 0)
        {
            Data[_index] = 0;
            Size--;
            return 0;
        }
        else if (_index == Size-1)
        {
            Data[_index] = 0;
            Size--;
            return _index - 1;
        }
        else
        {
            for(int i = _index;i<Size-1;i++)
            {
                Data[i] = Data[i+1];
            }
            Size--;
        }
        return _index;
    }
    inline void Clear(void) { Size = 0; }
    inline bool Empty(void) const { return (Size == 0); }
};

//----------------------------------------------------
/**
    \brief		Sablona pro async-signal-safe frontu
*/
//----------------------------------------------------

template<class T>
class AsyncSafeQueue
{
private:
    T * Data;
    int FrontIndex;
public:
    int Size;
    int MaxSize;

    AsyncSafeQueue(T * _data, int _maxsize) : Data(_data), FrontIndex(0), Size(0), MaxSize(_maxsize) {}
    ~AsyncSafeQueue(void) {}
    inline int PushBack(const T& data)
    {
        int index = (FrontIndex + Size++);
        if (index >= MaxSize) index -= MaxSize;
        Data[index] = data;
        return 0;
    }
    inline void PopFront(void)
    {
        if (++FrontIndex == MaxSize) FrontIndex = 0;
        Size--;
    }
    inline T * At(int _index)
    {
        _index += FrontIndex;
        if (_index >= MaxSize) _index -= MaxSize;
        return Data+_index;
    }
    inline const T * At(int _index) const
    {
        _index += FrontIndex;
        if (_index >= MaxSize) _index -= MaxSize;
        return Data+_index;
    }
    inline T * Front(void) { return Data+FrontIndex; }
    inline int Erase(int _index)
    {
        if (_index >= Size)
        {
            /* too big _index*/
            return _index;
        }
        int index = (FrontIndex + _index) % MaxSize;
        if (_index == 0 && Size == 1)
        {
            /* erasing last remaining element */
            Size--;
            return 0;
        }
        else if (index == Size - 1)
        {
            /* erase last element in queue */
            Size--;
            return _index - 1;
        }
        else
        {
            for(int i=_index;i<Size-1;i++)
            {
                Data[index] = Data[(index + 1) % MaxSize ];
                index = (index + 1) % MaxSize;
            }
            Size--;
        }
        return _index;
    }

    inline void Clear(void) { Size = 0; FrontIndex = 0; }
    inline bool Empty(void) const { return (Size == 0); }
};