1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 2 // 3 // MatrixColumn.h: Rcpp R/C++ interface class library -- matrices column 4 // 5 // Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois 6 // 7 // This file is part of Rcpp. 8 // 9 // Rcpp is free software: you can redistribute it and/or modify it 10 // under the terms of the GNU General Public License as published by 11 // the Free Software Foundation, either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Rcpp is distributed in the hope that it will be useful, but 15 // WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 21 22 #ifndef Rcpp__vector__MatrixColumn_h 23 #define Rcpp__vector__MatrixColumn_h 24 25 namespace Rcpp{ 26 27 template <int RTYPE> 28 class MatrixColumn : public VectorBase<RTYPE,true,MatrixColumn<RTYPE> > { 29 public: 30 typedef Matrix<RTYPE> MATRIX ; 31 typedef typename MATRIX::Proxy Proxy ; 32 typedef typename MATRIX::const_Proxy const_Proxy ; 33 typedef typename MATRIX::value_type value_type ; 34 typedef typename MATRIX::iterator iterator ; 35 typedef typename MATRIX::const_iterator const_iterator ; 36 MatrixColumn(MATRIX & parent,int i)37 MatrixColumn( MATRIX& parent, int i ) : 38 n(parent.nrow()), 39 start(parent.begin() + static_cast<R_xlen_t>(i) * n ), 40 const_start(const_cast<const MATRIX&>(parent).begin() + static_cast<R_xlen_t>(i) * n) 41 { 42 if( i < 0 || i >= parent.ncol() ) { 43 const char* fmt = "Column index is out of bounds: " 44 "[index=%i; column extent=%i]."; 45 throw index_out_of_bounds(fmt, i, parent.ncol()) ; 46 } 47 } 48 MatrixColumn(const MATRIX & parent,int i)49 MatrixColumn( const MATRIX& parent, int i ) : 50 n(parent.nrow()), 51 start( const_cast<MATRIX&>(parent).begin() + static_cast<R_xlen_t>(i) * n ), 52 const_start(parent.begin() + static_cast<R_xlen_t>(i) * n) 53 { 54 if( i < 0 || i >= parent.ncol() ) { 55 const char* fmt = "Column index is out of bounds: " 56 "[index=%i; column extent=%i]."; 57 throw index_out_of_bounds(fmt, i, parent.ncol()) ; 58 } 59 } 60 MatrixColumn(const MatrixColumn & other)61 MatrixColumn( const MatrixColumn& other ) : 62 n(other.n), 63 start(other.start), 64 const_start(other.const_start) {} 65 66 template <int RT, bool NA, typename T> 67 MatrixColumn& operator=( const Rcpp::VectorBase<RT,NA,T>& rhs ){ 68 const T& ref = rhs.get_ref() ; 69 RCPP_LOOP_UNROLL(start,ref) 70 return *this ; 71 } 72 73 MatrixColumn& operator=( const MatrixColumn& rhs ){ 74 iterator rhs_start = rhs.start ; 75 RCPP_LOOP_UNROLL(start,rhs_start) 76 return *this ; 77 } 78 79 inline Proxy operator[]( int i ){ 80 return start[i] ; 81 } 82 83 inline const_Proxy operator[]( int i ) const { 84 return const_start[i] ; 85 } 86 begin()87 inline const_iterator begin() const { 88 return const_start ; 89 } 90 end()91 inline const_iterator end() const { 92 return const_start + n ; 93 } 94 cbegin()95 inline const_iterator cbegin() const { 96 return const_start ; 97 } 98 cend()99 inline const_iterator cend() const { 100 return const_start + n ; 101 } 102 begin()103 inline iterator begin(){ 104 return start ; 105 } 106 end()107 inline iterator end(){ 108 return start + n ; 109 } 110 size()111 inline int size() const { 112 return n ; 113 } 114 115 private: 116 const int n ; 117 iterator start ; 118 const_iterator const_start ; 119 120 } ; 121 122 template <int RTYPE> 123 class ConstMatrixColumn : public VectorBase<RTYPE,true,ConstMatrixColumn<RTYPE> > { 124 public: 125 typedef Matrix<RTYPE> MATRIX ; 126 typedef typename MATRIX::const_Proxy const_Proxy ; 127 typedef typename MATRIX::value_type value_type ; 128 typedef typename MATRIX::const_iterator const_iterator ; 129 ConstMatrixColumn(const MATRIX & parent,int i)130 ConstMatrixColumn( const MATRIX& parent, int i ) : 131 n(parent.nrow()), 132 const_start(parent.begin() + i *n) 133 { 134 if( i < 0 || i >= parent.ncol() ) { 135 const char* fmt = "Column index is out of bounds: " 136 "[index=%i; column extent=%i]."; 137 throw index_out_of_bounds(fmt, i, parent.ncol()) ; 138 } 139 } 140 ConstMatrixColumn(const ConstMatrixColumn & other)141 ConstMatrixColumn( const ConstMatrixColumn& other ) : 142 n(other.n), 143 const_start(other.const_start) {} 144 145 inline const_Proxy operator[]( int i ) const { 146 return const_start[i] ; 147 } 148 begin()149 inline const_iterator begin() const { 150 return const_start ; 151 } 152 end()153 inline const_iterator end() const { 154 return const_start + n ; 155 } 156 cbegin()157 inline const_iterator cbegin() const { 158 return const_start ; 159 } 160 cend()161 inline const_iterator cend() const { 162 return const_start + n ; 163 } 164 size()165 inline int size() const { 166 return n ; 167 } 168 169 private: 170 const int n ; 171 const_iterator const_start ; 172 173 } ; 174 175 } 176 #endif 177