|
3 | 3 | // dispatch.h: Rcpp R/C++ interface class library -- macros for dispatch
|
4 | 4 | //
|
5 | 5 | // Copyright (C) 2012 - 2016 Dirk Eddelbuettel and Romain Francois
|
6 |
| -// Copyright (C) 2016 Dirk Eddelbuettel, Romain Francois and Artem Klevtsov |
| 6 | +// Copyright (C) 2016 Dirk Eddelbuettel, Romain Francois, Artem Klevtsov and Nathan Russell |
7 | 7 | //
|
8 | 8 | // This file is part of Rcpp.
|
9 | 9 | //
|
|
23 | 23 | #ifndef Rcpp__macros__dispatch_h
|
24 | 24 | #define Rcpp__macros__dispatch_h
|
25 | 25 |
|
| 26 | +// The variadic macros below incorporate techniques presented by |
| 27 | +// Stack Overflow user Richard Hansen in this answer |
| 28 | +// |
| 29 | +// http://stackoverflow.com/a/11172679/1869097 |
| 30 | +// |
| 31 | +// and are necessary to avoid the use of GNU compiler extensions. |
| 32 | + |
26 | 33 | #ifdef RCPP_USING_CXX11
|
27 |
| -#define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___OBJECT___, \ |
28 |
| - ___RCPPTYPE___, ...) \ |
29 |
| - case ___RTYPE___: \ |
30 |
| - return ___FUN___(::Rcpp::___RCPPTYPE___<___RTYPE___>(___OBJECT___), \ |
31 |
| - ##__VA_ARGS__); |
32 | 34 |
|
33 |
| -#define ___RCPP_RETURN___(__FUN__, __SEXP__, __RCPPTYPE__, ...) \ |
34 |
| - SEXP __TMP__ = __SEXP__; \ |
35 |
| - switch (TYPEOF(__TMP__)) { \ |
36 |
| - ___RCPP_HANDLE_CASE___(INTSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
37 |
| - ##__VA_ARGS__) \ |
38 |
| - ___RCPP_HANDLE_CASE___(REALSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
39 |
| - ##__VA_ARGS__) \ |
40 |
| - ___RCPP_HANDLE_CASE___(RAWSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
41 |
| - ##__VA_ARGS__) \ |
42 |
| - ___RCPP_HANDLE_CASE___(LGLSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
43 |
| - ##__VA_ARGS__) \ |
44 |
| - ___RCPP_HANDLE_CASE___(CPLXSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
45 |
| - ##__VA_ARGS__) \ |
46 |
| - ___RCPP_HANDLE_CASE___(STRSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
47 |
| - ##__VA_ARGS__) \ |
48 |
| - ___RCPP_HANDLE_CASE___(VECSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
49 |
| - ##__VA_ARGS__) \ |
50 |
| - ___RCPP_HANDLE_CASE___(EXPRSXP, __FUN__, __TMP__, __RCPPTYPE__, \ |
51 |
| - ##__VA_ARGS__) \ |
52 |
| - default: \ |
53 |
| - throw std::range_error("Not a vector"); \ |
| 35 | +#define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___RCPPTYPE___, ...) \ |
| 36 | + case ___RTYPE___: \ |
| 37 | + return ___FUN___(::Rcpp::___RCPPTYPE___<___RTYPE___>(RCPP_MACRO_FIRST(__VA_ARGS__)) \ |
| 38 | + RCPP_MACRO_REST(__VA_ARGS__)); |
| 39 | + |
| 40 | + |
| 41 | +#define ___RCPP_RETURN___(__FUN__, __RCPPTYPE__, ...) \ |
| 42 | + SEXP __TMP__ = RCPP_MACRO_FIRST(__VA_ARGS__); \ |
| 43 | + switch (TYPEOF(__TMP__)) { \ |
| 44 | + ___RCPP_HANDLE_CASE___(INTSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 45 | + ___RCPP_HANDLE_CASE___(REALSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 46 | + ___RCPP_HANDLE_CASE___(RAWSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 47 | + ___RCPP_HANDLE_CASE___(LGLSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 48 | + ___RCPP_HANDLE_CASE___(CPLXSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 49 | + ___RCPP_HANDLE_CASE___(STRSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 50 | + ___RCPP_HANDLE_CASE___(VECSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 51 | + ___RCPP_HANDLE_CASE___(EXPRSXP, __FUN__, __RCPPTYPE__, __VA_ARGS__) \ |
| 52 | + default: \ |
| 53 | + throw std::range_error("Not a vector"); \ |
54 | 54 | }
|
55 | 55 |
|
56 |
| -#define RCPP_RETURN_VECTOR(_FUN_, _SEXP_, ...) \ |
57 |
| - ___RCPP_RETURN___(_FUN_, _SEXP_, Vector, ##__VA_ARGS__) |
58 |
| -#define RCPP_RETURN_MATRIX(_FUN_, _SEXP_, ...) \ |
59 |
| - ___RCPP_RETURN___(_FUN_, _SEXP_, Matrix, ##__VA_ARGS__) |
| 56 | + |
| 57 | +#define RCPP_RETURN_VECTOR(_FUN_, ...) \ |
| 58 | + ___RCPP_RETURN___(_FUN_, Vector, __VA_ARGS__) |
| 59 | +#define RCPP_RETURN_MATRIX(_FUN_, ...) \ |
| 60 | + ___RCPP_RETURN___(_FUN_, Matrix, __VA_ARGS__) |
| 61 | + |
| 62 | + |
| 63 | +#define RCPP_MACRO_FIRST(...) RCPP_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway) |
| 64 | +#define RCPP_MACRO_FIRST_HELPER(first, ...) first |
| 65 | + |
| 66 | +#define RCPP_MACRO_REST(...) RCPP_MACRO_REST_HELPER(RCPP_MACRO_NUM(__VA_ARGS__), __VA_ARGS__) |
| 67 | +#define RCPP_MACRO_REST_HELPER(qty, ...) RCPP_MACRO_REST_HELPER2(qty, __VA_ARGS__) |
| 68 | +#define RCPP_MACRO_REST_HELPER2(qty, ...) RCPP_MACRO_REST_HELPER_##qty(__VA_ARGS__) |
| 69 | +#define RCPP_MACRO_REST_HELPER_ONE(first) |
| 70 | +#define RCPP_MACRO_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ |
| 71 | +#define RCPP_MACRO_NUM(...) \ |
| 72 | + RCPP_MACRO_SELECT_25TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, \ |
| 73 | + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, \ |
| 74 | + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, \ |
| 75 | + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, \ |
| 76 | + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) |
| 77 | +#define RCPP_MACRO_SELECT_25TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, \ |
| 78 | + a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, ...) a25 |
| 79 | + |
60 | 80 | #else
|
| 81 | + |
61 | 82 | #define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___OBJECT___, \
|
62 | 83 | ___RCPPTYPE___) \
|
63 | 84 | case ___RTYPE___: \
|
|
0 commit comments