C++ Encapsulated VectorOfVectors

#include <iostream>         // For cout
#include <string>           // For strings
#include <vector>
#include <cstdint>
#include <iomanip>
#include <random>

std::random_device rd;
std::mt19937 eng{rd()};
std::uniform_int_distribution<uint8_t> rng{0, 255};

void prettyprintbyte(uint8_t b)
{
    std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << unsigned(b) << " ";
    std::cout << std::dec;
}

template <class UINT>
class VectorOfVectors
{
public:
    VectorOfVectors() { m_data.push_back(std::vector<UINT>(0)); }

    // print the values in a table format 
    void print()
    {
        for(std::vector<UINT> row: m_data)
        {
            for(UINT col: row)
            {
                prettyprintbyte(col);
            }
            std::cout << std::dec << std::endl;
        }
    }

    // get the row count
    unsigned int rowsize() { return m_data.size(); }

    // get the col count
    unsigned int colsize(unsigned int row) 
    {
        if (row < m_data.size()) { return m_data[row].size(); }
        return 0;
    }

    // get cell count
    unsigned int size() 
    {
        int cell_count = 0;

        for(std::vector<UINT> row: m_data)
            cell_count += row.size();

        return cell_count;
    }

    // get cell value
    int get(const unsigned int row, const unsigned int col) {
        if (row < m_data.size())
        {
            if (col < m_data[row].size())
            {
                return m_data[row][col];
            }
        }
        return -1;
    } 
    // set cell value
    unsigned int set(const unsigned int row, const unsigned int col, const UINT &value) {
        if (row < m_data.size())
        {
            if (col < m_data[row].size())
            {
                m_data[row][col] = value;
                return 0;
            }
            else
            {
                m_data[row].push_back(value);
                return 0;
            }
        }
        else
        {
            m_data.push_back(std::vector<UINT>{value});
            return 0;
        }
        return 1;
    }

    // push new cell value to row
    unsigned int push_back(const unsigned int row, const UINT &value)
    {
        if (row < m_data.size())
        {
            m_data[row].push_back(value);
            return 0;
        }    
        else
        {
            m_data.push_back(std::vector<UINT>{value});
            return 0;
        }    
    }

    // row iterators object and getter
    struct RowIter
    {
        typename std::vector<std::vector<UINT>>::iterator begin;
        typename std::vector<std::vector<UINT>>::iterator end;
    };
    void get_row_iters(
        RowIter &iterpair
    )
    {
        iterpair.begin = m_data.begin();
        iterpair.end = m_data.end();
    }

    // column iterators object and getter
    struct ColIter
    {
        typename std::vector<UINT>::iterator begin;
        typename std::vector<UINT>::iterator end;
    };
    void get_column_iters(
        const typename std::vector<std::vector<UINT>>::iterator &rowiter,
        ColIter &coliterpair
    )
    {
            coliterpair.begin = (*rowiter).begin();
            coliterpair.end = (*rowiter).end();

    }

private:
    std::vector<std::vector<UINT>> m_data;
};


int main(int argc, char *argv[]) {
    using U8VectorOfVectors = VectorOfVectors<uint8_t>;

    {
        U8VectorOfVectors v2;
        for (int c = 0; c < 4; c++) { v2.push_back(0, rng(eng)); }
        for (int c = 0; c < 3; c++) { v2.push_back(1, rng(eng)); }
        for (int c = 0; c < 2; c++) { v2.push_back(2, rng(eng)); }
        for (int c = 0; c < 6; c++) { v2.push_back(3, rng(eng)); }

        std::cout << "=======================" << std::endl;
        v2.print();
        std::cout << "=======================" << std::endl;
        std::cout << "rows: " << v2.rowsize() << std::endl;
        std::cout << "row[1] size: " << v2.colsize(1) << std::endl;
        std::cout << "cells: " << v2.size() << std::endl;

        std::cout << "[3][4] = ";
        prettyprintbyte(v2.get(3, 4));
        std::cout << std::endl << "[5][5] = "<< (v2.get(5, 5)) << std::endl;

        U8VectorOfVectors::ColIter col_iters;
        U8VectorOfVectors::RowIter row_iters;

        // for(int i = 0; i < v2.rowsize(); i++)
        v2.get_row_iters(row_iters);
        for(auto rowit = row_iters.begin; rowit != row_iters.end; rowit++)
        {
            v2.get_column_iters(rowit, col_iters);
            // get some useful index info for demo purposes
            std::size_t rowpos = std::distance(row_iters.begin, rowit);
            std::cout << "row[" << rowpos << "] iterator: ";

            for(auto colit = col_iters.begin; colit != col_iters.end; colit++)
            {
                prettyprintbyte(*colit);
            }
            std::cout << std::endl;
        }
    }
    return 0;
}
=======================
0xd4 0x6f 0x27 0x4e 
0xb1 0x34 0x23 
0x39 0x1e 
0xa1 0xcd 0x5a 0x3c 0x57 0x70 
=======================
rows: 4
row[1] size: 3
cells: 15
[3][4] = 0x57 
[5][5] = -1
row[0] iterator: 0xd4 0x6f 0x27 0x4e 
row[1] iterator: 0xb1 0x34 0x23 
row[2] iterator: 0x39 0x1e 
row[3] iterator: 0xa1 0xcd 0x5a 0x3c 0x57 0x70

https://godbolt.org/z/35nMYs9YG

Categories: C++

Leave a Reply

Your email address will not be published. Required fields are marked *