Rcpp Version 1.0.14
Loading...
Searching...
No Matches
dispatch.h
Go to the documentation of this file.
1// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2//
3// dispatch.h: Rcpp R/C++ interface class library -- macros for dispatch
4//
5// Copyright (C) 2012 - 2016 Dirk Eddelbuettel and Romain Francois
6// Copyright (C) 2016 Dirk Eddelbuettel, Romain Francois, Artem Klevtsov and Nathan Russell
7//
8// This file is part of Rcpp.
9//
10// Rcpp is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 2 of the License, or
13// (at your option) any later version.
14//
15// Rcpp is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
22
23#ifndef Rcpp__macros__dispatch_h
24#define Rcpp__macros__dispatch_h
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
33#ifdef RCPP_USING_CXX11
34
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 }
55
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
80#else
81
82#define ___RCPP_HANDLE_CASE___(___RTYPE___, ___FUN___, ___OBJECT___, \
83 ___RCPPTYPE___) \
84 case ___RTYPE___: \
85 return ___FUN___(::Rcpp::___RCPPTYPE___<___RTYPE___>(___OBJECT___));
86
87#define ___RCPP_RETURN___(__FUN__, __SEXP__, __RCPPTYPE__) \
88 SEXP __TMP__ = __SEXP__; \
89 switch (TYPEOF(__TMP__)) { \
90 ___RCPP_HANDLE_CASE___(INTSXP, __FUN__, __TMP__, __RCPPTYPE__) \
91 ___RCPP_HANDLE_CASE___(REALSXP, __FUN__, __TMP__, __RCPPTYPE__) \
92 ___RCPP_HANDLE_CASE___(RAWSXP, __FUN__, __TMP__, __RCPPTYPE__) \
93 ___RCPP_HANDLE_CASE___(LGLSXP, __FUN__, __TMP__, __RCPPTYPE__) \
94 ___RCPP_HANDLE_CASE___(CPLXSXP, __FUN__, __TMP__, __RCPPTYPE__) \
95 ___RCPP_HANDLE_CASE___(STRSXP, __FUN__, __TMP__, __RCPPTYPE__) \
96 ___RCPP_HANDLE_CASE___(VECSXP, __FUN__, __TMP__, __RCPPTYPE__) \
97 ___RCPP_HANDLE_CASE___(EXPRSXP, __FUN__, __TMP__, __RCPPTYPE__) \
98 default: \
99 throw std::range_error("Not a vector"); \
100 }
101
102#define RCPP_RETURN_VECTOR(_FUN_, _SEXP_) \
103 ___RCPP_RETURN___(_FUN_, _SEXP_, Vector)
104#define RCPP_RETURN_MATRIX(_FUN_, _SEXP_) \
105 ___RCPP_RETURN___(_FUN_, _SEXP_, Matrix)
106#endif
107
108#endif