|
| 1 | +// Copyright © 2022 Thomas Nagler |
| 2 | +// |
| 3 | +// This file is part of the RcppThread and licensed under the terms of |
| 4 | +// the MIT license. For a copy, see the LICENSE.md file in the root |
| 5 | +// directory of RcppThread or |
| 6 | +// https://github.com/tnagler/RcppThread/blob/master/LICENSE.md. |
| 7 | + |
| 8 | +#pragma once |
| 9 | + |
| 10 | +#include <cstddef> |
| 11 | +#include <iterator> |
| 12 | + |
| 13 | +namespace RcppThread { |
| 14 | + |
| 15 | +template <typename T> class RMatrix { |
| 16 | +public: |
| 17 | + class Row { |
| 18 | + |
| 19 | + public: |
| 20 | + template <typename V> class row_iterator { |
| 21 | + |
| 22 | + public: |
| 23 | + using iterator_category = std::random_access_iterator_tag; |
| 24 | + using value_type = V; |
| 25 | + using difference_type = std::size_t; |
| 26 | + using pointer = value_type *; |
| 27 | + using reference = value_type &; |
| 28 | + |
| 29 | + inline row_iterator(Row &row, difference_type i) |
| 30 | + : start_(row.start_), parentNrow_(row.parent_.nrow()), index_(i) {} |
| 31 | + |
| 32 | + inline row_iterator(pointer start, difference_type parentNrow, |
| 33 | + difference_type index) |
| 34 | + : start_(start), parentNrow_(parentNrow), index_(index) {} |
| 35 | + |
| 36 | + inline row_iterator(const row_iterator &other) |
| 37 | + : start_(other.start_), parentNrow_(other.parentNrow_), |
| 38 | + index_(other.index_) {} |
| 39 | + |
| 40 | + inline row_iterator &operator++() { |
| 41 | + index_++; |
| 42 | + return *this; |
| 43 | + } |
| 44 | + |
| 45 | + inline row_iterator operator++(int) { |
| 46 | + row_iterator tmp(*this); |
| 47 | + operator++(); |
| 48 | + return tmp; |
| 49 | + } |
| 50 | + |
| 51 | + inline row_iterator &operator--() { |
| 52 | + index_--; |
| 53 | + return *this; |
| 54 | + } |
| 55 | + |
| 56 | + inline row_iterator operator--(int) { |
| 57 | + row_iterator tmp(*this); |
| 58 | + index_--; |
| 59 | + return tmp; |
| 60 | + } |
| 61 | + |
| 62 | + row_iterator operator+(difference_type n) const { |
| 63 | + return row_iterator(start_, parentNrow_, index_ + n); |
| 64 | + } |
| 65 | + row_iterator operator-(difference_type n) const { |
| 66 | + return row_iterator(start_, parentNrow_, index_ - n); |
| 67 | + } |
| 68 | + |
| 69 | + difference_type operator+(const row_iterator &other) const { |
| 70 | + return index_ + other.index_; |
| 71 | + } |
| 72 | + |
| 73 | + difference_type operator-(const row_iterator &other) const { |
| 74 | + return index_ - other.index_; |
| 75 | + } |
| 76 | + |
| 77 | + row_iterator &operator+=(difference_type n) { |
| 78 | + index_ += n; |
| 79 | + return *this; |
| 80 | + } |
| 81 | + row_iterator &operator-=(difference_type n) { |
| 82 | + index_ -= n; |
| 83 | + return *this; |
| 84 | + } |
| 85 | + |
| 86 | + bool operator==(const row_iterator &other) const { |
| 87 | + return index_ == other.index_; |
| 88 | + } |
| 89 | + bool operator!=(const row_iterator &other) const { |
| 90 | + return index_ != other.index_; |
| 91 | + } |
| 92 | + bool operator<(const row_iterator &other) const { |
| 93 | + return index_ < other.index_; |
| 94 | + } |
| 95 | + bool operator>(const row_iterator &other) const { |
| 96 | + return index_ > other.index_; |
| 97 | + } |
| 98 | + bool operator<=(const row_iterator &other) const { |
| 99 | + return index_ <= other.index_; |
| 100 | + } |
| 101 | + bool operator>=(const row_iterator &other) const { |
| 102 | + return index_ >= other.index_; |
| 103 | + } |
| 104 | + |
| 105 | + inline reference operator*() { return start_[index_ * parentNrow_]; } |
| 106 | + |
| 107 | + inline pointer operator->() { return &(start_[index_ * parentNrow_]); } |
| 108 | + |
| 109 | + inline reference operator[](int i) { |
| 110 | + return start_[(index_ + i) * parentNrow_]; |
| 111 | + } |
| 112 | + |
| 113 | + private: |
| 114 | + pointer start_; |
| 115 | + difference_type parentNrow_; |
| 116 | + difference_type index_; |
| 117 | + }; |
| 118 | + |
| 119 | + typedef row_iterator<T> iterator; |
| 120 | + typedef row_iterator<const T> const_iterator; |
| 121 | + |
| 122 | + inline Row(RMatrix &parent, std::size_t i) |
| 123 | + : parent_(parent), start_(parent.begin() + i) {} |
| 124 | + |
| 125 | + inline Row(const Row &other) |
| 126 | + : parent_(other.parent_), start_(other.start_) {} |
| 127 | + |
| 128 | + inline iterator begin() { return iterator(*this, 0); } |
| 129 | + |
| 130 | + inline iterator end() { return iterator(*this, parent_.ncol()); } |
| 131 | + |
| 132 | + inline const_iterator begin() const { return const_iterator(*this, 0); } |
| 133 | + |
| 134 | + inline const_iterator end() const { |
| 135 | + return const_iterator(*this, parent_.ncol()); |
| 136 | + } |
| 137 | + |
| 138 | + inline size_t length() const { return parent_.ncol(); } |
| 139 | + |
| 140 | + inline size_t size() const { return parent_.ncol(); } |
| 141 | + |
| 142 | + inline T &operator[](std::size_t i) { return start_[i * parent_.nrow()]; } |
| 143 | + |
| 144 | + inline const T &operator[](std::size_t i) const { |
| 145 | + return start_[i * parent_.nrow()]; |
| 146 | + } |
| 147 | + |
| 148 | + private: |
| 149 | + RMatrix &parent_; |
| 150 | + T *start_; |
| 151 | + }; |
| 152 | + |
| 153 | + class Column { |
| 154 | + |
| 155 | + public: |
| 156 | + typedef T *iterator; |
| 157 | + typedef const T *const_iterator; |
| 158 | + |
| 159 | + inline Column(RMatrix &parent, std::size_t i) |
| 160 | + : begin_(parent.begin() + (i * parent.nrow())), |
| 161 | + end_(begin_ + parent.nrow()) {} |
| 162 | + |
| 163 | + inline Column(const Column &other) |
| 164 | + : begin_(other.begin_), end_(other.end_) {} |
| 165 | + |
| 166 | + inline Column &operator=(const Column &rhs) { |
| 167 | + begin_ = rhs.begin_; |
| 168 | + end_ = rhs.end_; |
| 169 | + return *this; |
| 170 | + } |
| 171 | + |
| 172 | + inline iterator begin() { return begin_; } |
| 173 | + inline iterator end() { return end_; } |
| 174 | + |
| 175 | + inline const_iterator begin() const { return begin_; } |
| 176 | + inline const_iterator end() const { return end_; } |
| 177 | + |
| 178 | + inline size_t length() const { return end_ - begin_; } |
| 179 | + inline size_t size() const { return end_ - begin_; } |
| 180 | + |
| 181 | + inline T &operator[](std::size_t i) { return *(begin_ + i); } |
| 182 | + |
| 183 | + inline const T &operator[](std::size_t i) const { return *(begin_ + i); } |
| 184 | + |
| 185 | + private: |
| 186 | + T *begin_; |
| 187 | + T *end_; |
| 188 | + }; |
| 189 | + |
| 190 | + typedef T *iterator; |
| 191 | + typedef const T *const_iterator; |
| 192 | + |
| 193 | + template <typename Source> |
| 194 | + inline explicit RMatrix(const Source &source) |
| 195 | + : data_(const_cast<Source &>(source).begin()), nrow_(source.nrow()), |
| 196 | + ncol_(source.ncol()) {} |
| 197 | + |
| 198 | + inline RMatrix(T *data, std::size_t nrow, std::size_t ncol) |
| 199 | + : data_(data), nrow_(nrow), ncol_(ncol) {} |
| 200 | + |
| 201 | + inline iterator begin() { return data_; } |
| 202 | + inline iterator end() { return data_ + length(); } |
| 203 | + |
| 204 | + inline const_iterator begin() const { return data_; } |
| 205 | + inline const_iterator end() const { return data_ + length(); } |
| 206 | + |
| 207 | + inline std::size_t length() const { return nrow_ * ncol_; } |
| 208 | + |
| 209 | + inline std::size_t nrow() const { return nrow_; } |
| 210 | + inline std::size_t ncol() const { return ncol_; } |
| 211 | + |
| 212 | + inline T &operator()(std::size_t i, std::size_t j) { |
| 213 | + return *(data_ + (i + j * nrow_)); |
| 214 | + } |
| 215 | + |
| 216 | + inline const T &operator()(std::size_t i, std::size_t j) const { |
| 217 | + return *(data_ + (i + j * nrow_)); |
| 218 | + } |
| 219 | + |
| 220 | + inline Row row(std::size_t i) { return Row(*this, i); } |
| 221 | + |
| 222 | + inline const Row row(std::size_t i) const { |
| 223 | + return Row(*const_cast<RMatrix *>(this), i); |
| 224 | + } |
| 225 | + |
| 226 | + inline Column column(std::size_t i) { return Column(*this, i); } |
| 227 | + |
| 228 | + inline const Column column(std::size_t i) const { |
| 229 | + return Column(*const_cast<RMatrix *>(this), i); |
| 230 | + } |
| 231 | + |
| 232 | + inline T &operator[](std::size_t i) { return *(data_ + i); } |
| 233 | + |
| 234 | + inline const T &operator[](std::size_t i) const { return *(data_ + i); } |
| 235 | + |
| 236 | +private: |
| 237 | + T *data_; |
| 238 | + std::size_t nrow_; |
| 239 | + std::size_t ncol_; |
| 240 | +}; |
| 241 | + |
| 242 | +} // namespace RcppThread |
0 commit comments