#include <vector>
#include <algorithm>
#include <type_traits>
template<typename T> class Row;
template<typename T> class ConstRow;
template<typename T>
class Matrix2D
{
// Matrix aus bool nicht erlauben
static_assert( !std::is_same<bool,T>::value, "T must not be bool because of std::vector<bool> anomaly" );
public:
using value_type = T;
using reference = T&;
using const_reference = T const&;
using pointer = T*;
using const_pointer = T const*;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using row_type = Row<T>;
using const_row_type = ConstRow<T>;
private:
std::vector<T> Elements_;
size_type Rows_ = 0;
size_type Cols_ = 0;
public:
Matrix2D() = default;
Matrix2D( size_type rows, size_type cols ) :
Matrix2D( rows, cols, value_type() )
{
}
Matrix2D(size_type rows, size_type cols, const_reference v ) :
Elements_( rows * cols, v ),
Rows_( rows ),
Cols_( cols )
{
}
row_type operator[]( size_type index )
{
pointer beg = Elements_.data() + index * Cols_;
return row_type( beg, beg + Cols_ );
}
const_row_type operator[]( size_type index ) const
{
const_pointer beg = Elements_.data() + index * Cols_;
return const_row_type( beg, beg + Cols_ );
}
};
template<typename T>
class Row
{
T* Begin_= nullptr;
T* End_ = nullptr;
public:
Row( T* beg, T* end ) :
Begin_( beg ),
End_( end )
{
}
bool empty() const
{
return Begin_ == End_;
}
std::size_t size() const
{
return std::distance( begin(), end() );
}
T& operator[]( std::size_t index )
{
return Begin_[index];
}
T const& operator[]( std::size_t index ) const
{
return Begin_[index];
}
T* begin()
{
return Begin_;
}
T* end()
{
return End_;
}
T const* begin() const
{
return Begin_;
}
T const* end() const
{
return End_;
}
};
template<typename T>
class ConstRow
{
T const* Begin_ = nullptr;
T const* End_ = nullptr;
public:
ConstRow( T const* beg, T const* end ) :
Begin_( beg ),
End_( end )
{
}
ConstRow( Row<T> const& r ) :
Begin_( r.begin() ),
End_( r.end() )
{
}
T const& operator[]( std::size_t index ) const
{
return Begin_[index];
}
};
int main()
{
Matrix2D<int> m( 2, 2,-1 );
m[0][0] = 1;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3MgUm93Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBjbGFzcyBDb25zdFJvdzsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIE1hdHJpeDJECnsKICAgLy8gTWF0cml4IGF1cyBib29sIG5pY2h0IGVybGF1YmVuCiAgIHN0YXRpY19hc3NlcnQoICFzdGQ6OmlzX3NhbWU8Ym9vbCxUPjo6dmFsdWUsICJUIG11c3Qgbm90IGJlIGJvb2wgYmVjYXVzZSBvZiBzdGQ6OnZlY3Rvcjxib29sPiBhbm9tYWx5IiApOwoKcHVibGljOgogICB1c2luZyB2YWx1ZV90eXBlICAgICAgPSBUOwogICB1c2luZyByZWZlcmVuY2UgICAgICAgPSBUJjsKICAgdXNpbmcgY29uc3RfcmVmZXJlbmNlID0gVCBjb25zdCY7CiAgIHVzaW5nIHBvaW50ZXIgICAgICAgICA9IFQqOwogICB1c2luZyBjb25zdF9wb2ludGVyICAgPSBUIGNvbnN0KjsKICAgdXNpbmcgc2l6ZV90eXBlICAgICAgID0gc3RkOjpzaXplX3Q7CiAgIHVzaW5nIGRpZmZlcmVuY2VfdHlwZSA9IHN0ZDo6cHRyZGlmZl90OwogICB1c2luZyByb3dfdHlwZSAgICAgICAgPSBSb3c8VD47CiAgIHVzaW5nIGNvbnN0X3Jvd190eXBlICA9IENvbnN0Um93PFQ+OwoKcHJpdmF0ZToKICAgc3RkOjp2ZWN0b3I8VD4gRWxlbWVudHNfOwogICBzaXplX3R5cGUgICAgICBSb3dzXyA9IDA7CiAgIHNpemVfdHlwZSAgICAgIENvbHNfID0gMDsKCnB1YmxpYzoKICAgTWF0cml4MkQoKSA9IGRlZmF1bHQ7CiAgIE1hdHJpeDJEKCBzaXplX3R5cGUgcm93cywgc2l6ZV90eXBlIGNvbHMgKSA6CiAgICAgIE1hdHJpeDJEKCByb3dzLCBjb2xzLCB2YWx1ZV90eXBlKCkgKQogICB7CiAgIH0KCiAgIE1hdHJpeDJEKHNpemVfdHlwZSByb3dzLCBzaXplX3R5cGUgY29scywgY29uc3RfcmVmZXJlbmNlIHYgKSA6CiAgICAgIEVsZW1lbnRzXyggcm93cyAqIGNvbHMsIHYgKSwKICAgICAgUm93c18oIHJvd3MgKSwKICAgICAgQ29sc18oIGNvbHMgKQogICB7CiAgIH0KCiAgIHJvd190eXBlIG9wZXJhdG9yW10oIHNpemVfdHlwZSBpbmRleCApCiAgIHsKICAgICAgcG9pbnRlciBiZWcgPSBFbGVtZW50c18uZGF0YSgpICsgaW5kZXggKiBDb2xzXzsgCiAgICAgIHJldHVybiByb3dfdHlwZSggYmVnLCBiZWcgKyBDb2xzXyApOwogICB9CgogICBjb25zdF9yb3dfdHlwZSBvcGVyYXRvcltdKCBzaXplX3R5cGUgaW5kZXggKSBjb25zdAogICB7CiAgICAgICBjb25zdF9wb2ludGVyIGJlZyA9IEVsZW1lbnRzXy5kYXRhKCkgKyBpbmRleCAqIENvbHNfOyAKICAgICAgIHJldHVybiBjb25zdF9yb3dfdHlwZSggYmVnLCBiZWcgKyBDb2xzXyApOwogICAgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgUm93CnsKICAgVCogQmVnaW5fPSBudWxscHRyOwogICBUKiBFbmRfICA9IG51bGxwdHI7CgpwdWJsaWM6CiAgIFJvdyggVCogYmVnLCBUKiBlbmQgKSA6CiAgICAgIEJlZ2luXyggYmVnICksCiAgICAgIEVuZF8oIGVuZCApCiAgIHsKICAgfQoKICAgYm9vbCBlbXB0eSgpIGNvbnN0CiAgIHsKICAgICAgcmV0dXJuIEJlZ2luXyA9PSBFbmRfOwogICB9CgogICBzdGQ6OnNpemVfdCBzaXplKCkgY29uc3QKICAgewogICAgICByZXR1cm4gc3RkOjpkaXN0YW5jZSggYmVnaW4oKSwgZW5kKCkgKTsKICAgfQoKICAgVCYgb3BlcmF0b3JbXSggc3RkOjpzaXplX3QgaW5kZXggKQogICB7CiAgICAgIHJldHVybiBCZWdpbl9baW5kZXhdOwogICB9CgogICBUIGNvbnN0JiBvcGVyYXRvcltdKCBzdGQ6OnNpemVfdCBpbmRleCApIGNvbnN0CiAgIHsKICAgICAgcmV0dXJuIEJlZ2luX1tpbmRleF07CiAgIH0KCiAgIFQqIGJlZ2luKCkKICAgewogICAgICByZXR1cm4gQmVnaW5fOwogICB9CgogICBUKiBlbmQoKQogICB7CiAgICAgIHJldHVybiBFbmRfOwogICB9CgogICBUIGNvbnN0KiBiZWdpbigpIGNvbnN0CiAgIHsKICAgICAgcmV0dXJuIEJlZ2luXzsKICAgfQoKICAgVCBjb25zdCogZW5kKCkgY29uc3QKICAgewogICAgICByZXR1cm4gRW5kXzsKICAgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgQ29uc3RSb3cKewogICBUIGNvbnN0KiBCZWdpbl8gPSBudWxscHRyOwogICBUIGNvbnN0KiBFbmRfICAgPSBudWxscHRyOwoKcHVibGljOgogICBDb25zdFJvdyggVCBjb25zdCogYmVnLCBUIGNvbnN0KiBlbmQgKSA6CiAgICAgIEJlZ2luXyggYmVnICksCiAgICAgIEVuZF8oIGVuZCApCiAgIHsKICAgfQoKICAgQ29uc3RSb3coIFJvdzxUPiBjb25zdCYgciApIDoKICAgICAgQmVnaW5fKCByLmJlZ2luKCkgKSwKICAgICAgRW5kXyggci5lbmQoKSApCiAgIHsKICAgfQoKICAgVCBjb25zdCYgb3BlcmF0b3JbXSggc3RkOjpzaXplX3QgaW5kZXggKSBjb25zdAogICB7CiAgICAgIHJldHVybiBCZWdpbl9baW5kZXhdOwogICB9Cn07CgppbnQgbWFpbigpCnsKICAgTWF0cml4MkQ8aW50PiBtKCAyLCAyLC0xICk7CiAgIG1bMF1bMF0gPSAxOwp9