Skip to content

Commit 01c8f2f

Browse files
authored
Merge pull request #537 from artemklevtsov/master
Add variadic variants of the RCPP_RETURN_VECTOR/MATRIX macro
2 parents f2bcaf4 + fa1a4d6 commit 01c8f2f

File tree

5 files changed

+206
-19
lines changed

5 files changed

+206
-19
lines changed

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2016-08-09 Artem Klevtsov <[email protected]>
2+
3+
* inst/include/Rcpp/macros/dispatch.h: Add variadic conditional macro
4+
when C++11 compiler used
5+
* ints/include/unitTests/cpp/dispatch.cpp: Add unit tests for
6+
RCPP_RETURN_VECTOR and RCPP_RETURN_MATRIX macro
7+
* ints/include/unitTests/runit.dispatch.R: Idem
8+
19
2016-08-05 James J Balamuta <[email protected]>
210

311
* inst/examples/FastLM/fastLMviaArmadillo.r: format fix

inst/NEWS.Rd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
\ghit{387}).
2121
\item String constructors now set default UTF-8 encoding (Qiang Kou in
2222
\ghpr{529} fixing \ghit{263}).
23+
\item Add variadic variants of the \code{RCPP_RETURN_VECTOR} and
24+
\code{RCPP_RETURN_MATRIX} macro when C++11 compiler used (Artem Klevtsov
25+
in \ghpr{537} fixing \ghit{38}).
2326
}
2427
\item Changes in Rcpp unit tests
2528
\itemize{

inst/include/Rcpp/macros/dispatch.h

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,65 @@
2222
#ifndef Rcpp__macros__dispatch_h
2323
#define Rcpp__macros__dispatch_h
2424

25-
#define ___RCPP_HANDLE_CASE___( ___RTYPE___ , ___FUN___ , ___OBJECT___ , ___RCPPTYPE___ ) \
26-
case ___RTYPE___ : \
27-
return ___FUN___( ::Rcpp::___RCPPTYPE___< ___RTYPE___ >( ___OBJECT___ ) ) ;
25+
#ifdef RCPP_USING_CXX11
26+
#define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___OBJECT___, \
27+
___RCPPTYPE___, ...) \
28+
case ___RTYPE___: \
29+
return ___FUN___(::Rcpp::___RCPPTYPE___<___RTYPE___>(___OBJECT___), \
30+
##__VA_ARGS__);
2831

29-
#define ___RCPP_RETURN___( __FUN__, __SEXP__ , __RCPPTYPE__ ) \
30-
SEXP __TMP__ = __SEXP__ ; \
31-
switch( TYPEOF( __TMP__ ) ){ \
32-
___RCPP_HANDLE_CASE___( INTSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
33-
___RCPP_HANDLE_CASE___( REALSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
34-
___RCPP_HANDLE_CASE___( RAWSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
35-
___RCPP_HANDLE_CASE___( LGLSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
36-
___RCPP_HANDLE_CASE___( CPLXSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
37-
___RCPP_HANDLE_CASE___( STRSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
38-
___RCPP_HANDLE_CASE___( VECSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
39-
___RCPP_HANDLE_CASE___( EXPRSXP , __FUN__ , __TMP__ , __RCPPTYPE__ ) \
40-
default: \
41-
throw std::range_error( "not a vector" ) ; \
42-
}
32+
#define ___RCPP_RETURN___(__FUN__, __SEXP__, __RCPPTYPE__, ...) \
33+
SEXP __TMP__ = __SEXP__; \
34+
switch (TYPEOF(__TMP__)) { \
35+
___RCPP_HANDLE_CASE___(INTSXP, __FUN__, __TMP__, __RCPPTYPE__, \
36+
##__VA_ARGS__) \
37+
___RCPP_HANDLE_CASE___(REALSXP, __FUN__, __TMP__, __RCPPTYPE__, \
38+
##__VA_ARGS__) \
39+
___RCPP_HANDLE_CASE___(RAWSXP, __FUN__, __TMP__, __RCPPTYPE__, \
40+
##__VA_ARGS__) \
41+
___RCPP_HANDLE_CASE___(LGLSXP, __FUN__, __TMP__, __RCPPTYPE__, \
42+
##__VA_ARGS__) \
43+
___RCPP_HANDLE_CASE___(CPLXSXP, __FUN__, __TMP__, __RCPPTYPE__, \
44+
##__VA_ARGS__) \
45+
___RCPP_HANDLE_CASE___(STRSXP, __FUN__, __TMP__, __RCPPTYPE__, \
46+
##__VA_ARGS__) \
47+
___RCPP_HANDLE_CASE___(VECSXP, __FUN__, __TMP__, __RCPPTYPE__, \
48+
##__VA_ARGS__) \
49+
___RCPP_HANDLE_CASE___(EXPRSXP, __FUN__, __TMP__, __RCPPTYPE__, \
50+
##__VA_ARGS__) \
51+
default: \
52+
throw std::range_error("Not a vector"); \
53+
}
4354

44-
#define RCPP_RETURN_VECTOR( _FUN_, _SEXP_ ) ___RCPP_RETURN___( _FUN_, _SEXP_ , Vector )
45-
#define RCPP_RETURN_MATRIX( _FUN_, _SEXP_ ) ___RCPP_RETURN___( _FUN_, _SEXP_ , Matrix )
55+
#define RCPP_RETURN_VECTOR(_FUN_, _SEXP_, ...) \
56+
___RCPP_RETURN___(_FUN_, _SEXP_, Vector, ##__VA_ARGS__)
57+
#define RCPP_RETURN_MATRIX(_FUN_, _SEXP_, ...) \
58+
___RCPP_RETURN___(_FUN_, _SEXP_, Matrix, ##__VA_ARGS__)
59+
#else
60+
#define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___OBJECT___, \
61+
___RCPPTYPE___) \
62+
case ___RTYPE___: \
63+
return ___FUN___(::Rcpp::___RCPPTYPE___<___RTYPE___>(___OBJECT___));
4664

65+
#define ___RCPP_RETURN___(__FUN__, __SEXP__, __RCPPTYPE__) \
66+
SEXP __TMP__ = __SEXP__; \
67+
switch (TYPEOF(__TMP__)) { \
68+
___RCPP_HANDLE_CASE___(INTSXP, __FUN__, __TMP__, __RCPPTYPE__) \
69+
___RCPP_HANDLE_CASE___(REALSXP, __FUN__, __TMP__, __RCPPTYPE__) \
70+
___RCPP_HANDLE_CASE___(RAWSXP, __FUN__, __TMP__, __RCPPTYPE__) \
71+
___RCPP_HANDLE_CASE___(LGLSXP, __FUN__, __TMP__, __RCPPTYPE__) \
72+
___RCPP_HANDLE_CASE___(CPLXSXP, __FUN__, __TMP__, __RCPPTYPE__) \
73+
___RCPP_HANDLE_CASE___(STRSXP, __FUN__, __TMP__, __RCPPTYPE__) \
74+
___RCPP_HANDLE_CASE___(VECSXP, __FUN__, __TMP__, __RCPPTYPE__) \
75+
___RCPP_HANDLE_CASE___(EXPRSXP, __FUN__, __TMP__, __RCPPTYPE__) \
76+
default: \
77+
throw std::range_error("Not a vector"); \
78+
}
79+
80+
#define RCPP_RETURN_VECTOR(_FUN_, _SEXP_) \
81+
___RCPP_RETURN___(_FUN_, _SEXP_, Vector)
82+
#define RCPP_RETURN_MATRIX(_FUN_, _SEXP_) \
83+
___RCPP_RETURN___(_FUN_, _SEXP_, Matrix)
84+
#endif
4785

4886
#endif

inst/unitTests/cpp/dispatch.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2+
//
3+
// dispatch.cpp: Rcpp R/C++ interface class library -- dispatch macro unit tests
4+
//
5+
// Copyright (C) 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+
#include <Rcpp.h>
23+
using namespace Rcpp ;
24+
25+
template <typename T>
26+
T first_el_impl(const T& x) {
27+
T res(1);
28+
res[0] = x[0];
29+
return res;
30+
}
31+
32+
// [[Rcpp::export]]
33+
SEXP first_el(SEXP x) {
34+
RCPP_RETURN_VECTOR(first_el_impl, x);
35+
}
36+
37+
template <typename T>
38+
T first_cell_impl(const T& x) {
39+
T res(1, 1);
40+
res(0, 0) = x(0, 0);
41+
return res;
42+
}
43+
44+
// [[Rcpp::export]]
45+
SEXP first_cell(SEXP x) {
46+
RCPP_RETURN_MATRIX(first_cell_impl, x)
47+
}

inst/unitTests/runit.dispatch.R

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env r
2+
# -*- mode: R; tab-width: 4; -*-
3+
#
4+
# Copyright (C) 2009 - 2014 Dirk Eddelbuettel and Romain Francois
5+
#
6+
# This file is part of Rcpp.
7+
#
8+
# Rcpp is free software: you can redistribute it and/or modify it
9+
# under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 2 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# Rcpp is distributed in the hope that it will be useful, but
14+
# WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
20+
21+
.runThisTest <- Sys.getenv("RunAllRcppTests") == "yes"
22+
23+
if (.runThisTest) {
24+
.setUp <- Rcpp:::unitTestSetup("dispatch.cpp")
25+
26+
test.RawVector <- function() {
27+
x <- as.raw(0:9)
28+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (raw)")
29+
}
30+
31+
test.ComplexVector <- function() {
32+
x <- as.complex(0:9)
33+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (complex)")
34+
}
35+
36+
test.IntegerVector <- function() {
37+
x <- as.integer(0:9)
38+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (integer)")
39+
}
40+
41+
test.NumericVector <- function() {
42+
x <- as.numeric(0:9)
43+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (numeric)")
44+
}
45+
46+
test.ExpressionVector <- function() {
47+
x <- parse(text = "rnrom; rnrom(10); mean(1:10)")
48+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (numeric)")
49+
}
50+
51+
test.GenericVector <- function() {
52+
x <- list("foo", 10L, 10.2, FALSE)
53+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (list)")
54+
}
55+
56+
test.CharacterVector <- function() {
57+
x <- as.character(0:9)
58+
checkEquals(first_el(x), x[1], msg = "RCPP_RETURN_VECTOR (character)")
59+
}
60+
61+
test.RawMatrix <- function() {
62+
x <- matrix(as.raw(0:9), ncol = 2L)
63+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (raw)")
64+
}
65+
66+
test.ComplexMatrix <- function() {
67+
x <- matrix(as.complex(0:9), ncol = 2L)
68+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (complex)")
69+
}
70+
71+
test.IntegerMatrix <- function() {
72+
x <- matrix(as.integer(0:9), ncol = 2L)
73+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (integer)")
74+
}
75+
76+
test.NumericMatrix <- function() {
77+
x <- matrix(as.numeric(0:9), ncol = 2L)
78+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (numeric)")
79+
}
80+
81+
test.GenericMatrix <- function() {
82+
x <- matrix(lapply(0:9, function(.) 0:9), ncol = 2L)
83+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (list)")
84+
}
85+
86+
test.CharacterMatrix <- function() {
87+
x <- matrix(as.character(0:9), ncol = 2L)
88+
checkEquals(first_cell(x), x[1, 1, drop = FALSE], msg = "RCPP_RETURN_MATRIX (character)")
89+
}
90+
91+
}

0 commit comments

Comments
 (0)