#ifndef __POOL_H__
#define __POOL_H__

#include <cstddef>
#include <cstdint>

#include "platform/cm4/InterruptLock.h"

namespace pinetime
{

template <typename T, std::size_t sizeT>
class Pool
{
    union Item
    {
        uint8_t item[sizeof(T)];
        Item * next;
    };
    Item items[sizeT];
    uint8_t map[sizeT];

public:
    Pool()
    {
        for(unsigned int i = 0; i < sizeT; i++) {
            map[i] = 0;
        }
    }

    void *alloc()
    {
        pinetime::platform::cm4::InterruptLock lock;
        void * res = nullptr;
        for(unsigned int i = 0; i < sizeT; i++) {
            if(map[i] == 0) {
                map[i] = 0xff;
                res = static_cast<void *>(items + i);
                break;
            }
        }
        return res;
    }

    void free(T * ptr)
    {
        pinetime::platform::cm4::InterruptLock lock;
        // ptr is not assumed to be aligned, since the integer based aritmetic provides always the correct index and omits the ramainder.
        std::size_t index = (reinterpret_cast<std::uintptr_t>(ptr) - reinterpret_cast<std::uintptr_t>(items)) / sizeof(Item);
        map[index] = 0;
    }
};

}

#endif
