Skip to content

Instantly share code, notes, and snippets.

@juliangaal
Created November 14, 2018 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juliangaal/a88b9d95ab4d8eeb671b0cc4c46d2741 to your computer and use it in GitHub Desktop.
Save juliangaal/a88b9d95ab4d8eeb671b0cc4c46d2741 to your computer and use it in GitHub Desktop.
Matrix class with custom iterators
#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