Skip to content

Commit

Permalink
Minor code consistency improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
NicChr committed May 10, 2024
1 parent 5237e4b commit c8c7d2e
Showing 1 changed file with 43 additions and 23 deletions.
66 changes: 43 additions & 23 deletions src/lag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,19 +449,33 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
if (lag_size < 1){
Rf_error("lag must be a non-zero length integer vector");
}
bool has_order = o_size > 0;
bool has_rl = rl_size > 0;
bool has_order = !Rf_isNull(order);
bool has_rl = !Rf_isNull(run_lengths);
bool recycle_lag = lag_size != 1;

// When order is NULL we run through x from left to right (as usual)
// When run_lengths is NULL we run through x without resetting
// To do this properly we use dummy vectors so that
// we can statically assign int pointers
// While keeping order and run_lengths as NULL (if they are NULL)
// This is mainly done this way because lag2_ is recursive and
// hence order/run_lengths should remain NULL throughout each recursion
// if they are NULL

SEXP dummy_vec1 = Rf_protect(Rf_allocVector(INTSXP, 0));
++n_protections;
SEXP dummy_vec2 = Rf_protect(Rf_allocVector(INTSXP, 0));
++n_protections;
Rf_protect(lag = Rf_coerceVector(lag, INTSXP));
++n_protections;
Rf_protect(order = Rf_coerceVector(order, INTSXP));
Rf_protect(order = has_order ? Rf_coerceVector(order, INTSXP) : R_NilValue);
++n_protections;
Rf_protect(run_lengths = Rf_coerceVector(run_lengths, INTSXP));
Rf_protect(run_lengths = has_rl ? Rf_coerceVector(run_lengths, INTSXP) : R_NilValue);
++n_protections;
// std::variant<int*, double*> p_o;
// typedef std::conditional<true, int*, double*>::type p_o;
int *p_o = INTEGER(order);
int *p_rl = INTEGER(run_lengths);
int *p_o = INTEGER(has_order ? order : dummy_vec1);
int *p_rl = INTEGER(has_rl ? run_lengths : dummy_vec2);
int *p_lag = INTEGER(lag);
int rl; // Run-length
int run_start = 0; // Start index of current run
Expand All @@ -482,6 +496,8 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
Rf_setAttrib(out, R_NamesSymbol, new_names); \
} \

// Initialise range of possible order values to fast check
// user-supplied order values
unsigned int o_rng = o_size - 1;
SEXP out;
switch(TYPEOF(x)){
Expand All @@ -493,7 +509,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
case INTSXP: {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
int *p_x = INTEGER(x);
int fill_value = NA_INTEGER;
Expand All @@ -518,7 +534,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// int trick to calculate inclusive bounded between(x, lo, hi)
// unsigned int rng = (run_end - 1) - run_start;
Expand All @@ -544,15 +560,15 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
break;
}
case REALSXP: {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
double *p_x = REAL(x);
double fill_value = NA_REAL;
Expand All @@ -576,7 +592,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// Loop starting from the end of the previous run-length
for (int j = run_start; j != run_end; ++j){
Expand All @@ -597,15 +613,15 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
break;
}
case STRSXP: {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
SEXP *p_x = STRING_PTR(x);
SEXP fill_value = Rf_protect(fill_size >= 1 ? Rf_asChar(fill) : NA_STRING);
Expand All @@ -626,7 +642,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// Loop starting from the end of the previous run-length
for (int j = run_start; j != run_end; ++j){
Expand All @@ -647,15 +663,15 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
break;
}
case CPLXSXP: {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
Rcomplex *p_x = COMPLEX(x);
SEXP fill_sexp = Rf_protect(Rf_allocVector(CPLXSXP, 1));
Expand All @@ -680,7 +696,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// Loop starting from the end of the previous run-length
for (int j = run_start; j != run_end; ++j){
Expand All @@ -701,15 +717,15 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
break;
}
case RAWSXP: {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
Rbyte *p_x = RAW(x);
SEXP raw_sexp = Rf_protect(Rf_coerceVector(fill, RAWSXP));
Expand All @@ -731,7 +747,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// Loop starting from the end of the previous run-length
for (int j = run_start; j != run_end; ++j){
Expand All @@ -750,6 +766,10 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
}
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
break;
}
Expand All @@ -766,7 +786,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
} else {
int size = Rf_length(x);
if (has_order && (size != o_size)){
Rf_error("length(order) must equal length(x)");
Rf_error("length(order) must equal length(x) (%d)", size);
}
const SEXP *p_x = VECTOR_PTR_RO(x);
SEXP fill_value = Rf_protect(VECTOR_ELT(Rf_coerceVector(fill_size >= 1 ? fill : R_NilValue, VECSXP), 0));
Expand All @@ -787,7 +807,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
// If the cumulative run-length exceeds length(x) we stop
if (run_end > size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
// Loop starting from the end of the previous run-length
for (int j = run_start; j != run_end; ++j){
Expand All @@ -808,7 +828,7 @@ SEXP cpp_lag2(SEXP x, SEXP lag, SEXP order, SEXP run_lengths, SEXP fill, bool re
}
if (run_end != size){
Rf_unprotect(n_protections);
Rf_error("sum(run_lengths) must be equal to length(x)");
Rf_error("sum(run_lengths) must be equal to length(x) (%d)", size);
}
LAG_R_NAMES;
}
Expand Down

0 comments on commit c8c7d2e

Please sign in to comment.