Skip to content

Commit 295bd26

Browse files
committed
add allow_overwrite incl test case
1 parent 46b669d commit 295bd26

5 files changed

Lines changed: 31 additions & 15 deletions

File tree

R/RcppExports.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
22
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
33

4-
cpp_stack <- function(array_list, along, fill) {
5-
.Call('_narray_cpp_stack', PACKAGE = 'narray', array_list, along, fill)
4+
cpp_stack <- function(array_list, along, fill, ovr) {
5+
.Call('_narray_cpp_stack', PACKAGE = 'narray', array_list, along, fill, ovr)
66
}
77

R/stack.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ stack = function(..., along=length(dim(arrayList[[1]]))+1, fill=NA, drop=FALSE,
3333
}
3434

3535
arrayList = vectors_to_row_or_col(arrayList, along=along)
36-
result = cpp_stack(arrayList, along, fill)
36+
result = cpp_stack(arrayList, along, fill, allow_overwrite)
3737
drop_if(result, drop)
3838
}

src/RcppExports.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@ Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
1111
#endif
1212

1313
// cpp_stack
14-
SEXP cpp_stack(List array_list, int along, SEXP fill);
15-
RcppExport SEXP _narray_cpp_stack(SEXP array_listSEXP, SEXP alongSEXP, SEXP fillSEXP) {
14+
SEXP cpp_stack(List array_list, int along, SEXP fill, bool ovr);
15+
RcppExport SEXP _narray_cpp_stack(SEXP array_listSEXP, SEXP alongSEXP, SEXP fillSEXP, SEXP ovrSEXP) {
1616
BEGIN_RCPP
1717
Rcpp::RObject rcpp_result_gen;
1818
Rcpp::RNGScope rcpp_rngScope_gen;
1919
Rcpp::traits::input_parameter< List >::type array_list(array_listSEXP);
2020
Rcpp::traits::input_parameter< int >::type along(alongSEXP);
2121
Rcpp::traits::input_parameter< SEXP >::type fill(fillSEXP);
22-
rcpp_result_gen = Rcpp::wrap(cpp_stack(array_list, along, fill));
22+
Rcpp::traits::input_parameter< bool >::type ovr(ovrSEXP);
23+
rcpp_result_gen = Rcpp::wrap(cpp_stack(array_list, along, fill, ovr));
2324
return rcpp_result_gen;
2425
END_RCPP
2526
}
2627

2728
static const R_CallMethodDef CallEntries[] = {
28-
{"_narray_cpp_stack", (DL_FUNC) &_narray_cpp_stack, 3},
29+
{"_narray_cpp_stack", (DL_FUNC) &_narray_cpp_stack, 4},
2930
{NULL, NULL, 0}
3031
};
3132

src/stack.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using namespace Rcpp;
55
using namespace std;
66

7-
template<int RTYPE> Vector<RTYPE> cpp_stack_impl(List array_list, int along, Vector<RTYPE> fill) {
7+
template<int RTYPE> Vector<RTYPE> cpp_stack_impl(List array_list, int along, Vector<RTYPE> fill, bool ovr) {
88
auto dimnames = vector<CharacterVector>(along); // dim: names along
99
auto axmap = vector<unordered_map<string, int>>(along); // dim: element name->index
1010
auto ax_unnamed = vector<int>(along); // counter for unnamed dimension elements
@@ -105,7 +105,13 @@ template<int RTYPE> Vector<RTYPE> cpp_stack_impl(List array_list, int along, Vec
105105
}
106106

107107
// Rprintf("result[%i] = a[%i][%i]\n", *it[0] + dim_offset, ai, aidx);
108-
result[*it[0] + dim_offset] = a[aidx];
108+
int ri = *it[0] + dim_offset;
109+
auto newval = a[aidx];
110+
if (!ovr) {
111+
if (! (result[ri] == fill[0] || result[ri] == newval))
112+
stop("Different values on same position and allow_overwrite=FALSE");
113+
}
114+
result[ri] = newval;
109115

110116
it[0]++;
111117
for (int d=0; d<maxdim; d++) { // check if we're jumping dimensions
@@ -123,7 +129,7 @@ template<int RTYPE> Vector<RTYPE> cpp_stack_impl(List array_list, int along, Vec
123129
}
124130

125131
// [[Rcpp::export]]
126-
SEXP cpp_stack(List array_list, int along, SEXP fill) {
132+
SEXP cpp_stack(List array_list, int along, SEXP fill, bool ovr) {
127133
auto max_type = NILSXP;
128134
for (int ai=0; ai<array_list.size(); ai++) {
129135
int cur_type = TYPEOF(array_list[ai]);
@@ -134,11 +140,11 @@ SEXP cpp_stack(List array_list, int along, SEXP fill) {
134140
}
135141

136142
switch(max_type) {
137-
case LGLSXP: return cpp_stack_impl<LGLSXP>(array_list, along, as<LogicalVector>(fill));
138-
case INTSXP: return cpp_stack_impl<INTSXP>(array_list, along, as<IntegerVector>(fill));
139-
case REALSXP: return cpp_stack_impl<REALSXP>(array_list, along, as<NumericVector>(fill));
140-
case CPLXSXP: return cpp_stack_impl<CPLXSXP>(array_list, along, as<ComplexVector>(fill));
141-
case STRSXP: return cpp_stack_impl<STRSXP>(array_list, along, as<CharacterVector>(fill));
143+
case LGLSXP: return cpp_stack_impl<LGLSXP>(array_list, along, as<LogicalVector>(fill), ovr);
144+
case INTSXP: return cpp_stack_impl<INTSXP>(array_list, along, as<IntegerVector>(fill), ovr);
145+
case REALSXP: return cpp_stack_impl<REALSXP>(array_list, along, as<NumericVector>(fill), ovr);
146+
case CPLXSXP: return cpp_stack_impl<CPLXSXP>(array_list, along, as<ComplexVector>(fill), ovr);
147+
case STRSXP: return cpp_stack_impl<STRSXP>(array_list, along, as<CharacterVector>(fill), ovr);
142148
default: return R_NilValue; // this should not happen
143149
}
144150
}

tests/testthat/test-stack.r

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ test_that("keep_empty arg when stacking zero-length vectors", {
9191
expect_equal(re2, t(re3))
9292
})
9393

94+
test_that("allow overwrite", {
95+
ov = A
96+
ov[1,1] = 10
97+
expect_error(stack(ov, A, along=2))
98+
expect_error(stack(A, ov, along=2))
99+
expect_equal(stack(ov, A, along=2, allow_overwrite=TRUE), A)
100+
expect_equal(stack(A, ov, along=2, allow_overwrite=TRUE), ov)
101+
})
102+
94103
test_that("performance", {
95104
skip_on_cran()
96105

0 commit comments

Comments
 (0)