//
// Created by jedi on 11/2/18.
//

#ifndef MGL_DMXMENU_BUFFER_1_H
#define MGL_DMXMENU_BUFFER_1_H


#include <stdlib.h>
#include <stdint.h>

enum bufferBlocks{
    _1bit = 1, _2bit = 2, _4bit = 4, _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32
};

template <bufferBlocks N>
class buffer {
private:
    int *ptr_;
    int size_;
    constexpr static const int block_ = 8 * sizeof(int);
public:
    buffer(int size) : size_(size) {
        ptr_ = (int *) malloc(size * N / 8);
    }

    int get(int i) {
        if (i >= size_) return 0;
        return ptr_[i*N/block_] & ((1<<N)-1) << (i*N%block_);
    }

    void set(int i, int v) {
        if (i < size_) {
            ptr_[i*N/block_] &= ~(((1<<N)-1) << (i*N%block_));
            ptr_[i*N/block_] |= (((1<<N)-1)&v) << (i*N%block_);
        }
    }

    ~buffer() {
        free(ptr_);
    }
};

template <>
int buffer<_32bit>::get(int i);

template <>
void buffer<_32bit>::set(int i, int v);

#endif //MGL_DMXMENU_BUFFER_1_H