By the way, the implementation of the
inspector get_internal_rep() is out of order! My bad.
Change full header to this:
Code:
////////////////////////////////////////////////
// A 2D matrix, demonstrating the following: //
// - a nested std::vector in std::vector. //
// - various basic iterator techniques. //
// - basic exception error handling. //
////////////////////////////////////////////////
#ifndef C2DMATRIX_H
#define C2DMATRIX_H
#include <vector>
#include <string>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include <iterator>
using namespace std;
class C2DMatrixError
{
public:
C2DMatrixError(std::string msg) : sMsg_(msg)
{}
virtual std::string what() = 0;
protected:
std::string sMsg_;
};
//--
class BadSize : public C2DMatrixError
{
public:
BadSize(std::string msg) : C2DMatrixError(msg)
{}
std::string what()
{
return sMsg_;
}
};
//--
class BoundsViolation : public C2DMatrixError
{
public:
BoundsViolation(std::string msg) : C2DMatrixError(msg)
{}
std::string what()
{
return sMsg_;
}
};
//---------------------- C2DMatrix --------------------------
template<typename T>
class C2DMatrix
{
public:
C2DMatrix() {}
C2DMatrix(unsigned, unsigned );
T& operator() (unsigned, unsigned);
const T& operator() (unsigned , unsigned) const;
size_t nRows_;
size_t nCols_;
// Remember, "typename" is required because "T" can't be resolved yet.
const typename std::vector<std::vector<T> >::iterator first_row()
{
return data_.begin();
}
const typename std::vector<std::vector<T> >::iterator last_row()
{
data_.end();
}
private:
vector<vector<T> > data_;
template <typename _T>
friend ostream& operator<<(ostream& os, C2DMatrix<_T>& c2d );
};
//--------------------------------------------------------------
template<typename T>
C2DMatrix<T>::C2DMatrix(unsigned rows, unsigned cols)
{
if (rows == 0 || cols == 0)
{
throw BadSize("ERROR: Bad size");
}
data_.resize(rows);
nRows_=rows;
nCols_=cols;
for (unsigned i = 0; i < rows; ++i)
{
data_[i].resize(cols);
}
}
//----------------------------
template<typename T>
inline T& C2DMatrix<T>::operator() (unsigned row, unsigned col)
{
if (row >= nRows_ || col >= nCols_ )
{
throw BoundsViolation("ERROR in non-const operator(): Bounds Violation");
}
return data_[row][col];
}
//----------------------------
template<typename T>
inline const T& C2DMatrix<T>::operator() (unsigned row, unsigned col) const
{
if (row >= nRows_ || col >= nCols_)
{
throw BoundsViolation("ERROR in const operator()const: Bounds Violation");
}
return data_[row][col];
}
//-----------------------------
template <typename T>
class print_column
{
public:
void operator()(const std::vector<T>& v)
{
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " "));
std::cout << endl;
}
};
//-------------------------------
template <typename T>
ostream& operator<< (std::ostream& os, C2DMatrix<T>& matrix)
{
std::for_each( matrix.first_row(), matrix.last_row(), print_column<T>() );
return os;
}
#endif //C2DMATRIX_H