#include <iostream>
#include <vector>
#include <cstring>

typedef unsigned char   BYTE;
typedef BYTE            UINT8;
typedef unsigned short  UINT16;
typedef unsigned int    UINT32;

template <typename T>
class ImageData{
    public:
        ImageData(int);
        ~ImageData();
        void  setDataType(int); //設定資料儲存bits數
        int   getData(int);     //讀取第n筆資料

    private:
        BYTE* data;             //原始圖資
        int bits;
        int size;
};

template <typename T>
ImageData<T>::ImageData(int size){
    if(size < sizeof(T))
        throw std::string("Size must more than sizeof(T)");

    data = new (std::nothrow) BYTE[size];
    if(data == NULL)
        throw std::string("Memory allocation fail");

    this->size = size;
    memset(data, 0, sizeof(BYTE) * this->size);

    *((int*)data) = (int)sizeof(T);         // 只是方便觀察(非必要)
}

template <typename T>
ImageData<T>::~ImageData(){
    if(data != NULL){
        delete [] data;
    }
}

template <typename T>
void ImageData<T>::setDataType(int inputBits){
    bits = inputBits;
}

template <typename T>
int ImageData<T>::getData(int pos){
    decltype(data) endPtr = data + pos + sizeof(T);
    decltype(data) bound = data + size;

    // Boundary check
    if(endPtr > bound)
        throw std::string("Out of boundary");

    return (int) *((T*)data + pos);
}

int main(){
    try{
        // Case1:UINT8
        {
            ImageData<UINT8>* img = new ImageData<UINT8>(128);
            std::cout << img->getData(0) << std::endl;
        }

        // Case1:UINT16
        {
            ImageData<UINT16>* img = new ImageData<UINT16>(128);
            std::cout << img->getData(0) << std::endl;
        }

        // Case1:UINT32
        {
            ImageData<UINT32>* img = new ImageData<UINT32>(128);
            std::cout << img->getData(0) << std::endl;
        }
    }
    catch(std::string e){
        std::cout << "Exception: " << e << std::endl;
    }
    catch(std::exception e){
        std::cout << "Exception: " << e.what() << std::endl;
    }
	return 0;
}