Three-dimensional array in C++.
Version of 25 January 2014.
Dave Barber's other pages.

Class three_dim, below, is a general-purpose three-dimensional array in C++. The size is determined at run time, when the array is constructed. After that, the size cannot be changed. Subscripting is done with the at() function, which ensures that parameters are in range.

This differs significantly from a std::vector< std::vector< std::vector< component > > >, where the inner vectors need not all be the same size, and the size of any vector can be changed at any time after construction. Rather, three_dim has behavior closer to that of the traditional three dimensional array, as in Fortran.

For two dimensions, see this.


#include <iostream>
#include <vector>
#include <stdexcept>

template <typename component>
class three_dim {
    size_t a, b, c;
    std::vector <component> guts;
	
    size_t subs (size_t const x, size_t const y, size_t const z) const {
        if (x >= a) 
            throw std::out_of_range ("three_dim::1st_sub_range_check");	
        if (y >= b) 
            throw std::out_of_range ("three_dim::2nd_sub_range_check");	
        if (z >= c) 
            throw std::out_of_range ("three_dim::3rd_sub_range_check");	
        return (x * b + y) * c + z;
    }	
public:	
    three_dim (size_t const x, size_t const y, size_t const z, 
            component const & def = component() ) :
        a (x), b (y), c (z),
        guts (a * b * c, def)
    { }
	
    component & at (size_t const x, size_t const y, size_t const z) 
        { return guts.at (subs (x, y, z)); }	
	
    component const & at (size_t const x, size_t const y, size_t const z) const 
        { return guts.at (subs (x, y, z)); }		
	
    size_t size  () const { return a * b * c; }
    size_t size0 () const { return a; }
    size_t size1 () const { return b; }
    size_t size2 () const { return c; }
};	
     
int main () {
    // demonstrate the array

    size_t dim0;
    std::cout << "\n ceiling of 1st subscript ... ";
    std::cin >> dim0;
	
    size_t dim1;
    std::cout << "\n ceiling of 2nd subscript ... ";
    std::cin >> dim1;
	
    size_t dim2;
    std::cout << "\n ceiling of 3rd subscript ... ";
    std::cin >> dim2;
	  
    three_dim<int> table (dim0, dim1, dim2);
	
    // load table with some values that form a pattern
    for (size_t p (0); p < dim0; ++p) 
        for (size_t q (0); q < dim1; ++q) 
            for (size_t r (0); r < dim2; ++r) 
                table.at (p, q, r) = 1000 * (p + 1) + 100 * (q + 1) + 10 * (r + 1);
	
    // see what you've got:
    for (size_t p (0); p < dim0; ++p) {
        for (size_t q (0); q < dim1; ++q) 
            for (size_t r (0); r < dim2; ++r) 
                std::cout << "\n table.at(" << p
                    << "," << q << "," << r
                    << ") = " << table.at(p, q, r);
        std::cout << "\n";
    }	
	
    std::cout << "\n 1st subscript ceiling is " << table.size0();
    std::cout << "\n 2st subscript ceiling is " << table.size1();
    std::cout << "\n 3st subscript ceiling is " << table.size2();
    std::cout << "\n total size is " << table.size() << " components";
    return 0;
}