Skip to content

Commit f1953ac

Browse files
committed
Merge pull request #361 from dcdillon/Issue239
Added operator<<() and print() functions to Vector
2 parents 64a0292 + 685be0c commit f1953ac

File tree

5 files changed

+232
-1
lines changed

5 files changed

+232
-1
lines changed

inst/include/Rcpp/vector/Matrix.h

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,158 @@ inline internal::DimNameProxy colnames(SEXP x) {
210210
return internal::DimNameProxy(x, 1);
211211
}
212212

213+
template<template <class> class StoragePolicy >
214+
inline std::ostream &operator<<(std::ostream & s, const Matrix<REALSXP, StoragePolicy> & rhs) {
215+
typedef Matrix<REALSXP, StoragePolicy> MATRIX;
216+
217+
std::ios::fmtflags flags = s.flags();
218+
s.unsetf(std::ios::floatfield);
219+
std::streamsize precision = s.precision();
220+
221+
const int rows = rhs.rows();
222+
223+
for (int i = 0; i < rows; ++i) {
224+
typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
225+
226+
typename MATRIX::Row::iterator j = row.begin();
227+
typename MATRIX::Row::iterator jend = row.end();
228+
229+
if (j != jend) {
230+
s << std::setw(precision + 1) << (*j);
231+
j++;
232+
233+
for ( ; j != jend; j++) {
234+
s << " " << std::setw(precision + 1) << (*j);
235+
}
236+
}
237+
238+
s << std::endl;
239+
}
240+
241+
s.flags(flags);
242+
return s;
243+
}
244+
245+
template<template <class> class StoragePolicy >
246+
inline std::ostream &operator<<(std::ostream & s, const Matrix<INTSXP, StoragePolicy> & rhs) {
247+
typedef Matrix<INTSXP, StoragePolicy> MATRIX;
248+
typedef Vector<INTSXP, StoragePolicy> VECTOR;
249+
250+
std::ios::fmtflags flags = s.flags();
251+
252+
s << std::dec;
253+
254+
int min = std::numeric_limits<int>::max();
255+
int max = std::numeric_limits<int>::min();
256+
257+
typename VECTOR::iterator j = static_cast<VECTOR &>(const_cast<MATRIX &>(rhs)).begin();
258+
typename VECTOR::iterator jend = static_cast<VECTOR &>(const_cast<MATRIX &>(rhs)).end();
259+
260+
for ( ; j != jend; ++j) {
261+
if (*j < min) {
262+
min = *j;
263+
}
264+
265+
if (*j > max) {
266+
max = *j;
267+
}
268+
}
269+
270+
int digitsMax = (max >= 0) ? 0 : 1;
271+
int digitsMin = (min >= 0) ? 0 : 1;
272+
273+
while (min != 0)
274+
{
275+
++digitsMin;
276+
min /= 10;
277+
}
278+
279+
while (max != 0)
280+
{
281+
++digitsMax;
282+
max /= 10;
283+
}
284+
285+
int digits = std::max(digitsMin, digitsMax);
286+
287+
const int rows = rhs.rows();
288+
289+
for (int i = 0; i < rows; ++i) {
290+
typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
291+
292+
typename MATRIX::Row::iterator j = row.begin();
293+
typename MATRIX::Row::iterator jend = row.end();
294+
295+
if (j != jend) {
296+
s << std::setw(digits) << (*j);
297+
++j;
298+
299+
for ( ; j != jend; ++j) {
300+
s << " " << std::setw(digits) << (*j);
301+
}
302+
}
303+
304+
s << std::endl;
305+
}
306+
307+
s.flags(flags);
308+
return s;
309+
}
310+
311+
template<template <class> class StoragePolicy >
312+
inline std::ostream &operator<<(std::ostream & s, const Matrix<STRSXP, StoragePolicy> & rhs) {
313+
typedef Matrix<STRSXP, StoragePolicy> MATRIX;
314+
315+
const int rows = rhs.rows();
316+
317+
for (int i = 0; i < rows; ++i) {
318+
typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
319+
320+
typename MATRIX::Row::iterator j = row.begin();
321+
typename MATRIX::Row::iterator jend = row.end();
322+
323+
if (j != jend) {
324+
s << "\"" << (*j) << "\"";
325+
j++;
326+
327+
for ( ; j != jend; j++) {
328+
s << " \"" << (*j) << "\"";
329+
}
330+
}
331+
332+
s << std::endl;
333+
}
334+
335+
return s;
336+
}
337+
338+
template<int RTYPE, template <class> class StoragePolicy >
339+
inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePolicy> & rhs) {
340+
typedef Matrix<RTYPE, StoragePolicy> MATRIX;
341+
342+
const int rows = rhs.rows();
343+
344+
for (int i = 0; i < rows; ++i) {
345+
typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
346+
347+
typename MATRIX::Row::iterator j = row.begin();
348+
typename MATRIX::Row::iterator jend = row.end();
349+
350+
if (j != jend) {
351+
s << (*j);
352+
j++;
353+
354+
for ( ; j != jend; j++) {
355+
s << (*j);
356+
}
357+
}
358+
359+
s << std::endl;
360+
}
361+
362+
return s;
363+
}
364+
213365
}
214366

215367
#endif

inst/include/Rcpp/vector/Vector.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,6 @@ class Vector :
582582
return -1;
583583
}
584584

585-
586585
protected:
587586
inline int* dims() const {
588587
if( !::Rf_isMatrix(Storage::get__()) ) throw not_a_matrix() ;
@@ -1080,6 +1079,44 @@ class Vector :
10801079

10811080
} ; /* Vector */
10821081

1082+
template <int RTYPE, template <class> class StoragePolicy >
1083+
inline std::ostream &operator<<(std::ostream & s, const Vector<RTYPE, StoragePolicy> & rhs) {
1084+
typedef Vector<RTYPE, StoragePolicy> VECTOR;
1085+
1086+
typename VECTOR::iterator i = const_cast<VECTOR &>(rhs).begin();
1087+
typename VECTOR::iterator iend = const_cast<VECTOR &>(rhs).end();
1088+
1089+
if (i != iend) {
1090+
s << (*i);
1091+
++i;
1092+
1093+
for ( ; i != iend; ++i) {
1094+
s << " " << (*i);
1095+
}
1096+
}
1097+
1098+
return s;
1099+
}
1100+
1101+
template<template <class> class StoragePolicy >
1102+
inline std::ostream &operator<<(std::ostream & s, const Vector<STRSXP, StoragePolicy> & rhs) {
1103+
typedef Vector<STRSXP, StoragePolicy> VECTOR;
1104+
1105+
typename VECTOR::iterator i = const_cast<VECTOR &>(rhs).begin();
1106+
typename VECTOR::iterator iend = const_cast<VECTOR &>(rhs).end();
1107+
1108+
if (i != iend) {
1109+
s << "\"" << (*i) << "\"";
1110+
++i;
1111+
1112+
for ( ; i != iend; ++i) {
1113+
s << " \"" << (*i) << "\"";
1114+
}
1115+
}
1116+
1117+
return s;
1118+
}
1119+
10831120
}
10841121

10851122
#endif

inst/include/RcppCommon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace Rcpp {
4949
#include <iterator>
5050
#include <exception>
5151
#include <iostream>
52+
#include <iomanip>
5253
#include <sstream>
5354
#include <string>
5455
#include <list>

inst/unitTests/cpp/Vector.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include <climits>
2323
#include <Rcpp.h>
24+
#include <sstream>
25+
2426
using namespace Rcpp ;
2527

2628
inline double square( double x){ return x*x; }
@@ -782,3 +784,24 @@ int noprotect_matrix( Matrix<REALSXP, NoProtectStorage> x){
782784
int vec_access_with_bounds_checking(const IntegerVector x, int index) {
783785
return x.at(index);
784786
}
787+
788+
// [[Rcpp::export]]
789+
String vec_print_numeric(NumericVector v) {
790+
std::ostringstream buf;
791+
buf << v;
792+
return buf.str();
793+
}
794+
795+
// [[Rcpp::export]]
796+
String vec_print_character(CharacterVector v) {
797+
std::ostringstream buf;
798+
buf << v;
799+
return buf.str();
800+
}
801+
802+
// [[Rcpp::export]]
803+
String vec_print_integer(IntegerVector v) {
804+
std::ostringstream buf;
805+
buf << v;
806+
return buf.str();
807+
}

inst/unitTests/runit.Vector.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,5 +690,23 @@ if (.runThisTest) {
690690
checkException(vec_access_with_bounds_checking(x, 5) , msg = "index out of bounds not detected" )
691691
checkException(vec_access_with_bounds_checking(x, -1) , msg = "index out of bounds not detected" )
692692
}
693+
694+
test.NumericVector.print <- function() {
695+
v <- c(1.1, 2.2, 3.3, 4.4)
696+
s <- vec_print_numeric(v)
697+
checkEquals(s, "1.1 2.2 3.3 4.4")
698+
}
699+
700+
test.IntegerVector.print <- function() {
701+
v <- c(1, 2, 3, 4)
702+
s <-vec_print_integer(v)
703+
checkEquals(s, "1 2 3 4")
704+
}
705+
706+
test.CharacterVector.print <- function() {
707+
v <- c("a", "b", "c", "d")
708+
s <- vec_print_character(v)
709+
checkEquals(s, '"a" "b" "c" "d"')
710+
}
693711
}
694712

0 commit comments

Comments
 (0)