1
1
---
2
- title : |
3
- | Exposing \proglang{C++} functions and classes
2
+ title : |
3
+ | Exposing \proglang{C++} functions and classes
4
4
| with \pkg{Rcpp} modules
5
5
6
6
# Use letters for affiliations
@@ -180,7 +180,7 @@ Consider the simple `Uniform` class below:
180
180
```cpp
181
181
class Uniform {
182
182
public:
183
- Uniform(double min_, double max_) :
183
+ Uniform(double min_, double max_) :
184
184
min(min_), max(max_) {}
185
185
186
186
NumericVector draw(int n) {
@@ -203,15 +203,15 @@ with these two functions:
203
203
using namespace Rcpp ;
204
204
205
205
// / create external pointer to a Uniform object
206
- RcppExport SEXP Uniform__new (SEXP min_ ,
206
+ RcppExport SEXP Uniform__new (SEXP min_ ,
207
207
SEXP max_ ) {
208
208
// convert inputs to appropriate C++ types
209
- double min = as<double >(min_ ),
209
+ double min = as<double >(min_ ),
210
210
max = as<double >(max_ );
211
211
212
- // create pointer to an Uniform object and
212
+ // create pointer to an Uniform object and
213
213
// wrap it as an external pointer
214
- Rcpp::XPtr<Uniform>
214
+ Rcpp::XPtr<Uniform>
215
215
ptr( new Uniform( min, max ), true );
216
216
217
217
// return the external pointer to the R side
@@ -220,7 +220,7 @@ RcppExport SEXP Uniform__new(SEXP min_,
220
220
221
221
/// invoke the draw method
222
222
RcppExport SEXP Uniform__ draw(SEXP xp, SEXP n_ ) {
223
- // grab the object as a XPtr (smart pointer)
223
+ // grab the object as a XPtr (smart pointer)
224
224
// to Uniform
225
225
Rcpp::XPtr<Uniform > ptr(xp);
226
226
@@ -252,7 +252,7 @@ DE 21 Sep 2013: there must a bug somewhere in the vignette processing
252
252
```{r, eval=FALSE}
253
253
f1 <- cxxfunction( , "", includes = unifModCode,
254
254
plugin = "Rcpp" )
255
- getDynLib(f1) ## will display info about 'f1'
255
+ getDynLib(f1) ## will display info about 'f1'
256
256
```
257
257
258
258
The following listing shows some \textsl{manual} wrapping to access the code,
@@ -276,7 +276,7 @@ setMethod("$", "Uniform", function(x, name) {
276
276
# syntactic sugar to allow new( "Uniform", ... )
277
277
setMethod("initialize", "Uniform",
278
278
function(.Object, ...) {
279
- .Object@pointer <-
279
+ .Object@pointer <-
280
280
.Call(Uniform_method("new"), ...)
281
281
.Object
282
282
} )
@@ -295,7 +295,7 @@ class in a way that makes both the internal
295
295
296
296
297
297
298
- # Rcpp modules
298
+ # Rcpp modules
299
299
300
300
The design of Rcpp modules has been influenced by \proglang{Python} modules which are generated by the
301
301
` Boost.Python ` library \citep{Abrahams+Grosse-Kunstleve:2003: Boost .Python}.
@@ -447,7 +447,7 @@ double norm(double x, double y) {
447
447
}
448
448
449
449
RCPP_MODULE(mod) {
450
- function("norm", &norm,
450
+ function("norm", &norm,
451
451
"Provides a simple vector norm");
452
452
}
453
453
```
@@ -475,7 +475,7 @@ double norm(double x, double y) {
475
475
RCPP_MODULE(mod_formals) {
476
476
function("norm",
477
477
&norm,
478
- List::create(_["x"] = 0.0,
478
+ List::create(_["x"] = 0.0,
479
479
_["y"] = 0.0),
480
480
"Provides a simple vector norm");
481
481
}
@@ -515,7 +515,7 @@ args(norm)
515
515
```
516
516
517
517
The ellipsis (` ... ` ) can be used to denote that additional arguments
518
- are optional; it does not take a default value.
518
+ are optional; it does not take a default value.
519
519
520
520
``` {Rcpp mod_formals3, eval=FALSE}
521
521
using namespace Rcpp;
@@ -539,6 +539,11 @@ norm <- mod$norm
539
539
args(norm)
540
540
```
541
541
542
+ As of mid-2024, more recent versions of R no longer tolerate 'empty' strings
543
+ as placeholders for missing arguments. It is preferable to simply not list
544
+ any arguments for functions that take no arguments. Issue #1322 has an example.
545
+
546
+
542
547
## Exposing \proglang{C++} classes using Rcpp modules
543
548
544
549
Rcpp modules also provide a mechanism for exposing \proglang{C++} classes, based
@@ -553,7 +558,7 @@ class may be exposed to \proglang{R} as follows:
553
558
using namespace Rcpp;
554
559
class Uniform {
555
560
public:
556
- Uniform(double min_, double max_) :
561
+ Uniform(double min_, double max_) :
557
562
min(min_), max(max_) {}
558
563
559
564
NumericVector draw(int n) const {
@@ -680,7 +685,7 @@ The `.field_readonly` exposes a public field with read-only access from \proglan
680
685
It also accepts the description of the field.
681
686
682
687
``` cpp
683
- .field_readonly(" y" , &Foo::y,
688
+ .field_readonly(" y" , &Foo::y,
684
689
" documentation for y" )
685
690
```
686
691
@@ -691,11 +696,11 @@ allowed:
691
696
692
697
``` cpp
693
698
// with getter and setter
694
- .property(" z" , &Foo::get_z,
699
+ .property(" z" , &Foo::get_z,
695
700
&Foo::set_z, " Documentation for z" )
696
701
697
702
// with only getter
698
- .property(" z" ,
703
+ .property(" z" ,
699
704
&Foo::get_z, " Documentation for z" )
700
705
```
701
706
@@ -740,7 +745,7 @@ public:
740
745
}
741
746
742
747
IntegerVector stats() const {
743
- return
748
+ return
744
749
IntegerVector::create(_["read"] = nread,
745
750
_["write"] = nwrite);
746
751
}
@@ -822,7 +827,7 @@ to restrict the candidate methods.
822
827
823
828
### Special methods
824
829
825
- \pkg{Rcpp} considers the methods `[[` and `[[<-` special,
830
+ \pkg{Rcpp} considers the methods `[[` and `[[<-` special,
826
831
and promotes them to indexing methods on the \proglang{R} side.
827
832
828
833
### Object finalizers
@@ -930,14 +935,14 @@ RCPP_MODULE(yada){
930
935
using namespace Rcpp;
931
936
932
937
class_<World>("World")
933
-
938
+
934
939
// expose the default constructor
935
940
.constructor()
936
941
937
942
.method("greet", &World::greet)
938
943
.method("set", &World::set)
939
944
;
940
-
945
+
941
946
}
942
947
```
943
948
@@ -1015,24 +1020,24 @@ bar$handleFoo(foo)
1015
1020
The following example illustrates how to use Rcpp modules to expose
1016
1021
the class ` std::vector<double> ` from the STL.
1017
1022
1018
- ``` {Rcpp mod_vec, eval=FALSE}
1019
- typedef std::vector<double> vec;
1020
- void vec_assign(vec* obj,
1023
+ ``` {Rcpp mod_vec, eval=FALSE}
1024
+ typedef std::vector<double> vec;
1025
+ void vec_assign(vec* obj,
1021
1026
Rcpp::NumericVector data) {
1022
1027
obj->assign(data.begin(), data.end());
1023
1028
}
1024
- void vec_insert(vec* obj, int position,
1029
+ void vec_insert(vec* obj, int position,
1025
1030
Rcpp::NumericVector data) {
1026
1031
vec::iterator it = obj->begin() + position;
1027
1032
obj->insert(it, data.begin(), data.end());
1028
1033
}
1029
- Rcpp::NumericVector vec_asR( vec* obj ) {
1030
- return Rcpp::wrap( *obj );
1034
+ Rcpp::NumericVector vec_asR( vec* obj ) {
1035
+ return Rcpp::wrap( *obj );
1031
1036
}
1032
- void vec_set(vec* obj, int i, double value) {
1033
- obj->at( i ) = value;
1037
+ void vec_set(vec* obj, int i, double value) {
1038
+ obj->at( i ) = value;
1034
1039
}
1035
- // Fix for C++11, where we cannot directly expose
1040
+ // Fix for C++11, where we cannot directly expose
1036
1041
// member functions vec::resize and vec::push_back
1037
1042
void vec_resize (vec* obj, int n) {
1038
1043
obj->resize(n);
@@ -1044,7 +1049,7 @@ void vec_push_back (vec* obj, double value) {
1044
1049
RCPP_MODULE(mod_vec) {
1045
1050
using namespace Rcpp;
1046
1051
1047
- // we expose class std::vector<double>
1052
+ // we expose class std::vector<double>
1048
1053
// as "vec" on the R side
1049
1054
class_<vec>("vec")
1050
1055
@@ -1066,8 +1071,8 @@ RCPP_MODULE(mod_vec) {
1066
1071
.const_method("front", &vec::front)
1067
1072
.const_method("at", &vec::at )
1068
1073
1069
- // exposing free functions taking a
1070
- // std::vector<double>* as their first
1074
+ // exposing free functions taking a
1075
+ // std::vector<double>* as their first
1071
1076
// argument
1072
1077
.method("assign", &vec_assign)
1073
1078
.method("insert", &vec_insert)
@@ -1233,7 +1238,7 @@ objects are exposed.
1233
1238
1234
1239
### Deprecated legacy method using loadRcppModules
1235
1240
1236
- Prior to release 0.9.11, where ` loadModule ` was introduced,
1241
+ Prior to release 0.9.11, where ` loadModule ` was introduced,
1237
1242
loading all functions and classes from a module
1238
1243
into a package namespace was achieved using the ` loadRcppModules ` function
1239
1244
within the ` .onLoad ` body.
@@ -1246,7 +1251,7 @@ within the `.onLoad` body.
1246
1251
1247
1252
This will look in the package's ` DESCRIPTION ` file for the ` RcppModules `
1248
1253
field, load each declared module and populate their contents into the
1249
- package's namespace. For example, a package defining modules
1254
+ package's namespace. For example, a package defining modules
1250
1255
` yada ` , ` stdVector ` , ` NumEx ` would have this declaration:
1251
1256
1252
1257
```
@@ -1346,5 +1351,3 @@ This note introduced \textsl{Rcpp modules} and illustrated how to expose
1346
1351
\proglang{C++} function and classes more easily to \proglang{R}.
1347
1352
We hope that \proglang{R} and \proglang{C++} programmers
1348
1353
find \textsl{Rcpp modules} useful.
1349
-
1350
-
0 commit comments