A library for working with phylogenetic and population genetic data.
v0.27.0
row.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_CONTAINERS_MATRIX_ROW_H_
2 #define GENESIS_UTILS_CONTAINERS_MATRIX_ROW_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2020 Lucas Czech and HITS gGmbH
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
35 
36 #include <cstddef>
37 #include <iterator>
38 #include <stdexcept>
39 #include <type_traits>
40 #include <vector>
41 
42 namespace genesis {
43 namespace utils {
44 
45 // =================================================================================================
46 // Forward Declarations
47 // =================================================================================================
48 
49 template <typename T>
50 class Matrix;
51 
52 // =================================================================================================
53 // Matrix Row
54 // =================================================================================================
55 
59 template <typename MT, typename T>
60 class MatrixRow
61 {
62 public:
63 
64  // -------------------------------------------------------------
65  // Typedefs
66  // -------------------------------------------------------------
67 
69  using matrix_type = MT;
70  using value_type = T;
71 
72  using non_const_value_type = typename std::remove_const<T>::type;
73 
74  // -------------------------------------------------------------
75  // Constructors and Rule of Five
76  // -------------------------------------------------------------
77 
78  MatrixRow( matrix_type& mat, size_t row )
79  : mat_( &mat )
80  , row_( row )
81  {}
82 
83  ~MatrixRow() = default;
84 
85  MatrixRow(MatrixRow const&) = default;
86  MatrixRow(MatrixRow&&) = default;
87 
88  MatrixRow& operator= (MatrixRow const&) = default;
89  MatrixRow& operator= (MatrixRow&&) = default;
90 
91  // -------------------------------------------------------------
92  // Iterator
93  // -------------------------------------------------------------
94 
98  class Iterator
99  {
100  public:
101 
102  // -----------------------------------------------------
103  // Typedefs
104  // -----------------------------------------------------
105 
106  using iterator_category = std::random_access_iterator_tag;
108 
109  using value_type = T;
110  using pointer = T*;
111  using reference = T&;
112  using difference_type = ptrdiff_t;
113 
114  // -----------------------------------------------------
115  // Constructors and Rule of Five
116  // -----------------------------------------------------
117 
118  private:
119 
120  friend class MatrixRow;
121 
122  Iterator( matrix_type* mat, size_t row, size_t col )
123  : mat_( mat )
124  , row_( row )
125  , col_( col )
126  {}
127 
128  public:
129 
130  ~Iterator() = default;
131 
132  Iterator(Iterator const&) = default;
133  Iterator(Iterator&&) = default;
134 
135  Iterator& operator= (Iterator const&) = default;
136  Iterator& operator= (Iterator&&) = default;
137 
138  // -----------------------------------------------------
139  // Operators
140  // -----------------------------------------------------
141 
143  {
144  return (*mat_)( row_, col_ + n );
145  }
146 
148  {
149  return (*mat_)( row_, col_ );
150  }
151 
153  {
154  return &((*mat_)( row_, col_ ));
155  }
156 
158  {
159  ++col_;
160  return *this;
161  }
162 
164  {
165  self_type tmp = *this;
166  ++(*this);
167  return tmp;
168  }
169 
171  {
172  --col_;
173  return *this;
174  }
175 
177  {
178  self_type tmp = *this;
179  --(*this);
180  return tmp;
181  }
182 
184  {
185  col_ += n;
186  return *this;
187  }
188 
190  {
191  col_ -= n;
192  return *this;
193  }
194 
196  {
197  return self_type( it.mat_, it.row_, it.col_ + n );
198  }
199 
201  {
202  return self_type( it.mat_, it.row_, it.col_ + n );
203  }
204 
206  {
207  return self_type( it.mat_, it.row_, it.col_ - n );
208  }
209 
210  difference_type operator - ( self_type const& other ) const
211  {
212  return col_ - other.col_;
213  }
214 
215  bool operator == ( self_type const& other ) const
216  {
217  return other.mat_ == mat_ && other.row_ == row_ && other.col_ == col_;
218  }
219 
220  bool operator != ( self_type const& other ) const
221  {
222  return !(other == *this);
223  }
224 
225  bool operator < ( self_type const& other ) const
226  {
227  return col_ < other.col_;
228  }
229 
230  bool operator <= ( self_type const& other ) const
231  {
232  return col_ <= other.col_;
233  }
234 
235  bool operator > ( self_type const& other ) const
236  {
237  return col_ > other.col_;
238  }
239 
240  bool operator >= ( self_type const& other ) const
241  {
242  return col_ >= other.col_;
243  }
244 
245  void swap( self_type& other )
246  {
247  using std::swap;
248  swap( mat_, other.mat_ );
249  swap( row_, other.row_ );
250  swap( col_, other.col_ );
251  }
252 
253  friend void swap( self_type& lhs, self_type& rhs )
254  {
255  lhs.swap( rhs );
256  }
257 
258  // -----------------------------------------------------
259  // Data Members
260  // -----------------------------------------------------
261 
262  private:
263 
264  matrix_type* mat_ = nullptr;
265  size_t row_ = 0;
266  size_t col_ = 0;
267 
268  };
269 
270  // -------------------------------------------------------------
271  // Members
272  // -------------------------------------------------------------
273 
277  Iterator begin() const
278  {
279  return Iterator( mat_, row_, 0 );
280  }
281 
285  Iterator end() const
286  {
287  return Iterator( mat_, row_, mat_->cols() );
288  }
289 
293  value_type& at( size_t column ) const
294  {
295  return mat_->at( row_, column );
296  }
297 
301  value_type& operator[]( size_t column ) const
302  {
303  return (*mat_)( row_, column );
304  }
305 
310  {
311  return *mat_;
312  }
313 
317  size_t row() const
318  {
319  return row_;
320  }
321 
325  size_t size() const
326  {
327  return mat_->cols();
328  }
329 
330  // -------------------------------------------------------------
331  // Interaction Operators
332  // -------------------------------------------------------------
333 
337  operator std::vector<non_const_value_type>() const
338  {
339  return to_vector();
340  }
341 
345  std::vector<non_const_value_type> to_vector() const
346  {
347  auto result = std::vector<non_const_value_type>( mat_->cols() );
348  for( size_t i = 0; i < mat_->cols(); ++i ) {
349  result[i] = (*mat_)( row_, i );
350  }
351  return result;
352  }
353 
359  self_type& operator = ( std::vector<T> const& vec )
360  {
361  if( vec.size() != mat_->cols() ) {
362  throw std::runtime_error( "Cannot assign vector with different size to Matrix row." );
363  }
364 
365  for( size_t i = 0; i < vec.size(); ++i ) {
366  (*mat_)( row_, i ) = vec[i];
367  }
368 
369  return *this;
370  }
371 
378  self_type& assign( self_type const& other )
379  {
380  if( other.size() != mat_->cols() ) {
381  throw std::runtime_error( "Cannot assign row with different size to Matrix row." );
382  }
383 
384  for( size_t i = 0; i < other.size(); ++i ) {
385  (*mat_)( row_, i ) = other[i];
386  }
387 
388  return *this;
389  }
390 
391  // -------------------------------------------------------------
392  // Comparison Operators
393  // -------------------------------------------------------------
394 
399  bool operator == ( self_type const& other ) const
400  {
401  // Need to have the same length
402  if( mat_->cols() != other.mat_->cols() ) {
403  return false;
404  }
405 
406  // Element-wise comparison
407  for( size_t i = 0; i < mat_->cols(); ++i ) {
408  if( !( (*mat_)( row_, i ) == other[ i ] )) {
409  return false;
410  }
411  }
412  return true;
413  }
414 
419  bool operator != ( self_type const& other ) const
420  {
421  return !(*this == other);
422  }
423 
424  // -------------------------------------------------------------
425  // Data Members
426  // -------------------------------------------------------------
427 
428 private:
429 
430  matrix_type* mat_ = nullptr;
431  size_t row_ = 0;
432 
433 };
434 
435 } // namespace utils
436 } // namespace genesis
437 
438 #endif // include guard
genesis::utils::MatrixRow::to_vector
std::vector< non_const_value_type > to_vector() const
Explicit conversion to vector.
Definition: row.hpp:345
genesis::placement::swap
void swap(Sample &lhs, Sample &rhs)
Definition: sample.cpp:104
genesis::utils::MatrixRow::Iterator::operator+
friend self_type operator+(difference_type n, self_type const &it)
Definition: row.hpp:195
genesis::utils::MatrixRow::Iterator::operator*
value_type & operator*() const
Definition: row.hpp:147
genesis::utils::MatrixRow::assign
self_type & assign(self_type const &other)
Overwrite a row by the elements of another row.
Definition: row.hpp:378
genesis::utils::MatrixRow::Iterator::operator!=
bool operator!=(self_type const &other) const
Definition: row.hpp:220
genesis::utils::MatrixRow::matrix_type
MT matrix_type
Definition: row.hpp:69
genesis::utils::MatrixRow::Iterator::operator<=
bool operator<=(self_type const &other) const
Definition: row.hpp:230
genesis::utils::MatrixRow::Iterator::~Iterator
~Iterator()=default
genesis::utils::MatrixRow::Iterator::swap
void swap(self_type &other)
Definition: row.hpp:245
genesis::utils::MatrixRow::non_const_value_type
typename std::remove_const< T >::type non_const_value_type
Definition: row.hpp:72
genesis::utils::MatrixRow::Iterator
Random access iterator into a Matrix row.
Definition: row.hpp:98
genesis::utils::MatrixRow::MatrixRow
MatrixRow(matrix_type &mat, size_t row)
Definition: row.hpp:78
genesis::utils::MatrixRow::Iterator::operator<
bool operator<(self_type const &other) const
Definition: row.hpp:225
genesis::utils::MatrixRow::operator=
MatrixRow & operator=(MatrixRow const &)=default
genesis::utils::MatrixRow::operator!=
bool operator!=(self_type const &other) const
Return whether the elements of two rows are identical, using == for comparing elements.
Definition: row.hpp:419
genesis::utils::MatrixRow::Iterator::swap
friend void swap(self_type &lhs, self_type &rhs)
Definition: row.hpp:253
genesis::utils::MatrixRow::begin
Iterator begin() const
Return an iterator to the beginning of the row.
Definition: row.hpp:277
genesis::utils::MatrixRow::Iterator::pointer
T * pointer
Definition: row.hpp:110
genesis::utils::MatrixRow::Iterator::reference
T & reference
Definition: row.hpp:111
genesis::utils::MatrixRow::size
size_t size() const
Get the size of the row, that is, the number of columns of the Matrix.
Definition: row.hpp:325
genesis::utils::MatrixRow::end
Iterator end() const
Return an iterator to past-the-end of the row.
Definition: row.hpp:285
range.hpp
genesis::utils::MatrixRow::Iterator::operator++
self_type operator++()
Definition: row.hpp:157
genesis::utils::MatrixRow::Iterator::difference_type
ptrdiff_t difference_type
Definition: row.hpp:112
genesis::utils::MatrixRow::~MatrixRow
~MatrixRow()=default
genesis::utils::MatrixRow::Iterator::operator>=
bool operator>=(self_type const &other) const
Definition: row.hpp:240
genesis::utils::MatrixRow::Iterator::operator+=
self_type operator+=(difference_type n)
Definition: row.hpp:183
genesis::utils::MatrixRow::Iterator::operator--
self_type operator--()
Definition: row.hpp:170
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::MatrixRow::row
size_t row() const
Get the row index that this object represents.
Definition: row.hpp:317
genesis::utils::MatrixRow::Iterator::operator==
bool operator==(self_type const &other) const
Definition: row.hpp:215
genesis::utils::MatrixRow::Iterator::iterator_category
std::random_access_iterator_tag iterator_category
Definition: row.hpp:106
genesis::utils::MatrixRow::Iterator::operator=
Iterator & operator=(Iterator const &)=default
genesis::utils::MatrixRow::Iterator::value_type
T value_type
Definition: row.hpp:109
genesis::utils::MatrixRow::Iterator::operator-
friend self_type operator-(self_type const &it, difference_type n)
Definition: row.hpp:205
genesis::utils::MatrixRow::operator[]
value_type & operator[](size_t column) const
Return the element at a given column of the Matrix row.
Definition: row.hpp:301
genesis::utils::MatrixRow
View into a Matrix row.
Definition: row.hpp:60
genesis::utils::MatrixRow::operator==
bool operator==(self_type const &other) const
Return whether the elements of two rows are identical, using == for comparing elements.
Definition: row.hpp:399
genesis::utils::MatrixRow::Iterator::operator>
bool operator>(self_type const &other) const
Definition: row.hpp:235
genesis::utils::MatrixRow::value_type
T value_type
Definition: row.hpp:70
genesis::utils::MatrixRow::Iterator::operator-=
self_type operator-=(difference_type n)
Definition: row.hpp:189
genesis::utils::MatrixRow::at
value_type & at(size_t column) const
Return the element at a given column of the Matrix row.
Definition: row.hpp:293
genesis::utils::MatrixRow::Iterator::operator[]
value_type & operator[](difference_type n) const
Definition: row.hpp:142
genesis::utils::MatrixRow::matrix
matrix_type & matrix() const
Get the underlying Matrix.
Definition: row.hpp:309
genesis::utils::MatrixRow::Iterator::self_type
MatrixRow< MT, T >::Iterator self_type
Definition: row.hpp:107
genesis::utils::MatrixRow::Iterator::operator->
value_type * operator->() const
Definition: row.hpp:152