Created
November 14, 2018 13:27
-
-
Save juliangaal/a88b9d95ab4d8eeb671b0cc4c46d2741 to your computer and use it in GitHub Desktop.
Matrix class with custom iterators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <array> | |
struct Dims | |
{ | |
unsigned int rows; | |
unsigned int colums; | |
unsigned int size; | |
}; | |
template <typename T, unsigned int M, unsigned int N> | |
struct Matrix | |
{ | |
struct line_iterator | |
{ | |
using value_type = T; | |
using pointer = T*; | |
using reference = T&; | |
using self_type = line_iterator; | |
using difference_type = unsigned int; | |
using iterator_category = std::forward_iterator_tag ; | |
line_iterator(pointer ptr, difference_type width) : _ptr(ptr), _width(width) {} | |
self_type operator++() { _ptr += _width; return *this; } | |
self_type operator--() { _ptr -= _width; return *this; } | |
self_type operator--(int junk) { self_type i = *this; _ptr -= _width; return i; } | |
self_type operator++(int junk) { self_type i = *this; _ptr += _width; return i; } | |
reference operator*() const { return *_ptr; } | |
pointer operator->() const { return _ptr; } | |
self_type operator=(const self_type& other) { _ptr = other._ptr; return *this; } | |
bool operator==(const self_type &rhs) const { return rhs._ptr == _ptr; } | |
bool operator!=(const self_type &rhs) const { return rhs._ptr != _ptr; } | |
private: | |
pointer _ptr; | |
difference_type _width; | |
}; | |
struct iterator | |
{ | |
using value_type = T; | |
using pointer = T*; | |
using reference = T&; | |
using self_type = iterator; | |
using difference_type = unsigned int; | |
using iterator_category = std::forward_iterator_tag ; | |
iterator(pointer ptr) : _ptr(ptr) {} | |
self_type operator++() { _ptr++; return *this; } | |
self_type operator--() { _ptr--; return *this; } | |
self_type operator++(int junk) { self_type i = *this; _ptr++; return i; } | |
self_type operator--(int junk) { self_type i = *this; _ptr--; return i; } | |
self_type operator-(int i) { return _ptr - i; } | |
reference operator*() const { return *_ptr; } | |
pointer operator->() const { return _ptr; } | |
self_type operator=(const self_type& other) { _ptr = other._ptr; return *this; } | |
bool operator==(const self_type &rhs) const { return rhs._ptr == _ptr; } | |
bool operator!=(const self_type &rhs) const { return rhs._ptr != _ptr; } | |
private: | |
pointer _ptr; | |
}; | |
class const_iterator | |
{ | |
public: | |
typedef const_iterator self_type; | |
typedef T value_type; | |
typedef T& reference; | |
typedef T* pointer; | |
typedef int difference_type; | |
typedef std::forward_iterator_tag iterator_category; | |
const_iterator(pointer ptr) : _ptr(ptr) { } | |
self_type operator++() { _ptr++; return *this; } | |
self_type operator--() { _ptr--; return *this; } | |
self_type operator++(int junk) { self_type i = *this; _ptr++; return i; } | |
self_type operator--(int junk) { self_type i = *this; _ptr--; return i; } | |
const value_type& operator*() const { return *_ptr; } | |
const value_type* operator->() const { return _ptr; } | |
bool operator==(const self_type& rhs) const { return _ptr == rhs._ptr; } | |
bool operator!=(const self_type& rhs) const { return _ptr != rhs._ptr; } | |
private: | |
pointer _ptr; | |
}; | |
Matrix(const std::array<T, M*N> m) | |
: _matrix(new T[M * N]) | |
{ | |
auto mit = m.begin(); | |
auto it = this->begin(); | |
while(mit != m.end()) | |
{ | |
*it = *mit; | |
mit++; ++it; | |
} | |
_dims.rows = M; | |
_dims.colums = N; | |
_dims.size = M * N; | |
} | |
~Matrix() | |
{ | |
if (_matrix) | |
delete [] _matrix; | |
} | |
iterator begin() | |
{ | |
return iterator(_matrix); | |
} | |
const_iterator cbegin() const | |
{ | |
return const_iterator(_matrix); | |
} | |
line_iterator lbegin() | |
{ | |
return line_iterator(_matrix, _dims.rows); | |
} | |
iterator end() | |
{ | |
return iterator(_matrix + size()); | |
} | |
const_iterator cend() const | |
{ | |
return const_iterator(_matrix + size()); | |
} | |
line_iterator lend() | |
{ | |
return line_iterator(_matrix + size(), _dims.rows); | |
} | |
unsigned int size() const | |
{ | |
return _dims.size; | |
} | |
T& operator()(unsigned int row, unsigned int col) | |
{ | |
return _matrix[N * row + col]; | |
} | |
const T& at(unsigned int row, unsigned int col) const | |
{ | |
return _matrix[N * row + col]; | |
} | |
const T& matrix() const | |
{ | |
return matrix; | |
} | |
const Dims& dims() const | |
{ | |
return _dims; | |
} | |
private: | |
Dims _dims; | |
T *_matrix; | |
}; | |
template <typename T, unsigned int M, unsigned int N> | |
std::ostream& operator<<(std::ostream& os, Matrix<T, M, N> &m) | |
{ | |
auto it = m.cbegin(); | |
while (it != m.cend()) { | |
if (std::distance(it, m.cend()) % m.dims().rows == 0 && it != m.cbegin()) os << "\n"; | |
os << *(it++) << " "; | |
} | |
os << "\n"; | |
} | |
int main() | |
{ | |
Matrix<float, 10, 10> m({1., 2., 3., 1., 2., 3.}); | |
std::cout << m; | |
auto l = m.lbegin(); | |
while (l != m.lend()) | |
std::cout << *(l++) << std::endl; | |
return 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment