Skip to content

Commit 5e945fc

Browse files
authored
Merge pull request #14 from pachadotdev/matrix_attr
Matrix attr
2 parents 926b078 + fbded54 commit 5e945fc

File tree

5 files changed

+145
-9
lines changed

5 files changed

+145
-9
lines changed

cpp11test/R/cpp11.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ col_sums <- function(x) {
124124
.Call(`_cpp11test_col_sums`, x)
125125
}
126126

127+
mat_mat_copy_dimnames <- function(x) {
128+
.Call(`_cpp11test_mat_mat_copy_dimnames`, x)
129+
}
130+
131+
mat_sexp_copy_dimnames <- function(x) {
132+
.Call(`_cpp11test_mat_sexp_copy_dimnames`, x)
133+
}
134+
135+
mat_mat_create_dimnames <- function() {
136+
.Call(`_cpp11test_mat_mat_create_dimnames`)
137+
}
138+
127139
protect_one_ <- function(x, n) {
128140
invisible(.Call(`_cpp11test_protect_one_`, x, n))
129141
}

cpp11test/src/cpp11.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,27 @@ extern "C" SEXP _cpp11test_col_sums(SEXP x) {
236236
return cpp11::as_sexp(col_sums(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<cpp11::by_column>>>(x)));
237237
END_CPP11
238238
}
239+
// matrix.cpp
240+
cpp11::doubles_matrix<> mat_mat_copy_dimnames(cpp11::doubles_matrix<> x);
241+
extern "C" SEXP _cpp11test_mat_mat_copy_dimnames(SEXP x) {
242+
BEGIN_CPP11
243+
return cpp11::as_sexp(mat_mat_copy_dimnames(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<>>>(x)));
244+
END_CPP11
245+
}
246+
// matrix.cpp
247+
SEXP mat_sexp_copy_dimnames(cpp11::doubles_matrix<> x);
248+
extern "C" SEXP _cpp11test_mat_sexp_copy_dimnames(SEXP x) {
249+
BEGIN_CPP11
250+
return cpp11::as_sexp(mat_sexp_copy_dimnames(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<>>>(x)));
251+
END_CPP11
252+
}
253+
// matrix.cpp
254+
cpp11::doubles_matrix<> mat_mat_create_dimnames();
255+
extern "C" SEXP _cpp11test_mat_mat_create_dimnames() {
256+
BEGIN_CPP11
257+
return cpp11::as_sexp(mat_mat_create_dimnames());
258+
END_CPP11
259+
}
239260
// protect.cpp
240261
void protect_one_(SEXP x, int n);
241262
extern "C" SEXP _cpp11test_protect_one_(SEXP x, SEXP n) {
@@ -609,6 +630,9 @@ static const R_CallMethodDef CallEntries[] = {
609630
{"_cpp11test_gibbs_rcpp", (DL_FUNC) &_cpp11test_gibbs_rcpp, 2},
610631
{"_cpp11test_gibbs_rcpp2", (DL_FUNC) &_cpp11test_gibbs_rcpp2, 2},
611632
{"_cpp11test_grow_", (DL_FUNC) &_cpp11test_grow_, 1},
633+
{"_cpp11test_mat_mat_copy_dimnames", (DL_FUNC) &_cpp11test_mat_mat_copy_dimnames, 1},
634+
{"_cpp11test_mat_mat_create_dimnames", (DL_FUNC) &_cpp11test_mat_mat_create_dimnames, 0},
635+
{"_cpp11test_mat_sexp_copy_dimnames", (DL_FUNC) &_cpp11test_mat_sexp_copy_dimnames, 1},
612636
{"_cpp11test_grow_strings_cpp11_", (DL_FUNC) &_cpp11test_grow_strings_cpp11_, 2},
613637
{"_cpp11test_grow_strings_manual_", (DL_FUNC) &_cpp11test_grow_strings_manual_, 2},
614638
{"_cpp11test_grow_strings_rcpp_", (DL_FUNC) &_cpp11test_grow_strings_rcpp_, 2},

cpp11test/src/matrix.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "cpp11/matrix.hpp"
22
#include "Rmath.h"
33
#include "cpp11/doubles.hpp"
4+
#include "cpp11/list.hpp"
5+
#include "cpp11/strings.hpp"
46
using namespace cpp11;
57

68
[[cpp11::register]] SEXP gibbs_cpp(int N, int thin) {
@@ -104,3 +106,47 @@ using namespace Rcpp;
104106

105107
return sums;
106108
}
109+
110+
[[cpp11::register]] cpp11::doubles_matrix<> mat_mat_copy_dimnames(
111+
cpp11::doubles_matrix<> x) {
112+
cpp11::writable::doubles_matrix<> out = x;
113+
114+
// SEXP dimnames = x.attr("dimnames");
115+
// if (dimnames != R_NilValue) {
116+
// Rf_setAttrib(out.data(), R_DimNamesSymbol, dimnames);
117+
// }
118+
119+
out.attr("dimnames") = x.attr("dimnames");
120+
121+
return out;
122+
}
123+
124+
[[cpp11::register]] SEXP mat_sexp_copy_dimnames(cpp11::doubles_matrix<> x) {
125+
cpp11::writable::doubles_matrix<> out = x;
126+
127+
// SEXP dimnames = x.attr("dimnames");
128+
// if (dimnames != R_NilValue) {
129+
// Rf_setAttrib(out.data(), R_DimNamesSymbol, dimnames);
130+
// }
131+
132+
out.attr("dimnames") = x.attr("dimnames");
133+
134+
return out;
135+
}
136+
137+
[[cpp11::register]] cpp11::doubles_matrix<> mat_mat_create_dimnames() {
138+
cpp11::writable::doubles_matrix<> out(2, 2);
139+
140+
out(0, 0) = 1;
141+
out(0, 1) = 2;
142+
out(1, 0) = 3;
143+
out(1, 1) = 4;
144+
145+
cpp11::writable::list dimnames(2);
146+
dimnames[0] = cpp11::strings({"a", "b"});
147+
dimnames[1] = cpp11::strings({"c", "d"});
148+
149+
out.attr("dimnames") = dimnames;
150+
151+
return out;
152+
}

cpp11test/tests/testthat/test-matrix.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,19 @@ test_that("col_sums gives same result as colSums", {
2323
y[3, ] <- NA;
2424
expect_equal(col_sums(y), colSums(y))
2525
})
26+
27+
test_that("doubles_matrix<> can return a matrix with colnames and rownames", {
28+
x <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)
29+
colnames(x) <- letters[1:2]
30+
rownames(x) <- letters[3:4]
31+
32+
y <- mat_mat_copy_dimnames(x)
33+
z <- mat_sexp_copy_dimnames(x)
34+
35+
expect_equal(x, y)
36+
expect_equal(x, z)
37+
38+
r <- mat_mat_create_dimnames()
39+
expect_equal(rownames(r), c("a", "b"))
40+
expect_equal(colnames(r), c("c", "d"))
41+
})

inst/include/cpp11/matrix.hpp

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#pragma once
22

3+
#include <initializer_list> // for initializer_list
34
#include <iterator>
45
#include <string> // for string
56

6-
#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
7-
#include "cpp11/r_bool.hpp" // for r_bool
8-
#include "cpp11/r_string.hpp" // for r_string
9-
#include "cpp11/r_vector.hpp" // for r_vector
10-
#include "cpp11/sexp.hpp" // for sexp
7+
#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
8+
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
9+
#include "cpp11/r_bool.hpp" // for r_bool
10+
#include "cpp11/r_string.hpp" // for r_string
11+
#include "cpp11/r_vector.hpp" // for r_vector
12+
#include "cpp11/sexp.hpp" // for sexp
1113

1214
namespace cpp11 {
1315

@@ -188,13 +190,49 @@ class matrix : public matrix_slices<S> {
188190

189191
operator SEXP() const { return SEXP(vector_); }
190192

191-
// operator sexp() { return sexp(vector_); }
193+
attribute_proxy<V> attr(const char* name) { return attribute_proxy<V>(vector_, name); }
192194

193-
sexp attr(const char* name) const { return SEXP(vector_.attr(name)); }
195+
attribute_proxy<V> attr(const std::string& name) {
196+
return attribute_proxy<V>(vector_, name.c_str());
197+
}
198+
199+
attribute_proxy<V> attr(SEXP name) { return attribute_proxy<V>(vector_, name); }
200+
201+
void attr(const char* name, SEXP value) { vector_.attr(name) = value; }
202+
203+
void attr(const std::string& name, SEXP value) { vector_.attr(name) = value; }
204+
205+
void attr(SEXP name, SEXP value) { vector_.attr(name) = value; }
206+
207+
void attr(const char* name, std::initializer_list<SEXP> value) {
208+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
209+
int i = 0;
210+
for (SEXP v : value) {
211+
SET_VECTOR_ELT(attr, i++, v);
212+
}
213+
vector_.attr(name) = attr;
214+
UNPROTECT(1);
215+
}
194216

195-
sexp attr(const std::string& name) const { return SEXP(vector_.attr(name)); }
217+
void attr(const std::string& name, std::initializer_list<SEXP> value) {
218+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
219+
int i = 0;
220+
for (SEXP v : value) {
221+
SET_VECTOR_ELT(attr, i++, v);
222+
}
223+
vector_.attr(name) = attr;
224+
UNPROTECT(1);
225+
}
196226

197-
sexp attr(SEXP name) const { return SEXP(vector_.attr(name)); }
227+
void attr(SEXP name, std::initializer_list<SEXP> value) {
228+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
229+
int i = 0;
230+
for (SEXP v : value) {
231+
SET_VECTOR_ELT(attr, i++, v);
232+
}
233+
vector_.attr(name) = attr;
234+
UNPROTECT(1);
235+
}
198236

199237
r_vector<r_string> names() const { return r_vector<r_string>(vector_.names()); }
200238

0 commit comments

Comments
 (0)