Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/build/vignette.rds and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/build/vignette.rds differ diff -Nru rcpp-1.0.2/ChangeLog rcpp-1.0.3/ChangeLog --- rcpp-1.0.2/ChangeLog 2019-07-20 13:49:35.000000000 +0000 +++ rcpp-1.0.3/ChangeLog 2019-11-08 12:26:34.000000000 +0000 @@ -1,3 +1,140 @@ +2019-11-08 Dirk Eddelbuettel + + * DESCRIPTION (Date, Version): Release 1.0.3 + + * inst/include/Rcpp/config.h: Idem + * inst/NEWS.Rd: Idem + * inst/bib/Rcpp.bib: Idem + * vignettes/Rcpp.bib: Idem + +2019-11-06 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + + * inst/include/Rcpp/XPtr.h: Provided fallback for old constructor + when C++11 is not available (follow-up to #1003) + * inst/unitTests/runit.XPTr.R (test.XPtr): On Windows (as a proxy for + old compilers) do not test new feature + + * tests/doRUnit.R: Protect printing to /tmp from Windows use + + * vignettes/rmd/Rcpp.bib: Updated + * inst/bib/Rcpp.bib: Idem + +2019-11-02 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + + * inst/include/Rcpp/Reference.h: Shield Rf_mkstring inside Rf_lang2 + * inst/include/Rcpp/Environment.h: Idem (inside Rf_lang4) + * inst/include/Rcpp/proxy/FieldProxy.h: Idem (inside Rf_lang3 and 4) + +2019-10-31 Romain Francois + + * inst/include/Rcpp/DataFrame.h: Protect temporaries from gc + * inst/include/Rcpp/Environment.h: Idem + * inst/include/Rcpp/r_cast.h: Idem + +2019-10-27 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + + * inst/unitTests/runit.exposeClass.R: Updated to pass with r-devel + + * vignettes/rmd/Rcpp-FAQ.Rmd: Two new short section on speedier + compilation and lack of exceptions / stop() across shared libraries + +2019-10-26 Dirk Eddelbuettel + + * vignettes/Rcpp-package.Rnw: Another wrapper + * vignettes/Rcpp-jss-2011.Rnw: Idem + + * vignettes/Makefile: Refinements + * vignettes/rmd/Makefile: Idem + + * cleanup: Removed bashism, added invocation of make clean + +2019-10-23 Dirk Eddelbuettel + + * vignettes/Rcpp-*.Rnw: Wrappers around pdf/*pdf + * vignettes/Makefile: Added + +2019-10-21 Dirk Eddelbuettel + + * vignettes/rmd/*: Moved from parent directory + * vignettes/pdf/*: New target directory + +2019-10-20 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + + * vignettes/Rcpp-FAQ.Rmd: Turn off knitr cache + * vignettes/Rcpp-introduction.Rmd: Idem + + * vignettes/Makefile: Add simple Makefile + * .Rbuildignore: Exclude vignettes/Makefile + +2019-10-19 Stephen Wade + + * inst/include/Rcpp/XPtr.h: XPtr constructor split up, a single + argument does not modify tags and protected data of the external pointer + * inst/unitTests/cpp/Xptr.cpp: Added test + * inst/unitTests/runit.XPtr.R: Idem + +2019-10-14 Dirk Eddelbuettel + + * README.md: Added CRAN + BioConductor badges for reverse depends, + +2019-10-11 Dirk Eddelbuettel + + * inst/include/Rcpp/exceptions.h: Condition use of typeid() on + absence of RCPP_NO_RTTI in two places + * inst/include/Rcpp/r/headers.h: RCPP_NO_RTTI implies RCPP_NO_MODULES + +2019-10-04 Dirk Eddelbuettel + + * vignettes/Rcpp-attributes.Rmd: Correct two unevaluated knitr C++ + chunks to mode 'Rcpp' rather than the (unregistered) C++ mode + * vignettes/Rcpp-extending.Rmd: Minor white-space tweak to avoid + paragraph-spacing warnings from latex and its mdframed style + * vignettes/Rcpp-modules.Rmd: Idem + * vignettes/Rcpp-sugar.Rmd: Idem + +2019-10-01 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + +2019-09-30 Kevin Ushey + + * inst/include/Rcpp.h: add RCPP_NO_MODULES + * inst/include/Rcpp/api/meat/is.h: Idem + * inst/include/Rcpp/api/meat/meat.h: Idem + +2019-09-28 Dirk Eddelbuettel + + * README.md: Add a stackoverflow tag to indicate where to ask questions, + also updated package counts on CRAN and BioC for Rcpp users + +2019-08-06 Riccardo Porreca + + * vignettes/Rcpp-modules.Rmd: Extensive review and edit improving the + Modules vignette + +2019-08-04 Dirk Eddelbuettel + + * README.md: Add thre doi badges + + * inst/NEWS.Rd: Two minor edits + +2019-07-21 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + +2019-07-21 Riccardo Porreca + + * R/Module.R: Use an explicit Rcpp:: in the initalize method for C++ + classes wrapped inside modules to ensure proper initialization + 2019-07-20 Dirk Eddelbuettel * DESCRIPTION: Release 1.0.2 @@ -12,7 +149,7 @@ * src/attributes.cpp: Correct parsing of default function values * inst/unitTests/cpp/attributes.cpp: Added tests * inst/unitTests/runit.attributes.R: Idem - + 2019-07-16 Dirk Eddelbuettel * debian/: Removed, see https://salsa.debian.org/edd/r-base/ instead @@ -25,7 +162,7 @@ 2019-05-05 Dirk Eddelbuettel * .Rbuildignore: Small tweak - + 2019-04-27 Dirk Eddelbuettel * R/Rcpp.package.skeleton.R (Rcpp.package.skeleton): Use getRcppVersion() diff -Nru rcpp-1.0.2/cleanup rcpp-1.0.3/cleanup --- rcpp-1.0.2/cleanup 2019-07-20 14:40:03.000000000 +0000 +++ rcpp-1.0.3/cleanup 2019-11-08 18:25:33.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh #cd inst/doc && rm -f index.html *.tex *.bbl *.blg *.aux *.out *.log && cd - @@ -30,7 +30,10 @@ vignettes/*.toc vignettes/*.tpt vignettes/*.xwm rm -rf autom4te.cache inst/lib/ inst/doc/man/ inst/doc/html/ inst/doc/latex/ \ - inst/doc/auto inst/bib/auto inst/doc/Rcpp-*/auto/ src-* vignettes/auto + inst/doc/auto inst/bib/auto inst/doc/Rcpp-*/auto/ src-* vignettes/auto find . -name \*~ -exec rm {} \; find . -name \*.flc -exec rm {} \; + +(cd vignettes/ && make clean && cd -) >/dev/null +(cd vignettes/rmd/ && make clean && cd -) >/dev/null diff -Nru rcpp-1.0.2/debian/changelog rcpp-1.0.3/debian/changelog --- rcpp-1.0.2/debian/changelog 2019-07-25 15:36:08.000000000 +0000 +++ rcpp-1.0.3/debian/changelog 2019-11-08 23:58:09.000000000 +0000 @@ -1,3 +1,9 @@ +rcpp (1.0.3-1) unstable; urgency=medium + + * New upstream release + + -- Dirk Eddelbuettel Fri, 08 Nov 2019 17:58:09 -0600 + rcpp (1.0.2-1) unstable; urgency=medium * New upstream release diff -Nru rcpp-1.0.2/DESCRIPTION rcpp-1.0.3/DESCRIPTION --- rcpp-1.0.2/DESCRIPTION 2019-07-25 10:10:04.000000000 +0000 +++ rcpp-1.0.3/DESCRIPTION 2019-11-08 23:15:32.000000000 +0000 @@ -1,7 +1,7 @@ Package: Rcpp Title: Seamless R and C++ Integration -Version: 1.0.2 -Date: 2019-07-20 +Version: 1.0.3 +Date: 2019-11-08 Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Douglas Bates and John Chambers Maintainer: Dirk Eddelbuettel @@ -27,6 +27,6 @@ rcpp-devel@lists.r-forge.r-project.org RoxygenNote: 6.1.1 NeedsCompilation: yes -Packaged: 2019-07-20 14:40:03.829344 UTC; edd +Packaged: 2019-11-08 18:25:32.94843 UTC; edd Repository: CRAN -Date/Publication: 2019-07-25 10:10:04 UTC +Date/Publication: 2019-11-08 23:44:12 diff -Nru rcpp-1.0.2/inst/bib/Rcpp.bib rcpp-1.0.3/inst/bib/Rcpp.bib --- rcpp-1.0.2/inst/bib/Rcpp.bib 2019-07-20 13:50:10.000000000 +0000 +++ rcpp-1.0.3/inst/bib/Rcpp.bib 2019-11-08 12:27:16.000000000 +0000 @@ -100,7 +100,7 @@ title = {RQuantLib: {R} interface to the {QuantLib} library}, author = {Dirk Eddelbuettel and Khanh Nguyen and Terry Leitch}, year = 2019, - note = {R package version 0.4.9}, + note = {R package version 0.4.10}, url = CRAN # "package=RQuantLib" } @@ -119,7 +119,7 @@ Allaire and Kevin Ushey and Qiang Kou and Nathan Russel and John Chambers and Douglas Bates}, year = 2019, - note = {R package version 1.0.2}, + note = {R package version 1.0.3}, url = CRAN # "package=Rcpp" } @@ -128,7 +128,7 @@ author = {J. J. Allaire and Dirk Eddelbuettel and Romain Fran\c{c}ois}, title = {{Rcpp} Attributes}, - year = 2018, + year = 2019, note = {Vignette included in R package Rcpp}, url = CRAN # "package=Rcpp" } @@ -137,7 +137,7 @@ crossref = {CRAN:Rcpp}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, title = {Frequently Asked Questions About {Rcpp}}, - year = 2018, + year = 2019, note = {Vignette included in R package {Rcpp}}, url = CRAN # "package=Rcpp" } @@ -146,7 +146,7 @@ crossref = {CRAN:Rcpp}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, title = {Exposing {C++} functions and classes with {Rcpp} modules}, - year = 2018, + year = 2019, note = {Vignette included in R package Rcpp}, url = CRAN # "package=Rcpp" } @@ -155,7 +155,7 @@ crossref = {CRAN:Rcpp}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, title = {Writing a package that uses {Rcpp}}, - year = 2018, + year = 2019, note = {Vignette included in R package {Rcpp}}, url = CRAN # "package=Rcpp" } @@ -164,7 +164,7 @@ crossref = {CRAN:Rcpp}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, title = {Rcpp syntactic sugar}, - year = 2018, + year = 2019, note = {Vignette included in R package {Rcpp}}, url = CRAN # "package=Rcpp" } @@ -175,7 +175,7 @@ author = {Dirk Eddelbuettel and Romain Fran\c{c}ois and Douglas Bates and Binxiang Ni}, year = 2019, - note = {R package version 0.9.600.4.0}, + note = {R package version 0.9.800.1.0}, url = CRAN # "package=RcppArmadillo" } @@ -208,16 +208,16 @@ title = {RcppExamples: Examples using {Rcpp} to interface {R} and {C++}}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2016, - note = {R package version 0.1.8}, + year = 2019, + note = {R package version 0.1.9}, url = CRAN # "package=RcppExamples" } @Manual{CRAN:RcppGSL, title = {RcppGSL: Rcpp integration for GNU GSL vectors and matrices}, author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.3.6}, + year = 2019, + note = {R package version 0.3.7}, url = CRAN # "package=RcppGSL" } @@ -318,8 +318,8 @@ @Manual{CRAN:roxygen2, title = {roxygen2: In-source documentation for R}, author = {Hadley Wickham and Peter Danenberg and Manuel Eugster}, - year = 2017, - note = {R package version 6.0.1}, + year = 2018, + note = {R package version 6.1.1}, url = CRAN # "package=roxygen2" } Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-attributes.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-attributes.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-attributes.R rcpp-1.0.3/inst/doc/Rcpp-attributes.R --- rcpp-1.0.2/inst/doc/Rcpp-attributes.R 2019-07-20 14:38:15.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-attributes.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -## ---- eval = FALSE------------------------------------------------------- -# sourceCpp("convolve.cpp") -# convolveCpp(x, y) - -## ---- eval = FALSE------------------------------------------------------- -# function(file, colNames=character(), -# comment="#", header=TRUE) - -## ---- eval = FALSE------------------------------------------------------- -# cppFunction(' -# int fibonacci(const int x) { -# if (x < 2) -# return x; -# else -# return (fibonacci(x-1)) + fibonacci(x-2); -# } -# ') -# -# evalCpp('std::numeric_limits::max()') - -## ---- eval = FALSE------------------------------------------------------- -# cppFunction(depends='RcppArmadillo', code='...') - -## ---- eval = FALSE------------------------------------------------------- -# Rcpp.package.skeleton("NewPackage", -# attributes = TRUE) - -## ---- eval = FALSE------------------------------------------------------- -# Rcpp.package.skeleton("NewPackage", -# example_code = FALSE, -# cpp_files = c("convolve.cpp")) - -## ---- eval = FALSE------------------------------------------------------- -# compileAttributes() - -## ---- eval = FALSE------------------------------------------------------- -# #' The length of a string (in characters). -# #' -# #' @param str input character vector -# #' @return characters in each element of the vector -# strLength <- function(str) - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-attributes.Rmd rcpp-1.0.3/inst/doc/Rcpp-attributes.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-attributes.Rmd 2018-09-18 22:45:39.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-attributes.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,846 +0,0 @@ ---- -title: \pkg{Rcpp} Attributes - -# Use letters for affiliations -author: - - name: J.J. Allaire - affiliation: a - - name: Dirk Eddelbuettel - affiliation: b - - name: Romain François - affiliation: c - -address: - - code: a - address: \url{https://rstudio.com} - - code: b - address: \url{http://dirk.eddelbuettel.com} - - code: c - address: \url{https://romain.rbind.io/} - -# For footer text TODO(fold into template, allow free form two-authors) -lead_author_surname: Allaire, Eddelbuettel, François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - \textsl{Rcpp attributes} provide a high-level syntax for declaring \proglang{C++} - functions as callable from \proglang{R} and automatically generating the code - required to invoke them. Attributes are intended to facilitate both interactive use - of \proglang{C++} within \proglang{R} sessions as well as to support \proglang{R} - package development. The implementation of attributes is based on previous - work in the \pkg{inline} package \citep{CRAN:inline}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - attributes - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-attributes} - %\VignetteKeywords{Rcpp, attributes, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -Attributes are a new feature of \pkg{Rcpp} version 0.10.0 \citep{CRAN:Rcpp,JSS:Rcpp} -that provide infrastructure for seamless language bindings between \proglang{R} and -\proglang{C++}. The motivation for attributes is several-fold: - -1. Reduce the learning curve associated with using C++ and R together -1. Eliminate boilerplate conversion and marshaling code wherever - possible -1. Seamless use of C++ within interactive R sessions -1. Unified syntax for interactive work and package development - -The core concept is to add annotations to \proglang{C++} source -files that provide the context required to automatically generate \proglang{R} -bindings to \proglang{C++} functions. Attributes and their supporting -functions include: - -- `Rcpp::export` attribute to export a \proglang{C++} function - to \proglang{R} -- `sourceCpp` function to source exported functions from a file -- `cppFunction` and `evalCpp` functions for inline - declarations and execution -- `Rcpp::depends` attribute for specifying additional build - dependencies for `sourceCpp` - -Attributes can also be used for package development via the -`compileAttributes` function, which automatically generates -`extern "C"` and `.Call` wrappers for \proglang{C++} -functions within packages. - -# Using Attributes - -Attributes are annotations that are added to C++ source files to provide -additional information to the compiler. \pkg{Rcpp} supports attributes -to indicate that C++ functions should be made available as R functions, -as well as to optionally specify additional build dependencies for source files. - -\proglang{C++11} specifies a standard syntax for attributes -\citep{Maurer+Wong:2008:AttributesInC++}. Since this standard isn't yet -fully supported across all compilers, \pkg{Rcpp} attributes are included in -source files using specially formatted comments. - -## Exporting C++ Functions - -The `sourceCpp` function parses a \proglang{C++} file and looks for -functions marked with the `Rcpp::export` attribute. A shared -library is then built and its exported functions are made available as R -functions in the specified environment. For example, this source file -contains an implementation of convolve (note the `Rcpp::export` -attribute in the comment above the function): - -```{Rcpp, eval = FALSE} -#include -using namespace Rcpp; - -// [[Rcpp::export]] -NumericVector convolveCpp(NumericVector a, - NumericVector b) { - - int na = a.size(), nb = b.size(); - int nab = na + nb - 1; - NumericVector xab(nab); - - for (int i = 0; i < na; i++) - for (int j = 0; j < nb; j++) - xab[i + j] += a[i] * b[j]; - - return xab; -} -``` - -The addition of the export attribute allows us to do this from the \proglang{R} -prompt: - -```{r, eval = FALSE} -sourceCpp("convolve.cpp") -convolveCpp(x, y) -``` - -We can now write \proglang{C++} functions using built-in \proglang{C++} types -and \pkg{Rcpp} wrapper types and then source them just as we would an -\proglang{R} script. - -The `sourceCpp` function performs caching based on the last -modified date of the source file and it's local dependencies so as -long as the source does not change the compilation will occur only -once per R session. - -## Specifying Argument Defaults - -If default argument values are provided in the C++ function definition -then these defaults are also used for the exported R function. For example, -the following C++ function: - -```{Rcpp, eval = FALSE} -DataFrame readData(CharacterVector file, - CharacterVector colNames = - CharacterVector::create(), - std::string comment = "#", - bool header = true) -``` - -Will be exported to R as: - -```{r, eval = FALSE} -function(file, colNames=character(), - comment="#", header=TRUE) -``` - -Note that C++ rules for default arguments still apply: they must occur -consecutively at the end of the function signature and (unlike R) can't rely -on the values of other arguments. - -Not all \proglang{C++} default argument values can be parsed into their -\proglang{R} equivalents, however the most common cases are supported, including: - -- String literals delimited by quotes (e.g. `"foo"`) -- Decimal numeric values (e.g. `10` or `4.5`) -- Pre-defined constants including `true`, `false`, - `R_NilValue`, `NA_STRING`, `NA_INTEGER`, - `NA_REAL`, and `NA_LOGICAL`. -- Selected vector types (`CharacterVector`, `IntegerVector`, - and `NumericVector`) instantiated using the `::create` - static member function. -- `Matrix` types instantiated using the `rows`, - `cols` constructor. - -## Signaling Errors - -Within \proglang{R} code the `stop` function is typically used to signal -errors. Within \proglang{R} extensions written in \proglang{C} the `Rf_error` function is typically used. However, within \proglang{C++} code you cannot -safely use `Rf_error` because it results in a `longjmp` over -any \proglang{C++} destructors on the stack. - -The correct way to signal errors within \proglang{C++} functions is to throw an `Rcpp::exception`. For example: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - throw Rcpp::exception("Unexpected " - "condition occurred"); -``` - -There is also an `Rcpp::stop` function that is shorthand for throwing -an `Rcpp::exception`. For example: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - Rcpp::stop("Unexpected condition occurred"); -``` - -In both cases the \proglang{C++} exception will be caught by \pkg{Rcpp} -prior to returning control to \proglang{R} and converted into the correct -signal to \proglang{R} that execution should stop with the specified message. - -You can similarly also signal warnings with the `Rcpp::warning` -function: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - Rcpp::warning("Unexpected condition occurred"); -``` - -## Supporting User Interruption - -If your function may run for an extended period of time, users will appreciate -the ability to interrupt it's processing and return to the REPL. This is -handled automatically for R code (as R checks for user interrupts periodically -during processing) however requires explicit accounting for in C and C++ -extensions to R. To make computations interrupt-able, you should periodically -call the `Rcpp::checkUserInterrupt` function, for example: - -```{Rcpp, eval = FALSE} -for (int i=0; i<1000000; i++) { - // check for interrupt every 1000 iterations - if (i % 1000 == 0) - Rcpp::checkUserInterrupt(); - - // ...do some expensive work... -} -``` - -A good guideline is to call `Rcpp::checkUserInterrupt` every 1 or 2 -seconds that your computation is running. In the above code, if the user -requests an interrupt then an exception is thrown and the attributes wrapper -code arranges for the user to be returned to the REPL. - -Note that R provides a \proglang{C} API for the same purpose -(`R_CheckUserInterrupt`) however this API is not safe to use in -\proglang{C++} code as it uses `longjmp` to exit the current scope, -bypassing any C++ destructors on the stack. The `Rcpp::checkUserInterrupt` -function is provided as a safe alternative for \proglang{C++} code. - -## Embedding R Code - -Typically \proglang{C++} and \proglang{R} code are kept in their own source -files. However, it's often convenient to bundle code from both languages into -a common source file that can be executed using single call to `sourceCpp`. - -To embed chunks of \proglang{R} code within a \proglang{C++} -source file you include the \proglang{R} code within a block comment that -has the prefix of `/*** R`. For example: - -```{Rcpp, eval = FALSE} -/*** R - -# Call the fibonacci function defined in C++ -fibonacci(10) - -*/ -``` - -Multiple \proglang{R} code chunks can be included in a \proglang{C++} file. The -`sourceCpp` function will first compile the \proglang{C++} code into a -shared library and then source the embedded \proglang{R} code. - -## Modifying Function Names - -You can change the name of an exported function as it appears to \proglang{R} by -adding a name parameter to `Rcpp::export`. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::export(name = ".convolveCpp")]] -NumericVector convolveCpp(NumericVector a, - NumericVector b) -``` - -Note that in this case since the specified name is prefaced by a \code{.} the -exported R function will be hidden. You can also use this method to provide -implementations of S3 methods (which wouldn't otherwise be possible because -C++ functions can't contain a '.' in their name). - -## Function Requirements - -Functions marked with the `Rcpp::export` attribute must meet several -requirements to be correctly handled: - -- Be defined in the global namespace (i.e. not within a C++ namespace declaration) -- Have a return type that is either void or compatible with `Rcpp::wrap` - and parameter types that are compatible with `Rcpp::as` (see sections - 3.1 and 3.2 of the '\textsl{Rcpp-jss-2011}' vignette for more details). -- Use fully qualified type names for the return value and all parameters. - Rcpp types may however appear without a namespace qualifier (i.e. - `DataFrame` is okay as a type name but `std::string` must be - specified fully). - -## Random Number Generation - -\proglang{R} functions implemented in \proglang{C} or \proglang{C++} need -to be careful to surround use of internal random number generation routines -(e.g. `unif_rand`) with calls to `GetRNGstate` and -`PutRNGstate`. - -Within \pkg{Rcpp}, this is typically done using the `RNGScope` class. -However, this is not necessary for \proglang{C++} functions exported using -attributes because an `RNGScope` is established for them automatically. -Note that \pkg{Rcpp} implements `RNGScope` using a counter, so it's -still safe to execute code that may establish it's own `RNGScope` (such -as the \pkg{Rcpp} sugar functions that deal with random number generation). - -The overhead associated with using `RNGScope` is negligible (only a -couple of milliseconds) and it provides a guarantee that all C++ code -will inter-operate correctly with R's random number generation. If you are -certain that no C++ code will make use of random number generation and the -2ms of execution time is meaningful in your context, you can disable the -automatic injection of `RNGScope` using the `rng` parameter -of the `Rcpp::export` attribute. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::export(rng = false)]] -double myFunction(double input) { - // ...code that never uses the - // R random number generation... -} -``` - -## Importing Dependencies - -It's also possible to use the `Rcpp::depends` attribute to declare -dependencies on other packages. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(RcppArmadillo)]] - -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List fastLm(NumericVector yr, NumericMatrix Xr) { - - int n = Xr.nrow(), k = Xr.ncol(); - - arma::mat X(Xr.begin(), n, k, false); - arma::colvec y(yr.begin(), yr.size(), false); - - arma::colvec coef = arma::solve(X, y); - arma::colvec rd = y - X*coef; - - double sig2 = - arma::as_scalar(arma::trans(rd)*rd/(n-k)); - arma::colvec sderr = arma::sqrt(sig2 * - arma::diagvec(arma::inv(arma::trans(X)*X))); - - return List::create(Named("coef") = coef, - Named("sderr")= sderr); -} -``` - -The inclusion of the `Rcpp::depends` attribute causes `sourceCpp` -to configure the build environment to correctly compile and link against the -\pkg{RcppArmadillo} package. Source files can declare more than one dependency -either by using multiple `Rcpp::depends` attributes or with syntax like this: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(Matrix, RcppArmadillo)]] -``` - -Dependencies are discovered both by scanning for package include directories -and by invoking \pkg{inline} plugins if they are available for a package. - -Note that while the `Rcpp::depends` attribute establishes dependencies -for `sourceCpp`, it's important to note that if you include the same -source file in an \proglang{R} package these dependencies must still be -listed in the `Imports` and/or `LinkingTo` fields of the package -`DESCRIPTION` file. - -## Sharing Code - -The core use case for `sourceCpp` is the compilation of a single -self-contained source file. Code within this file can import other C++ code -by using the `Rcpp::depends` attribute as described above. - -The recommended practice for sharing C++ code across many uses of -`sourceCpp` is therefore to create an R package to wrap the C++ -code. This has many benefits not the least of which is easy distribution of -shared code. More information on creating packages that contain C++ code -is included in the Package Development section below. - -### Shared Code in Header Files - -If you need to share a small amount of C++ code between source files -compiled with `sourceCpp` and the option of creating a package -isn't practical, then you can also share code using local includes of C++ -header files. To do this, create a header file with the definition of -shared functions, classes, enums, etc. For example: - -```{Rcpp, eval = FALSE} -#ifndef __UTILITIES__ -#define __UTILITIES__ - -inline double timesTwo(double x) { - return x * 2; -} - -#endif // __UTILITIES__ -``` - -Note the use of the `#ifndef` include guard, this is important to ensure -that code is not included more than once in a source file. You should -use an include guard and be sure to pick a unique name for the corresponding -`#define`. - -Also note the use of the \code{inline} keyword preceding the function. This -is important to ensure that there are not multiple definitions of -functions included from header files. Classes fully defined in header files -automatically have inline semantics so don't require this treatment. - -To use this code in a source file you'd just include -it based on it's relative path (being sure to use `"` as the -delimiter to indicate a local file reference). For example: - -```{Rcpp, eval = FALSE} -#include "shared/utilities.hpp" - -// [[Rcpp::export]] -double transformValue(double x) { - return timesTwo(x) * 10; -} -``` - -### Shared Code in C++ Files - -When scanning for locally included header files \code{sourceCpp} also checks -for a corresponding implementation file and automatically includes it in the -compilation if it exists. - -This enables you to break the shared code entirely into it's own source file. -In terms of the above example, this would mean having only a function -declaration in the header: - -```{Rcpp, eval = FALSE} -#ifndef __UTILITIES__ -#define __UTILITIES__ - -double timesTwo(double x); - -#endif // __UTILITIES__ -``` - -Then actually defining the function in a separate source file with the -same base name as the header file but with a .cpp extension (in the above -example this would be \code{utilities.cpp}): - -```{Rcpp, eval = FALSE} -#include "utilities.hpp" - -double timesTwo(double x) { - return x * 2; -} -``` - -It's also possible to use attributes to declare dependencies and exported -functions within shared header and source files. This enables you to take -a source file that is typically used standalone and include it when compiling -another source file. - -Note that since additional source files are processed as separate translation -units the total compilation time will increase proportional to the number of -files processed. From this standpoint it's often preferable to use shared -header files with definitions fully inlined as demonstrated above. - -Note also that embedded R code is only executed for the main source file not -those referenced by local includes. - -## Including C++ Inline - -Maintaining C++ code in it's own source file provides several benefits including -the ability to use \proglang{C++} aware text-editing tools and straightforward -mapping of compilation errors to lines in the source file. However, it's also -possible to do inline declaration and execution of C++ code. - -There are several ways to accomplish this, including passing a code -string to `sourceCpp` or using the shorter-form `cppFunction` -or `evalCpp` functions. For example: - -```{r, eval = FALSE} -cppFunction(' - int fibonacci(const int x) { - if (x < 2) - return x; - else - return (fibonacci(x-1)) + fibonacci(x-2); - } -') - -evalCpp('std::numeric_limits::max()') -``` - -You can also specify a depends parameter to `cppFunction` or `evalCpp`: - -```{r, eval = FALSE} -cppFunction(depends='RcppArmadillo', code='...') -``` - -# Package Development - -One of the goals of \pkg{Rcpp} attributes is to simultaneously facilitate -ad-hoc and interactive work with \proglang{C++} while also making it very easy to -migrate that work into an \proglang{R} package. There are several benefits of -moving code from a standalone \proglang{C++} source file to a package: - -1. Your code can be made available to users without \proglang{C++} development - tools (at least on Windows or Mac OS X where binary packages are common) -1. Multiple source files and their dependencies are handled automatically - by the \proglang{R} package build system -1. Packages provide additional infrastructure for testing, documentation - and consistency - -## Package Creation - -To create a package that is based on \pkg{Rcpp} you should follow the -guidelines in the '\textsl{Rcpp-package}' vignette. For a new package this -is most conveniently done using the `Rcpp.package.skeleton` function. - -To generate a new package with a simple hello, world function that uses -attributes you can do the following: - -```{r, eval = FALSE} -Rcpp.package.skeleton("NewPackage", - attributes = TRUE) -``` - -To generate a package based on \proglang{C++} files that you've been using -with `sourceCpp` you can use the `cpp_files` parameter: - -```{r, eval = FALSE} -Rcpp.package.skeleton("NewPackage", - example_code = FALSE, - cpp_files = c("convolve.cpp")) -``` - -## Specifying Dependencies - -Once you've migrated \proglang{C++} code into a package, the dependencies for -source files are derived from the `Imports` and `LinkingTo` fields -in the package `DESCRIPTION` file rather than the `Rcpp::depends` -attribute. Some packages also require the addition of an entry to the package -`NAMESPACE` file to ensure that the package's shared library is loaded -prior to callers using the package. For every package you import C++ code from -(including \pkg{Rcpp}) you need to add these entries. - -Packages that provide only C++ header files (and no shared library) need only -be referred to using `LinkingTo`. You should consult the documentation -for the package you are using for the requirements particular to that package. - -For example, if your package depends on \pkg{Rcpp} you'd have the following -entries in the `DESCRIPTION` file: - -```{bash, eval = FALSE} -Imports: Rcpp (>= 0.11.4) -LinkingTo: Rcpp -``` - -And the following entry in your `NAMESPACE` file: - -```{bash, eval = FALSE} -importFrom(Rcpp, evalCpp) -``` - -If your package additionally depended on the \pkg{BH} (Boost headers) package -you'd just add an entry for \pkg{BH} to the `LinkingTo` field since -\pkg{BH} is a header-only package: - -```{bash, eval = FALSE} -Imports: Rcpp (>= 0.11.4) -LinkingTo: Rcpp, BH -``` - - -## Exporting R Functions - -Within interactive sessions you call the `sourceCpp` function -on individual files to export \proglang{C++} functions into the global -environment. However, for packages you call a single utility function to -export all \proglang{C++} functions within the package. - -The `compileAttributes` function scans the source files within a package -for export attributes and generates code as required. For example, executing -this from within the package working directory: - -```{r, eval = FALSE} -compileAttributes() -``` - -Results in the generation of the following two source files: - -- `src/RcppExports.cpp` -- The `extern "C"` wrappers required - to call exported \proglang{C++} functions within the package. -- `R/RcppExports.R` -- The `.Call` wrappers required to call - the `extern "C"` functions defined in `RcppExports.cpp`. - -You should re-run `compileAttributes` whenever functions are added, -removed, or have their signatures changed. Note that if you are using either -RStudio or \pkg{devtools} to build your package then the -`compileAttributes` function is called automatically whenever your -package is built. - -The `compileAttributes` function deals only with exporting -\proglang{C++} functions to \proglang{R}. If you want the functions to -additionally be publicly available from your package's namespace another -step may be required. Specifically, if your package `NAMESPACE` file -does not use a pattern to export functions then you should add an explicit -entry to `NAMESPACE` for each R function you want publicly available. - -## Package Init Functions - -Rcpp attribute compilation will automatically generate a package R_init function that does native routine registration as described here: . - -You may however want to add additional C++ code to the package initialization sequence. To do this, you can add the `[[Rcpp::init]]` attribute to functions within your package. For example: - -```{cpp, eval = FALSE} -// [[Rcpp::init]] -void my_package_init(DllInfo *dll) { - // initialization code here -} -``` - -In this case, a call to `my_package_init()` will be added to the end of the automatically generated R_init function within RcppExports.cpp. For example: - -```{cpp, eval = FALSE} -void my_package_init(DllInfo *dll); -RcppExport void R_init_pkgname(DllInfo *dll) { - R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); - R_useDynamicSymbols(dll, FALSE); - my_package_init(dll); -} -``` - -## Types in Generated Code - -In some cases the signatures of the C++ functions that are generated within -`RcppExports.cpp` may have additional type requirements beyond the core -standard library and \pkg{Rcpp} types (e.g. `CharacterVector`, -`NumericVector`, etc.). Examples might include convenience typedefs, -as/wrap handlers for marshaling between custom types and SEXP, or types -wrapped by the Rcpp `XPtr` template. - -In this case, you can create a header file that contains these type definitions -(either defined inline or by including other headers) and have this header -file automatically included in `RcppExports.cpp`. Headers named with -the convention `pkgname_types` are automatically included along with -the generated C++ code. For example, if your package is named \pkg{fastcode} -then any of the following header files would be automatically included in -`RcppExports.cpp`: - -```{Rcpp, eval = FALSE} -src/fastcode_types.h -src/fastcode_types.hpp -inst/include/fastcode_types.h -inst/include/fastcode_types.hpp -``` - -There is one other mechanism for type visibility in `RcppExports.cpp`. -If your package provides a master include file for consumption by C++ clients -then this file will also be automatically included. For example, if the -\pkg{fastcode} package had a C++ API and the following header file: - -```{Rcpp, eval = FALSE} -inst/include/fastcode.h -``` - -This header file will also automatically be included in -`RcppExports.cpp`. Note that the convention of using `.h` for -header files containing C++ code may seem unnatural, but this comes from the -recommended practices described in '\textsl{Writing R Extensions}' -\citep{R:Extensions}. - -## Roxygen Comments - -The \pkg{roxygen2} package \citep{CRAN:roxygen2} provides a facility for -automatically generating \proglang{R} documentation files based on specially -formatted comments in \proglang{R} source code. - -If you include roxygen comments in your \proglang{C++} source file with a -`//'` prefix then `compileAttributes` will transpose them -into R roxygen comments within `R/RcppExports.R`. For example the -following code in a \proglang{C++} source file: - -```{Rcpp, eval = FALSE} -//' The length of a string (in characters). -//' -//' @param str input character vector -//' @return characters in each element of the vector -// [[Rcpp::export]] -NumericVector strLength(CharacterVector str) -``` - -Results in the following code in the generated \proglang{R} source file: - -```{r, eval = FALSE} -#' The length of a string (in characters). -#' -#' @param str input character vector -#' @return characters in each element of the vector -strLength <- function(str) -``` - -## Providing a C++ Interface - -The interface exposed from \proglang{R} packages is most typically a set of -\proglang{R} functions. However, the \proglang{R} package system also provides -a mechanism to allow the exporting of \proglang{C} and \proglang{C++} -interfaces using package header files. This is based on the -`R_RegisterCCallable` and `R_GetCCallable` functions described in -'\textsl{Writing R Extensions}' \citep{R:Extensions}. - -\proglang{C++} interfaces to a package are published within the -top level `include` directory of the package (which within the package -source directory is located at `inst/include`). The \proglang{R} build -system automatically adds the required `include` directories for all -packages specified in the `LinkingTo` field of the package -`DESCRIPTION` file. - -### Interfaces Attribute - -The `Rcpp::interfaces` attribute can be used to automatically -generate a header-only interface to your \proglang{C++} functions -within the `include` directory of your package. - -The `Rcpp::interfaces` attribute is specified on a per-source -file basis, and indicates which interfaces (\proglang{R}, \proglang{C++}, -or both) should be provided for exported functions within the file. - -For example, the following specifies that both R and \proglang{C++} interfaces -should be generated for a source file: - -```{Rcpp, eval = FALSE} -// [[Rcpp::interfaces(r, cpp)]] -``` - -Note that the default behavior if an `Rcpp::interfaces` attribute -is not included in a source file is to generate an R interface only. - -### Generated Code - -If you request a `cpp` interface for a source file then -`compileAttributes` generates the following header files -(substituting \emph{Package} with the name of the package code is being -generated for): - -```{bash, eval = FALSE} -inst/include/Package.h -inst/include/Package_RcppExports.h -``` - -The `Package_RcppExports.h` file has inline definitions for all -exported \proglang{C++} functions that enable calling them using the -`R_GetCCallable` mechanism. - -The `Package.h` file does nothing other than include the -`Package_RcppExports.h` header. This is done so -that package authors can replace the `Package.h` header with -a custom one and still be able to include the automatically generated exports -(details on doing this are provided in the next section). - -The exported functions are defined within a \proglang{C++} namespace that matches -the name of the package. For example, an exported \proglang{C++} function -`bar` could be called from package `MyPackage` as follows: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(MyPackage)]] - -#include - -void foo() { - MyPackage::bar(); -} -``` - -### Including Additional Code - -You might wish to use the `Rcpp::interfaces` attribute to generate -a part of your package's \proglang{C++} interface but also provide -additional custom \proglang{C++} code. In this case you -should replace the generated `Package.h` file with one of your own. - -Note that the way \pkg{Rcpp} distinguishes user verses generated files is by checking -for the presence a special token in the file (if it's present then it's known -to be generated and thus safe to overwrite). You'll see this token at the top -of the generated `Package.h` file, be sure to remove it if you want -to provide a custom header. - -Once you've established a custom package header file, you need only include the -`Package_RcppExports.h` file within your header to make available -the automatically generated code alongside your own. - -If you need to include code from your custom header files within the -compilation of your package source files, you will also need to add the -following entry to `Makevars` and `Makevars.win` (both are -in the `src` directory of your package): - -```{bash, eval = FALSE} -PKG_CPPFLAGS += -I../inst/include/ -``` - -Note that the R package build system does not automatically force a rebuild -when headers in `inst/include` change, so you should be sure to perform a -full rebuild of the package after making changes to these headers. diff -Nru rcpp-1.0.2/inst/doc/Rcpp-attributes.Rnw rcpp-1.0.3/inst/doc/Rcpp-attributes.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-attributes.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-attributes.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-attributes} +%\VignetteKeywords{Rcpp, attributes, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-attributes.pdf} +\end{document} diff -Nru rcpp-1.0.2/inst/doc/Rcpp.bib rcpp-1.0.3/inst/doc/Rcpp.bib --- rcpp-1.0.2/inst/doc/Rcpp.bib 2019-07-20 13:50:10.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp.bib 1970-01-01 00:00:00.000000000 +0000 @@ -1,857 +0,0 @@ -@String{CRAN = "http://CRAN.R-Project.org/" } -@String{manuals = CRAN # "doc/manuals/" } -@String{RCoreTeam = "{R Core Team}" } -@String{RFoundation = "R Foundation for Statistical Computing" } -@String{R-Forge = "http://R-Forge.R-Project.org/" } - -@manual{Abrahams+Grosse-Kunstleve:2003:Boost.Python, - author = { David Abrahams and Ralf W. Grosse-Kunstleve }, - organization = "Boost Consulting", - title = "Building Hybrid Systems with Boost.Python", - year = 2003, - url = "http://www.boostpro.com/writing/bpl.pdf" -} - -@Book{Abrahams+Gurtovoy:2004:TemplateMetaprogramming, - author = {David Abrahams and Aleksey Gurtovoy}, - title = {{C++} {T}emplate {M}etaprogramming: Concepts, Tools - and Techniques from {B}oost and Beyond}, - publisher = {Addison-Wesley}, - year = 2004, - address = {Boston} -} - -@book{Anderson:1990:UGLAPACK, - author = {Anderson, E. and Bai, Z. and Bischof, C. and - Blackford, S. and Demmel, J. and Dongarra, J. and Du - Croz, J. and Greenbaum, A. and Hammarling, S. and - McKenney, A. and Sorensen, D.}, - title = {{LAPACK} Users' Guide}, - edition = {Third}, - publisher = {Society for Industrial and Applied Mathematics}, - year = 1999, - address = {Philadelphia, PA}, - isbn = {0-89871-447-8 (paperback)} -} - -@Manual{Armstrong:2009:RAbstraction, - title = {{RAbstraction}: {C++} abstraction for {R} objects}, - author = {Whit Armstrong}, - year = 2009, - note = {Code repository last updated 2009-07-22.}, - url = {http://github.com/armstrtw/rabstraction} -} - -@Manual{Armstrong:2009:RObjects, - title = {{RObjects}: {C++} wrapper for R objects (a better - implementation of {RAbstraction}}, - author = {Whit Armstrong}, - year = 2009, - note = {Code repository last updated 2009-11-28.}, - url = {http://github.com/armstrtw/RObjects} -} - -@InProceedings{Bates+DebRoy:2001:C++Classes, - author = {Douglas M. Bates and Saikat DebRoy}, - title = {{C++} Classes for {R} Objects}, - booktitle = {Proceedings of the 2nd International Workshop on Distributed - Statistical Computing, March 15--17, 2001, Technische - Universit\"at Wien, Vienna, Austria}, - editor = {Kurt Hornik and Friedrich Leisch}, - year = {2001}, - url = {http://www.ci.tuwien.ac.at/Conferences/DSC-2001/Proceedings/}, - note = {ISSN 1609-395X} -} - - -@Misc{Brokken:2011:Cpp, - author = {Frank B. Brokken}, - title = {C++ Annotations}, - howpublished = {Electronic book, University of Groningen}, - year = 2011, - url = {http://www.icce.rug.nl/documents/cplusplus/} -} - -@Manual{CRAN:Matrix, - title = {\pkg{Matrix}: Sparse and Dense Matrix Classes and Methods}, - author = {Douglas Bates and Martin Maechler}, - year = 2019, - note = {R package version 1.2-17}, - url = CRAN # "package=Matrix" -} - -@Manual{CRAN:RInside, - title = {RInside: C++ classes to embed R in C++ applications}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2019, - note = {R package version 0.2.15}, - url = CRAN # "package=RInside" -} - -@Manual{CRAN:RProtoBuf, - title = {RProtoBuf: R Interface to the Protocol Buffers API}, - author = {Romain Fran\c{c}ois and Dirk Eddelbuettel and Murray Stokely and Jeroen Ooms}, - year = 2019, - note = {R package version 0.4.14}, - url = CRAN # "package=RProtoBuf" -} - -@Manual{CRAN:RQuantLib, - title = {RQuantLib: {R} interface to the {QuantLib} library}, - author = {Dirk Eddelbuettel and Khanh Nguyen and Terry Leitch}, - year = 2019, - note = {R package version 0.4.9}, - url = CRAN # "package=RQuantLib" -} - -@Manual{CRAN:RUnit, - title = {RUnit: R Unit Test Framework}, - author = {Matthias Burger and Klaus Juenemann and Thomas - Koenig}, - year = 2015, - note = {R package version 0.4.31}, - url = {https://CRAN.R-project.org/package=RUnit}, -} - -@Manual{CRAN:Rcpp, - title = {{Rcpp}: Seamless {R} and {C++} Integration}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois and JJ - Allaire and Kevin Ushey and Qiang Kou and - Nathan Russel and John Chambers and Douglas Bates}, - year = 2019, - note = {R package version 1.0.2}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Attributes, - crossref = {CRAN:Rcpp}, - author = {J. J. Allaire and Dirk Eddelbuettel and Romain - Fran\c{c}ois}, - title = {{Rcpp} Attributes}, - year = 2018, - note = {Vignette included in R package Rcpp}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:FAQ, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Frequently Asked Questions About {Rcpp}}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Modules, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Exposing {C++} functions and classes with {Rcpp} modules}, - year = 2018, - note = {Vignette included in R package Rcpp}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Package, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Writing a package that uses {Rcpp}}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Sugar, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Rcpp syntactic sugar}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:RcppArmadillo, - title = {RcppArmadillo: Rcpp integration for Armadillo - templated linear algebra library}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois and - Douglas Bates and Binxiang Ni}, - year = 2019, - note = {R package version 0.9.600.4.0}, - url = CRAN # "package=RcppArmadillo" -} - -@Manual{CRAN:RcppClassic, - title = {RcppClassic: Deprecated 'classic' Rcpp API}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.9.11}, - url = CRAN # "package=RcppClassic" -} - -@Manual{CRAN:RcppDE, - title = {RcppDE: Global optimization by differential evolution in C++}, - author = {Dirk Eddelbuettel}, - year = 2018, - note = {R package version 0.1.6}, - url = CRAN # "package=RcppDE" -} - -@Manual{CRAN:RcppEigen, - title = {RcppEigen: Rcpp integration for the Eigen templated linear - algebra library}, - author = {Douglas Bates and Dirk Eddelbuettel and Romain Fran\c{c}ois and Yixuan Qiu}, - year = 2018, - note = {{R} package version 0.3.3.5.0}, - url = CRAN # "package=RcppEigen" -} - -@Manual{CRAN:RcppExamples, - title = {RcppExamples: Examples using {Rcpp} to interface {R} - and {C++}}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2016, - note = {R package version 0.1.8}, - url = CRAN # "package=RcppExamples" -} - -@Manual{CRAN:RcppGSL, - title = {RcppGSL: Rcpp integration for GNU GSL vectors and matrices}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.3.6}, - url = CRAN # "package=RcppGSL" -} - -@Manual{CRAN:RcppZiggurat, - title = {RcppZiggurat: Rcpp Integration of Different Ziggurat Normal RNG Implementations}, - author = {Dirk Eddelbuettel}, - year = 2018, - note = {R package version 0.1.5}, - url = CRAN # "package=RcppZiggurat" -} - -@Manual{CRAN:Rserve, - title = {Rserve: Binary R server}, - author = {Simon Urbanek}, - year = 2019, - note = {R package version 1.7-3.1}, - url = CRAN # "package=Rserve" -} - -@Manual{CRAN:cxxPack, - title = {cxxpack: {R/C++} Tools for Literate Statistical - Practice}, - author = {Dominick Samperi}, - year = 2010, - note = {R package version 7.0.6}, - url = CRAN # "package=cxxPack" -} - -@Manual{CRAN:devtools, - title = {devtools: Tools to Make Developing R Packages - Easier}, - author = {Hadley Wickham and Winston Chang}, - year = 2016, - note = {R package version 1.12.0}, - url = {https://CRAN.R-project.org/package=devtools}, -} - -@Manual{CRAN:highlight, - title = {highlight: Syntax highlighter}, - author = {Romain Fran\c{c}ois}, - year = 2017, - note = {R package with version 0.4.7.2}, - url = CRAN # "package=highlight" -} - -@Manual{CRAN:inline, - title = {inline: Inline C, C++, Fortran function calls from - R}, - author = {Oleg Sklyar and Duncan Murdoch and Mike Smith and - Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.3.15}, - url = CRAN # "package=inline" -} - -@Manual{CRAN:littler, - title = {littler: {R} at the {Command-Line} via r}, - author = {Dirk Eddelbuettel and Jeffrey Horner}, - year = 2017, - note = {R package version 0.3.2}, - url = CRAN # "package=littler" -} - -@Manual{CRAN:microbenchmark, - title = {microbenchmark: Accurate Timing Functions}, - author = {Olaf Mersmann}, - year = 2015, - note = {R package version 1.4-2.1}, - url = {https://CRAN.R-project.org/package=microbenchmark} -} - -@Manual{CRAN:minqa, - title = {minqa: Derivative-free optimization algorithms by - quadratic approximation}, - author = {Douglas Bates and Katharine M. Mullen and John - C. Nash and Ravi Varadhan}, - year = 2014, - note = {R package version 1.2.4}, - url = CRAN # "package=minqa" -} - -@Manual{CRAN:profvis, - title = {profvis: Interactive Visualizations for Profiling R Code}, - author = {Winston Chang and Javier Luraschi}, - year = 2017, - note = {R package version 0.3.3}, - url = {https://CRAN.R-project.org/package=profvis}, -} - -@Manual{CRAN:rbenchmark, - title = {\pkg{rbenchmark}: Benchmarking routine for R}, - author = {Wacek Kusnierczyk}, - year = 2012, - note = {R package version 1.0.0}, - url = CRAN # "package=rbenchmark" -} - -@Manual{CRAN:roxygen2, - title = {roxygen2: In-source documentation for R}, - author = {Hadley Wickham and Peter Danenberg and Manuel Eugster}, - year = 2017, - note = {R package version 6.0.1}, - url = CRAN # "package=roxygen2" -} - -@Article{CRAN:testthat, - author = {Hadley Wickham}, - title = {testthat: Get Started with Testing}, - journal = {The R Journal}, - year = 2011, - volume = 3, - pages = {5--10}, -} - -@Book{Chambers:1998:PwD, - author = {John M. Chambers}, - title = {Programming with Data: {A} Guide to the {S} Language}, - publisher = {Springer-Verlag}, - year = 1998, - address = {Heidelberg}, - note = {{ISBN} 978-0387985039} -} - -@Book{Chambers:2008:SoDA, - author = {John M. Chambers}, - title = {Software for Data Analysis: Programming with {R}}, - publisher = {Springer-Verlag}, - year = 2008, - series = {Statistics and Computing}, - address = {Heidelberg}, - note = {{ISBN} 978-0-387-75935-7} -} - -@Book{Chambers:2016:ExtR, - author = {John M. Chambers}, - title = {Extending R}, - publisher = {Chapman and Hall/CRC}, - year = 2016, - series = {{The R Series}}, - address = {London}, - note = {{ISBN} 9781498775717} -} - -@Misc{Cpp11, - author = "ISO/IEC", - organization = "{International Organization for Standardization}", - title = "\proglang{C++} 2011 Standard Document 14882:2011", - howpublished = {ISO/IEC Standard Group for Information Technology / Programming Languages / C++}, - year = 2011, - url = "http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372", - urlansi = "http://webstore.ansi.org/RecordDetail.aspx?sku=ISO/IEC%2014882:2011" -} - -@book{Dongarra:1979:UGLINPACK, - title = {LINPACK users' guide}, - author = {Dongarra, Jack J and Moler, Cleve B and Bunch, James - R and Stewart, Gilbert W}, - year = 1979, - publisher = {SIAM} -} - -@Article{Eddelbuettel+Sanderson:2013:RcppArmadillo, - title = {{RcppArmadillo}: Accelerating {R} with High-Performance {C++} Linear Algebra}, - author = {Dirk Eddelbuettel and Conrad Sanderson}, - journal = {Computational Statistics and Data Analysis}, - year = 2014, - volume = 71, - month = {March}, - pages = {1054--1063}, - doi = {10.1016/j.csda.2013.02.005}, - url = {http://dx.doi.org/10.1016/j.csda.2013.02.005} -} - -@Article{Eddelbuettel+Sanderson:2014:RcppArmadillo, - title = {{RcppArmadillo}: Accelerating {R} with High-Performance {C++} Linear Algebra}, - author = {Dirk Eddelbuettel and Conrad Sanderson}, - journal = {Computational Statistics and Data Analysis}, - year = 2014, - volume = 71, - month = {March}, - pages = {1054--1063}, - doi = {10.1016/j.csda.2013.02.005}, - url = {http://dx.doi.org/10.1016/j.csda.2013.02.005} -} - -@Book{Eddelbuettel:2013:Rcpp, - author = {Dirk Eddelbuettel}, - title = {Seamless R and C++ Integration with Rcpp}, - publisher = {Springer}, - series = {Use R!}, - year = 2013, - address = {New York}, - isbn = {978-1-4614-6867-7} -} - -@article{Efron:1979:Bootstrap, - URL = {http://www.jstor.org/stable/2958830}, - author = {Efron, B.}, - journal = {The Annals of Statistics}, - number = {1}, - pages = {1-26}, - publisher = {Institute of Mathematical Statistics}, - title = {Bootstrap Methods: Another Look at the Jackknife}, - volume = {7}, - year = {1979} -} - -@MISC{Eigen:Web, - author = {Ga\"{e}l Guennebaud and Beno\^{i}t Jacob and others}, - title = {Eigen v3}, - year = 2012, - url = {http://eigen.tuxfamily.org}, -} -; see http://eigen.tuxfamily.org/index.php?title=BibTeX -; replaced 'howpublished' with 'url' and updated year to 2011, and again to 2012 - -@Manual{GSL, - title = {{GNU} {S}cientific {L}ibrary {R}eference {M}anual}, - author = {Mark Galassi and Jim Davies and James Theiler and Brian Gough and Gerard Jungman and Patrick Alken and Michael Booth and Fabrice Rossi}, - year = {2010}, - edition = {3rd}, - note = {Version 1.14. {ISBN} 0954612078}, - url = {http://www.gnu.org/software/gsl} -} - -@Book{Gentleman:2009:RProgramming, - author = {Robert Gentleman}, - title = {R Programming for Bioinformatics}, - publisher = {Chapman \& Hall/CRC}, - year = 2009, - series = {Computer Science and Data Analysis}, - address = {Boca Raton, FL} -} - -@Manual{GitHub:Rperform, - title = {Rperform: Rperform - Performance testing for R packages}, - author = {Akash Tandon and Toby Dylan Hocking}, - year = {2015}, - note = {R package version 0.0.0.9000}, -} - -@Article{Gropp+Lusk+Doss+Skjellum:1996:MPI, - author = {William Gropp and Ewing Lusk and Nathan Doss and Anthony Skjellum}, - title = {A high-performance, portable implementation of the {MPI} message passing interface standard}, - journal = {Parallel Computing}, - year = 1996, - url = {http://dx.doi.org/10.1016/0167-8191(96)00024-5}, - volume = 22, - number = 6, - pages = {789--828} -} - -@Book{Gropp+Lusk+Skjellum:1999:MPI, - author = {William Gropp and Ewing Lusk and Anthony Skjellum}, - title = {Using {MPI}: Portable Parallel Programming with the Message Passing Interface}, - publisher = {MIT Press}, - year = 1999, - series = {Scientific and Engineering Computation Series}, - edition = {2nd}, - month = {November}, - note = {{ISBN} 978-0-262-57132-6} -} - -@article{Ihaka:1996, - Author = {Ihaka, Ross and Gentleman, Robert}, - Journal = {Journal of Computational and Graphical Statistics}, - Number = 3, - Pages = {299--314}, - Title = {R: A Language for Data Analysis and Graphics}, - Volume = 5, - Year = 1996 -} - -@article{JOSS:RcppCNPy, - doi = {10.21105/joss.00055}, - url = {https://doi.org/10.21105/joss.00055}, - year = {2016}, - month = {sep}, - publisher = {The Open Journal}, - volume = {1}, - number = {5}, - author = {Dirk Eddelbuettel and Wush Wu}, - title = {{RcppCNPy}: Read-Write Support for {NumPy} Files in R}, - journal = {The Journal of Open Source Software} -} - -@Article{JSS:RProtoBuf, - title = {{RProtoBuf}: Efficient Cross-Language Data Serialization in - {R}}, - author = {Dirk Eddelbuettel and Murray Stokely and Jeroen Ooms}, - journal = {Journal of Statistical Software}, - year = {2016}, - volume = {71}, - number = {2}, - pages = {1--24}, - doi = {10.18637/jss.v071.i02}, -} - -@Article{JSS:Rcpp, - title = {{Rcpp}: Seamless {R} and {C++} Integration}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - journal = {Journal of Statistical Software}, - year = 2011, - volume = 40, - number = 8, - pages = {1--18}, - url = {http://www.jstatsoft.org/v40/i08/}, -} - -@Article{JSS:RcppEigen, - title = {Fast and Elegant Numerical Linear Algebra Using the - {RcppEigen} Package}, - author = {Douglas Bates and Dirk Eddelbuettel}, - journal = {Journal of Statistical Software}, - year = {2013}, - volume = {52}, - number = {5}, - pages = {1--24}, - url = {http://www.jstatsoft.org/v52/i05/}, -} - -@Unpublished{Java+Gaile+Manly:2007:RCpp, - author = {James J. Java and Daniel P. Gaile and Kenneth - E. Manly}, - title = {{R/Cpp}: Interface Classes to Simplify Using {R} - Objects in {C++} Extensions}, - note = {Unpublished manuscript, University at Buffalo}, - url = - {http://sphhp.buffalo.edu/biostat/research/techreports/UB_Biostatistics_TR0702.pdf}, - month = {July}, - year = 2007 -} - -@misc{KDE-TechBase:2012, - author = {KDE-TechBase}, - title = {Binary Compatibility Issues With {C++}}, - url = "http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++", - year = 2012, - note = "[Online; accessed 24-November-2012]" -} - -@InProceedings{Leisch:2008:Tutorial, - author = {Friedrich Leisch}, - title = {Tutorial on {C}reating \proglang{R} {P}ackages}, - booktitle = {COMPSTAT 2008 -- Proceedings in Computational - Statistics}, - year = 2008, - editor = {Paula Brito}, - address = {Heidelberg}, - publisher = {Physica Verlag}, - url = CRAN # "doc/contrib/Leisch-CreatingPackages.pdf" -} - -@Manual{Liang:2008:rcppbind, - title = {rcppbind: {A} template library for R/C++ developers}, - author = {Gang Liang}, - year = 2008, - note = {R package version 1.0}, - url = R-Forge # "projects/rcppbind" -} - -@Book{Lippman+Lajoie+Moo:2005:Cpp_Primer, - author = {Stanley B. Lippman and Jos\'{e}e Lajoie and Barbara E. Moo}, - title = {The C++ Primer}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 2005, - edition = {4th} -} - -@Book{Matloff:2011:ArtOfR, - author = {Norman Matloff}, - title = {The Art of R Programming: A Tour of Statistical Software Design}, - publisher = {No Starch Press}, - address = {San Francisco, CA}, - year = 2011 -} - -@InProceedings{Maurer+Wong:2008:AttributesInC++, - author = {Jens Maurer and Michael Wong}, - title = {Towards support for attributes in {C++} (Revision - 6)}, - booktitle = {JTC1/SC22/WG21 - The C++ Standards Committee}, - year = {2008}, - url = - {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf}, - note = {{N2761=08-0271}} -} - -@book{Meyers:1995:MoreEffectiveC++, - author = {Scott Meyers}, - title = {More Effective C++: 35 New Ways to Improve Your - Programs and Designs}, - year = 1995, - note = {{ISBN} 020163371X}, - publisher = {Addison-Wesley}, - address = {Boston} -} - -@book{Meyers:2001:EffectiveSTL, - author = {Scott Meyers}, - title = {Effective STL: 50 specific ways to improve your use - of the standard template library}, - year = 2001, - note = {{ISBN} 0-201-74962-9}, - publisher = {Addison-Wesley}, - address = {Essex} -} - -@book{Meyers:2005:EffectiveC++, - author = {Scott Meyers}, - title = {Effective C++: 55 Specific Ways to Improve Your - Programs and Designs}, - year = 2005, - note = {{ISBN} 978-0321334879}, - publisher = {Addison-Wesley}, - address = {Boston}, - edition = {3rd}, -} - -@Article{PeerJ:Rcpp, - author = {Dirk Eddelbuettel and James Joseph Balamuta}, - title = {Extending R with C++: A Brief Introduction to Rcpp}, - journal = {PeerJ Preprints}, - volume = 5, - issue = {e3188v1}, - year = 2017, - month = {August}, - doi = {10.7287/peerj.preprints.3188v1/}, -} - -@Book{Plauger+Et+Al:2000:STL, - author = {P.J. Plauger and Alexander Stepanov and Meng Lee and - David R. Musser}, - title = {The {C++} Standard Template Library}, - publisher = {Prentice Hall PTR}, - year = 2000, - note = {{ISBN} 978-0134376332}, -} - -@manual{R:Administration, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R Installation and Administration", - annote = {{ISBN} 3-900051-09-7}, - url = manuals # "R-admin.html" -} - -@manual{R:Extensions, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "Writing R extensions", - annote = {{ISBN} 3-900051-11-9}, - url = manuals # "R-exts.html" -} - -@manual{R:Internals, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R internals", - annote = {{ISBN} 3-900051-14-3}, - url = manuals # "R-ints.html" -} - -@manual{R:Language, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R language", - annote = {{ISBN} 3-900051-13-5}, - url = manuals # "R-lang.html" -} - -@Manual{R:Main, - title = {R: A Language and Environment for Statistical - Computing}, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - url = {https://www.R-project.org/} -} - -@InProceedings{Runnalls:2009:CXXR, - author = {Andrew Runnalls}, - title = {Aspects of {CXXR} internals}, - booktitle = {Directions in Statistical Computing}, - address = {University of Copenhagen, Denmark}, - year = 2009 -} - -@Manual{Samperi:2009:RcppTemplate, - title = {RcppTemplate: Rcpp {R/C++} Object Mapping Library - and Package Template}, - author = {Dominick Samperi}, - year = 2009, - note = {(Archived) R package version 6.1}, - url = CRAN # "/src/contrib/Archive/RcppTemplate" -} - -@article{Sanderson+Curtin:2016, - doi = {10.21105/joss.00026}, - url = {http://dx.doi.org/10.21105/joss.00026}, - year = 2016, - month = {{June}}, - publisher = {The Open Journal}, - volume = 1, - number = 2, - author = {Conrad Sanderson and Ryan Curtin}, - title = {Armadillo: {A Template-Based C++ Library for Linear - Algebra}}, - journal = {{JOSS}} -} - -@TechReport{Sanderson:2010:Armadillo, - author = {Conrad Sanderson}, - title = {{Armadillo}: {An} open source {C++} Algebra Library - for Fast Prototyping and Computationally Intensive - Experiments }, - institution = {{NICTA}}, - year = 2010, - url = "http://arma.sf.net" -} - -@Book{Stroustrup:1997:Cpp, - author = {Bjarne Stroustrup}, - title = {The C++ Programming Language}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 1997, - edition = {3rd} -} - -@Book{Stroustrup:2013:Cpp, - author = {Bjarne Stroustrup}, - title = {The C++ Programming Language}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 2013, - pages = 1368, - edition = {4th} -} - -@Article{TAS:Rcpp, - author = {Dirk Eddelbuettel and James Joseph Balamuta}, - title = {Extending R with C++: A Brief Introduction to Rcpp}, - journal = {The American Statistician}, - volume = 72, - number = 1, - year = 2018, - month = {August}, - doi = {10.1080/00031305.2017.1375990} -} - -@Article{TempleLang:2009:ModestProposal, - author = {Duncan {Temple Lang}}, - title = {A modest proposal: an approach to making the - internal {R} system extensible}, - journal = {Computational Statistics}, - year = 2009, - volume = 24, - number = 2, - pages = {271-281}, - month = {May} -} - -@Article{TempleLang:2009:RGCCTranslationUnit, - author = {Duncan {Temple Lang}}, - title = {Working with meta-data from {C/C++} code in {R}: the - {RGCCTranslationUnit} package}, - journal = {Computational Statistics}, - year = 2009, - volume = 24, - number = 2, - pages = {283-293}, - month = {May} -} - -@InProceedings{Urbanek:2003:Rserve, - author = {Simon Urbanek}, - title = {{Rserve}: A Fast Way to Provide {R} Functionality to - Applications}, - booktitle = {Proceedings of the 3rd International Workshop on Distributed - Statistical Computing, Vienna, Austria}, - editor = {Kurt Hornik and Friedrich Leisch and Achim Zeileis}, - year = {2003}, - url = {http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/}, - note = {{ISSN 1609-395X}} -} - -@Book{Vandevoorde+Josuttis:2003:Templates, - author = {David Vandevoorde and Nicolai M. Josuttis}, - title = {{C++} {T}emplates: The Complete Guide}, - publisher = {Addison-Wesley}, - year = 2003, - address = {Boston} -} - -@inproceedings{Veldhuizen:1998:Blitz, - author = {Todd L. Veldhuizen}, - title = {Arrays in {Blitz++}}, - booktitle = {ISCOPE '98: Proceedings of the Second International - Symposium on Computing in Object-Oriented Parallel - Environments}, - note = {{ISBN} 3-540-65387-2}, - year = 1998, - pages = {223--230}, - publisher = {Springer-Verlag}, - address = {London}, -} - -@Book{Venables+Ripley:2000:SProgramming, - author = {Willian N. Venables and Brian D. Ripley}, - title = {S Programming}, - publisher = {Springer-Verlag}, - year = 2000, - series = {Statistics and Computing}, - address = {New York} -} - -@Book{Venables+Ripley:2002:MASS, - title = {Modern Applied Statistics with S}, - author = {W. N. Venables and B. D. Ripley}, - publisher = {Springer}, - edition = {Fourth}, - address = {New York}, - year = 2002, - note = {ISBN 0-387-95457-0}, - url = {http://www.stats.ox.ac.uk/pub/MASS4}, -} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-extending.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-extending.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-extending.R rcpp-1.0.3/inst/doc/Rcpp-extending.R --- rcpp-1.0.2/inst/doc/Rcpp-extending.R 2019-07-20 14:38:24.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-extending.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -## ------------------------------------------------------------------------ -# Run sourceCpp compilation to include file -# Rcpp::sourceCpp(file= "code.cpp") -input <- list( x = seq(1, 10, by = 0.5) ) -fx(input) - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-extending.Rmd rcpp-1.0.3/inst/doc/Rcpp-extending.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-extending.Rmd 2019-03-27 10:06:05.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-extending.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,383 +0,0 @@ ---- -title: \pkg{Rcpp} Extending - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note provides an overview of the steps programmers should follow to - extend \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp} for use with their own classes. This document - is based on our experience in extending \pkg{Rcpp} to work with the - \pkg{Armadillo} \citep{Sanderson:2010:Armadillo} classes, available in the separate package - \pkg{RcppArmadillo} \citep{CRAN:RcppArmadillo}. This document assumes - knowledge of \pkg{Rcpp} as well as some knowledge of \proglang{C++} - templates \citep{Abrahams+Gurtovoy:2004:TemplateMetaprogramming}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - extending - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-extending} - %\VignetteKeywords{Rcpp, extending, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Introduction - -\pkg{Rcpp} facilitates data interchange between \proglang{R} and -\proglang{C++} through the templated functions `Rcpp::as` (for -conversion of objects from \proglang{R} to \proglang{C++}) and -`Rcpp::wrap` (for conversion from \proglang{C++} to \proglang{R}). In -other words, we convert between the so-called \proglang{S}-expression -pointers (in type `SEXP`) to a templated \proglang{C++} type, and vice -versa. The corresponding function declarations are as follows: - -```{Rcpp, eval = FALSE} -// conversion from R to C++ -template T as(SEXP x); - -// conversion from C++ to R -template SEXP wrap(const T& object); -``` - -These converters are often used implicitly, as in the following code chunk: - -```{Rcpp} -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List fx(List input) { // we get a list from R -// pull std::vector from R list -// this is achieved through an implicit -// call to Rcpp::as -std::vector x = input["x"]; - -// return an R list; this is achieved -// through an implicit call to Rcpp::wrap -return List::create(_["front"] = x.front(), - _["back"] = x.back()); -} -``` - -Example: - -```{r} -# Run sourceCpp compilation to include file -# Rcpp::sourceCpp(file= "code.cpp") -input <- list( x = seq(1, 10, by = 0.5) ) -fx(input) -``` - -The \pkg{Rcpp} converter function `Rcpp::as` and `Rcpp::wrap` have been -designed to be extensible to user-defined types and third-party types. - -# Extending `Rcpp::wrap` - -The \pkg{Rcpp::wrap} converter is extensible in essentially two ways : intrusive -and non-intrusive. - -## Intrusive extension - -When extending \pkg{Rcpp} with your own data type, the recommended way is to -implement a conversion to `SEXP`. This lets `Rcpp::wrap` know -about the new data type. The template meta programming (or TMP) dispatch is able to -recognize that a type is convertible to a `SEXP` and -`Rcpp::wrap` will use that conversion. - -The caveat is that the type must be declared before the main header -file `Rcpp.h` is included. - -```{Rcpp, eval = FALSE} -#include - -class Foo { -public: - Foo(); - - // this operator enables implicit Rcpp::wrap - operator SEXP(); -} - -#include -``` - -This is called \emph{intrusive} because the conversion to `SEXP` -operator has to be declared within the class. - -## Non-intrusive extension - -It is often desirable to offer automatic conversion to third-party types, over -which the developer has no control and can therefore not include a conversion -to `SEXP` operator in the class definition. - -To provide automatic conversion from \proglang{C++} to \proglang{R}, one must -declare a specialization of the `Rcpp::wrap` template between the -includes of `RcppCommon.h` and `Rcpp.h`. - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares class Bar -#include - -// declaring the specialization -namespace Rcpp { - template <> SEXP wrap(const Bar&); -} - -// this must appear after the specialization, -// otherwise the specialization will not be -// seen by Rcpp types -#include -``` - -It should be noted that only the declaration is required. The implementation -can appear after the `Rcpp.h` file is included, and therefore take -full advantage of the \pkg{Rcpp} type system. - -Another non-intrusive option is to expose an external pointer. The macro -`RCPP_EXPOSED_WRAP` provides an easy way to expose a \proglang{C++} class -to \proglang{R} as an external pointer. It can be used instead of specializing -`Rcpp::wrap`, and should not be used simultaneously. Note that the -\proglang{C++} class has to use Rcpp modules. See the Rcpp modules vignette for -more details. - -```{Rcpp, eval = FALSE} -#include -#include - -RCPP_EXPOSED_WRAP(Bar) -``` - -## Templates and partial specialization - -It is perfectly valid to declare a partial specialization for the -`Rcpp::wrap` template. The compiler will identify the appropriate -overload: - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares -// a template class Bling -#include - -// declaring the partial specialization -namespace Rcpp { - namespace traits { - - template - SEXP wrap(const Bling&); - - } -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include - -``` - - -# Extending `Rcpp::as` - -Conversion from \proglang{R} to \proglang{C++} is also possible -in both intrusive and non-intrusive ways. - -## Intrusive extension - -As part of its template meta programming dispatch logic, `Rcpp::as` -will attempt to use the constructor of the target class taking a `SEXP`. - -```{Rcpp, eval = FALSE} -#include - -class Foo{ - public: - Foo(); - - // this ctor enables implicit Rcpp::as - Foo(SEXP); -} - - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -## Non-intrusive extension - -It is also possible to fully specialize `Rcpp::as` to enable -non-intrusive implicit conversion capabilities. - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares class Bar -#include - -// declaring the specialization -namespace Rcpp { - template <> Bar as(SEXP); -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -Furthermore, another non-intrusive option is to opt for sharing an R -external pointer. The macro `RCPP_EXPOSED_AS` provides an easy way to -extend `Rcpp::as` to expose \proglang{R} external pointers to -\proglang{C++}. It can be used instead of specializing `Rcpp::as`, and -should not be used simultaneously. Note that the \proglang{C++} class -has to use Rcpp modules. See the Rcpp modules vignette for more details. - -```{Rcpp, eval = FALSE} -#include -#include - -RCPP_EXPOSED_AS(Bar) -``` - -With this being said, there is one additional macro that can be used to -simultaneously define both `Rcpp::wrap` and `Rcpp::as` -specialization for an external pointer. The macro `RCPP_EXPOSED_CLASS` -can be use to transparently exchange a class between \proglang{R} and -\proglang{C++} as an external pointer. Do not simultaneously use it alongside -`RCPP_EXPOSED_AS`, `RCPP_EXPOSED_WRAP`, `Rcpp::wrap`, or -`Rcpp::as`. - - -## Templates and partial specialization - -The signature of `Rcpp::as` does not allow partial specialization. -When exposing a templated class to `Rcpp::as`, the programmer must -specialize the \pkg{Rcpp::traits::Exporter} template class. The TMP dispatch -will recognize that a specialization of `Exporter` is available -and delegate the conversion to this class. \pkg{Rcpp} defines -the `Rcpp::traits::Exporter` template class as follows : - -```{Rcpp, eval = FALSE} -namespace Rcpp { - namespace traits { - - template class Exporter{ - public: - Exporter(SEXP x) : t(x){} - inline T get() { return t; } - - private: - T t; - }; - } -} -``` - -This is the reason why the default behavior of `Rcpp::as` is to -invoke the constructor of the type `T` taking a `SEXP`. - -Since partial specialization of class templates is allowed, we can expose -a set of classes as follows: - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares -// a template class Bling -#include - -// declaring the partial specialization -namespace Rcpp { - namespace traits { - template - class Exporter< Bling >; - } -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -Using this approach, the requirements for the -`Exporter< Bling >` class are: - -- it should have a constructor taking a `SEXP` -- it should have a methods called `get` that returns an instance - of the `Bling` type. - -# Summary - -The \pkg{Rcpp} package greatly facilitates the transfer of objects between -\proglang{R} and \proglang{C++}. This note has shown how to extend \pkg{Rcpp} -to either user-defined or third-party classes via the `Rcpp::as` and -`Rcpp::wrap` template functions. Both intrusive and non-intrusive -approaches were discussed. diff -Nru rcpp-1.0.2/inst/doc/Rcpp-extending.Rnw rcpp-1.0.3/inst/doc/Rcpp-extending.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-extending.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-extending.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-extending} +%\VignetteKeywords{Rcpp, extending, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-extending.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-FAQ.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-FAQ.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-FAQ.R rcpp-1.0.3/inst/doc/Rcpp-FAQ.R --- rcpp-1.0.2/inst/doc/Rcpp-FAQ.R 2019-07-20 14:39:05.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-FAQ.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ -## ----setup, include=FALSE----------------------- -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -library(inline) -options("width"=50, digits=5) - -## ---- eval=FALSE-------------------------------- -# vignette("Rcpp-jss-2011") -# vignette("Rcpp-introduction") -# vignette("Rcpp-attributes") - -## ---- eval=FALSE-------------------------------- -# vignette("Rcpp-package") - -## ----------------------------------------------- -fx <- cxxfunction(signature(x = "numeric"), - 'NumericVector xx(x); - return wrap( - std::accumulate(xx.begin(), - xx.end(), - 0.0) - );', - plugin = "Rcpp") -res <- fx(seq(1, 10, by=0.5)) -res - -## ---- eval=FALSE-------------------------------- -# fx <- cxxfunction(signature(), -# paste(readLines("myfile.cpp"), -# collapse="\n"), -# plugin = "Rcpp") - -## ----------------------------------------------- -cppFunction('double accu(NumericVector x) { - return( - std::accumulate(x.begin(), x.end(), 0.0) - ); -}') -res <- accu(seq(1, 10, by=0.5)) -res - -## ----------------------------------------------- -inc <- 'template - class square : - public std::unary_function { - public: - T operator()( T t) const { - return t*t; - } - }; - ' - -src <- ' - double x = Rcpp::as(xs); - int i = Rcpp::as(is); - square sqdbl; - square sqint; - return Rcpp::DataFrame::create( - Rcpp::Named("x", sqdbl(x)), - Rcpp::Named("i", sqint(i))); - ' -fun <- cxxfunction(signature(xs="numeric", - is="integer"), - body=src, include=inc, - plugin="Rcpp") - -fun(2.2, 3L) - -## ---- eval = FALSE------------------------------ -# lines = '// copy the data to armadillo structures -# arma::colvec x = Rcpp::as (x_); -# arma::mat Y = Rcpp::as(Y_) ; -# arma::colvec z = Rcpp::as(z_) ; -# -# // calculate the result -# double result = arma::as_scalar( -# arma::trans(x) * arma::inv(Y) * z -# ); -# -# // return it to R -# return Rcpp::wrap( result );' -# -# writeLines(a, file = "myfile.cpp") - -## ---- eval = FALSE------------------------------ -# fx <- cxxfunction(signature(x_="numeric", -# Y_="matrix", -# z_="numeric" ), -# paste(readLines("myfile.cpp"), -# collapse="\n"), -# plugin="RcppArmadillo" ) -# fx(1:4, diag(4), 1:4) - -## ----------------------------------------------- -fx <- cxxfunction(signature(), - 'RNGScope(); - return rnorm(5, 0, 100);', - plugin="Rcpp") -set.seed(42) -fx() -fx() - -## ----------------------------------------------- -cppFunction('Rcpp::NumericVector ff(int n) { - return rnorm(n, 0, 100); }') -set.seed(42) -ff(5) -ff(5) -set.seed(42) -rnorm(5, 0, 100) -rnorm(5, 0, 100) - -## ----------------------------------------------- -src <- 'Rcpp::NumericVector v(4); - v[0] = R_NegInf; // -Inf - v[1] = NA_REAL; // NA - v[2] = R_PosInf; // Inf - v[3] = 42; // c.f. Hitchhiker Guide - return Rcpp::wrap(v);' -fun <- cxxfunction(signature(), src, plugin="Rcpp") -fun() - -## ---- eval = FALSE------------------------------ -# txt <- 'arma::mat Am = Rcpp::as< arma::mat >(A); -# arma::mat Bm = Rcpp::as< arma::mat >(B); -# return Rcpp::wrap( Am * Bm );' -# mmult <- cxxfunction(signature(A="numeric", -# B="numeric"), -# body=txt, -# plugin="RcppArmadillo") -# A <- matrix(1:9, 3, 3) -# B <- matrix(9:1, 3, 3) -# C <- mmult(A, B) -# C - -## ---- eval = FALSE------------------------------ -# # simple example of seeding RNG and -# # drawing one random number -# gslrng <- ' -# int seed = Rcpp::as(par) ; -# gsl_rng_env_setup(); -# gsl_rng *r = gsl_rng_alloc (gsl_rng_default); -# gsl_rng_set (r, (unsigned long) seed); -# double v = gsl_rng_get (r); -# gsl_rng_free(r); -# return Rcpp::wrap(v);' -# -# plug <- Rcpp::Rcpp.plugin.maker( -# include.before = "#include ", -# libs = paste( -# "-L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp", -# "-Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib", -# "-L/usr/lib -lgsl -lgslcblas -lm") -# ) -# registerPlugin("gslDemo", plug ) -# fun <- cxxfunction(signature(par="numeric"), -# gslrng, plugin="gslDemo") -# fun(0) - -## ---- eval=FALSE-------------------------------- -# myplugin <- getPlugin("Rcpp") -# myplugin$env$PKG_CXXFLAGS <- "-std=c++11" -# f <- cxxfunction(signature(), -# settings = myplugin, body = ' -# // fails without -std=c++0x -# std::vector x = { 1.0, 2.0, 3.0 }; -# return Rcpp::wrap(x); -# ') -# f() - -## ---- eval = FALSE------------------------------ -# src <- ' -# Rcpp::NumericMatrix x(2,2); -# x.fill(42); // or another value -# Rcpp::List dimnms = // list with 2 vecs -# Rcpp::List::create( // with static names -# Rcpp::CharacterVector::create("cc", "dd"), -# Rcpp::CharacterVector::create("ee", "ff") -# ); -# // and assign it -# x.attr("dimnames") = dimnms; -# return(x); -# ' -# fun <- cxxfunction(signature(), -# body=src, plugin="Rcpp") -# fun() - -## ---- eval = FALSE------------------------------ -# BigInts <- cxxfunction(signature(), -# 'std::vector bigints; -# bigints.push_back(12345678901234567LL); -# bigints.push_back(12345678901234568LL); -# Rprintf("Difference of %ld\\n", -# 12345678901234568LL - 12345678901234567LL); -# return wrap(bigints);', -# plugin="Rcpp", includes="#include ") -# -# retval <- BigInts() -# -# # Unique 64-bit integers were cast to identical -# # lower precision numerics behind my back with -# # no warnings or errors whatsoever. Error. -# -# stopifnot(length(unique(retval)) == 2) - -## ----------------------------------------------- -a <- 1.5:4.5 -b <- 1.5:4.5 -implicit_ref(a) -a -explicit_ref(b) -b - -## ----------------------------------------------- -a <- 1:5 -b <- 1:5 -class(a) -int_vec_type(a) -a # variable a changed as a side effect -num_vec_type(b) -b # b unchanged as copy was made for numeric - -## ----------------------------------------------- -x <- 1:10 # an integer sequence -# returning an altered value -const_override_ex(x) -# but the original value is altered too! -x - -## ----------------------------------------------- -vec_scalar_assign(5L, 3.14) - -## ----------------------------------------------- -mat_scalar_assign(2L, 3.0) - -## ----------------------------------------------- -test_long_vector_support() - -## ----------------------------------------------- -set.seed(123) -(X <- sample(c(LETTERS[1:5], letters[1:6]), 11)) -preferred_sort(X) -stl_sort(X) - -## ----------------------------------------------- -x <- c("B", "b", "c", "A", "a") -sort(x) -rcpp_sort(x) - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-FAQ.Rmd rcpp-1.0.3/inst/doc/Rcpp-FAQ.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-FAQ.Rmd 2018-09-21 16:24:39.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-FAQ.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,1722 +0,0 @@ ---- -title: \pkg{Rcpp} FAQ - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document attempts to answer the most Frequently Asked - Questions (FAQ) regarding the \pkg{Rcpp} - \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} package. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - FAQ - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - -vignette: > - %\VignetteIndexEntry{Rcpp-FAQ} - %\VignetteKeywords{Rcpp, FAQ, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -\tableofcontents - -```{r setup, include=FALSE} -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -library(inline) -options("width"=50, digits=5) -``` - -# Getting started - -## How do I get started - -If you have \pkg{Rcpp} installed, please execute the following command -in \proglang{R} to access the introductory vignette (which is a -variant of the \citet{JSS:Rcpp} and \citet{PeerJ:Rcpp,TAS:Rcpp} papers) for a -detailed introduction, ideally followed by at least the Rcpp -Attributes \citep{CRAN:Rcpp:Attributes} vignette: - -```{r, eval=FALSE} -vignette("Rcpp-jss-2011") -vignette("Rcpp-introduction") -vignette("Rcpp-attributes") -``` - -If you do not have \pkg{Rcpp} installed, these documents should also be available -whereever you found this document, \textsl{i.e.,} on every mirror site of CRAN. - -## What do I need - -Obviously, \proglang{R} must be installed. \pkg{Rcpp} provides a -\proglang{C++} API as an extension to the \proglang{R} system. As such, it -is bound by the choices made by \proglang{R} and is also influenced by how -\proglang{R} is configured. - -In general, the standard environment for building a CRAN package from source -(particularly when it contains \proglang{C} or \proglang{C++} code) is required. This -means one needs: - -- a development environment with a suitable compiler (see - below), header files and required libraries; -- \proglang{R} should be built in a way that permits linking and possibly - embedding of \proglang{R}; this is typically ensured by the - `--enable-shared-lib` option; -- standard development tools such as `make` etc. - -Also see the [RStudio documentation](http://www.rstudio.com/ide/docs/packages/prerequisites) -on pre-requisites for R package development. - -## What compiler can I use - -On almost all platforms, the GNU Compiler Collection (or `gcc`, which -is also the name of its \proglang{C} language compiler) has to be used along -with the corresponding `g++` compiler for the \proglang{C++} language. -A minimal suitable version is a final 4.2.* release; earlier 4.2.* were -lacking some \proglang{C++} features (and even 4.2.1, still used on OS X as the -last gcc release), has issues). - -Generally speaking, the default compilers on all the common platforms are suitable. - -Specific per-platform notes: - -\begin{description} - \item[Windows] users need the \texttt{Rtools} package from the site maintained by - Duncan Murdoch which contains all the required tools in a single package; - complete instructions specific to Windows are in the `R Administration' - manual \citep[Appendix D]{R:Administration}. As of August 2014, it still - installs the \texttt{gcc/g++} 4.6.* compiler which limits the ability to use - modern C++ standards so only \code{s-std=c++0x} is supported. R 3.1.0 and - above detect this and set appropriate flags. - \item[OS X] users, as noted in the `R Administration' manual \citep[Appendix - C.4]{R:Administration}, need to install the Apple Developer Tools - (\textsl{e.g.}, \href{https://itunes.apple.com/us/app/xcode/id497799835?mt=12}{Xcode} (OS X $\le 10.8$) or \href{https://developer.apple.com/library/ios/technotes/tn2339/_index.html}{Xcode Command Line Tools} (OS X $\ge 10.9$) (as well as \texttt{gfortran} if \proglang{R} or - Fortran-using packages are to be built); also see \faq{q:OSX} and - \faq{q:OSXArma} below. Depending on whether on OS X release before or after - Mavericks is used, different additional installation may be needed. Consult - the \code{r-sig-mac} list (and its archives) for (current) details. - \item[Linux] user need to install the standard developement packages. Some - distributions provide helper packages which pull in all the required - packages; the \texttt{r-base-dev} package on Debian and Ubuntu is an example. -\end{description} - -The `clang` and `clang++` compilers from the LLVM project can -also be used. On Linux, they are inter-operable with `gcc` et al. On -OS X, they are unfortunately not ABI compatible. The `clang++` -compiler is interesting as it emits much more comprehensible error messages -than `g++` (though `g++` 4.8 and 4.9 have caught up). - -The Intel `icc` family has also been used successfully as its output -files can also be combined with those from `gcc`. - -## What other packages are useful - -Additional packages that we have found useful are: - -\begin{description} -\item[\pkg{inline}] which is invaluable for direct compilation, linking and loading - of short code snippets---but now effectively superseded by the Rcpp - Attributes (see \faq{using-attributes} and - \faq{prototype-using-attributes}) feature provided by \pkg{Rcpp}; -\item[\pkg{RUnit}] is used for unit testing; the package is recommended and - will be needed to re-run some of our tests but it is not strictly required - during use of \pkg{Rcpp}; -\item[\pkg{rbenchmark}] to run simple timing comparisons and benchmarks; it is also - recommended but not required. -\item[\pkg{microbenchmark}] is an alternative for benchmarking. -\item[\pkg{devtools}] can help the process of building, compiling and testing - a package but it too is entirely optional. -\end{description} - -## What licenses can I choose for my code - -The \pkg{Rcpp} package is licensed under the terms of the -[GNU GPL 2 or later](http://www.gnu.org/licenses/gpl-2.0.html), just like -\proglang{R} itself. A key goal of the \pkg{Rcpp} package is to make -extending \proglang{R} more seamless. But by \textsl{linking} your code against -\proglang{R} (as well as \pkg{Rcpp}), the combination is bound by the GPL as -well. This is very clearly -stated at the -[FSF website](https://www.gnu.org/licenses/gpl-faq.html#GPLStaticVsDynamic): - -> Linking a GPL covered work statically or dynamically with other modules is -> making a combined work based on the GPL covered work. Thus, the terms and -> conditions of the GNU General Public License cover the whole combination. - -So you are free to license your work under whichever terms you find suitable -(provided they are GPL-compatible, see the -[FSF site for details](http://www.gnu.org/licenses/licenses.html)). However, -the combined work will remain under the terms and conditions of the GNU General -Public License. This restriction comes from both \proglang{R} which is GPL-licensed -as well as from \pkg{Rcpp} and whichever other GPL-licensed components you may -be linking against. - - -# Compiling and Linking - -## How do I use \pkg{Rcpp} in my package {#make-package} - -\pkg{Rcpp} has been specifically designed to be used by other packages. -Making a package that uses \pkg{Rcpp} depends on the same mechanics that are -involved in making any \proglang{R} package that use compiled code --- so -reading the \textsl{Writing R Extensions} manual \citep{R:Extensions} is a required -first step. - -Further steps, specific to \pkg{Rcpp}, are described in a separate vignette. - -```{r, eval=FALSE} -vignette("Rcpp-package") -``` - -## How do I quickly prototype my code - -There are two toolchains which can help with this: - -- The older one is provided by the \pkg{inline} package and described in - Section~\ref{using-inline}. -- Starting with \pkg{Rcpp} 0.10.0, the Rcpp Attributes feature (described - in Section~\ref{using-attributes}) offered an even easier alternative via - the function \rdoc{Rcpp}{evalCpp}, \rdoc{Rcpp}{cppFunction} and - \rdoc{Rcpp}{sourceCpp}. - -The next two subsections show an example each. - -### Using inline - -The \pkg{inline} package \citep{CRAN:inline} provides the functions -\rdoc{inline}{cfunction} and \rdoc{inline}{cxxfunction}. Below is a simple -function that uses `accumulate` from the (\proglang{C++}) Standard -Template Library to sum the elements of a numeric vector. - -```{r} -fx <- cxxfunction(signature(x = "numeric"), - 'NumericVector xx(x); - return wrap( - std::accumulate(xx.begin(), - xx.end(), - 0.0) - );', - plugin = "Rcpp") -res <- fx(seq(1, 10, by=0.5)) -res -``` - -One might want to use code that lives in a \proglang{C++} file instead of writing -the code in a character string in R. This is easily achieved by using -\rdoc{base}{readLines}: - -```{r, eval=FALSE} -fx <- cxxfunction(signature(), - paste(readLines("myfile.cpp"), - collapse="\n"), - plugin = "Rcpp") -``` - -The `verbose` argument of \rdoc{inline}{cxxfunction} is very -useful as it shows how \pkg{inline} runs the show. - -### Using Rcpp Attributes {#using-attributes} - -Rcpp Attributes \citep{CRAN:Rcpp:Attributes}, and also discussed in -\faq{prototype-using-attributes} below, permits an even easier -route to integrating R and C++. It provides three key functions. -First, \rdoc{Rcpp}{evalCpp} provide a means to evaluate simple C++ -expression which is often useful for small tests, or to simply check -if the toolchain is set up correctly. Second, \rdoc{Rcpp}{cppFunction} -can be used to create C++ functions for R use on the fly. Third, -`Rcpp::sourceCpp` can integrate entire files in order to define -multiple functions. - -The example above can now be rewritten as: - -```{r} -cppFunction('double accu(NumericVector x) { - return( - std::accumulate(x.begin(), x.end(), 0.0) - ); -}') -res <- accu(seq(1, 10, by=0.5)) -res -``` - -The \rdoc{Rcpp}{cppFunction} parses the supplied text, extracts the desired -function names, creates the required scaffolding, compiles, links and loads -the supplied code and makes it available under the selected identifier. - -Similarly, \rdoc{Rcpp}{sourceCpp} can read in a file and compile, link and load -the code therein. - -## How do I convert my prototyped code to a package {#from-inline-to-package} - -Since release 0.3.5 of \pkg{inline}, one can combine \faq{using-inline} and -\faq{make-package}. See `help("package.skeleton-methods")` once -\pkg{inline} is loaded and use the skeleton-generating functionality to -transform a prototyped function into the minimal structure of a package. -After that you can proceed with working on the package in the spirit of -\faq{make-package}. - -Rcpp Attributes \citep{CRAN:Rcpp:Attributes} also offers a means to convert -functions written using Rcpp Attributes into a function via the -\rdoc{Rdoc}{compileAttributes} function; see the vignette for details. - -## How do I quickly prototype my code in a package {#using-a-package} - -The simplest way may be to work directly with a package. Changes to both the -\proglang{R} and \proglang{C++} code can be compiled and tested from the -command line via: - -```{bash, eval = FALSE} -$ R CMD INSTALL mypkg && \ - Rscript --default-packages=mypkg -e \ - 'someFunctionToTickle(3.14)' -``` - -This first installs the packages, and then uses the command-line tool -\rdoc{utils}{Rscript} (which ships with `R`) to load the package, and execute -the \proglang{R} expression following the `-e` switch. Such an -expression can contain multiple statements separated by semicolons. -\rdoc{utils}{Rscript} is available on all three core operating systems. - -On Linux, one can also use `r` from the `littler` package by Horner -and Eddelbuettel which is an alternative front end to \proglang{R} designed -for both `#!` (hashbang) scripting and command-line use. It has slightly -faster start-up times than \rdoc{utils}{Rscript}; and both give a guaranteed clean -slate as a new session is created. - -The example then becomes - -```{bash, eval = FALSE} -$ R CMD INSTALL mypkg && \ - r -l mypkg -e 'someFunctionToTickle(3.14)' -``` - -The `-l` option calls 'suppressMessages(library(mypkg))' before executing the -\proglang{R} expression. Several packages can be listed, separated by a comma. - -More choice are provide by the \pkg{devtools} package, and by using -RStudio. See the respective documentation for details. - -## But I want to compile my code with R CMD SHLIB {#using-r-cmd-shlib} - -The recommended way is to create a package and follow \faq{make-package}. The -alternate recommendation is to use \pkg{inline} and follow \faq{using-inline} -because it takes care of all the details. - -However, some people have shown that they prefer not to follow recommended -guidelines and compile their code using the traditional `R CMD SHLIB`. To -do so, we need to help `SHLIB` and let it know about the header files -that \pkg{Rcpp} provides and the \proglang{C++} library the code must link -against. - -On the Linux command-line, you can do the following: - -```{bash, eval = FALSE} -$ # if Rcpp older than 0.11.0 -$ export PKG_LIBS=`Rscript -e "Rcpp:::LdFlags()"` -$ export PKG_CXXFLAGS=\ - `Rscript -e "Rcpp:::CxxFlags()"` -$ R CMD SHLIB myfile.cpp -``` - -which first defines and exports two relevant environment variables which -`R CMD SHLIB` then relies on. On other operating systems, appropriate -settings may have to be used to define the environment variables. - -This approach corresponds to the very earliest ways of building programs and -can still be found in some deprecated documents (as _e.g._ some of -Dirk's older 'Intro to HPC with R' tutorial slides). It is still not -recommended as there are tools and automation mechanisms that can do the work -for you. - -\pkg{Rcpp} versions 0.11.0 or later can do with the definition of -`PKG_LIBS` as a user-facing library is no longer needed (and hence no -longer shipped with the package). One still needs to set `PKG_CXXFLAGS` -to tell R where the \pkg{Rcpp} headers files are located. - -Once `R CMD SHLIB` has created the dyanmically-loadable file (with -extension `.so` on Linux, `.dylib` on OS X or `.dll` on -Windows), it can be loaded in an R session via \rdoc{base}{dyn.load}, and the -function can be executed via \rdoc{base}{.Call}. Needless to say, we -\emph{strongly} recommend using a package, or at least Rcpp Attributes as -either approach takes care of a lot of these tedious and error-prone manual -steps. - - -## But R CMD SHLIB still does not work - -We have had reports in the past where build failures occurred when users had -non-standard code in their `~/.Rprofile` or `Rprofile.site` (or -equivalent) files. - -If such code emits text on `stdout`, the frequent and implicit -invocation of `Rscript -e "..."` (as in \faq{using-r-cmd-shlib} -above) to retrieve settings directly from \pkg{Rcpp} will fail. - -You may need to uncomment such non-standard code, or protect it by wrapping -it inside `if (interactive())`, or possibly try to use -`Rscript --vanilla` instead of plain `Rscript`. - -## What about `LinkingTo ` - -\proglang{R} has only limited support for cross-package linkage. - -We now employ the `LinkingTo` field of the `DESCRIPTION` file -of packages using \pkg{Rcpp}. But this only helps in having \proglang{R} -compute the location of the header files for us. - -The actual library location and argument still needs to be provided by the -user. How to do so has been shown above, and we recommned you use either -\faq{make-package} or \faq{using-inline} both which use the \pkg{Rcpp} -function `Rcpp:::LdFlags()`. - -If and when `LinkingTo` changes and lives up to its name, we will be -sure to adapt \pkg{Rcpp} as well. - -An important change arrive with \pkg{Rcpp} release 0.11.0 and concern the -automatic registration of functions; see Section~\ref{function-registration} below. - - -## Does \pkg{Rcpp} work on windows - -Yes of course. See the Windows binaries provided by CRAN. - -## Can I use \pkg{Rcpp} with Visual Studio - -Not a chance. - -And that is not because we are meanies but because \proglang{R} and Visual -Studio simply do not get along. As \pkg{Rcpp} is all about extending -\proglang{R} with \proglang{C++} interfaces, we are bound by the available -toolchain. And \proglang{R} simply does not compile with Visual Studio. Go -complain to its vendor if you are still upset. - -## I am having problems building Rcpp on macOS, any help {#q:OSX} - -There are three known issues regarding Rcpp build problems on macOS. If you are -building packages with RcppArmadillo, there is yet another issue that is -addressed separately in \faq{q:OSXArma} below. - -### Lack of a Compiler - -By default, macOS does not ship with an active compiler. Depending on the -\proglang{R} version being used, there are different development environment -setup procedures. For the current \proglang{R} version, we recommend observing -the official procedure used in -[Section 6.3.2 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS-packages) -and [Section C.3 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) -of the [R Installation and Administration](https://cran.r-project.org/doc/manuals/r-release/R-admin.html) -manual. - -### Differing macOS R Versions Leading to Binary Failures - -There are currently _three_ distinct versions of R for macOS. -The first version is a legacy version meant for macOS 10.6 (Snow Leopard) - -10.8 (Mountain Lion). The second version is for more recent system -macOS 10.9 (Mavericks) and 10.10 (Yosemite). Finally, the third and most -up-to-date version supports macOS 10.11 (El Capitan), 10.12 (Sierra), and 10.13 (High Sierra). -The distinction comes as a result of a change in the compilers shipped with the -operating system as highlighted previously. As a result, avoid sending -\textbf{package binaries} to collaborators if they are working on older -operating systems as the \proglang{R} binaries for these versions will not be -able to mix. In such cases, it is better to provide collaborators with the -\textbf{package source} and allow them to build the package locally. - -### OpenMP Support - -By default, the macOS operating environment lacks the ability to parallelize -sections of code using the \proglang{[OpenMP](http://openmp.org/wp/)} -standard. Within \proglang{R} 3.4.*, the default developer environment was -_changed_ to allow for \proglang{OpenMP} to be used on macOS by using -a non-default toolchain provided by R Core Team maintainers for macOS. -Having said this, it is still important to protect any reference to -\proglang{OpenMP} as some users may not yet have the ability to -use \proglang{OpenMP}. - -To setup the appropriate protection for using \proglang{OpenMP}, the process -is two-fold. First, protect the inclusion of headers with: - -```cpp -#ifdef _OPENMP - #include -#endif -``` - -Second, when parallelizing portions of code use: - -```cpp -#ifdef _OPENMP - // multithreaded OpenMP version of code -#else - // single-threaded version of code -#endif -``` - -Under this approach, the code will be _safely_ parallelized when -support exists for \proglang{OpenMP} on Windows, macOS, and Linux. - -### Additional Information and Help - -Below are additional resources that provide information regarding compiling Rcpp code on macOS. - -1. A helpful post was provided by Brian Ripley regarding the use of - compiling R code with macOS in April 2014 - [on the `r-sig-mac` list](https://stat.ethz.ch/pipermail/r-sig-mac/2014-April/010835.html), - which is generally recommended for OS X-specific questions and further consultation. -2. Another helpful write-up for installation / compilation on OS X Mavericks is provided - [by the BioConductor project](http://www.bioconductor.org/developers/how-to/mavericks-howto/). -3. Lastly, another resource that exists for installation / compilation - help is provided at - . - -\textbf{Note:} If you are running into trouble compiling code with \pkg{RcppArmadillo}, please also see \faq{q:OSXArma} listed below. - - - -## Does \pkg{Rcpp} work on solaris/suncc - -Yes, it generally does. But as we do not have access to such systems, some -issues persist on the CRAN test systems. - -## Does \pkg{Rcpp} work with Revolution R - -We have not tested it yet. \pkg{Rcpp} might need a few tweaks to work -with the compilers used by Revolution R (if those differ from the defaults). - -## Is it related to Rho (formerly CXXR) - -Rho, previously known as CXXR, is an ambitious project that aims to -totally refactor the \proglang{R} interpreter in \proglang{C++}. There -are a few similaritites with \pkg{Rcpp} but the projects are -unrelated. - -Rho / CXXR and \pkg{Rcpp} both want \proglang{R} to make more use of \proglang{C++} -but they do it in very different ways. - -## How do I quickly prototype my code using Attributes {#prototype-using-attributes} - -\pkg{Rcpp} version 0.10.0 and later offer a new feature 'Rcpp Attributes' -which is described in detail in its own vignette -\citep{CRAN:Rcpp:Attributes}. In short, it offers functions \rdoc{Rcpp}{evalCpp}, -\rdoc{Rcpp}{cppFunction} and \rdoc{Rcpp}{sourceCpp} which extend the functionality of the -\rdoc{Rcpp}{cxxfunction} function. - - -## What about the new 'no-linking' feature {#function-registration} - -Starting with \pkg{Rcpp} 0.11.0, functionality provided by \pkg{Rcpp} and -used by packages built with \pkg{Rcpp} accessed via the registration facility -offered by R (and which is used by \pkg{lme4} and \pkg{Matrix}, as well as by -\pkg{xts} and \pkg{zoo}). This requires no effort from the user / -programmer, and even frees us from explicit linking instruction. In most -cases, the files `src/Makevars` and `src/Makevars.win` can now be -removed. Exceptions are the use of \pkg{RcppArmadillo} (which needs an entry -`PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)`) and packages linking -to external libraries they use. - -But for most packages using \pkg{Rcpp}, only two things are required: - -- an entry in `DESCRIPTION` such as `Imports: Rcpp` (which may - be versioned as in `Imports: Rcpp (>= 0.11.0)`), and -- an entry in `NAMESPACE` to ensure \pkg{Rcpp} is correctly - instantiated, for example `importFrom(Rcpp, evalCpp)`. - -The name of the symbol does not really matter; once one symbol is imported all -symbols should be available. - -## I am having problems building RcppArmadillo on macOS, any help {#q:OSXArma} - -Odds are your build failures are due to the absence of `gfortran` -and its associated libraries. The errors that you may receive are related to either -`-lgfortran` or `-lquadmath`. - -To rectify the root of these errors, there are two options available. The first -option is to download and use a fixed set of `gfortran` binaries that are -used to compile R for macOS (e.g. given by the maintainers of the macOS build). -The second option is to either use pre-existing `gfortran` binaries on -your machine or download the latest. These options are described in-depth -in [Section C.3 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) -of the [R Installation and Administration](https://cran.r-project.org/doc/manuals/r-release/R-admin.html) -manual. Please consult this manual for up-to-date information regarding `gfortran` -binaries on macOS. We have also documented _other_ common macOS compile -issues in Section \faq{q:OSX}. - -# Examples - -The following questions were asked on the -[Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list, which is our preferred place to ask questions as it guarantees -exposure to a number of advanced Rcpp users. The -[StackOverflow tag for rcpp](http://stackoverflow.com/questions/tagged/rcpp) -is an alternative; that site is also easily searchable. - -Several dozen fully documented examples are provided at the -[Rcpp Gallery](http://gallery.rcpp.org) -- which is also open for new contributions. - - -## Can I use templates with \pkg{Rcpp} - -> I'm curious whether one can provide a class definition inline in an R -> script and then initialize an instance of the class and call a method on -> the class, all inline in R. - -This question was initially about using templates with \pkg{inline}, and we -show that (older) answer first. It is also easy with Rcpp Attributes which is -what we show below. - - -### Using inline with Templated Code -Most certainly, consider this simple example of a templated class -which squares its argument: - -```{r} -inc <- 'template - class square : - public std::unary_function { - public: - T operator()( T t) const { - return t*t; - } - }; - ' - -src <- ' - double x = Rcpp::as(xs); - int i = Rcpp::as(is); - square sqdbl; - square sqint; - return Rcpp::DataFrame::create( - Rcpp::Named("x", sqdbl(x)), - Rcpp::Named("i", sqint(i))); - ' -fun <- cxxfunction(signature(xs="numeric", - is="integer"), - body=src, include=inc, - plugin="Rcpp") - -fun(2.2, 3L) -``` - -### Using Rcpp Attributes with Templated Code - -We can also use 'Rcpp Attributes' \citep{CRAN:Rcpp:Attributes}---as described -in \faq{using-attributes} and \faq{prototype-using-attributes} above. Simply -place the following code into a file and use \rdoc{Rcpp}{sourceCpp} on it. It -will even run the R part at the end. - -```cpp -#include - -template class square : - public std::unary_function { - public: - T operator()( T t) const { - return t*t ; - } -}; - -// [[Rcpp::export]] -Rcpp::DataFrame fun(double x, int i) { - square sqdbl; - square sqint; - return Rcpp::DataFrame::create( - Rcpp::Named("x", sqdbl(x)), - Rcpp::Named("i", sqint(i))); -} - -/*** R -fun(2.2, 3L) -*/ -``` - -## Can I do matrix algebra with Rcpp {#matrix-algebra} - - -> \pkg{Rcpp} allows element-wise operations on vector and matrices through -> operator overloading and STL interface, but what if I want to multiply a -> matrix by a vector, etc ... - -\noindent Currently, \pkg{Rcpp} does not provide binary operators to allow operations -involving entire objects. Adding operators to \pkg{Rcpp} would be a major -project (if done right) involving advanced techniques such as expression -templates. We currently do not plan to go in this direction, but we would -welcome external help. Please send us a design document. - -However, we have developed the \pkg{RcppArmadillo} package -\citep{CRAN:RcppArmadillo,Eddelbuettel+Sanderson:2014:RcppArmadillo} that -provides a bridge between \pkg{Rcpp} and \pkg{Armadillo} -\citep{Sanderson:2010:Armadillo}. \pkg{Armadillo} -supports binary operators on its types in a way that takes full advantage of -expression templates to remove temporaries and allow chaining of -operations. That is a mouthful of words meaning that it makes the code go -faster by using fiendishly clever ways available via the so-called template -meta programming, an advanced \proglang{C++} technique. -Also, the \pkg{RcppEigen} package \citep{JSS:RcppEigen} provides an alternative using the -[Eigen](http://eigen.tuxfamily.org) template library. - -### Using inline with RcppArmadillo {#using-inline-armadillo} - -The following example is adapted from the examples available at the project -page of Armadillo. It calculates $x' \times Y^{-1} \times z$ - -```{r, eval = FALSE} -lines = '// copy the data to armadillo structures -arma::colvec x = Rcpp::as (x_); -arma::mat Y = Rcpp::as(Y_) ; -arma::colvec z = Rcpp::as(z_) ; - -// calculate the result -double result = arma::as_scalar( - arma::trans(x) * arma::inv(Y) * z - ); - -// return it to R -return Rcpp::wrap( result );' - -writeLines(a, file = "myfile.cpp") -``` - -If stored in a file `myfile.cpp`, we can use it via \pkg{inline}: - -```{r, eval = FALSE} -fx <- cxxfunction(signature(x_="numeric", - Y_="matrix", - z_="numeric" ), - paste(readLines("myfile.cpp"), - collapse="\n"), - plugin="RcppArmadillo" ) -fx(1:4, diag(4), 1:4) -``` - -The focus is on the code `arma::trans(x) * arma::inv(Y) * z`, which -performs the same operation as the R code `t(x) %*% solve(Y) %*% z`, -although Armadillo turns it into only one operation, which makes it quite fast. -Armadillo benchmarks against other \proglang{C++} matrix algebra libraries -are provided on [the Armadillo website](http://arma.sourceforge.net/speed.html). - -It should be noted that code below depends on the version `0.3.5` of -\pkg{inline} and the version `0.2.2` of \pkg{RcppArmadillo}. - -### Using Rcpp Attributes with RcppArmadillo - -We can also write the same example for use with Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::depends(RcppArmadillo)]] - -// [[Rcpp::export]] -double fx(arma::colvec x, arma::mat Y, - arma::colvec z) { - // calculate the result - double result = arma::as_scalar( - arma::trans(x) * arma::inv(Y) * z - ); - return result; -} - -/*** R -fx(1:4, diag(4), 1:4) -*/ -``` - -Here, the additional `Rcpp::depends(RcppArmadillo)` ensures that code -can be compiled against the \pkg{RcppArmadillo} header, and that the correct -libraries are linked to the function built from the supplied code example. - -Note how we do not have to concern ourselves with conversion; R object -automatically become (Rcpp)Armadillo objects and we can focus on the single -computing a (scalar) result. - -## Can I use code from the Rmath header and library with \pkg{Rcpp} - -> Can I call functions defined in the Rmath header file and the -> standalone math library for R--as for example the random number generators? - -\noindent Yes, of course. This math library exports a subset of R, but \pkg{Rcpp} has -access to much more. Here is another simple example. Note how we have to use -and instance of the `RNGScope` class to set and re-set the -random-number generator. This also illustrates Rcpp sugar as we are using a -vectorised call to `rnorm`. Moreover, because the RNG is reset, the -two calls result in the same random draws. If we wanted to control the draws, -we could explicitly set the seed after the `RNGScope` object has been -instantiated. - -```{r} -fx <- cxxfunction(signature(), - 'RNGScope(); - return rnorm(5, 0, 100);', - plugin="Rcpp") -set.seed(42) -fx() -fx() -``` - -Newer versions of Rcpp also provide the actual Rmath function in the `R` -namespace, \textsl{i.e.} as `R::rnorm(m,s)` to obtain a scalar -random variable distributed as $N(m,s)$. - -Using Rcpp Attributes, this can be as simple as - -```{r} -cppFunction('Rcpp::NumericVector ff(int n) { - return rnorm(n, 0, 100); }') -set.seed(42) -ff(5) -ff(5) -set.seed(42) -rnorm(5, 0, 100) -rnorm(5, 0, 100) -``` - -This illustrates the Rcpp Attributes adds the required `RNGScope` object -for us. It also shows how setting the seed from R affects draws done via C++ -as well as R, and that identical random number draws are obtained. - -## Can I use `NA` and `Inf` with \pkg{Rcpp} - -> R knows about `NA` and `Inf`. How do I use them from C++? - -\noindent Yes, see the following example: - -```{r} -src <- 'Rcpp::NumericVector v(4); - v[0] = R_NegInf; // -Inf - v[1] = NA_REAL; // NA - v[2] = R_PosInf; // Inf - v[3] = 42; // c.f. Hitchhiker Guide - return Rcpp::wrap(v);' -fun <- cxxfunction(signature(), src, plugin="Rcpp") -fun() -``` - -Similarly, for Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::export]] -Rcpp::NumericVector fun(void) { - Rcpp::NumericVector v(4); - v[0] = R_NegInf; // -Inf - v[1] = NA_REAL; // NA - v[2] = R_PosInf; // Inf - v[3] = 42; // c.f. Hitchhiker Guide - return v; -} -``` - -## Can I easily multiply matrices - -> Can I multiply matrices easily? - -\noindent Yes, via the \pkg{RcppArmadillo} package which builds upon \pkg{Rcpp} and the -wonderful Armadillo library described above in \faq{matrix-algebra}: - -```{r, eval = FALSE} -txt <- 'arma::mat Am = Rcpp::as< arma::mat >(A); - arma::mat Bm = Rcpp::as< arma::mat >(B); - return Rcpp::wrap( Am * Bm );' -mmult <- cxxfunction(signature(A="numeric", - B="numeric"), - body=txt, - plugin="RcppArmadillo") -A <- matrix(1:9, 3, 3) -B <- matrix(9:1, 3, 3) -C <- mmult(A, B) -C -``` - -Armadillo supports a full range of common linear algebra operations. - -The \pkg{RcppEigen} package provides an alternative using the -[Eigen](http://eigen.tuxfamily.org) template library. - -Rcpp Attributes, once again, makes this even easier: - -```cpp - -#include - -// [[Rcpp::depends(RcppArmadillo)]] - -// [[Rcpp::export]] -arma::mat mult(arma::mat A, arma::mat B) { - return A*B; -} - -/*** R -A <- matrix(1:9, 3, 3) -B <- matrix(9:1, 3, 3) -mult(A,B) -*/ -``` - -which can be built, and run, from R via a simple \rdoc{Rcpp}{sourceCpp} -call---and will also run the small R example at the end. - -## How do I write a plugin for \pkg{inline} and/or Rcpp Attributes - -> How can I create my own plugin for use by the \pkg{inline} package? - -Here is an example which shows how to it using GSL libraries as an -example. This is merely for demonstration, it is also not perfectly general -as we do not detect locations first---but it serves as an example: - -```{r, eval = FALSE} -# simple example of seeding RNG and -# drawing one random number -gslrng <- ' -int seed = Rcpp::as(par) ; -gsl_rng_env_setup(); -gsl_rng *r = gsl_rng_alloc (gsl_rng_default); -gsl_rng_set (r, (unsigned long) seed); -double v = gsl_rng_get (r); -gsl_rng_free(r); -return Rcpp::wrap(v);' - -plug <- Rcpp::Rcpp.plugin.maker( - include.before = "#include ", - libs = paste( -"-L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp", -"-Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib", -"-L/usr/lib -lgsl -lgslcblas -lm") -) -registerPlugin("gslDemo", plug ) -fun <- cxxfunction(signature(par="numeric"), - gslrng, plugin="gslDemo") -fun(0) -``` - -Here the \pkg{Rcpp} function `Rcpp.plugin.maker` is used to create a -plugin 'plug' which is then registered, and subsequently used by \pkg{inline}. - -The same plugins can be used by Rcpp Attributes as well. - -## How can I pass one additional flag to the compiler - -> How can I pass another flag to the `g++` compiler without writing a new plugin? - -The quickest way is to modify the return value from an existing plugin. Here -we use the default one from \pkg{Rcpp} itself in order to pass the new flag -`-std=c++0x`. As it does not set the `PKG_CXXFLAGS` variable, we -simply assign this. For other plugins, one may need to append to the existing -values instead. - -```{r, eval=FALSE} -myplugin <- getPlugin("Rcpp") -myplugin$env$PKG_CXXFLAGS <- "-std=c++11" -f <- cxxfunction(signature(), - settings = myplugin, body = ' - // fails without -std=c++0x - std::vector x = { 1.0, 2.0, 3.0 }; - return Rcpp::wrap(x); -') -f() -``` - -For Rcpp Attributes, the attributes `Rcpp::plugin()` can be -used. Currently supported plugins are for C++11 as well as for OpenMP. - -## How can I set matrix row and column names - -> Ok, I can create a matrix, but how do I set its row and columns names? - -Pretty much the same way as in \proglang{R} itself: We define a list with two -character vectors, one each for row and column names, and assign this to the -`dimnames` attribute: - -```{r, eval = FALSE} -src <- ' - Rcpp::NumericMatrix x(2,2); - x.fill(42); // or another value - Rcpp::List dimnms = // list with 2 vecs - Rcpp::List::create( // with static names - Rcpp::CharacterVector::create("cc", "dd"), - Rcpp::CharacterVector::create("ee", "ff") - ); - // and assign it - x.attr("dimnames") = dimnms; - return(x); -' -fun <- cxxfunction(signature(), - body=src, plugin="Rcpp") -fun() -``` - -The same logic, but used with Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::export]] -Rcpp::List fun(void) { - Rcpp::NumericMatrix x(2,2); - x.fill(42); // or another value - Rcpp::List dimnms = // list with 2 vecs - Rcpp::List::create( // with static names - Rcpp::CharacterVector::create("cc", "dd"), - Rcpp::CharacterVector::create("ee", "ff")); - // and assign it - x.attr("dimnames") = dimnms; - return(x); -} -``` - -## Why can long long types not be cast correctly - -That is a good and open question. We rely on the basic \proglang{R} types, -notably `integer` and `numeric`. These can be cast to and from -\proglang{C++} types without problems. But there are corner cases. The -following example, contributed by a user, shows that we cannot reliably cast -`long` types (on a 64-bit machines). - -```{r, eval = FALSE} -BigInts <- cxxfunction(signature(), - 'std::vector bigints; - bigints.push_back(12345678901234567LL); - bigints.push_back(12345678901234568LL); - Rprintf("Difference of %ld\\n", - 12345678901234568LL - 12345678901234567LL); - return wrap(bigints);', - plugin="Rcpp", includes="#include ") - -retval <- BigInts() - -# Unique 64-bit integers were cast to identical -# lower precision numerics behind my back with -# no warnings or errors whatsoever. Error. - -stopifnot(length(unique(retval)) == 2) -``` - -While the difference of one is evident at the \proglang{C++} level, it is no -longer present once cast to \proglang{R}. The 64-bit integer values get cast -to a floating point types with a 53-bit mantissa. We do not have a good -suggestion or fix for casting 64-bit integer values: 32-bit integer values -fit into `integer` types, up to 53 bit precision fits into -`numeric` and beyond that truly large integers may have to converted -(rather crudely) to text and re-parsed. Using a different representation as -for example from the [GNU Multiple Precision Arithmetic Library](http://gmplib.org/) -may be an alternative. - -## What LaTeX packages do I need to typeset the vignettes - -> I would like to typeset the vignettes. What do I need? - -The [TeXLive](https://www.tug.org/texlive/) distribution seems to get -bigger and bigger. What you need to install may depend on your operating -system. - -Specific per-platform notes: - -- **Windows** users probably want the [MiKTeX](http://miktex.org/). - Suggestions for a more detailed walk through would be appreciated. -- **OS X** users seem to fall into camps which like or do not like brew / - homebrew. One suggestion was to install - [MacTeX](https://tug.org/mactex/mactex-download.html) but at - approximately 2.5gb (as of January 2016) this is not lightweight. -- **Linux** users probably want the full - [TeXLive](https://www.tug.org/texlive/) set from their distribution. On - [Debian](http://www.debian.org) these packages are installed to build - the R package itself: `texlive-base, texlive-latex-base, - texlive-generic-recommended, texlive-fonts-recommended, - texlive-fonts-extra, texlive-extra-utils, texlive-latex-recommended, - texlive-latex-extra`. Using `texlive-full` may be a shortcut. - Fedora and other distributions should have similar packages. - -## Why is there a limit of 20 on some constructors - -> Ok, I would like to pass $N$ object but you only allow 20. How come? - -In essence, and in order to be able to compile it with the largest number of -compilers, \pkg{Rcpp} is constrained by the older C++ standards which do not -support variadic function arguments. So we actually use macros and code -generator scripts to explicitly enumerate arguments, and that number has to stop -at some limit. We chose 20. - -A good discussion is available at -[this StackOverflow question](http://stackoverflow.com/questions/27371543) -concering data.frame creation with \pkg{Rcpp}. One solution offers a custom -`ListBuilder` class to circumvent the limit; another suggests to simply -nest lists. - -## Can I use default function parameters with \pkg{Rcpp} - -Yes, you can use default parameters with _some_ limitations. -The limitations are mainly related to string literals and empty vectors. -This is what is currently supported: - -- String literals delimited by quotes (e.g. `"foo"`) -- Integer and Decimal numeric values (e.g. `10` or `4.5`) -- Pre-defined constants including: - - Booleans: `true` and `false` - - Null Values: `R_NilValue`, `NA_STRING`, `NA_INTEGER`, `NA_REAL`, and `NA_LOGICAL`. -- Selected vector types can be instantiated using the empty form of the - `::create` static member function. - - `CharacterVector`, `IntegerVector`, and `NumericVector` -- Matrix types instantiated using the rows, cols constructor - `Rcpp::Matrix n(rows,cols)` - - `CharacterMatrix`, `IntegerMatrix`, and `NumericMatrix` - -To illustrate, please consider the following example that provides a short -how-to: - -```cpp -#include - -// [[Rcpp::export]] -void sample_defaults( - NumericVector x = - NumericVector::create(), // Size 0 vector - bool bias = true, // Set to true - std::string method = - "rcpp rules!") { // Set string - - Rcpp::Rcout << "x size: " << x.size() << ", "; - Rcpp::Rcout << "bias value: " << bias << ", "; - Rcpp::Rcout << "method value: " << "."; - -} - -/*** R -sample_defaults() # all defaults -sample_defaults(1:5) # supply x values - -sample_defaults(bias = FALSE, # supply bool - method = "Rlang") # and string -*/ -``` - -Note: In `cpp`, the default `bool` values are `true` and -`false` whereas in R the valid types are `TRUE` or `FALSE`. - -## Can I use C++11, C++14, C++17, ... with \pkg{Rcpp} - -But of course. In a nutshell, this boils down to \emph{what your compiler - supports}, and also \emph{what R supports}. We expanded a little on this in -[Rcpp Gallery article](http://gallery.rcpp.org/articles/rcpp-and-c++11-c++14-c++17/) providing more detail. What follows in an abridged summary. - -You can always \emph{locally} set appropriate `PKG_CXXFLAGS` as an -environment variable, or via `~/.R/Makevars`. You can also plugins and/or R -support from `src/Makevars`: - -- _C++11_: has been supported since early 2013 via a plugin selecting - the language standard which is useful for `sourceCpp()` etc. For - packages, R has supported it since R 3.1.0 which added the option to select - the language standard via `CXX_STD = CXX11`. As of early 2017, over 120 - packages on CRAN use this. -- _C++14_: has been supported since early 2016 via a plugin selecting - the language standard which is useful for `sourceCpp()` etc. For - packages, R supports it since R 3.4.0 adding the option to select the language - standard via `CXX_STD = CXX14`. -- _C++17_: is itself more experimental now, but if you have a compiler - supporting (at least parts of) it, you can use it via plugin (starting with - Rcpp 0.12.10) for use via `sourceCpp()`, or via `PKG_CXXFLAGS` or - other means to set compiler options. R support may be available at a later - date. - -## How do I use it within (Python's) Conda setup? - -In a comment to [issue ticket #770](https://github.com/RcppCore/Rcpp/issues/770#issuecomment-346716808) it is stated that running - -```sh -conda install gxx_linux-64 -``` - -helps within this environment as it installs the corresponding -`x86_64-conda_cos6-linux-gnu-c++` compiler. Documentation for this and other -systems is provided -[at this page](https://conda.io/docs/user-guide/tasks/build-packages/compiler-tools.html). - -# Support - -## Is the API documented - -You bet. We use \proglang{doxygen} to generate html, latex and man page -documentation from the source. The html documentation is available for -[browsing](http://dirk.eddelbuettel.com/code/rcpp/html/index.html), as a -[very large pdf file](http://dirk.eddelbuettel.com/code/rcpp/Rcpp_refman.pdf), -and all three formats are also available a zip-archives: -[html](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-html.zip), -[latex](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-latex.zip), and -[man](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-man.zip). - -## Does it really work - -We take quality seriously and have developped an extensive unit test suite to -cover many possible uses of the \pkg{Rcpp} API. - -We are always on the look for more coverage in our testing. Please let us know -if something has not been tested enough. - -## Where can I ask further questions - -The -[Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list hosted at R-forge is by far the best place. You may also want -to look at the list archives to see if your question has been asked before. - -You can also use [StackOverflow via its 'rcpp' tag](http://stackoverflow.com/questions/tagged/rcpp). - -## Where can I read old questions and answers - -The normal [Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list hosting at R-forge contains an archive, which can be -[searched via swish](http://lists.r-forge.r-project.org/mailman/swish.cgi?query=listname=rcpp-devel). - -Alternatively, one can also use -[Mail-Archive on Rcpp-devel](http://www.mail-archive.com/rcpp-devel@lists.r-forge.r-project.org/info.html) -which offers web-based interfaces, including searching. - -## I like it. How can I help {#helping} - -We maintain a list of -[open issues in the Github repository](https://github.com/RcppCore/Rcpp/issues?state=open). -We welcome pull requests and suggest that code submissions -come corresponding unit tests and, if applicable, documentation. - -If you are willing to donate time and have skills in C++, let us know. If you are -willing to donate money to sponsor improvements, let us know too. - -You can also spread the word about \pkg{Rcpp}. There are many packages on CRAN -that use \proglang{C++}, yet are not using \pkg{Rcpp}. You could blog about -it, or get the word out otherwise. - -Last but not least the [Rcpp Gallery](http://gallery.rcpp.org) is open -for user contributions. - -## I don't like it. How can I help {#dont-like-help} - -It is very generous of you to still want to help. Perhaps you can tell us -what it is that you dislike. We are very open to \emph{constructive} criticism. - -## Can I have commercial support for \pkg{Rcpp} - -Sure you can. Just send us an email, and we will be happy to discuss the -request. - -## I want to learn quickly. Do you provide training courses - -Yes. Just send us an email. - -## Where is the code repository - -From late 2008 to late 2013, we used the -[Subversion repository at R-Forge](https://r-forge.r-project.org/scm/?group_id=155) -which contained \pkg{Rcpp} and a number of related packages. It still has the full -history as well as number of support files. - -We have since switched to a [Git repository at Github](http://github.com/RcppCore/Rcpp) -for \pkg{Rcpp} (as well as for \pkg{RcppArmadillo} and \pkg{RcppEigen}). - -# Known Issues - -Contained within this section is a list of known issues regarding \pkg{Rcpp}. -The issues listed here are either not able to be fixed due to breaking -application binary interface (ABI), would impact the ability to reproduce -pre-existing results, or require significant work. Generally speaking, these -issues come to light only when pushing the edge capabilities of \pkg{Rcpp}. - -## \pkg{Rcpp} changed the (const) object I passed by value - -\pkg{Rcpp} objects are wrappers around the underlying \proglang{R} objects' `SEXP`, -or S-expression. The `SEXP` is a pointer variable that holds the location -of where the \proglang{R} object data has been stored \citep[][Section 1.1]{R:Internals}. -That is to say, the `SEXP` does _not_ hold the actual data of the -\proglang{R} object but merely a reference to where the data resides. When creating a new -\pkg{Rcpp} object for an \proglang{R} object to enter \proglang{C++}, this object will -use the same `SEXP` that powers the original \proglang{R} object if the types match -otherwise a new `SEXP` must be created to be type safe. In essence, the -underlying `SEXP` objects are passed by reference without explicit copies -being made into \proglang{C++}. We refer to this arrangement as a -_proxy model_. - -As for the actual implementation, there are a few consequences of the proxy -model. The foremost consequence within this paradigm is that pass by value is -really a pass by reference. In essence, the distinction between the following -two functions is only visual sugar: - -```cpp -void implicit_ref(NumericVector X); -void explicit_ref(NumericVector& X); -``` - -In particular, when one is passing by value what occurs is the instantiation of -the new \pkg{Rcpp} object that uses the same `SEXP` for the \proglang{R} object. -As a result, the \pkg{Rcpp} object is ``linked'' to the original \proglang{R} object. -Thus, if an operation is performed on the \pkg{Rcpp} object, such as adding 1 -to each element, the operation also updates the \proglang{R} object causing the change to be propagated to \proglang{R}'s interactive environment. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void implicit_ref(Rcpp::NumericVector X) { - X = X + 1.0; -} - -// [[Rcpp::export]] -void explicit_ref(Rcpp::NumericVector& X) { - X = X + 1.0; -} -``` - -R use - -```{r} -a <- 1.5:4.5 -b <- 1.5:4.5 -implicit_ref(a) -a -explicit_ref(b) -b -``` - -There are two exceptions to this rule. The first exception is that a deep copy -of the object can be made by explicit use of `Rcpp:clone()`. In this case, -the cloned object has no link to the original \proglang{R} object. However, there is a -time cost associated with this procedure as new memory must be allocated and -the previous values must be copied over. The second exception, which was -previously foreshadowed, is encountered when \pkg{Rcpp} and \proglang{R} object types -do not match. One frequent example of this case is when the \proglang{R} object generated -from `seq()` or `a:b` reports a class of `"integer"` while the -\pkg{Rcpp} object is setup to receive the class of `"numeric"` as its -object is set to `NumericVector` or `NumericMatrix`. In such cases, -this would lead to a new `SEXP` object being created behind the scenes -and, thus, there would _not_ be a link between the \pkg{Rcpp} object -and \proglang{R} object. So, any changes in \proglang{C++} would not be propagated to -\proglang{R} unless otherwise specified. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void int_vec_type(Rcpp::IntegerVector X) { - X = X + 1.0; -} - -// [[Rcpp::export]] -void num_vec_type(Rcpp::NumericVector X) { - X = X + 1.0; -} -``` - -R use: - -```{r} -a <- 1:5 -b <- 1:5 -class(a) -int_vec_type(a) -a # variable a changed as a side effect -num_vec_type(b) -b # b unchanged as copy was made for numeric -``` - -With this being said, there is one last area of contention with the proxy model: -the keyword `const`. The `const` declaration indicates that an object -is not allowed to be modified by any action. Due to the way the proxy -model paradigm works, there is a way to "override" the `const` designation. -Simply put, one can create a new \pkg{Rcpp} object without the `const` -declaration from a pre-existing one. As a result, the new \pkg{Rcpp} object -would be allowed to be modified by the compiler and, thus, modifying the initial -`SEXP` object. Therefore, the initially secure \proglang{R} object would be altered. -To illustrate this phenomenon, consider the following scenario: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::IntegerVector const_override_ex( - const Rcpp::IntegerVector& X) { - - Rcpp::IntegerVector Y(X); // Create object - // from SEXP - - Y = Y * 2; // Modify new object - - return Y; // Return new object -} -``` - -R use: - -```{r} -x <- 1:10 # an integer sequence -# returning an altered value -const_override_ex(x) -# but the original value is altered too! -x -``` - -So we see that with `SEXP` objects, the `const` declaration can be -circumvented as it is really a pointer to the underlying R object. - - -## Issues with implicit conversion from an \pkg{Rcpp} object to a scalar or other \pkg{Rcpp} object - -Not all \pkg{Rcpp} expressions are directly compatible with -`operator=`. Compability issues stem from many \pkg{Rcpp} objects and -functions returning an intermediary result which requires an explicit -conversion. In such cases, the user may need to assist the compiler -with the conversion. - -There are two ways to assist with the conversion. The first is to construct -storage variable for a result, calculate the result, and then store a value -into it. This is typically what is needed when working with -`Character` and `String` in \pkg{Rcpp} due to the -`Rcpp::internal::string_proxy` class. Within the following code snippet, -the aforementioned approach is emphasized: - -```cpp -#include - -// [[Rcpp::export]] -std::string explicit_string_conv( - Rcpp::CharacterVector X) { - - std::string s; // define storage - s = X[0]; // assign from CharacterVector - - return s; -} -``` - -If one were to use a direct allocation and assignment strategy, -e.g. `std::string s = X[0]`, this would result in the compiler triggering -a conversion error on _some_ platforms. The error would be similar to: - -```{bash, eval = FALSE} -error: no viable conversion from 'Proxy' -(aka 'string_proxy<16>') to 'std::string' -(aka 'basic_string, -allocator >') -``` - -The second way to help the compiler is to use an explicit \pkg{Rcpp} type conversion -function, if one were to exist. Examples of \pkg{Rcpp} type conversion functions -include `as()`, `.get()` for `cumsum()`, `is_true()` -and `is_false()` for `any()` or `all()`. - - -## Using `operator=` with a scalar replaced the object instead of filling element-wise - -Assignment using the `operator=` with either `Vector` and -`Matrix` classes will not elicit an element-wise fill. If you seek an -element-wise fill, then use the `.fill()` member method to propagate a -single value throughout the object. With this being said, the behavior of -`operator=` differs for the `Vector` and `Matrix` classes. - -The implementation of the `operator=` for the `Vector` class will -replace the existing vector with the assigned value. This behavior is valid -even if the assigned value is a scalar value such as 3.14 or 25 as the object -is cast into the appropriate \pkg{Rcpp} object type. Therefore, if a -`Vector` is initialized to have a length of 10 and a scalar is assigned -via `operator=`, then the resulting `Vector` would have a length of -1. See the following code snippet for the aforementioned behavior. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void vec_scalar_assign(int n, double fill_val) { - Rcpp::NumericVector X(n); - Rcpp::Rcout << "Value of Vector " << - "on Creation: " << - std::endl << X << std::endl; - - X = fill_val; - - Rcpp::Rcout << "Value of Vector " << - "after Assignment: " << - std::endl << X << std::endl; -} -``` - -R use: - -```{r} -vec_scalar_assign(5L, 3.14) -``` - - -Now, the `Matrix` class does not define its own `operator=` but -instead uses the `Vector` class implementation. This leads to unexpected -results while attempting to use the assignment operator with a scalar. In -particular, the scalar will be coerced into a square `Matrix` and then -assigned. For an example of this behavior, consider the following code: - -```{Rcpp} -#include - -// [[Rcpp::export]] -void mat_scalar_assign(int n, double fill_val) { - Rcpp::NumericMatrix X(n, n); - Rcpp::Rcout << "Value of Matrix " << - "on Creation: " << - std::endl << X << std::endl; - - X = fill_val; - - Rcpp::Rcout << "Value of Matrix " << - "after Assignment: " << - std::endl << X << std::endl; -} -``` - -R use: - -```{r} -mat_scalar_assign(2L, 3.0) -``` - -## Long Vector support on Windows - -Prior to \proglang{R}'s 3.0.0, the largest vector one could obtain was at most $2^{31} - 1$ -elements. With the release of \proglang{R}'s 3.0.0, long vector support was added to -allow for largest vector possible to increase up to $2^{52}$ elements on x64 bit -operating systems (c.f. [Long Vectors help entry](https://stat.ethz.ch/R-manual/R-devel/library/base/html/LongVectors.html)). -Once this was established, support for long vectors within the \pkg{Rcpp} paradigm -was introduced with \pkg{Rcpp} version 0.12.0 (c.f [\pkg{Rcpp} 0.12.0 annoucement](http://dirk.eddelbuettel.com/blog/2015/07/25/)). - -However, the requirement for using long vectors in \pkg{Rcpp} necessitates the -presence of compiler support for the `R_xlen_t`, which is platform -dependent on how `ptrdiff_t` is implemented. Unfortunately, this means -that on the Windows platform the definition of `R_xlen_t` is of type -`long` instead of `long long` when compiling under the -\proglang{C++98} specification. Therefore, to solve this issue one must compile -under the specification for \proglang{C++11} or later version. - -There are three options to trigger compilation with \proglang{C++11}. -The first -- and most likely option to use -- will be the plugin support offered -by \pkg{Rcpp} attributes. This is engaged by adding -`// [[Rcpp::plugins(cpp11)]]` to the top of the \proglang{C++} script. -For diagnostic and illustrativative purposes, consider the following code -which checks to see if `R_xlen_t` is available on your platform: - -```{Rcpp} -#include -// Force compilation mode to C++11 -// [[Rcpp::plugins(cpp11)]] - -// [[Rcpp::export]] -bool test_long_vector_support() { -#ifdef RCPP_HAS_LONG_LONG_TYPES - return true; -#else - return false; -#endif -} -``` - -R use: - -```{r} -test_long_vector_support() -``` - -The remaining two options are for users who have opted to embed \pkg{Rcpp} code -within an \proglang{R} package. In particular, the second option requires adding -`CXX_STD = CXX11` to a `Makevars` file found in the `/src` -directory. Finally, the third option is to add `SystemRequirements:C++11` -in the package's `DESCRIPTION` file. - -Please note that the support for \proglang{C++11} prior to \proglang{R} v3.3.0 on Windows -is limited. Therefore, plan accordingly if the goal is to support older -versions of \proglang{R}. - -## Sorting with STL on a `CharacterVector` produces problematic results - -The Standard Template Library's (STL) `std::sort` algorithm performs -adequately for the majority of \pkg{Rcpp} data types. The notable exception -that makes what would otherwise be a universal quantifier into an existential -quantifier is the `CharacterVector` data type. Chiefly, the issue with -sorting strings is related to how the `CharacterVector` relies upon the -use of `Rcpp::internal::string_proxy`. -In particular, `Rcpp::internal::string_proxy` is _not_ MoveAssignable since the -left hand side of `operator=(const string_proxy \&rhs)` is _not_ -viewed as equivalent to the right hand side before the -operation \citep[][p. 466, Table 22]{Cpp11}. This further complicates matters -when using `CharacterVector` with `std::swap`, `std::move`, -`std::copy` and their variants. - -To avoid unwarranted pain with sorting, the preferred approach is to use the -`.sort()` member function of \pkg{Rcpp} objects. The member function -correctly applies the sorting procedure to \pkg{Rcpp} objects regardless of -type. Though, sorting is slightly problematic due to locale as explained in the -next entry. In the interim, the following code example illustrates the preferred -approach alongside the problematic STL approach: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::CharacterVector preferred_sort( - Rcpp::CharacterVector x) { - - Rcpp::CharacterVector y = Rcpp::clone(x); - y.sort(); - - return y; -} - -// [[Rcpp::export]] -Rcpp::CharacterVector stl_sort( - Rcpp::CharacterVector x) { - - Rcpp::CharacterVector y = Rcpp::clone(x); - std::sort(y.begin(), y.end()); - - return y; -} -``` - -R use: - -```{r} -set.seed(123) -(X <- sample(c(LETTERS[1:5], letters[1:6]), 11)) -preferred_sort(X) -stl_sort(X) -``` - -In closing, the results of using the STL approach do change depending on -whether `libc++` or `libstdc++` standard library is used to compile -the code. When debugging, this does make the issue particularly complex to -sort out. Principally, compilation with `libc++` and STL has been shown -to yield the correct results. However, it is not wise to rely upon this library -as a majority of code is compiled against `libstdc++` as it more complete. - -## Lexicographic order of string sorting differs due to capitalization - -Comparing strings within \proglang{R} hinges on the ability to process the locale or -native-language environment of the string. In \proglang{R}, there is a function called -`Scollate` that performs the comparison on locale. Unfortunately, this -function has not been made publicly available and, thus, \pkg{Rcpp} does -_not_ have access to it within its implementation of `StrCmp`. -As a result, strings that are sorted under the `.sort()` member function -are ordered improperly. Specifically, if capitalization is present, then -capitalized words are sorted together followed by the sorting of lowercase -words instead of a mixture of capitalized and lowercase words. The issue is -illustrated by the following code example: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::CharacterVector rcpp_sort( - Rcpp::CharacterVector X) { - X.sort(); - return X; -} -``` - -R use: - -```{r} -x <- c("B", "b", "c", "A", "a") -sort(x) -rcpp_sort(x) -``` - -## Package building fails with 'symbols not found' - -R 3.4.0 and later strongly encourage registering dynamically loadable -symbols. In the stronger form (where `.registration=TRUE` is added to the -`useDynLib()` statement in `NAMESPACE`), only registered symbols can be -loaded. This is fully supported by Rcpp 0.12.12 and later, and the required code -is added to `src/RcppExports.cpp`. - -However, the transition from the previously generated file `src/RcppExports.cpp` -to the new one may require running `compileAttributes()` twice (which does not -happen when, _e.g._, devtools is used). When `Rcpp::compileAttributes()` is -called, it also calls `tools::package_native_routine_registration_skeleton()`, -which crawls through usages of `.Call()` in the `R/` source files of the package to -figure out what routines need to be registered. If an older `RcppExports.R` file -is discovered, its out-of-date symbol names get picked up, and registration -rules for those symbols get written as well. This will register more symbols for -the package than are actually defined, leading to an error. This point has been -discussed at some length both in the GitHub issue tickes, on StackOverflow and -elsewhere. - -So if your autogenerated file fails, and a `symbols not found` error is reported -by the linker, consider running `compileAttributes()` twice. Deleting -`R/RcppExports.R` and `src/RcppExports.cpp` may also work. diff -Nru rcpp-1.0.2/inst/doc/Rcpp-FAQ.Rnw rcpp-1.0.3/inst/doc/Rcpp-FAQ.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-FAQ.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-FAQ.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-FAQ} +%\VignetteKeywords{Rcpp, FAQ, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-FAQ.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-introduction.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-introduction.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-introduction.R rcpp-1.0.3/inst/doc/Rcpp-introduction.R --- rcpp-1.0.2/inst/doc/Rcpp-introduction.R 2019-07-20 14:39:30.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-introduction.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -## ----setup, include=FALSE----------------------- -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -options("width"=50, digits=5) - -## ----evalCpp------------------------------------ -library("Rcpp") -evalCpp("2 + 2") - -## ----isOddR, cache=TRUE------------------------- -isOddR <- function(num = 10L) { - result <- (num %% 2L == 1L) - return(result) -} -isOddR(42L) - -## ----isOddRcpp---------------------------------- -library("Rcpp") -cppFunction(" -bool isOddCpp(int num = 10) { - bool result = (num % 2 == 1); - return result; -}") -isOddCpp(42L) - -## ----microbenchmark_isOdd, dependson=c("isOddR", "isOddRcpp"), eval=FALSE---- -# library("microbenchmark") -# results <- microbenchmark(isOddR = isOddR(12L), -# isOddCpp = isOddCpp(12L)) -# print(summary(results)[, c(1:7)],digits=1) - -## ----rnormScalar-------------------------------- -evalCpp("R::rnorm(0, 1)") - -## ----normWithSeed------------------------------- -set.seed(123) -evalCpp("R::rnorm(0, 1)") - -## ----rnormWithSeedFromR------------------------- -set.seed(123) -# Implicit mean of 0, sd of 1 -rnorm(1) - -## ----rnormExCpp--------------------------------- -set.seed(123) -evalCpp("Rcpp::rnorm(3)") - -## ----rnormExR----------------------------------- -set.seed(123) -rnorm(3) - -## ----bootstrap_in_r----------------------------- -# Function declaration -bootstrap_r <- function(ds, B = 1000) { - - # Preallocate storage for statistics - boot_stat <- matrix(NA, nrow = B, ncol = 2) - - # Number of observations - n <- length(ds) - - # Perform bootstrap - for(i in seq_len(B)) { - # Sample initial data - gen_data <- ds[ sample(n, n, replace=TRUE) ] - # Calculate sample data mean and SD - boot_stat[i,] <- c(mean(gen_data), - sd(gen_data)) - } - - # Return bootstrap result - return(boot_stat) -} - -## ----bootstrap_example-------------------------- -# Set seed to generate data -set.seed(512) -# Generate data -initdata <- rnorm(1000, mean = 21, sd = 10) -# Set a new _different_ seed for bootstrapping -set.seed(883) -# Perform bootstrap -result_r <- bootstrap_r(initdata) - -## ----dist_graphs, echo = FALSE, results = "hide"---- -make_boot_graph <- function(ds, actual, type, ylim){ - hist(ds, main = paste(type, "Bootstrap"), xlab = "Samples", - col = "lightblue", lwd = 2, prob = TRUE, ylim = ylim, cex.axis = .85, cex.lab = .90) - abline(v = actual, col = "orange2", lwd = 2) - lines(density(ds)) -} -pdf("figures/bootstrap.pdf", width=6.5, height=3.25) -par(mfrow=c(1,2)) -make_boot_graph(result_r[,1], 21, "Mean", c(0, 1.23)) -make_boot_graph(result_r[,2], 10, "SD", c(0, 1.85)) -dev.off() - -## ----bootstrap_cpp------------------------------ -# Use the same seed use in R and C++ -set.seed(883) -# Perform bootstrap with C++ function -result_cpp <- bootstrap_cpp(initdata) - -## ----check_r_to_cpp----------------------------- -# Compare output -all.equal(result_r, result_cpp) - -## ----benchmark_r_to_cpp------------------------- -library(rbenchmark) - -benchmark(r = bootstrap_r(initdata), - cpp = bootstrap_cpp(initdata))[, 1:4] - -## ----skeleton, eval = FALSE--------------------- -# library("Rcpp") -# Rcpp.package.skeleton("samplePkg") - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-introduction.Rmd rcpp-1.0.3/inst/doc/Rcpp-introduction.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-introduction.Rmd 2018-07-27 12:39:57.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-introduction.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,921 +0,0 @@ ---- -title: | - | Extending \rlang with C++: - | A Brief Introduction to Rcpp - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: James Joseph Balamuta - affiliation: b -address: - - code: a - address: Debian and R Projects; Chicago, IL, USA; \url{edd@debian.org} - - code: b - address: Depts of Informatics and Statistics, Univ. of Illinois at Urbana-Champaign; Champaign, IL, USA; \url{balamut2@illinois.edu} - -# For footer text TODO(fold into template, allow free form two-authors) -lead_author_surname: Eddelbuettel and Balamuta - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - \rlang has always provided an application programming interface (API) for extensions. - Based on the \clang language, it uses a number of macros and other low-level constructs - to exchange data structures between the \rlang process and any dynamically-loaded component - modules authors added to it. With the introduction of the \rcpp package, and its later - refinements, this process has become considerably easier yet also more robust. By now, \rcpp has - become the most popular extension mechanism for \rlangns. This article introduces \rcppns, and - illustrates with several examples how the _Rcpp Attributes_ mechanism in particular - eases the transition of objects between \rlang and \cpp code. - -# Acknowledgements -acknowledgements: | - We thank Bob Rudis and Lionel Henry for excellent comments and suggestion on an earlier - draft of this manuscript. Furthermore, we appreciate the improved \cpp annotated function - graphic provided by Bob Rudis. This version is a pre-print of \citet{PeerJ:Rcpp,TAS:Rcpp}. - -# One or more keywords -keywords: - - applications and case studies - - statistical computing - - computationally intensive methods - - simulation - -# Bibliography -bibliography: Rcpp - -# Enable a watermark on the document -watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -# Local additiona of a few definitions we use -header-includes: > - \newcommand{\TODO}{\marginnote{TODO}} - \newcommand{\rlang}{\textit{R }} - \newcommand{\rlangns}{\textit{R}} - \newcommand{\slang}{\textit{S }} - \newcommand{\rcpp}{\textit{Rcpp }} - \newcommand{\rcppns}{\textit{Rcpp}} - \newcommand{\clang}{\textit{C }} - \newcommand{\clangns}{\textit{C}} - \newcommand{\cpp}{\textit{C++ }} - \newcommand{\cppns}{\textit{C++}} - \newcommand{\fortran}{\textit{Fortran }} - \newcommand{\fortranns}{\textit{Fortran}} - \newcommand{\python}{\textit{Python}} - \newcommand{\julia}{\textit{Julia}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-introduction} - %\VignetteKeywords{Rcpp, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r setup, include=FALSE} -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -options("width"=50, digits=5) -``` - - -# Introduction - -The \rlang language and environment \citep{R:main} has established itself as -both an increasingly dominant facility for data analysis, and the -*lingua franca* for statistical computing in both research and -application settings. - -Since the beginning, and as we argue below, "by design", -the \rlang system has always provided an application programming interface (API) -suitable for extending \rlang with code written in \clang or \fortranns. Being -implemented chiefly in \rlang and \clang (with a generous sprinkling of \fortran -for well-established numerical subroutines), \rlang has always been -extensible via a \clang interface. Both the actual -implementation and the \clang interface use a number of macros and other -low-level constructs to exchange data structures between the \rlang process -and any dynamically-loaded component modules authors added to it. - -A \clang interface will generally also be accessible to other languages. -Particularly noteworthy here is the \cpp language, developed originally as a -'better \clangns', which is by its design very interoperable with -\clangns. And with the introduction of the \rcpp package -\citep{JSS:Rcpp,Eddelbuettel:2013:Rcpp,CRAN:Rcpp}, and its later refinements, this -process of extending \rlang has become considerably easier yet also more robust. -To date, \rcpp has become the most popular extension system for -\rlangns. This article introduces \rcppns, and illustrates with several -examples how the _Rcpp Attributes_ mechanism -\citep{CRAN:Rcpp:Attributes} in particular eases the transition of -objects between \rlang and \cpp code. - - -## Background - -\citet[p. 3]{Chambers:2008:SoDA} provides a very thorough discussion of -desirable traits for a system designed to _program with data_, -and the \rlang system in particular. Two key themes motivate the introductory -discussion. First, the _Mission_ is to aid exploration in order to -provide the best platform to analyse data: "to boldly go where no one -has gone before." Second, the _Prime Directive_ is that the software -systems we build must be _trustworthy_: "the many computational steps -between original data source and displayed result must all be -trustful." The remainder of the book then discusses \rlangns, leading -to two final chapters on interfaces. - -\citet[p. 4]{Chambers:2016:ExtR} builds and expands on this theme. Two core -facets of what "makes" \rlang are carried over from the previous book. The -first states what \rlang is composed of: _Everything that exists in \rlang is -an object_. The second states how these objects are created or -altered: _Everything that happens in \rlang is a function call_. A third -statement is now added: _Interfaces to other software are part of \rlangns_. - -This last addition is profound. If and when suitable and performant -software for a task exists, it is in fact desirable to have a (preferably -also perfomant) interface to this software from \rlangns. -\cite{Chambers:2016:ExtR} discusses several possible approaches for simpler -interfaces and illustrates them with reference implementations to both \python\ and -\julia. However, the most performant interface for \rlang is provided at the -subroutine level, and rather than discussing the older \clang interface for -\rlangns, \cite{Chambers:2016:ExtR} prefers to discuss \rcppns. This article -follows the same school of thought and aims to introduce \rcpp to -analysts and data scientists, aiming to enable them to use---and -create--- further _interfaces_ for \rlang which aid the _mission_ while -staying true to the _prime directive_. Adding interfaces in such a way is in -fact a natural progression from the earliest designs for its predecessor -\slang which was after all designed to provide a more useable 'interface' to -underlying routines in \fortranns. - -The rest of the paper is structured as follows. We start by discussing -possible first steps, chiefly to validate correct installations. This -is followed by an introduction to simple \cpp functions, comparison to -the \clang API, a discussion of packaging with \rcpp and a linear algebra -example. The appendix contains some empirical illustrations of the -adoption of \rcppns. - - -# First Steps with \rcpp - -\rcpp is a CRAN package and can be installed -by using `install.packages('Rcpp')` just like any other \rlang package. On -some operating systems this will download _pre-compiled_ binary packages; on -others an installation from source will be attempted. But \rcpp is a little -different from many standard \rlang packages in one important aspect: it helps the user -to _write C(++) programs more easily_. The key aspect to note here is \cpp -programs: to operate, \rcpp needs not only \rlang but also an additional -_toolchain_ of a compiler, linker and more in order to be able to create _binary_ object -code extending \rlangns. - -We note that this requirement is no different from what is needed with base \rlang when -compilation of extensions is attempted. How to achieve this using only base \rlang is described in -some detail in the _Writing R Extensions_ manual \citep{R:Extensions} that is included -with \rlangns. As for the toolchain requirements, on Linux and macOS, all required -components are likely to be present. The macOS can offer additional challenges as toolchain -elements can be obtained in different ways. Some of these are addressed in the _Rcpp FAQ_ -\citep{CRAN:Rcpp:FAQ} in sections 2.10 and 2.16. On Windows, users will have to install -the Rtools kit provided by R Core available at . -Details of these installation steps are beyond the scope of this -paper. However, many external resources exist that provide detailed -installation guides for \rlang toolschains in -[Windows](http://thecoatlessprofessor.com/programming/rcpp/install-rtools-for-rcpp/) -and -[macOS](http://thecoatlessprofessor.com/programming/r-compiler-tools-for-rcpp-on-os-x/). - -As a first step, and chiefly to establish that the toolchain is set up correctly, consider -a minimal use case such as the following: - -```{r evalCpp} -library("Rcpp") -evalCpp("2 + 2") -``` - -Here the \rcpp package is loaded first via the `library()` function. Next, we deploy one -of its simplest functions, `evalCpp()`, which is described in the _Rcpp Attributes_ vignette -\citep{CRAN:Rcpp:Attributes}. It takes the first (and often only) argument---a character -object---and evaluates it as a minimal \cpp expression. The value assignment and return -are implicit, as is the addition of a trailing semicolon and more. In fact, `evalCpp()` -surrounds the expression with the required 'glue' to make it a minimal source file which -can be compiled, linked and loaded. The exact details behind this process -are available in-depth when the `verbose` option of the function is set. -If everything is set up correctly, the newly-created \rlang function will be -returned. - -While such a simple expression is not interesting in itself, it serves a -useful purpose here to unequivocally establish whether \rcpp is correctly -set up. Having accomplished that, we can proceed to the next step of -creating simple functions. - -# A first \cpp function using \rcpp - -As a first example, consider the determination of whether a number is odd or even. The -default practice is to use modular arithmetic to check if a remainder exists under $x -\bmod 2$. Within \rlangns, this can be implemented as follows: - -```{r isOddR, cache=TRUE} -isOddR <- function(num = 10L) { - result <- (num %% 2L == 1L) - return(result) -} -isOddR(42L) -``` - -The operator `%%` implements the $\bmod$ operation in \rlangns. For the default -(integer) argument of ten used in the example, $10 \bmod 2$ results in zero, which is then -mapped to `FALSE` in the context of a logical expression. - -Translating this implementation into \cppns, several small details have to be -considered. First and foremost, as \cpp is a _statically-typed language_, there needs to -be additional (compile-time) information provided for each of the variables. Specifically, -a *type*, _i.e._ the kind of storage used by a variable must be explicitly -defined. Typed languages generally offer benefits in terms of both correctness -(as it is harder to accidentally assign to an ill-matched type) and -performance (as the compiler can optimize code based on the storage and cpu -characteristics). Here we have an `int` argument, but return a logical, or -`bool` for short. Two more smaller differences are that each statement -within the body must be concluded with a semicolon, and that `return` does -not require parentheses around its argument. A graphical breakdown of all -aspects of a corresponding \cpp function is given in Figure \ref{fig:cpp-function-annotation}. - -\begin{figure*} - \begin{center} - \includegraphics[width=5.5in]{figures/function_annotation_cpp.png} - \caption{Graphical annotation of the \texttt{is\_odd\_cpp} function.} - \label{fig:cpp-function-annotation} - \end{center} -\end{figure*} - -When using \rcppns, such \cpp functions can be directly embedded and compiled in an \rlang -script file through the use of the `cppFunction()` provided by _Rcpp Attributes_ -\citep{CRAN:Rcpp:Attributes}. The first parameter of the function accepts string input -that represents the \cpp code. Upon calling the `cppFunction()`, and similarly to the -earlier example involving `evalCpp()`, the \cpp code is both _compiled_ and _linked_, and -then _imported_ into \rlang under the name of the function supplied (_e.g._ here `isOddCpp()`). - -```{r isOddRcpp} -library("Rcpp") -cppFunction(" -bool isOddCpp(int num = 10) { - bool result = (num % 2 == 1); - return result; -}") -isOddCpp(42L) -``` - -# Extending \rlang via its \clang API - -Let us first consider the case of 'standard \rlangns', _i.e._ the API as -defined in the core \rlang documentation. Extending \rlang with routines written -using the \clang language requires the use of internal macros and functions -documented in Chapter 5 of _Writing R Extensions_ \citep{R:Extensions}. - -```{Rcpp convolutionC, eval = FALSE} -#include -#include - -SEXP convolve2(SEXP a, SEXP b) { - int na, nb, nab; - double *xa, *xb, *xab; - SEXP ab; - - a = PROTECT(coerceVector(a, REALSXP)); - b = PROTECT(coerceVector(b, REALSXP)); - na = length(a); nb = length(b); - nab = na + nb - 1; - ab = PROTECT(allocVector(REALSXP, nab)); - xa = REAL(a); xb = REAL(b); xab = REAL(ab); - for (int i = 0; i < nab; i++) - xab[i] = 0.0; - for (int i = 0; i < na; i++) - for (int j = 0; j < nb; j++) - xab[i + j] += xa[i] * xb[j]; - UNPROTECT(3); - return ab; -} -``` - -This function computes a _convolution_ of two vectors supplied on input, $a$ and -$b$, which is defined to be ${ab_{k + 1}} = \sum\limits_{i + j == k} {{a_i} \cdot {b_j}}$. -Before computing the convolution (which is really just the three lines involving two -nested for loops with indices $i$ and $j$), a total of ten lines of mere housekeeping -are required. Vectors $a$ and $b$ are coerced to `double`, and a results vector `ab` is -allocated. This expression involves three calls to the `PROTECT` macro for which a _precisely_ -matching `UNPROTECT(3)` is required as part of the interfacing of internal memory -allocation. The vectors are accessed through pointer equivalents `xa`, `xb` and `xab`; and -the latter has to be explicitly zeroed prior to the convolution calculation involving -incremental summary at index $i+j$. - - -# Extending \rlang via the \cpp API of \rcpp - -Using the idioms of \rcppns, the above example can be written in a much more -compact fashion---leading to code that is simpler to read and -maintain. - -```{Rcpp convolutionRcpp, eval = FALSE} -#include "Rcpp.h" -using namespace Rcpp; - -// [[Rcpp::export]] -NumericVector -convolve_cpp(const NumericVector& a, - const NumericVector& b) { - - // Declare loop counters, and vector sizes - int i, j, - na = a.size(), nb = b.size(), - nab = na + nb - 1; - - // Create vector filled with 0 - NumericVector ab(nab); - - // Crux of the algorithm - for(i = 0; i < na; i++) { - for(j = 0; j < nb; j++) { - ab[i + j] += a[i] * b[j]; - } - } - - // Return result - return ab; -} -``` - -To deploy such code from within an \rlang script or session, first save it into a new -file---which could be called **convolve.cpp**---in either the working directory, a -temporary directoy or a project directory. Then from within the \rlang session, -use `Rcpp::sourceCpp("convolve.cpp")` (possibly using a path as well as the filename). This -not only compiles, links and loads the code within the external file but also adds the -necessary "glue" to make the \rcpp function available in the \rlang environment. Once the -code is compiled and linked, call the newly-created `convolve_cpp()` function with the -appropriate parameters as done in previous examples. - -What is notable about the \rcpp version is that it has no `PROTECT` or `UNPROTECT` -which not only frees the programmer from a tedious (and error-prone) step but -more importantly also shows that memory management can be handled automatically. -The result vector is already initialized at zero as well, -reducing the entire function to just the three lines for the two nested loops, -plus some variable declarations and the `return` statement. The resulting code is -shorter, easier to read, comprehend and maintain. Furthermore, the \rcpp code -is more similar to traditional \rlang code, which reduces -the barrier of entry. - - -# Data Driven Performance Decisions with \rcpp - -When beginning to implement an idea, more so an algorithm, there are many ways -one is able to correctly implement it. Prior to the routine being used in -production, two questions must be asked: - -1. Does the implementation produce the _correct_ results? -2. What implementation of the routine is the _best_? - -The first question is subject to a binary pass-fail unit test verification -while the latter question is where the details of an implementation are scrutinized -to extract maximal efficiency from the routine. The quality of the _best_ routine -follows first and foremost from its correctness. To that end, -\rlang offers many different unit testing frameworks such as \pkg{RUnit} by -\cite{CRAN:RUnit}, which is used to construct \rcppns's 1385+ unit tests, and -\pkg{testthat} by \cite{CRAN:testthat}. Only when correctness is -achieved is it wise to begin the procedure of optimizing the efficiency of -the routine and, in turn, selecting the best routine. - -Optimization of an algorithm involves performing a quantitative analysis of the -routine's properties. There are two main approaches to analyzing the behavior -of a routine: theoretical analysis\footnote{ -Theoretical analysis is often directed to describing -the limiting behavior of a function through asymptotic notation, -commonly referred to as Big O and denoted as $\mathcal{O}(\cdot)$.} -or an empirical examination using profiling tools.\footnote{ -Within base \rlangns, profiling can be activated by \code{utils::Rprof()} -for individual command timing information, \code{utils::Rprofmem()} for memory -information, and \code{System.time(\{\})} for a quick overall execution timing. -Additional profiling \rlang packages such as \pkg{profvis} by -\cite{CRAN:profvis}, \pkg{Rperform} by \cite{GitHub:Rperform}, and -benchmarking packages have extended the ability to analyze performance.} -Typically, the latter option is more prominently used -as the routine's theoretical properties are derived prior to an implementation -being started. Often the main concern regarding an implementation in \rlang relates -to the speed of the algorithm as it impacts how quickly analyses -can be done and reports can be provided to decision makers. Coincidentally, the -speed of code is one of the key governing use cases of \rcppns. Profiling \rlang -code will reveal shortcomings related to loops, _e.g._ `for`, `while`, and `repeat`; -conditional statements, _e.g._ `if`-`else if`-`else` and `switch`; -and recursive functions, _i.e._ a function written in terms of itself such that the -problem is broken down on each call in a reduced state until an answer can be -obtained. In contrast, the overhead for such operations is significantly less -in \cppns. Thus, critical components of a given routine should be written -in \rcpp to capture maximal efficiency. - -Returning to the second question, to decide which -implementation works the best, one needs to employ a benchmark -to obtain _quantifiable results_. Benchmarks are an ideal way to quantify how -well a method performs because they have the ability to show the amount of time the -code has been running and where bottlenecks exist within functions. -This does not imply that benchmarks are completely infallible as user error -can influence the end results. For example, if a user decides -to benchmark code in one \rlang session and in another session performs a heavy -computation, then the benchmark will be biased (if "wall clock" is measured). - -There are different levels of magnification that a benchmark can provide. For a more macro -analysis, one should benchmark data using `benchmark(test = func(), test2 = func2())`, -a function from the \pkg{rbenchmark} \rlang package by \cite{CRAN:rbenchmark}. This form of -benchmarking will be used when the computation is more intensive. -The motivating example `isOdd()` -(which is only able to accept a single `integer`) warrants a much more -microscopic timing comparison. In cases such as this, the objective -is to obtain precise results in the amount of nanoseconds elapsed. Using the -`microbenchmark` function from the \pkg{microbenchmark} \rlang package by -\cite{CRAN:microbenchmark} is more helpful to obtain timing information. -To perform the benchmark: - -```{r microbenchmark_isOdd, dependson=c("isOddR", "isOddRcpp"), eval=FALSE} -library("microbenchmark") -results <- microbenchmark(isOddR = isOddR(12L), - isOddCpp = isOddCpp(12L)) -print(summary(results)[, c(1:7)],digits=1) -``` - -By looking at the summary of 100 evaluations, we note that the -\rcpp function performed better than the equivalent in \rlang by achieving -a lower run time on average. The lower run time in this part is not necessarily -critical as the difference is nanoseconds on a trivial computation. -However, each section of code does contribute to a faster overall runtime. - -# Random Numbers within \rcppns: An Example of _Rcpp Sugar_ - -\rcpp connects \rlang with \cppns. Only the former is vectorized: \cpp is not. -_Rcpp Sugar_, however, provides a convenient way to work with high-performing -\cpp functions in a similar way to how \rlang offers vectorized operations. -The _Rcpp Sugar_ vignette \citep{CRAN:Rcpp:Sugar} details these, as well as -many more functions directly accessible to \rcpp in a way that should feel -familiar to \rlang users. Some examples of _Rcpp Sugar_ functions -include special math functions like gamma and beta, statistical distributions -and random number generation. - -We will illustrate a case of random number generation. Consider drawing one -or more $N(0,1)$-distributed random variables. The very -simplest case can just use `evalCpp()`: - -```{r rnormScalar} -evalCpp("R::rnorm(0, 1)") -``` - -By setting a seed, we can make this reproducible: - -```{r normWithSeed} -set.seed(123) -evalCpp("R::rnorm(0, 1)") -``` - -One important aspect of the behind-the-scenes code generation for the single expression -(as well as all code created via _Rcpp Attributes_) is the automatic preservation of the -state of the random nunber generators in \rlangns. This means that from a given seed, we will -receive _identical_ draws of random numbers whether we access them from \rlang or via \cpp code -accessing the same generators (via the \rcpp interfaces). To illustrate, the -same number is drawn via \rlang code after resetting the seed: - -```{r rnormWithSeedFromR} -set.seed(123) -# Implicit mean of 0, sd of 1 -rnorm(1) -``` - -We can make the _Rcpp Sugar_ -function `rnorm()` accessible from \rlang in the same way to return a vector of values: - -```{r rnormExCpp} -set.seed(123) -evalCpp("Rcpp::rnorm(3)") -``` - -Note that we use the `Rcpp::` namespace explicitly here to -contrast the vectorised `Rcpp::rnorm()` with the scalar `R::rnorm()` -also provided as a convenience wrapper for the \clang API of \rlangns. - -And as expected, this too replicates from \rlang as the very -same generators are used in both cases along with consistent handling -of generator state permitting to alternate: - -```{r rnormExR} -set.seed(123) -rnorm(3) -``` - -# Translating Code from \rlang into \rcppns: Bootstrap Example - -Statistical inference relied primarily upon asymptotic theory until -\cite{Efron:1979:Bootstrap} proposed the bootstrap. Bootstrapping is known -to be computationally intensive due to the need to use loops. Thus, it is an ideal candidate to use as an -example. Before starting to write \cpp code using \rcpp, prototype the code in \rlangns. - -```{r bootstrap_in_r} -# Function declaration -bootstrap_r <- function(ds, B = 1000) { - - # Preallocate storage for statistics - boot_stat <- matrix(NA, nrow = B, ncol = 2) - - # Number of observations - n <- length(ds) - - # Perform bootstrap - for(i in seq_len(B)) { - # Sample initial data - gen_data <- ds[ sample(n, n, replace=TRUE) ] - # Calculate sample data mean and SD - boot_stat[i,] <- c(mean(gen_data), - sd(gen_data)) - } - - # Return bootstrap result - return(boot_stat) -} -``` - -Before continuing, check that the initial prototype \rlang code works. To -do so, write a short \rlang script. Note the use of `set.seed()` to ensure -reproducible draws. - -```{r bootstrap_example} -# Set seed to generate data -set.seed(512) -# Generate data -initdata <- rnorm(1000, mean = 21, sd = 10) -# Set a new _different_ seed for bootstrapping -set.seed(883) -# Perform bootstrap -result_r <- bootstrap_r(initdata) -``` - -Figure \ref{fig:bootstrap-graphs} shows that the bootstrap procedure worked well! - -```{r dist_graphs, echo = FALSE, results = "hide"} -make_boot_graph <- function(ds, actual, type, ylim){ - hist(ds, main = paste(type, "Bootstrap"), xlab = "Samples", - col = "lightblue", lwd = 2, prob = TRUE, ylim = ylim, cex.axis = .85, cex.lab = .90) - abline(v = actual, col = "orange2", lwd = 2) - lines(density(ds)) -} -pdf("figures/bootstrap.pdf", width=6.5, height=3.25) -par(mfrow=c(1,2)) -make_boot_graph(result_r[,1], 21, "Mean", c(0, 1.23)) -make_boot_graph(result_r[,2], 10, "SD", c(0, 1.85)) -dev.off() -``` - -\begin{figure*} - \begin{center} - \includegraphics[width=6.5in, height=3.25in]{figures/bootstrap} - \caption{Results of the bootstrapping procedure for sample mean and variance.} - \label{fig:bootstrap-graphs} - \end{center} -\end{figure*} - -With reassurances that the method to be implemented within \rcpp works -appropriately in \rlangns, proceed to translating the code -into \rcppns. As indicated previously, there are many convergences between \rcpp -syntax and base \rlang via \rcpp Sugar. - - -```{Rcpp bootstrap_in_cpp} -#include - -// Function declaration with export tag -// [[Rcpp::export]] -Rcpp::NumericMatrix -bootstrap_cpp(Rcpp::NumericVector ds, - int B = 1000) { - - // Preallocate storage for statistics - Rcpp::NumericMatrix boot_stat(B, 2); - - // Number of observations - int n = ds.size(); - - // Perform bootstrap - for(int i = 0; i < B; i++) { - // Sample initial data - Rcpp::NumericVector gen_data = - ds[ floor(Rcpp::runif(n, 0, n)) ]; - // Calculate sample mean and std dev - boot_stat(i, 0) = mean(gen_data); - boot_stat(i, 1) = sd(gen_data); - } - - // Return bootstrap results - return boot_stat; -} -``` - -In the \rcpp version of the bootstrap function, there are a few additional -changes that occurred during the translation. In particular, the use of -`Rcpp::runif(n, 0, n)` enclosed by `floor()`, which rounds down to the nearest integer, -in place of `sample(n, n, replace = TRUE)` to sample row ids. This is an -equivalent substitution since equal weight is being placed upon all row ids and -replacement is allowed.\footnote{For more flexibility in sampling see Christian Gunning's -Sample extension for \pkg{RcppArmadillo} and -\href{http://gallery.rcpp.org/articles/using-the-Rcpp-based-sample-implementation/}{Rcpp Gallery: Using the \pkg{RcppArmadillo}-based Implementation of R's sample()} or consider using the \code{Rcpp::sample()} sugar function added in 0.12.9 by Nathan Russell.} -Note that the upper bound of the interval, `n`, will never be reached. While -this may seem flawed, it is important to note that vectors and matrices in -\cpp use a zero-based indexing system, meaning that they begin at 0 instead of 1 -and go up to $n-1$ instead of $n$, which is unlike \rlangns's system. Thus, an -out of bounds error would be triggered if `n` was used as that point does _not_ -exist within the data structure. The application of this logic can be seen -in the span the `for` loop takes in \cpp when compared to \rlangns. Another -syntactical change is the use of `()` in place of `[]` -while accessing the matrix. This change is due to the governance of \cpp -and its comma operator making it impossible to place multiple indices inside -the square brackets. - -To validate that the translation was successful, first run the \cpp function -under the _same_ data and seed as was given for the \rlang function. - -```{r bootstrap_cpp} -# Use the same seed use in R and C++ -set.seed(883) -# Perform bootstrap with C++ function -result_cpp <- bootstrap_cpp(initdata) -``` - -Next, check the output between the functions using \rlang's `all.equal()` function -that allows for an $\varepsilon$-neighborhood around a number. - -```{r check_r_to_cpp} -# Compare output -all.equal(result_r, result_cpp) -``` - -Lastly, make sure to benchmark the newly translated \rcpp function against the -\rlang implementation. As stated earlier, data is paramount to making a decision -related to which function to use in an analysis or package. - -```{r benchmark_r_to_cpp} -library(rbenchmark) - -benchmark(r = bootstrap_r(initdata), - cpp = bootstrap_cpp(initdata))[, 1:4] -``` - -# Using \rcpp as an Interface to External Libraries: Exploring Linear Algebra Extensions - -Many of the previously illustrated \rcpp examples were directed primarily to -show the gains in computational efficiency that are possible by implementing -code directly in \cppns; however, this is only one potential application of \rcppns. -Perhaps one of the most understated features of \rcpp is its ability to -enable \cite{Chambers:2016:ExtR}'s third statement of -_Interfaces to other software are part of \rlangns_. In particular, \rcpp is -designed to facilitate interfacing libraries written in \cpp or \clang to \rlangns. -Hence, if there is a specific feature within a \cpp or \clang library, -then one can create a bridge to it using \rcpp to enable it from within \rlangns. - -An example is the use of \cpp matrix algebra libraries like -\pkg{Armadillo} \citep{Sanderson:2010:Armadillo} - -or \pkg{Eigen} \citep{Eigen:Web}. By outsourcing complex linear -algebra operations to matrix libraries, the need to directly call -functions within \pkg{Linear Algebra PACKage (LAPACK)} -\citep{Anderson:1990:UGLAPACK} is negated. Moreover, the \rcpp design -allows for seamless transfer between object types by using automatic -converters governed by `wrap()`, \cpp to \rlang, and `as()`, \rlang -to \cpp with the `T` indicating the type of object being cast into. -These two helper functions provide a non-invasive way to work with an -external object. Thus, a further benefit to using external \cpp -libraries is the ability to have a portable code base that can be -implemented within a standalone \cpp program or within another -computational language. - - -## Compute RNG draws from a multivariate Normal - -A common application in statistical computing is simulating from a multivariate normal distribution. -The algorithm relies on a linear transformation of the -standard Normal distribution. -Letting $\boldsymbol{Y}_{m \times 1} = \boldsymbol{A}_{m\times n}\boldsymbol{Z}_{n\times 1} + \boldsymbol{b}_{m\times 1}$, -where $\boldsymbol{A}$ is a $m \times n$ matrix, $\boldsymbol{b} \in \mathbb{R}^m$, $\boldsymbol{Z} \sim N(\boldsymbol{0}_{n},\boldsymbol{I}_n)$, -and $\boldsymbol{I}_n$ is the identity matrix, then ${\boldsymbol{Y}} \sim N_{m}\left({\boldsymbol{\mu} = \boldsymbol{b}, \boldsymbol{\Sigma} = \boldsymbol{A}\boldsymbol{A}^T}\right)$. -To obtain the matrix $\boldsymbol{A}$ from $\boldsymbol{\Sigma}$, either a Cholesky or Eigen decomposition -is required. As noted in \citet{Venables+Ripley:2002:MASS}, the Eigen decomposition is more -stable in addition to being more computationally demanding compared to -the Cholesky decomposition. For simplicity and speed, we have opted to implement -the sampling procedure using a Cholesky decomposition. Regardless, there -is a need to involve one of the above matrix libraries to make the sampling -viable in \cppns. - -Here, we demonstrate how to take advantage of the *Armadillo* linear algebra template -classes \citep{Sanderson+Curtin:2016} via the \pkg{RcppArmadillo} package -\citep{Eddelbuettel+Sanderson:2013:RcppArmadillo, CRAN:RcppArmadillo}. Prior to -running this example, the \pkg{RcppArmadillo} package must be installed using -`install.packages('RcppArmadillo')`.\footnote{macOS users may encounter `-lgfortran` -and `-lquadmath` errors on compilations with this package if the development environment -is not appropriately set up. \href{https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-FAQ.pdf}{Section 2.16 of the Rcpp FAQ} provides details regarding the necessary `gfortran` binaries.} -One important caveat when using additional packages -within the \rcpp ecosystem is the correct header file may not be `Rcpp.h`. -In a majority of cases, the additional package ships a dedicated header -(as _e.g._ `RcppArmadillo.h` here) which not only declares data -structures from both systems, but may also add complementary integration and conversion -routines. It typically needs to be listed in an `include` statement along with a -`depends()` attribute to tell \rlang where to find the additional header files: - -```{Rcpp armaDepends, eval = F} -// Use the RcppArmadillo package -// Requires different header file from Rcpp.h -#include -// [[Rcpp::depends(RcppArmadillo)]] -``` - -With this in mind, sampling from a multivariate normal distribution can -be obtained in a straightforward manner. Using only _Armadillo_ -data types and values: - -```{Rcpp rmvnorm, eval = FALSE} -#include -// [[Rcpp::depends(RcppArmadillo)]] - -// Sample N x P observations from a Standard -// Multivariate Normal given N observations, a -// vector of P means, and a P x P cov matrix -// [[Rcpp::export]] -arma::mat rmvnorm(int n, - const arma::vec& mu, - const arma::mat& Sigma) { - unsigned int p = Sigma.n_cols; - - // First draw N x P values from a N(0,1) - Rcpp::NumericVector draw = Rcpp::rnorm(n*p); - - // Instantiate an Armadillo matrix with the - // drawn values using advanced constructor - // to reuse allocated memory - arma::mat Z = arma::mat(draw.begin(), n, p, - false, true); - - // Simpler, less performant alternative - // arma::mat Z = Rcpp::as(draw); - - // Generate a sample from the Transformed - // Multivariate Normal - arma::mat Y = arma::repmat(mu, 1, n).t() + - Z * arma::chol(Sigma); - - return Y; -} -``` - -As a result of using a random number generation (RNG), there is an -additional requirement to ensure reproducible results: the necessity -to explicitly set a seed (as shown above). Because of the -(programmatic) interface provided by \rlang to its own RNGs, this setting of the -seed has to occur at the \rlang level -via the `set.seed()` function as no (public) interface is provided by -the \rlang header files. - - -## Faster linear model fits - -As a second example, consider the problem of estimating a common -linear model repeatedly. One use case might be the -simulation of size and power of standard tests. Many users of \rlang would -default to using `lm()`, however, the overhead associated with this function -greatly impacts speed with which an estimate can be obtained. Another approach -would be to take the base \rlang function `lm.fit()`, which is called by `lm()`, -to compute estimated $\hat{\beta}$ in just about the fastest time possible. -However, this approach is also not viable as it does not report the estimated -standard errors. As a result, we cannot use any default -\rlang functions in the context of simulating finite sample population -effects on inference. - -One alternative is provided by the `fastLm()` function in -\pkg{RcppArmadillo} \citep{CRAN:RcppArmadillo}. - -```{Rcpp fastLm, eval = FALSE} -#include -// [[Rcpp::depends(RcppArmadillo)]] - -// Compute coefficients and their standard error -// during multiple linear regression given a -// design matrix X containing N observations with -// P regressors and a vector y containing of -// N responses -// [[Rcpp::export]] -Rcpp::List fastLm(const arma::mat& X, - const arma::colvec& y) { - // Dimension information - int n = X.n_rows, p = X.n_cols; - // Fit model y ~ X - arma::colvec coef = arma::solve(X, y); - // Compute the residuals - arma::colvec res = y - X*coef; - // Estimated variance of the random error - double s2 = - std::inner_product(res.begin(), res.end(), - res.begin(), 0.0) - / (n - p); - - // Standard error matrix of coefficients - arma::colvec std_err = arma::sqrt(s2 * - arma::diagvec(arma::pinv(X.t()*X))); - - // Create named list with the above quantities - return Rcpp::List::create( - Rcpp::Named("coefficients") = coef, - Rcpp::Named("stderr") = std_err, - Rcpp::Named("df.residual") = n - p ); -} -``` - -The interface is very simple: a matrix $X_{n \times p}$ of regressors, and a -dependent variable $y_{n \times 1}$ as a vector. We invoke the standard Armadillo -function `solve()` to fit the model `y ~ X`.\footnote{We should note -that this will use the standard \pkg{LAPACK} functionality via Armadillo whereas R -uses an internal refinement of \pkg{LINPACK} \citep{Dongarra:1979:UGLINPACK} via pivoting, -rendering the operation numerically more stable. That is an important -robustness aspect---though common datasets on current hardware almost -never lead to actual differences. That said, if in doubt, stick with -the R implementation. What is shown here is mostly for exposition of -the principles.} We then compute residuals, and extract the -(appropriately scaled) diagonal of the covariance matrix, also taking -its square root, in order to return both estimates $\hat{\beta}$ and $\hat{\sigma}$. - -# \rcpp in Packages - -Once a project containing compiled code has matured to the point of sharing it with -collaborators\footnote{It is sometimes said that every project has two collaborators: -self, and future self. Packaging code is \textsl{best practices} even for code not -intended for public uploading.} or using it within a parallel computing environments, the -ideal way forward is to embed the code within an \rlang package. Not only does an \rlang -package provide a way to automatically compile source code, but also enables the use of -the \rlang help system to document how the written functions should be used. As a further -benefit, the package format enables the use of unit tests to ensure that the functions are -producing the correct output. Lastly, having a package provides the option of uploading -to a repository such as CRAN for wider dissemination. - -To facilitate package building, \rcpp provides a function `Rcpp.package.skeleton()` that -is modeled after the base \rlang function `package.skeleton()`. This function automates -the creation of a skeleton package appropriate for distributing \rcppns: - -```{r skeleton, eval = FALSE} -library("Rcpp") -Rcpp.package.skeleton("samplePkg") -``` - -\begin{figure} - \begin{center} - \includegraphics[width=3in]{figures/samplePkg-files-light-bg.png} - \caption{Graphical annotation of the \texttt{is\_odd\_cpp} function.} - \label{fig:package-files} - \end{center} -\end{figure} - - -This shows how distinct directories `man`, `R`, `src` are created for, -respectively, the help pages, files with \rlang code and files with -\cpp code. Generally speaking, all compiled code, be it from \clangns, -\cpp or \fortran sources, should be placed within the `src/` -directory. - -Alternatively, one can achieve similar results to using -`Rcpp.package.skeleton()` by using a feature of the -RStudio IDE. Specifically, while creating a new package project there -is an option to select the type of package by engaging a dropdown menu -to select "Package w/ Rcpp" in RStudio versions prior to v1.1.0. In RStudio -versions later than v1.1.0, support for package templates has been added -allowing users to directly create \rcppns-based packages that use Eigen or Armadillo. - -Lastly, one more option exists for users who are familiar with the \pkg{devtools} -\rlang package. To create the \rlang package skeleton -use `devtools::create("samplePkg")`. From here, part of the -structure required by \rcpp can be added by using `devtools::use_rcpp()`. -The remaining aspects needed by \rcpp must be manually copied from -the roxygen tags written to console and pasted into one of the package's \rlang -files to successfully incorporate the dynamic library and link to \rcppns's -headers. - -All of these methods take care of a number of small settings one would have to enable -manually otherwise. These include an 'Imports:' and 'LinkingTo:' declaration in file -DESCRIPTION, as well as 'useDynLib' and 'importFrom' in NAMESPACE. For _Rcpp Attributes_ -use, the `compileAttributes()` function has to be called. Similarly, to take advantage of -its documentation-creation feature, the `roxygenize()` function from \pkg{roxygen2} has to -be called.\footnote{The \pkg{littler} package \citep{CRAN:littler} has a helper script `roxy.r` -for this.} Additional details on using \rcpp within a package scope are detailed in -\citet{CRAN:Rcpp:Package}. - -# Conclusion - -\rlang has always provided mechanisms to extend it. The bare-bones \clang API is already used -to great effect by a large number of packages. By taking advantage of a number of \cpp -features, \rcpp has been able to make extending \rlang easier, offering a combination of -both speed _and_ ease of use that has been finding increasingly widespread utilization by -researchers and data scientists. We are thrilled about this adoption, and look forward to -seeing more exciting extensions to \rlang being built. diff -Nru rcpp-1.0.2/inst/doc/Rcpp-introduction.Rnw rcpp-1.0.3/inst/doc/Rcpp-introduction.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-introduction.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-introduction.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,11 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-introduction} +%\VignetteKeywords{Rcpp, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-introduction.pdf} +\end{document} + Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-jss-2011.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-jss-2011.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-jss-2011.R rcpp-1.0.3/inst/doc/Rcpp-jss-2011.R --- rcpp-1.0.2/inst/doc/Rcpp-jss-2011.R 2019-07-20 14:40:03.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-jss-2011.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -### R code from vignette source 'Rcpp-jss-2011.Rnw' - -################################################### -### code chunk number 1: prelim -################################################### -library(Rcpp) -rcpp.version <- packageDescription("Rcpp")$Version -rcpp.date <- packageDescription("Rcpp")$Date -now.date <- strftime(Sys.Date(), "%B %d, %Y") - - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-jss-2011.Rnw rcpp-1.0.3/inst/doc/Rcpp-jss-2011.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-jss-2011.Rnw 2018-05-05 12:58:40.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-jss-2011.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -1,1079 +1,11 @@ -%% use JSS class -- use 'nojss' to turn off header -\documentclass[shortnames,nojss,article]{jss} -\usepackage{booktabs,flafter,thumbpdf} +\documentclass{article} +\usepackage{pdfpages} %\VignetteIndexEntry{Rcpp-JSS-2011} %\VignetteKeywords{Rcpp, foreign function interface, .Call, C++, R} -%\VignetteDepends{Rcpp} -\SweaveOpts{concordance=FALSE} - -\author{Dirk Eddelbuettel\\Debian Project \And Romain Fran\c{c}ois\\\proglang{R} Enthusiasts} -\Plainauthor{Dirk Eddelbuettel, Romain Fran\c{c}ois} - -\title{\pkg{Rcpp}: Seamless \proglang{R} and \proglang{C++} Integration} -\Plaintitle{Rcpp: Seamless R and C++ Integration} - -\Abstract{ - The \pkg{Rcpp} package simplifies integrating \proglang{C++} code with \proglang{R}. It - provides a consistent \proglang{C++} class hierarchy that maps various types of \proglang{R} - objects (vectors, matrices, functions, environments, \dots) to dedicated \proglang{C++} - classes. Object interchange between \proglang{R} and \proglang{C++} is managed by - simple, flexible and extensible concepts which include broad support for - \proglang{C++} Standard Template Library idioms. \proglang{C++} code can both be - compiled, linked and loaded on the fly, or added via packages. - Flexible error and exception code handling is provided. - \pkg{Rcpp} substantially lowers the barrier for programmers wanting to - combine \proglang{C++} code with \proglang{R}. -} - -\Keywords{\proglang{R}, \proglang{C++}, foreign function interface, \code{.Call}} -\Plainkeywords{R, C++, foreign function interface, .Call} - -\Volume{40} -\Issue{8} -\Month{April} -\Year{2011} -\Submitdate{2010-11-15} -\Acceptdate{2011-03-21} - -\Address{ - Dirk Eddelbuettel \\ - Debian Project \\ - River Forest, IL, United States of America\\ - E-mail: \email{edd@debian.org}\\ - URL: \url{http://dirk.eddelbuettel.com/}\\ - - Romain Fran\c{c}ois\\ - Professional \proglang{R} Enthusiast\\ - 1 rue du Puits du Temple\\ - 34 000 Montpellier, France \\ - E-mail: \email{romain@r-enthusiasts.com}\\ - URL: \url{http://romainfrancois.blog.free.fr/} -} - -%% need no \usepackage{Sweave.sty} - -<>= -library(Rcpp) -rcpp.version <- packageDescription("Rcpp")$Version -rcpp.date <- packageDescription("Rcpp")$Date -now.date <- strftime(Sys.Date(), "%B %d, %Y") -@ -% - +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} \begin{document} - -\vspace*{-0.25cm} - -\section{Introduction} - -\proglang{R} \citep{R:Main} is an extensible system. -The `Writing \proglang{R} Extensions' manual \citep{R:Extensions} -describes in detail how to augment \proglang{R} with compiled code, -focusing mostly on the \proglang{C} language, but also mentioning -\proglang{C++} and \proglang{Fortran}. The \proglang{R} application programming -interface (API) described in `Writing \proglang{R} Extensions' is -based on a set of functions and macros operating on \code{SEXP} (pointers to -\code{SEXPREC} or `\proglang{S} expression' structures, see the `\proglang{R} Language' -manual \citealp{R:Language} for details) which are the internal -representation of \proglang{R} objects. -In this article, we discuss the functionality of the \pkg{Rcpp} -package \citep{CRAN:Rcpp}, which simplifies the usage of \proglang{C++} code -in \proglang{R}. Combining \proglang{R} and \proglang{C++} is not a new idea, so we start with -a short review of other approaches and give some historical -background on the development of \pkg{Rcpp}. - -The \pkg{Rcpp} package provides a consistent API for seamlessly accessing, -extending or modifying \proglang{R} objects at the \proglang{C++} level. The API is a rewritten -and extended version of an earlier API which we refer to as the `classic -\pkg{Rcpp} API'. It is still provided in the \pkg{RcppClassic} package \citep{CRAN:RcppClassic} -to ensure compatibility, but its use is otherwise deprecated. -All new development should use the richer second API which -is enclosed in the \pkg{Rcpp} \proglang{C++} -namespace, and corresponds to the redesigned code base. -This article highlights some of the key design and implementation choices of -the new API: Lightweight encapsulation of \proglang{R} objects in \proglang{C++} classes, automatic -garbage collection strategy, code inlining, data interchange between \proglang{R} and -\proglang{C++}, and error handling. - -Several examples are included to illustrate the benefits of using \pkg{Rcpp} -as opposed to the traditional \proglang{R} API. Many more examples are available within -the package, both as explicit examples and as part of the numerous unit tests. -% -The \pkg{Rcpp} package is available from the Comprehensive \proglang{R} Archive Network (CRAN) -at \url{http://CRAN.R-project.org/package=Rcpp}. - -\makeatletter -\if@nojss - This vignette corresponds to the paper published in the \textsl{Journal of - Statistical Software} (and is still mostly identical to the published paper). - It had been distributed with the \pkg{Rcpp} package as file - \textsf{Rcpp-introduction.pdf} for several years but has now been superceded by - an updated introduction \citep{PeerJ:Rcpp,TAS:Rcpp}. - - For citations, please use the \cite{JSS:Rcpp} or - \cite{Eddelbuettel:2013:Rcpp}; details are also provided in \proglang{R} via - \texttt{citation("Rcpp")}. - - This version corresponds to \pkg{Rcpp} version \Sexpr{rcpp.version} and was - typeset on \Sexpr{now.date}. -\fi -\makeatother - - -\subsection{Historical context} - -\pkg{Rcpp} first appeared in 2005 as a contribution (by Dominick Samperi) to the -\pkg{RQuantLib} package \citep{CRAN:RQuantLib} and became a CRAN package -in early 2006. Several releases (all by Samperi) followed in quick succession -under the name \pkg{Rcpp}. The package was then renamed to -\pkg{RcppTemplate}; several more releases followed during 2006 under the new -name. However, no further releases were made during 2007, 2008 or most of -2009. Following a few updates in late 2009, it was withdrawn from CRAN. - -Given the continued use of the package, Eddelbuettel decided to revitalize it. New -releases, using the initial name \pkg{Rcpp}, started in November 2008. These -included an improved build and distribution process, additional -documentation, and new functionality---while retaining the existing -`classic \pkg{Rcpp}' interface. While not described here, this API will -be provided for the foreseeable future via the \pkg{RcppClassic} package. - -Reflecting evolving \proglang{C++} coding standards \citep[see][]{Meyers:2005:EffectiveC++}, -Eddelbuettel and Fran\c{c}ois started a significant redesign of the -code base in 2009. This added numerous new features several of which are described -in this article as well as in multiple -vignettes included with the package. This new API is our current focus, -and we intend to both extend and support the API in future development of the -\pkg{Rcpp} package. - -\subsection{Related work} - -Integration of \proglang{C++} and \proglang{R} has been addressed by several authors; the earliest -published reference is probably \cite{Bates+DebRoy:2001:C++Classes}. -An unpublished paper by \cite{Java+Gaile+Manly:2007:RCpp} expresses several ideas -that are close to some of our approaches, though not yet fully fleshed out. -The \pkg{Rserve} package \citep{Urbanek:2003:Rserve,CRAN:Rserve} acts as a -socket server for \proglang{R}. On the server side, \pkg{Rserve} translates \proglang{R} data -structures into a binary serialization format and uses TCP/IP for -transfer. On the client side, objects are reconstructed as instances of \proglang{Java} -or \proglang{C++} classes that emulate the structure of \proglang{R} objects. - -The packages \pkg{rcppbind} \citep{Liang:2008:rcppbind}, \pkg{RAbstraction} -\citep{Armstrong:2009:RAbstraction} and \pkg{RObjects} -\citep{Armstrong:2009:RObjects} are all implemented using \proglang{C++} templates. -None of them have matured to the point of a CRAN release. -\pkg{CXXR} \citep{Runnalls:2009:CXXR} approaches this topic from the other direction: -Its aim is to completely refactor \proglang{R} on a stronger \proglang{C++} foundation. -\pkg{CXXR} is therefore concerned with all aspects of the \proglang{R} interpreter, -read-eval-print loop (REPL), and threading; object interchange between \proglang{R} and \proglang{C++} is but one -part. A similar approach is discussed by \cite{TempleLang:2009:ModestProposal} -who suggests making low-level internals extensible by package developers in -order to facilitate extending \proglang{R}. -\cite{TempleLang:2009:RGCCTranslationUnit}, using compiler output for -references on the code in order to add bindings and wrappers, offers -a slightly different angle. - -\subsection[Rcpp use cases]{\pkg{Rcpp} use cases} -\label{sec:classic_rcpp} - -The core focus of \pkg{Rcpp} has always been on helping the -programmer to more easily add \proglang{C++}-based functions. -Here, we use `function' in the standard mathematical sense of providing -results (output) given a set of parameters or data (input). -This was -facilitated from the earliest releases using \proglang{C++} classes for receiving -various types of \proglang{R} objects, converting them to \proglang{C++} objects and allowing the -programmer to return the results to \proglang{R} with relative ease. - -This API therefore supports two typical use cases. First, existing \proglang{R} code -may be replaced by equivalent \proglang{C++} code in order to reap -performance gains. This case is conceptually easy when there are -(built- or run-time) dependencies on other \proglang{C} or \proglang{C++} libraries. It typically -involves setting up data and parameters---the right-hand side components of a -function call---before making the call in order to provide the result that is -to be assigned to the left-hand side. Second, \pkg{Rcpp} facilitates calling -functions provided by other libraries. The use resembles the first case but -with an additional level of abstraction: data -and parameters are passed via \pkg{Rcpp} to a function set-up to call code -from an external library. - -Apart from this `vertical mode' of calling \proglang{C++} from \proglang{R}, additional -features in the new API also support a more `horizontal mode' of directly -calling \pkg{Rcpp} objects. This was motivated by the needs of other -projects such as \pkg{RInside} \citep{CRAN:RInside} for easy embedding of \proglang{R} -in \proglang{C++} applications and \pkg{RProtoBuf} \citep{CRAN:RProtoBuf} to -interface with the Protocol Buffers library. This use will be touched upon -in the next section, but a more detailed discussion is outside the scope of -this paper. Lastly, the more recent additions `\pkg{Rcpp} modules' and `\pkg{Rcpp} sugar' -also expand the use cases; see Section~\ref{sec:ongoing} below. - -\section[The Rcpp API]{The \pkg{Rcpp} API} -\label{sec:new_rcpp} - -\subsection{A first example} - -We can illustrate the \pkg{Rcpp} API by revisiting the convolution example -from the `Writing \proglang{R} Extensions' manual \citep[Chapter 5]{R:Extensions}. Using -\pkg{Rcpp}, this function can be written as follows: -% -\begin{Code} -#include - -RcppExport SEXP convolve3cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a); - Rcpp::NumericVector xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - int nab = n_xa + n_xb - 1; - Rcpp::NumericVector xab(nab); - - for (int i = 0; i < n_xa; i++) - for (int j = 0; j < n_xb; j++) - xab[i + j] += xa[i] * xb[j]; - - return xab; -} -\end{Code} -% -We can highlight several aspects. -\begin{enumerate} -\item Only a single header file - \code{Rcpp.h} is needed to use the \pkg{Rcpp} API. -\item \code{RcppExport} is a convenience macro helping with calling a - \proglang{C} function from \proglang{C++}. -\item Given two - arguments of type \code{SEXP}, a third is returned (as using only - \code{SEXP} types for input and output is prescribed by the \code{.Call()} - interface of the \proglang{R} API). -\item Both inputs are - converted to \proglang{C++} vector types provided by \pkg{Rcpp} (and we have more to say about these - conversions below). -\item The - usefulness of these classes can be seen when we query the vectors directly - for their size---using the \code{size()} member function---in order to - reserve a new result type of appropriate length, - and with the use of the - \verb|operator[]| to extract and set individual elements of the vector. -\item The computation itself is - straightforward embedded looping just as in the original examples in the - `Writing \proglang{R} Extensions' manual \citep{R:Extensions}. -\item The return conversion - from the \code{NumericVector} to the \code{SEXP} type is also automatic. -\end{enumerate} - -We argue that this \pkg{Rcpp}-based usage is much easier to read, write and debug than the -\proglang{C} macro-based approach supported by \proglang{R} itself. - - - -\subsection[Rcpp class hierarchy]{\pkg{Rcpp} class hierarchy} - -The \code{Rcpp::RObject} class is the basic class of the new \pkg{Rcpp} API. -An instance of the \code{RObject} class encapsulates an \proglang{R} object -(itself represented by the \proglang{R} type \code{SEXP}), exposes methods that are appropriate for all types -of objects and transparently manages garbage collection. - -The most important aspect of the \code{RObject} class is that it is -a very thin wrapper around the \code{SEXP} it encapsulates. The -\code{SEXP} is indeed the only data member of an \code{RObject}. The -\code{RObject} class does not interfere with the way \proglang{R} manages its -memory and does not perform copies of the object into a suboptimal -\proglang{C++} representation. Instead, it merely acts as a proxy to the -object it encapsulates so that methods applied to the \code{RObject} -instance are relayed back to the \code{SEXP} in terms of the standard -\proglang{R} API. - -The \code{RObject} class takes advantage of the explicit life cycle of -\proglang{C++} objects to manage exposure of the underlying \proglang{R} object to the -garbage collector. The \code{RObject} effectively treats -its underlying \code{SEXP} as a resource. -The constructor of the \code{RObject} class takes -the necessary measures to guarantee that the underlying \code{SEXP} -is protected from the garbage collector, and the destructor -assumes the responsibility to withdraw that protection. - -By assuming the entire responsibility of garbage collection, \pkg{Rcpp} -relieves the programmer from writing boiler plate code to manage -the protection stack with \code{PROTECT} and \code{UNPROTECT} macros. - -The \code{RObject} class defines a set of member functions applicable -to any \proglang{R} object, regardless of its type. This ranges from -querying properties of the object (\texttt{isNULL}, \texttt{isObject}, -\texttt{isS4}), management of the attributes -(\texttt{attributeNames}, \texttt{hasAttribute}, \texttt{attr}) to -handling of slots\footnote{Member functions dealing with slots -are only applicable to \proglang{S}4 objects; otherwise an exception is thrown.} -(\texttt{hasSlot}, \texttt{slot}). - -\subsection{Derived classes} - -Internally, an \proglang{R} object must have one type amongst the set of -predefined types, commonly referred to as SEXP types. The `\proglang{R} Internals' -manual \citep{R:Internals} documents these various types. -\pkg{Rcpp} associates a dedicated \proglang{C++} class for most SEXP types, and -therefore only exposes functionality that is relevant to the \proglang{R} object -that it encapsulates. - -For example \code{Rcpp::Environment} contains -member functions to manage objects in the associated environment. -Similarly, classes related to vectors---\code{IntegerVector}, \code{NumericVector}, -\code{RawVector}, \code{LogicalVector}, \code{CharacterVector}, -\code{GenericVector} (also known as \code{List}) and -\code{ExpressionVector}---expose functionality to extract and set values from the vectors. - -The following sections present typical uses of \pkg{Rcpp} classes in -comparison with the same code expressed using functions and macros of the \proglang{R} API. - -\subsection{Numeric vectors} - -The next code snippet is taken from `Writing \proglang{R} Extensions' -\citep[Section 5.9.1]{R:Extensions}. It allocates a \code{numeric} vector of two elements -and assigns some values to it using the \proglang{R} API. -% -\begin{Code} -SEXP ab; -PROTECT(ab = allocVector(REALSXP, 2)); -REAL(ab)[0] = 123.45; -REAL(ab)[1] = 67.89; -UNPROTECT(1); -\end{Code} -% -Although this is one of the simplest examples in `Writing \proglang{R} Extensions', -it seems verbose and yet it is not obvious at first sight what is happening. -Memory is allocated by \code{allocVector}; we must also supply it with -the type of data (\code{REALSXP}) and the number of elements. Once -allocated, the \code{ab} object must be protected from garbage -collection. -Lastly, the \code{REAL} macro returns a pointer to the -beginning of the actual array; its indexing does not resemble either \proglang{R} or -\proglang{C++}. - -The code can be simplified using the \code{Rcpp::NumericVector} class: -% -\begin{Code} -Rcpp::NumericVector ab(2); -ab[0] = 123.45; -ab[1] = 67.89; -\end{Code} -% -The code contains fewer idiomatic decorations. The \code{NumericVector} -constructor is given the number of elements the vector contains (2), which -hides the call to the \code{allocVector} in the original code example. Also hidden is -protection of the object from garbage collection, which is a behavior that -\code{NumericVector} inherits from \code{RObject}. Values are assigned to -the first and second elements of the vector as \code{NumericVector} overloads -the \code{operator[]}. - -The snippet can also be written more concisely as a single statement using the \code{create} -static member function of the \code{NumericVector} class: -% -\begin{Code} -Rcpp::NumericVector ab = Rcpp::NumericVector::create(123.45, 67.89); -\end{Code} - - -\subsection{Character vectors} - -A second example deals with character vectors and emulates this \proglang{R} code: -% -\begin{CodeInput} -R> c("foo", "bar") -\end{CodeInput} -% -Using the traditional \proglang{R} API, the vector can be allocated and filled as such: -% -\begin{Code} -SEXP ab; -PROTECT(ab = allocVector(STRSXP, 2)); -SET_STRING_ELT( ab, 0, mkChar("foo") ); -SET_STRING_ELT( ab, 1, mkChar("bar") ); -UNPROTECT(1); -\end{Code} -% -This imposes on the programmer knowledge of \code{PROTECT}, \code{UNPROTECT}, -\code{SEXP}, \code{allocVector}, \code{SET\_STRING\_ELT}, and \code{mkChar}. -% -Using the \code{Rcpp::CharacterVector} class, we can express the same -code more concisely: -% -\begin{Code} -Rcpp::CharacterVector ab(2); -ab[0] = "foo"; -ab[1] = "bar"; -\end{Code} - -\section[R and C++ data interchange]{\proglang{R} and \proglang{C++} data interchange} - -In addition to classes, the \pkg{Rcpp} package contains two -functions to perform conversion of \proglang{C++} objects to \proglang{R} objects and back. - -\subsection[C++ to R: wrap]{\proglang{C++} to \proglang{R}: \code{wrap}} - -The \proglang{C++} to \proglang{R} conversion is performed by the \code{Rcpp::wrap} templated -function. It uses advanced template metaprogramming techniques\footnote{A - discussion of template metaprogramming - \citep{Vandevoorde+Josuttis:2003:Templates,Abrahams+Gurtovoy:2004:TemplateMetaprogramming} is beyond the - scope of this article.} to convert a wide and extensible set of types and -classes to the most appropriate type of \proglang{R} object. The signature of the -\code{wrap} template is as follows: -% -\begin{Code} -template SEXP wrap(const T& object); -\end{Code} -% -The templated function takes a reference to a `wrappable' -object and converts this object into a \code{SEXP}, which is what \proglang{R} expects. -Currently wrappable types are: -\begin{itemize} -\item primitive types: \code{int}, \code{double}, \code{bool}, \dots which are converted -into the corresponding atomic \proglang{R} vectors; -\item \code{std::string} objects which are converted to \proglang{R} atomic character vectors; -\item Standard Template Library (STL) containers such as \code{std::vector} or \code{std::map}, -as long as the template parameter type \code{T} is itself wrappable; -\item STL maps which use \code{std::string} for keys -({e.g.}, \code{std::map}); as long as -the type \code{T} is wrappable; -\item any type that implements implicit conversion to \code{SEXP} through the -\code{operator SEXP()}; -\item any type for which the \code{wrap} template is -fully specialized. -\end{itemize} - -Wrappability of an object type is resolved at compile time using -modern techniques of template meta programming and class traits. The -\code{Rcpp-extending} vignette in the \pkg{Rcpp} package discusses in depth how to extend \code{wrap} -to third-party types. The \pkg{RcppArmadillo} -\citep*{CRAN:RcppArmadillo} and \pkg{RcppGSL} \citep{CRAN:RcppGSL} packages -feature several examples. -The following segment of code illustrates that the design allows -composition: - -\begin{Code} -RcppExport SEXP someFunction() { - std::vector > v; - std::map m1; - std::map m2; - - m1["foo"]=1; - m1["bar"]=2; - m2["foo"]=1; - m2["bar"]=2; - m2["baz"]=3; - - v.push_back( m1 ); - v.push_back( m2 ); - return Rcpp::wrap( v ); -} -\end{Code} -% -In this example, the STL types \verb+vector+ and \verb+map+ are used to -create a list of two named vectors. The member function \verb+push_back+ -insert a given element into a vector. This example is equivalent to the -result of this \proglang{R} statement: -% -\begin{Code} -list(c(bar = 2L, foo = 1L), c(bar = 2L, baz = 3L, foo = 1L)) -\end{Code} - - -\subsection[R to C++: as]{\proglang{R} to \proglang{C++}: \code{as}} - -The reverse conversion from an \proglang{R} object to a \proglang{C++} object is implemented by variations of the -\code{Rcpp::as} template whose signature is: -% -\begin{Code} -template T as(SEXP x); -\end{Code} -% -It offers less flexibility and currently -handles conversion of \proglang{R} objects into primitive types ({e.g.}, \code{bool}, \code{int}, \code{std::string}, \dots), -STL vectors of primitive types ({e.g.}, \code{std::vector}, -\code{std::vector}, \dots) and arbitrary types that offer -a constructor that takes a \code{SEXP}. In addition \code{as} can -be fully or partially specialized to manage conversion of \proglang{R} data -structures to third-party types as can be seen for example in the -\pkg{RcppArmadillo} package which eases transfer of \proglang{R} matrices and vectors to -the optimised data structures in the \pkg{Armadillo} linear algebra library \citep{Sanderson:2010:Armadillo}. - - -\subsection{Implicit use of converters} - -The converters offered by \code{wrap} and \code{as} provide a very -useful framework to implement code logic in terms of \proglang{C++} -data structures and then explicitly convert data back to \proglang{R}. - -In addition, the converters are also used implicitly -in various places in the \code{Rcpp} API. -Consider the following code that uses the \code{Rcpp::Environment} class to -interchange data between \proglang{C++} and \proglang{R}. It accesses a vector -\texttt{x} from the global environment, creates an STL \texttt{map} of string -types and pushes this back to \proglang{R}: -% -\begin{Code} -Rcpp::Environment global = Rcpp::Environment::global_env(); -std::vector vx = global["x"]; - -std::map map; -map["foo"] = "oof"; -map["bar"] = "rab"; - -global["y"] = map; -\end{Code} -% -In the first part of the example, the code extracts a -\code{std::vector} from the global environment. In order to achieve this, -the \code{operator[]} of \code{Environment} uses the proxy pattern -\citep{Meyers:1995:MoreEffectiveC++} -to distinguish between left hand side (LHS) and right hand side (RHS) use. - -The output of the \code{operator[]} is an instance of the nested class -\code{Environment::Binding}. This class defines a templated implicit conversion -operator. It is this conversion operator which allows a \code{Binding} -object to be assigned to any type that \code{Rcpp::as} is able to handle. - -In the last part of the example, the LHS use of the \code{Binding} instance is -implemented through its assignment operator. This is also templated and uses -\code{Rcpp::wrap} to perform the conversion to a \code{SEXP} that can be -assigned to the requested symbol in the global environment. - -The same mechanism is used throughout the API. Examples include access/modification -of object attributes, slots, elements of generic vectors (lists), -function arguments, nodes of dotted pair lists, language calls and more. - -\section{Function calls} -\label{sec:functions} - -\begin{table}[t!] - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Environment: Using the \pkg{Rcpp} API}} - \begin{Code} -Environment stats("package:stats"); -Function rnorm = stats["rnorm"]; -return rnorm(10, - Named("sd", 100.0)); - \end{Code} -\end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Environment: Using the \proglang{R} API}} - \begin{Code} -SEXP stats = PROTECT( - R_FindNamespace( - mkString("stats"))); -SEXP rnorm = PROTECT( - findVarInFrame(stats, - install("rnorm"))); -SEXP call = PROTECT( - LCONS( rnorm, - CONS(ScalarInteger(10), - CONS(ScalarReal(100.0), - R_NilValue)))); -SET_TAG(CDDR(call),install("sd")); -SEXP res = PROTECT(eval(call, - R_GlobalEnv)); -UNPROTECT(4); -return res; - \end{Code} - \end{minipage} - -\bigskip - - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Language: Using the \pkg{Rcpp} API}} - \begin{Code} -Language call("rnorm", 10, - Named("sd",100.0)); -return call.eval(); - \end{Code} - \end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Language: Using the \proglang{R} API}} - \begin{Code} -SEXP call = PROTECT( - LCONS(install("rnorm"), - CONS(ScalarInteger(10), - CONS(ScalarReal(100.0), - R_NilValue)))); -SET_TAG(CDDR(call),install("sd")); -SEXP res = PROTECT(eval(call, - R_GlobalEnv)); -UNPROTECT(2); -return res; - \end{Code} - \end{minipage} - -\bigskip - - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Sugar: Using the \pkg{Rcpp} API}} - \begin{Code} -RNGScope scope; -return rnorm(10, 0, 100); - \end{Code} -\end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Sugar: Using the \proglang{R} API}} - - \medskip - (not applicable) - \end{minipage} - -\bigskip - - \caption{\pkg{Rcpp} versus the \proglang{R} API: Five ways of calling - \code{rnorm(10L, sd = 100)} in \proglang{C}/\proglang{C++}.} - \label{fig:rnormCode} - \medskip \small - Note that we have removed the \code{Rcpp::} prefix for readability; this corresponds to adding a directive - \texttt{using namespace Rcpp;} in the code. The versions that use callbacks to \proglang{R} do not require handling - of the state of the random number generator. The version that uses \pkg{Rcpp} sugar requires it, which - is done via the instantiation of the \code{RNGScope} variable. -\end{table} - -The next example shows how to use \pkg{Rcpp} to emulate the \proglang{R} code -\code{rnorm(10L, sd = 100.0)}. -As shown in Table~\ref{fig:rnormCode}, the code can be expressed in several -ways in either \pkg{Rcpp} or the standard \proglang{R} API. The first version shows the -use of the \code{Environment} and \code{Function} classes by -\pkg{Rcpp}. -The second version shows the use of the \code{Language} class, which -manages calls (LANGSXP). -For comparison, we also show both versions using the standard \proglang{R} API. -Finally, we also show a variant using `\pkg{Rcpp} sugar', a topic which is -discussed in Sections~\ref{sec:perfcomp} and \ref{sec:ongoing} below. - -This example illustrates that the \pkg{Rcpp} API permits us to work with code -that is easier to read, write and maintain. More examples are available as -part of the documentation included in the \pkg{Rcpp} package, as well as -among its over seven hundred and fifty unit tests. - -\section{Using code `inline'} -\label{sec:inline} - -Extending \proglang{R} with compiled code requires a mechanism for reliably compiling, -linking, and loading the code. While using a package is preferable in the long run, -it may be too involved for quick explorations. An alternative is -provided by the \pkg{inline} package \citep{CRAN:inline} which compiles, -links and loads a \proglang{C}, \proglang{C++} or \proglang{Fortran} function---directly from the \proglang{R} prompt -using simple functions \code{cfunction} and \code{cxxfunction}. The latter provides an extension which -works particularly well with \pkg{Rcpp} via so-called `plugins' which provide -information about additional header file and -library locations. - -The use of \pkg{inline} is possible as \pkg{Rcpp} can be installed and -updated just like any other \proglang{R} package using, for examples, the -\code{install.packages()} function for initial installation as well as -\code{update.packages()} for upgrades. So even though \proglang{R}/\proglang{C++} interfacing -would otherwise require source code, the \pkg{Rcpp} library is always provided -ready for use as a pre-built library through the CRAN package -mechanism.\footnote{This presumes a platform for which pre-built binaries are - provided. \pkg{Rcpp} is available in binary form for Windows and OS~X users from - CRAN, and as a \code{.deb} package for Debian and Ubuntu users. For other systems, the - \pkg{Rcpp} library is automatically built from source during installation - or upgrades.} - -The library and header files provided by \pkg{Rcpp} for use by other packages -are installed along with the \pkg{Rcpp} package. The \code{LinkingTo:}~\code{Rcpp} -directive in the \code{DESCRIPTION} file lets \proglang{R} properly reference the header files. -The \pkg{Rcpp} package provides appropriate information for the \code{-L} -switch needed for linking via the function \code{Rcpp:::LdFlags()}. -It can be used by \code{Makevars} files of other -packages, and \pkg{inline} makes use of it internally so that all of this is -done behind the scenes without the need for explicitly setting compiler or -linker options. - -The convolution example provided above can be rewritten for use by -\pkg{inline} as shown below. The function body is provided by the \proglang{R} character -variable \code{src}, the function header is defined by the argument -\code{signature}, and we only need to enable \code{plugin = "Rcpp"} to obtain a -new \proglang{R} function \code{fun} based on the \proglang{C++} code in \code{src}: -% -\begin{CodeChunk} -\begin{CodeInput} -R> src <- ' -+ Rcpp::NumericVector xa(a); -+ Rcpp::NumericVector xb(b); -+ int n_xa = xa.size(), n_xb = xb.size(); -+ -+ Rcpp::NumericVector xab(n_xa + n_xb - 1); -+ for (int i = 0; i < n_xa; i++) -+ for (int j = 0; j < n_xb; j++) -+ xab[i + j] += xa[i] * xb[j]; -+ return xab; -+ ' -R> fun <- cxxfunction(signature(a = "numeric", b = "numeric"), -+ src, plugin = "Rcpp") -R> fun(1:3, 1:4) -\end{CodeInput} -\begin{CodeOutput} -[1] 1 4 10 16 17 12 -\end{CodeOutput} -\end{CodeChunk} -% -With one assignment to the \proglang{R} variable \code{src}, and one call of the \proglang{R} function -\code{cxxfunction} (provided by the \pkg{inline} package), we have created a new \proglang{R} -function \code{fun} that uses the \proglang{C++} code we assigned to -\code{src}---and all this functionality can be used directly from the \proglang{R} -prompt making prototyping with \proglang{C++} functions straightforward. - -\textsl{Update}: \pkg{Rcpp} version 0.10.0 and later contain new and powerful feature -called 'Rcpp Attributes' which provides an even more powerful mechanism; see -\cite{CRAN:Rcpp:Attributes} for more details. - -\section{Using Standard Template Library algorithms} - -The STL offers a variety of generic -algorithms designed to be used on ranges of elements -\citep{Plauger+Et+Al:2000:STL}. A range is any sequence of objects that can be -accessed through iterators or pointers. All \pkg{Rcpp} classes from the new -API representing vectors (including lists) can produce ranges through their -member functions \code{begin()} and \code{end()}, effectively supporting -iterating over elements of an \proglang{R} vector. - -The following code illustrates how \pkg{Rcpp} might be used -to emulate a -simpler\footnote{The version of \code{lapply} does not allow use of the -ellipsis (\code{...}).} version of \code{lapply} -using the \code{transform} algorithm from the STL. -% -\begin{CodeChunk} -\begin{CodeInput} -R> src <- ' -+ Rcpp::List input(data); -+ Rcpp::Function f(fun); -+ Rcpp::List output(input.size()); -+ std::transform(input.begin(), input.end(), output.begin(), f); -+ output.names() = input.names(); -+ return output; -+ ' -R> cpp_lapply <- cxxfunction(signature(data = "list", fun = "function"), -+ src, plugin = "Rcpp") -\end{CodeInput} -\end{CodeChunk} -% -We can now use this \code{cpp_lapply} function to calculate a summary of each -column of the \code{faithful} data set included with \proglang{R}. -% -\begin{CodeInput} -R> cpp_lapply(faithful, summary) -\end{CodeInput} -\begin{CodeOutput} -$eruptions - Min. 1st Qu. Median Mean 3rd Qu. Max. -1.600 2.163 4.000 3.488 4.454 5.100 - -$waiting - Min. 1st Qu. Median Mean 3rd Qu. Max. - 43.0 58.0 76.0 70.9 82.0 96.0 -\end{CodeOutput} - - -\section{Error handling} - -Code that uses both \proglang{R} and \proglang{C++} has to deal with two distinct -error handling models. \pkg{Rcpp} simplifies this and allows both -systems to work together. - -\subsection[C++ exceptions in R]{\proglang{C++} exceptions in \proglang{R}} - -The internals of the \proglang{R} condition mechanism and the implementation of -\proglang{C++} exceptions are both based on a layer above POSIX jumps. These layers -both assume total control over the call stack and should not be used together -without extra precaution. \pkg{Rcpp} contains facilities to combine both systems -so that \proglang{C++} exceptions are caught and recycled into the \proglang{R} condition -mechanism. - -\pkg{Rcpp} defines the \code{BEGIN\_RCPP} and \code{END\_RCPP} macros that should -be used to bracket code that might throw \proglang{C++} exceptions. -% -\begin{Code} -RcppExport SEXP fun( SEXP x ) { -BEGIN_RCPP - int dx = Rcpp::as(x); - if( dx > 10 ) - throw std::range_error("too big"); - return Rcpp::wrap( dx * dx); -END_RCPP -} -\end{Code} -% -The macros are simply defined to avoid code repetition. They expand to -simple \code{try}/\code{catch} blocks so that the above example becomes: -% -\begin{Code} -RcppExport SEXP fun( SEXP x ) { - try { - int dx = Rcpp::as(x); - if( dx > 10 ) - throw std::range_error("too big"); - return Rcpp::wrap( dx * dx); - } catch( std::exception& __ex__ ) { - forward_exception_to_r( __ex__ ); - } catch(...) { - ::Rf_error( "c++ exception (unknown reason)" ); - } -} -\end{Code} -% -Using \code{BEGIN\_RCPP} and \code{END\_RCPP}---or the expanded -versions---guarantees that the stack is first unwound in terms of \proglang{C++} -exceptions, before the problem is converted to the standard \proglang{R} error -management system using the function \code{Rf\_error} of the \proglang{R} API. - -The \code{forward\_exception\_to\_r} function uses run-time type information to -extract information about the class of the \proglang{C++} exception and its message so that -dedicated handlers can be installed on the \proglang{R} side. -% -\begin{CodeChunk} -\begin{CodeInput} -R> f <- function(x) .Call("fun", x) -R> tryCatch(f(12), "std::range_error" = function(e) { conditionMessage(e) }) -\end{CodeInput} -\begin{CodeOutput} -[1] "too big" -\end{CodeOutput} -\begin{CodeInput} -R> tryCatch(f(12), "std::range_error" = function(e) { class(e) }) -\end{CodeInput} -\begin{CodeOutput} -[1] "std::range_error" "C++Error" "error" "condition" -\end{CodeOutput} -\end{CodeChunk} -% -A serious limitation of this approach is the lack of support for calling -handlers. \proglang{R} calling handlers are also based on POSIX jumps, and using both -calling handlers from the \proglang{R} engine as well \proglang{C++} exception forwarding might -lead to undetermined results. Future versions of \pkg{Rcpp} might attempt to -to improve this issue. - -\subsection[R errors in C++]{\proglang{R} errors in \proglang{C++}} - -\proglang{R} itself currently does not offer \proglang{C}-level mechanisms to deal with errors. To -overcome this problem, \pkg{Rcpp} uses the \code{Rcpp\_eval} -function to evaluate an \proglang{R} expression in an R-level \code{tryCatch} -block. The error, if any, that occurs while evaluating the -function is then translated into an \proglang{C++} exception that can be dealt with using -regular \proglang{C++} \code{try}/\code{catch} syntax. - -An open (and rather hard) problem, however, is posed by the fact that calls -into the \proglang{C} API offered by \proglang{R} cannot be reliably protected. Such -calls can always encounter an error condition of their own triggering a call -to \code{Rf_error} which will lead to a sudden death of the program. In -particular, neither \proglang{C++} class destructors nor \code{catch} parts of outer -\code{try}/\code{catch} blocks will be called. This leaves the potential for -memory or resource leakage. So while newly written code can improve on this -situation via use of \proglang{C++} exception handling, existing code calling -into the \proglang{C} API of \proglang{R} cannot be amended just by having an outer layer -of exception handling around it. - - -\section{Performance comparison} -\label{sec:perfcomp} - -In this section, we present several different ways to leverage \pkg{Rcpp} to -rewrite the convolution example from `Writing \proglang{R} Extensions' \citep[Chapter 5]{R:Extensions} -first discussed in Section~\ref{sec:new_rcpp}. -As part of the redesign of \pkg{Rcpp}, data copy is kept to the -absolute minimum: The \code{RObject} class and all its derived -classes are just a container for a \code{SEXP} object. We let \proglang{R} perform -all memory management and access data though the macros or functions -offered by the standard \proglang{R} API. - -The implementation of the \code{operator[]} is designed to be as -efficient as possible, using both inlining and caching, -but even this implementation is still less efficient than the -reference \proglang{C} implementation described in \cite{R:Extensions}. - -\pkg{Rcpp} follows design principles from the STL, and classes such -as \code{NumericVector} expose iterators that can be used for -sequential scans of the data. Algorithms using iterators are -usually more efficient than those that operate on objects using the -\code{operator[]}. The following version of the convolution function -illustrates the use of the \code{NumericVector::iterator}. -% -\begin{Code} -#include - -RcppExport SEXP convolve4cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a), xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - Rcpp::NumericVector xab(n_xa + n_xb - 1); - - typedef Rcpp::NumericVector::iterator vec_iterator; - vec_iterator ia = xa.begin(), ib = xb.begin(); - vec_iterator iab = xab.begin(); - for (int i = 0; i < n_xa; i++) - for (int j = 0; j < n_xb; j++) - iab[i + j] += ia[i] * ib[j]; - - return xab; -} -\end{Code} -% -One of the focuses of recent developments of \pkg{Rcpp} is called `\pkg{Rcpp} sugar', -and aims to provide R-like syntax in \proglang{C++}. While a fuller discussion of \pkg{Rcpp} sugar is -beyond the scope of this article, we have included -another version of the convolution algorithm based on \pkg{Rcpp} sugar for illustrative purposes here: -% -\begin{Code} -#include - -RcppExport SEXP convolve11cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a), xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - Rcpp::NumericVector xab(n_xa + n_xb-1, 0.0); - - Rcpp::Range r( 0, n_xb-1 ); - for (int i=0; i} & 683 & 3.13 \\ - \bottomrule - \end{tabular} - \end{small} - \caption{Run-time performance of the different convolution examples.} - \label{tab:benchmark} - \end{center} -\end{table} - -The first implementation, written in \proglang{C} and using the traditional \proglang{R} API, -provides our base case. It takes advantage of pointer arithmetics and therefore -does not to pay the price of \proglang{C++} object encapsulation or operator overloading. - -The slowest solution illustrates the price of object encapsulation. Calling an overloaded -\code{operator[]} as opposed to using direct pointer arithmetics as in the -reference case costs about 29\% in performance. - -The next implementation uses iterators rather than indexing. Its performance -is indistinguishable from the base case. -This also shows that the use of \proglang{C++} may not necessarily imply any performance -penalty. Further, \proglang{C++} \code{iterators} can be used to achieve the performance -of \proglang{C} pointers, but without the potential dangers of direct memory -access via pointers. - -Finally, the fastest implementation uses \pkg{Rcpp} sugar. It performs -significantly better than the base case. Explicit loop unrolling provides us with -vectorization at the \proglang{C++} level which is responsible for this particular speedup. - -\section{On-going development} -\label{sec:ongoing} - -\pkg{Rcpp} is in very active development: Current work in the -package (and in packages such as \pkg{RcppArmadillo}) -focuses on further improving interoperability between \proglang{R} and \proglang{C++}. -Two core themes for on-going development are `\pkg{Rcpp} sugar' as well as `\pkg{Rcpp} modules', both of which are -also discussed in more detail in specific vignettes in the \pkg{Rcpp} package. - -`\pkg{Rcpp} sugar' offers syntactic -sugar at the \proglang{C++} level, including optimized binary operators and many -\proglang{R} functions such as \code{ifelse}, \code{sapply}, \code{any}, \code{head}, -\code{tail}, and more. -The main technique used in \pkg{Rcpp} sugar is -expression templates pioneered by the \pkg{Blitz++} library \citep{Veldhuizen:1998:Blitz} -and since adopted -by projects such as \pkg{Armadillo} \citep{Sanderson:2010:Armadillo}. -Access to most of the d/p/q/r-variants of the statistical distribution -functions has also been added, enabling the use of expressions such as -\code{dnorm(X, m, s)} for a numeric vector \code{X} and scalars \code{m} and -\code{s}. This was shown in Table~\ref{fig:rnormCode} in -Section~\ref{sec:functions} above where -the \proglang{R} expression \code{rnorm(10L, sd = 100)} -was rewritten in \proglang{C++} as \code{rnorm(10, 0, 100)}. Note that -\proglang{C++} semantics require the second parameter to be used here, which is -different from the \proglang{R} case. - -`\pkg{Rcpp} modules' allows programmers to expose \proglang{C++} functions and classes at the -\proglang{R} level. This offers access to \proglang{C++} code from \proglang{R} using even less interface -code than by writing accessor functions. Modules are inspired by the -\pkg{Boost.Python} library -\citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python} which provides similar -functionality for \proglang{Python}. \proglang{C++} classes exposed by \pkg{Rcpp} modules are -shadowed by reference classes which have been introduced in \proglang{R} 2.12.0. - -\textsl{Update}: Besides the vignettes for '\pkg{Rcpp} Sugar' -\citep{CRAN:Rcpp:Sugar} and '\pkg{Rcpp} Modules' \citep{CRAN:Rcpp:Modules}, -the aforementioned vignette for '\pkg{Rcpp} Attributes' -\citep{CRAN:Rcpp:Attributes} describes a new possibility for even more direct -integration between \proglang{Rcpp} and \proglang{C++}. - -\section{Summary} - -The \pkg{Rcpp} package presented in this paper greatly simplifies integration of -compiled \proglang{C++} code with \proglang{R}. -\pkg{Rcpp} provides a \proglang{C++} class hierarchy which allows manipulation of \proglang{R} data structures in \proglang{C++} -using member functions and operators directly related to the type -of object being used, thereby reducing the level of expertise -required to master the various functions and macros offered by the -internal \proglang{R} API. The classes assume the entire -responsibility of garbage collection of objects, relieving the -programmer from book-keeping operations with the protection stack -and enabling him/her to focus on the underlying problem. - -Data interchange between \proglang{R} and \proglang{C++} code is performed by the \code{wrap()} and -\code{as()} template functions. They allow the programmer to write logic in terms -of \proglang{C++} data structures, and facilitate use of modern libraries such as the -Standard Template Library (STL) and its containers and algorithms. The -\code{wrap()} and \code{as()} template functions are extensible by -design. They are also used either explicitly or implicitly throughout the API. -By using only thin wrappers around \code{SEXP} objects and adopting \proglang{C++} -idioms such as iterators, the footprint of the \pkg{Rcpp} API -is very lightweight, and does not incur a significant performance penalty. - -The \pkg{Rcpp} API offers opportunities to dramatically reduce the complexity -of code, which should lower the initial cost of writing code and improve code readability, maintainability, and -reuse---without incurring noticeable penalties in run-time performance. - -\section*{Acknowledgments} - -Detailed comments and suggestions by editors as well as anonymous referees -are gratefully acknowledged. We are also thankful for code contributions by -Douglas Bates and John Chambers, as well as for very helpful suggestions by Uwe -Ligges, Brian Ripley and Simon Urbanek concerning the build systems for different -platforms. Last but not least, several users provided very fruitful -ideas for new or extended features via the \code{rcpp-devel} mailing list. - -\bibliography{\Sexpr{Rcpp:::bib()}} - -\vspace*{-0.35cm} - +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-jss-2011.pdf} \end{document} -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-modules.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-modules.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-modules.R rcpp-1.0.3/inst/doc/Rcpp-modules.R --- rcpp-1.0.2/inst/doc/Rcpp-modules.R 2019-07-20 14:39:37.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-modules.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -## ---- eval=FALSE--------------------------------------------------------- -# f1 <- cxxfunction( , "", includes = unifModCode, -# plugin = "Rcpp" ) -# getDynLib(f1) ## will display info about 'f1' - -## ---- eval=FALSE--------------------------------------------------------- -# setClass("Uniform", -# representation( pointer = "externalptr")) -# -# # helper -# Uniform_method <- function(name) { -# paste("Uniform", name, sep = "__") -# } -# -# # syntactic sugar to allow object$method( ... ) -# setMethod("$", "Uniform", function(x, name) { -# function(...) -# .Call(Uniform_method(name) , -# x@pointer, ...) -# } ) -# # syntactic sugar to allow new( "Uniform", ... ) -# setMethod("initialize", "Uniform", -# function(.Object, ...) { -# .Object@pointer <- -# .Call(Uniform_method("new"), ...) -# .Object -# } ) -# -# u <- new("Uniform", 0, 10) -# u$draw( 10L ) - -## ---- eval=FALSE--------------------------------------------------------- -# inc <- ' -# using namespace Rcpp; -# -# double norm( double x, double y ) { -# return sqrt(x*x + y*y); -# } -# -# RCPP_MODULE(mod) { -# function("norm", &norm); -# } -# ' -# -# fx <- cxxfunction(signature(), -# plugin="Rcpp", include=inc) -# mod <- Module("mod", getDynLib(fx)) - -## ---- eval=FALSE--------------------------------------------------------- -# require(nameOfMyModulePackage) -# mod <- new( mod ) -# mod$norm( 3, 4 ) - -## ---- eval=FALSE--------------------------------------------------------- -# require(Rcpp) -# -# yd <- Module("yada", getDynLib(fx)) -# yd$bar(2L) -# yd$foo(2L, 10.0) -# yd$hello() -# yd$bla() -# yd$bla1(2L) -# yd$bla2(2L, 5.0) - -## ---- eval=FALSE--------------------------------------------------------- -# require(myModulePackage) ## if another name -# -# bar(2L) -# foo(2L, 10.0) -# hello() -# bla() -# bla1(2L) -# bla2(2L, 5.0) - -## ---- eval=FALSE--------------------------------------------------------- -# mod <- Module("mod", getDynLib(fx)) -# show(mod$norm) - -## ---- eval=FALSE--------------------------------------------------------- -# norm <- mod$norm -# norm() -# norm(y = 2) -# norm(x = 2, y = 3) -# args(norm) - -## ---- eval=FALSE--------------------------------------------------------- -# norm <- mod$norm -# args(norm) - -## ---- eval=FALSE--------------------------------------------------------- -# norm <- mod$norm -# args(norm) - -## ---- eval=FALSE--------------------------------------------------------- -# ## assumes fx_unif <- cxxfunction(...) ran -# unif_module <- Module("unif_module", -# getDynLib(fx_unif)) -# Uniform <- unif_module$Uniform -# u <- new(Uniform, 0, 10) -# u$draw(10L) -# u$range() -# u$max <- 1 -# u$range() -# u$draw(10) - -## ---- eval=FALSE--------------------------------------------------------- -# Bar <- mod_bar$Bar -# b <- new(Bar, 10) -# b$x + b$x -# b$stats() -# b$x <- 10 -# b$stats() - -## ---- eval=FALSE--------------------------------------------------------- -# dv1 <- new(Base, "d1") -# dv1$name() # returns "Derived1" -# dv2 <- new(Base, "d2") -# dv2$name() # returns "Derived2" - -## ---- eval=FALSE--------------------------------------------------------- -# setMethod("show", yada$World , function(object) { -# msg <- paste("World object with message : ", -# object$greet()) -# writeLines(msg) -# } ) - -## ---- eval=FALSE--------------------------------------------------------- -# foo <- new(Foo) -# bar <- new(Bar) -# bar$handleFoo(foo) -# #> Got a Foo! - -## ---- eval=FALSE--------------------------------------------------------- -# # for code compiled on the fly using -# # cxxfunction() into 'fx_vec', we use -# mod_vec <- Module("mod_vec", -# getDynLib(fx_vec), -# mustStart = TRUE) -# vec <- mod_vec$vec -# # and that is not needed in a package -# # setup as e.g. one created -# # via Rcpp.package.skeleton(..., module=TRUE) -# v <- new(vec) -# v$reserve(50L) -# v$assign(1:10) -# v$push_back(10) -# v$size() -# v$capacity() -# v[[ 0L ]] -# v$as.vector() - -## ---- echo=FALSE,eval=TRUE----------------------------------------------- -options( prompt = " ", continue = " " ) - -## ---- eval=FALSE--------------------------------------------------------- -# import(Rcpp) - -## ---- eval=FALSE--------------------------------------------------------- -# import(Rcpp, evalCpp) - -## ---- eval=FALSE--------------------------------------------------------- -# .onLoad <- function(libname, pkgname) { -# loadRcppModules() -# } - -## ---- eval=FALSE--------------------------------------------------------- -# loadModule("yada") -# loadModule("stdVector") -# loadModule("NumEx") - -## ---- eval=FALSE--------------------------------------------------------- -# yada <- Module( "yada" ) -# -# .onLoad <- function(libname, pkgname) { -# # placeholder -# } - -## ---- echo=FALSE,eval=TRUE----------------------------------------------- -options(prompt = "> ", continue = "+ ") - -## ---- eval=FALSE--------------------------------------------------------- -# Rcpp.package.skeleton("testmod", module = TRUE) - -## ---- eval=FALSE--------------------------------------------------------- -# yada <- Module("yada") -# prompt(yada, "yada-module.Rd") - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-modules.Rmd rcpp-1.0.3/inst/doc/Rcpp-modules.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-modules.Rmd 2019-03-27 10:06:05.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-modules.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,1233 +0,0 @@ ---- -title: | - | Exposing \proglang{C++} functions and classes - | with \pkg{Rcpp} modules - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note discusses \textsl{Rcpp modules}. \textsl{Rcpp modules} allow programmers to - expose \proglang{C++} functions and classes to \proglang{R} with relative - ease. \textsl{Rcpp modules} are inspired from the \pkg{Boost.Python} - \proglang{C++} library \citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python} - which provides similar features for \proglang{Python}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - modules - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - \newcommand{\ith}{\textsl{i}-\textsuperscript{th}} - -vignette: > - %\VignetteIndexEntry{Rcpp-modules} - %\VignetteKeywords{Rcpp, modules, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Motivation - -Exposing \proglang{C++} functionality to \proglang{R} is greatly facilitated -by the \pkg{Rcpp} package and its underlying \proglang{C++} library -\citep{CRAN:Rcpp,JSS:Rcpp}. \pkg{Rcpp} smoothes many of the rough edges in -\proglang{R} and \proglang{C++} integration by replacing the traditional -\proglang{R} Application Programming Interface (API) described in -'\textsl{Writing R Extensions}' \citep{R:Extensions} with a consistent set of \proglang{C++} -classes. The '\textsl{Rcpp-jss-2011}' vignette \citep{CRAN:Rcpp,JSS:Rcpp} describes the API and -provides an introduction to using \pkg{Rcpp}. - -These \pkg{Rcpp} facilities offer a lot of assistance to the programmer -wishing to interface \proglang{R} and \proglang{C++}. At the same time, these -facilities are limited as they operate on a function-by-function basis. The -programmer has to implement a `.Call` compatible function (to -conform to the \proglang{R} API) using classes of the \pkg{Rcpp} API as -described in the next section. - -## Exposing functions using \pkg{Rcpp} - -Exposing existing \proglang{C++} functions to \proglang{R} through \pkg{Rcpp} -usually involves several steps. One approach is to write an additional wrapper -function that is responsible for converting input objects to the appropriate -types, calling the actual worker function and converting the results back to -a suitable type that can be returned to \proglang{R} (`SEXP`). -Consider the `norm` function below: - -```cpp -double norm( double x, double y ) { - return sqrt( x*x + y*y ); -} -``` - -This simple function does not meet the requirements set by the `.Call` -convention, so it cannot be called directly by \proglang{R}. Exposing the -function involves writing a simple wrapper function -that does match the `.Call` requirements. \pkg{Rcpp} makes this easy. - -```cpp -using namespace Rcpp; -RcppExport SEXP norm_wrapper(SEXP x_, SEXP y_) { - // step 0: convert input to C++ types - double x = as(x_), y = as(y_); - - // step 1: call the underlying C++ function - double res = norm(x, y); - - // step 2: return the result as a SEXP - return wrap(res); -} -``` - -Here we use the (templated) \pkg{Rcpp} converter `as()` which can -transform from a `SEXP` to a number of different \proglang{C++} and -\pkg{Rcpp} types. The \pkg{Rcpp} function `wrap()` offers the opposite -functionality and converts many known types to a `SEXP`. - -This process is simple enough, and is used by a number of CRAN packages. -However, it requires direct involvement from the programmer, which quickly -becomes tiresome when many functions are involved. \textsl{Rcpp modules} -provides a much more elegant and unintrusive way to expose \proglang{C++} -functions such as the `norm` function shown above to \proglang{R}. - -We should note that \pkg{Rcpp} now has \textsl{Rcpp attributes} which extends -certain aspect of \textsl{Rcpp modules} and makes binding to simple functions -such as this one even easier. With \textsl{Rcpp attribues} we can just write - -```cpp -# include - -// [[Rcpp::export]] -double norm(double x, double y) { - return sqrt(x*x + y*y); -} -``` - -See the corresponding vignette \citep{CRAN:Rcpp:Attributes} for details, but -read on for \textsl{Rcpp modules} which contains to provide features not -covered by \textsl{Rcpp attributes}, particularly when it comes to binding -entire C++ classes and more. - -## Exposing classes using Rcpp - -Exposing \proglang{C++} classes or structs is even more of a challenge because it -requires writing glue code for each member function that is to be exposed. - -Consider the simple `Uniform` class below: - -```cpp -class Uniform { -public: - Uniform(double min_, double max_) : - min(min_), max(max_) {} - - NumericVector draw(int n) { - RNGScope scope; - return runif(n, min, max); - } - -private: - double min, max; -}; -``` - -To use this class from R, we at least need to expose the constructor and -the `draw` method. External pointers -\citep{R:Extensions} are the perfect vessel for this, and using the -`Rcpp:::XPtr` template from \pkg{Rcpp} we can expose the class -with these two functions: - -```cpp -using namespace Rcpp; - -/// create external pointer to a Uniform object -RcppExport SEXP Uniform__new(SEXP min_, - SEXP max_) { - // convert inputs to appropriate C++ types - double min = as(min_), - max = as(max_); - - // create pointer to an Uniform object and - // wrap it as an external pointer - Rcpp::XPtr - ptr( new Uniform( min, max ), true ); - - // return the external pointer to the R side - return ptr; -} - -/// invoke the draw method -RcppExport SEXP Uniform__draw(SEXP xp, SEXP n_) { - // grab the object as a XPtr (smart pointer) - // to Uniform - Rcpp::XPtr ptr(xp); - - // convert the parameter to int - int n = as(n_); - - // invoke the function - NumericVector res = ptr->draw( n ); - - // return the result to R - return res; -} -``` - -As it is generally a bad idea to expose external pointers `as is', -they usually get wrapped as a slot of an S4 class. - -Using `cxxfunction()` from the \pkg{inline} package, we can build this -example on the fly. Suppose the previous example code assigned to a text variable -`unifModcode`, we could then do - - - -```{r, eval=FALSE} -f1 <- cxxfunction( , "", includes = unifModCode, - plugin = "Rcpp" ) -getDynLib(f1) ## will display info about 'f1' -``` - -The following listing shows some \textsl{manual} wrapping to access the code, -we will see later how this can be automated: - -```{r, eval=FALSE} -setClass("Uniform", - representation( pointer = "externalptr")) - -# helper -Uniform_method <- function(name) { - paste("Uniform", name, sep = "__") -} - -# syntactic sugar to allow object$method( ... ) -setMethod("$", "Uniform", function(x, name) { - function(...) - .Call(Uniform_method(name) , - x@pointer, ...) -} ) -# syntactic sugar to allow new( "Uniform", ... ) -setMethod("initialize", "Uniform", - function(.Object, ...) { - .Object@pointer <- - .Call(Uniform_method("new"), ...) - .Object -} ) - -u <- new("Uniform", 0, 10) -u$draw( 10L ) -``` - -\pkg{Rcpp} considerably simplifies the code that would -be involved for using external pointers with the traditional \proglang{R} API. -Yet this still involves a lot of mechanical code that quickly -becomes hard to maintain and error prone. -\textsl{Rcpp modules} offer an elegant way to expose the `Uniform` -class in a way that makes both the internal -\proglang{C++} code and the \proglang{R} code easier. - - - -# Rcpp modules - -The design of Rcpp modules has been influenced by \proglang{Python} modules which are generated by the -`Boost.Python` library \citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python}. -Rcpp modules provide a convenient and easy-to-use way -to expose \proglang{C++} functions and classes to \proglang{R}, grouped -together in a single entity. - -A Rcpp module is created in a `cpp` file using the `RCPP_MODULE` -macro, which then provides declarative code of what the module -exposes to \proglang{R}. - -## Exposing \proglang{C++} functions using Rcpp modules - -Consider the `norm` function from the previous section. -We can expose it to \proglang{R} : - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm); -} -``` - -The code creates an Rcpp module called `mod` -that exposes the `norm` function. \pkg{Rcpp} automatically -deduces the conversions that are needed for input and output. This alleviates -the need for a wrapper function using either \pkg{Rcpp} or the \proglang{R} API. - -On the \proglang{R} side, the module is retrieved by using the -`Module` function from \pkg{Rcpp} - -```{r, eval=FALSE} -inc <- ' -using namespace Rcpp; - -double norm( double x, double y ) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm); -} -' - -fx <- cxxfunction(signature(), - plugin="Rcpp", include=inc) -mod <- Module("mod", getDynLib(fx)) -``` - -Note that this example assumed that the previous code segment defining the -module was returned by the `cxxfunction()` (from the \pkg{inline} -package) as callable R function `fx` from which we can extract the -relevant pointer using `getDynLib()`. In the case of using Rcpp modules -via a package (which is detailed in Section \ref{sec:package} below), modules -are actually loaded differently and we would have used - -```{r, eval=FALSE} -require(nameOfMyModulePackage) -mod <- new( mod ) -mod$norm( 3, 4 ) -``` - -where the module is loaded upon startup and we use the constructor -directly. More details on this aspect follow below. - -A module can contain any number of calls to `function` to register -many internal functions to \proglang{R}. For example, these 6 functions : - -```cpp -std::string hello() { - return "hello"; -} - -int bar( int x) { - return x*2; -} - -double foo( int x, double y) { - return x * y; -} - -void bla( ) { - Rprintf("hello\\n"); -} - -void bla1( int x) { - Rprintf("hello (x = %d)\\n", x); -} - -void bla2( int x, double y) { - Rprintf("hello (x = %d, y = %5.2f)\\n", x, y); -} -``` - -can be exposed with the following minimal code: - -```cpp -RCPP_MODULE(yada) { - using namespace Rcpp; - - function("hello" , &hello); - function("bar" , &bar ); - function("foo" , &foo ); - function("bla" , &bla ); - function("bla1" , &bla1 ); - function("bla2" , &bla2 ); -} -``` - -which can then be used from \proglang{R}: - -```{r, eval=FALSE} -require(Rcpp) - -yd <- Module("yada", getDynLib(fx)) -yd$bar(2L) -yd$foo(2L, 10.0) -yd$hello() -yd$bla() -yd$bla1(2L) -yd$bla2(2L, 5.0) -``` - -In the case of a package (as for example the one created by -`Rcpp.package.skeleton()` with argument `module=TRUE`; more on that -below), we can use - -```{r, eval=FALSE} -require(myModulePackage) ## if another name - -bar(2L) -foo(2L, 10.0) -hello() -bla() -bla1(2L) -bla2(2L, 5.0) -``` - - -The requirements for a function to be exposed to \proglang{R} via Rcpp modules -are: - -- The function takes between 0 and 65 parameters. -- The type of each input parameter must be manageable by the `Rcpp::as` template. -- The return type of the function must be either `void` or any type that - can be managed by the `Rcpp::wrap` template. -- The function name itself has to be unique in the module. - In other words, no two functions with - the same name but different signatures are allowed. C++ allows overloading - functions. This might be added in future versions of modules. - -### Documentation for exposed functions using Rcpp modules - -In addition to the name of the function and the function pointer, it is possible -to pass a short description of the function as the third parameter of `function`. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm, - "Provides a simple vector norm"); -} -``` - -The description is used when displaying the function to the R prompt: - -```{r, eval=FALSE} -mod <- Module("mod", getDynLib(fx)) -show(mod$norm) -``` - -### Formal arguments specification - -`function` also gives the possibility to specify the formal arguments -of the R function that encapsulates the C++ function, by passing -a `Rcpp::List` after the function pointer. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals) { - function("norm", - &norm, - List::create(_["x"] = 0.0, - _["y"] = 0.0), - "Provides a simple vector norm"); -} -``` - -A simple usage example is provided below: - -```{r, eval=FALSE} -norm <- mod$norm -norm() -norm(y = 2) -norm(x = 2, y = 3) -args(norm) -``` - -To set formal arguments without default values, simply omit the rhs. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals2) { - function("norm", &norm, - List::create(_["x"], _["y"] = 0.0), - "Provides a simple vector norm"); -} -``` - -This can be used as follows: - -```{r, eval=FALSE} -norm <- mod$norm -args(norm) -``` - -The ellipsis (`...`) can be used to denote that additional arguments -are optional; it does not take a default value. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals3) { - function("norm", &norm, - List::create(_["x"], _["..."]), - "documentation for norm"); -} -``` - -and from the R side: - -```{r, eval=FALSE} -norm <- mod$norm -args(norm) -``` - - -## Exposing \proglang{C++} classes using Rcpp modules - -Rcpp modules also provide a mechanism for exposing \proglang{C++} classes, based -on the reference classes introduced in R 2.12.0. - -### Initial example - -A class is exposed using the `class_` keyword. The `Uniform` -class may be exposed to \proglang{R} as follows: - -```cpp -using namespace Rcpp; -class Uniform { -public: - Uniform(double min_, double max_) : - min(min_), max(max_) {} - - NumericVector draw(int n) const { - RNGScope scope; - return runif(n, min, max); - } - - double min, max; -}; - -double uniformRange(Uniform* w) { - return w->max - w->min; -} - -RCPP_MODULE(unif_module) { - - class_("Uniform") - - .constructor() - - .field("min", &Uniform::min) - .field("max", &Uniform::max) - - .method("draw", &Uniform::draw) - .method("range", &uniformRange) - ; - -} -``` - -```{r, eval=FALSE} -## assumes fx_unif <- cxxfunction(...) ran -unif_module <- Module("unif_module", - getDynLib(fx_unif)) -Uniform <- unif_module$Uniform -u <- new(Uniform, 0, 10) -u$draw(10L) -u$range() -u$max <- 1 -u$range() -u$draw(10) -``` - -`class_` is templated by the \proglang{C++} class or struct -that is to be exposed to \proglang{R}. -The parameter of the `class_` constructor is the name we will -use on the \proglang{R} side. It usually makes sense to use the same name as the class -name. While this is not enforced, it might be useful when exposing a class -generated from a template. - -Then constructors, fields and methods are exposed. - -### Exposing constructors using Rcpp modules - -Public constructors that take from 0 and 6 parameters can be exposed -to the R level using the `.constuctor` template method of `.class_`. - -Optionally, `.constructor` can take a description as the first argument. - -```cpp - .constructor("sets the min and " - "max value of the distribution") -``` - -Also, the second argument can be a function pointer (called validator) -matching the following type : - -```cpp -typedef bool (*ValidConstructor)(SEXP*,int); -``` - -The validator can be used to implement dispatch to the appropriate constructor, -when multiple constructors taking the same number of arguments are exposed. -The default validator always accepts the constructor as valid if it is passed -the appropriate number of arguments. For example, with the call above, the default -validator accepts any call from R with two `double` arguments (or -arguments that can be cast to `double`). - -TODO: include validator example here - -### Exposing fields and properties - -`class_` has three ways to expose fields and properties, as -illustrated in the example below : - -```cpp -using namespace Rcpp; -class Foo { -public: - Foo(double x_, double y_, double z_): - x(x_), y(y_), z(z_) {} - - double x; - double y; - - double get_z() { return z; } - void set_z(double z_) { z = z_; } - -private: - double z; -}; - -RCPP_MODULE(mod_foo) { - class_( "Foo" ) - - .constructor() - - .field("x", &Foo::x) - .field_readonly("y", &Foo::y) - - .property("z", &Foo::get_z, &Foo::set_z) - ; -} -``` - -The `.field` method exposes a public field with read/write access from R. -`field` accepts an extra parameter to give a short description of the -field: - -```cpp - .field("x", &Foo::x, "documentation for x") -``` - -The `.field_readonly` exposes a public field with read-only access from R. -It also accepts the description of the field. - -```cpp - .field_readonly("y", &Foo::y, - "documentation for y") -``` - -The `.property` method allows indirect access to fields through -a getter and a setter. The setter is optional, and the property is considered -read-only if the setter is not supplied. A description of the property is also -allowed: - -```cpp - // with getter and setter - .property("z", &Foo::get_z, - &Foo::set_z, "Documentation for z") - - // with only getter - .property("z", - &Foo::get_z, "Documentation for z") -``` - -The type of the field (\textbf{T}) is deduced from the return type of the getter, and if a -setter is given its unique parameter should be of the same type. - -Getters can be member functions taking no parameter and returning a \textbf{T} -(for example `get_z` above), or -a free function taking a pointer to the exposed -class and returning a \textbf{T}, for example: - -```cpp -double z_get(Foo* foo) { return foo->get_z(); } -``` - -Setters can be either a member function taking a `T` and returning void, such -as `set_z` above, or a free function taking a pointer to the target -class and a \textbf{T} : - -```cpp -void z_set(Foo* foo, double z) { foo->set_z(z); } -``` - -Using properties gives more flexibility in case field access has to be tracked -or has impact on other fields. For example, this class keeps track of how many times -the `x` field is read and written. - -```cpp -class Bar { -public: - - Bar(double x_) : x(x_), nread(0), nwrite(0) {} - - double get_x() { - nread++; - return x; - } - - void set_x(double x_) { - nwrite++; - x = x_; - } - - IntegerVector stats() const { - return - IntegerVector::create(_["read"] = nread, - _["write"] = nwrite); - } - -private: - double x; - int nread, nwrite; -}; - -RCPP_MODULE(mod_bar) { - class_( "Bar" ) - - .constructor() - - .property( "x", &Bar::get_x, &Bar::set_x ) - .method( "stats", &Bar::stats ) - ; -} -``` - -Here is a simple usage example: - -```{r, eval=FALSE} -Bar <- mod_bar$Bar -b <- new(Bar, 10) -b$x + b$x -b$stats() -b$x <- 10 -b$stats() -``` - -### Exposing methods using Rcpp modules - -`class_` has several overloaded and templated `.method` -functions allowing the programmer to expose a method associated with the class. - -A legitimate method to be exposed by `.method` can be: - -- A public member function of the class, either const or non const, that - returns void or any type that can be handled by `Rcpp::wrap`, and that - takes between 0 and 65 parameters whose types can be handled by `Rcpp::as`. -- A free function that takes a pointer to the target class as its first - parameter, followed by 0 or more (up to 65) parameters that can be handled by - `Rcpp::as` and returning a type that can be handled by `Rcpp::wrap` - or void. - -### Documenting methods - -`.method` can also include a short documentation of the method, after the method -(or free function) pointer. - -```cpp -.method("stats", &Bar::stats, - "vector indicating the number of " - "times x has been read and written") -``` - -TODO: mention overloading, need good example. - - -### Const and non-const member functions - -`method` is able to expose both `const` and `non const` -member functions of a class. There are however situations where -a class defines two versions of the same method, differing only in their -signature by the `const`-ness. It is for example the case of the -member functions `back` of the `std::vector` template from -the STL. - -```cpp -reference back ( ); -const_reference back ( ) const; -``` - -To resolve the ambiguity, it is possible to use `const_method` -or `nonconst_method` instead of `method` in order -to restrict the candidate methods. - -### Special methods - -\pkg{Rcpp} considers the methods `[[` and `[[<-` special, -and promotes them to indexing methods on the \proglang{R} side. - -### Object finalizers - -The `.finalizer` member function of `class_` can be used to -register a finalizer. A finalizer is a free function that takes a pointer -to the target class and return `void`. The finalizer is called -before the destructor and so operates on a valid object of the target class. - -It can be used to perform operations, releasing resources, etc ... - -The finalizer is called automatically when the \proglang{R} object that encapsulates -the \proglang{C++} object is garbage collected. - -### Object factories - -The `.factory` member function of `class_` can be used to register a -[factory](https://en.wikipedia.org/wiki/Factory_method_pattern) that -can be used as alternative to a constructor. A factory can be a -static member function or a free function that returns a pointer to -the target class. Typical use-cases include creating objects in a -hierarchy: - -```cpp -#include -using namespace Rcpp; - -// abstract class -class Base { - public: - virtual ~Base() {} - virtual std::string name() const = 0; -}; - -// first derived class -class Derived1: public Base { - public: - Derived1() : Base() {} - virtual std::string name() const { - return "Derived1"; - } -}; - -// second derived class -class Derived2: public Base { - public: - Derived2() : Base() {} - virtual std::string name() const { - return "Derived2"; - } -}; - -Base *newBase( const std::string &name ) { - if (name == "d1"){ - return new Derived1; - } else if (name == "d2"){ - return new Derived2; - } else { - return 0; - } -} - -RCPP_MODULE(mod) { - Rcpp::class_< Base >("Base") - .factory(newBase) - .method("name", &Base::name); -} -``` - -The `newBase` method returns a pointer to a `Base` object. Since that -class is an abstract class, the objects are actually instances of -`Derived1` or `Derived2`. The same behavior is now available in R: - -```{r, eval=FALSE} -dv1 <- new(Base, "d1") -dv1$name() # returns "Derived1" -dv2 <- new(Base, "d2") -dv2$name() # returns "Derived2" -``` - -### S4 dispatch - -When a \proglang{C++} class is exposed by the `class_` template, -a new S4 class is registered as well. The name of the S4 class is -obfuscated in order to avoid name clashes (i.e. two modules exposing the -same class). - -This allows implementation of \proglang{R}-level -(S4) dispatch. For example, one might implement the `show` -method for \proglang{C++} `World` objects: - -```{r, eval=FALSE} -setMethod("show", yada$World , function(object) { - msg <- paste("World object with message : ", - object$greet()) - writeLines(msg) -} ) -``` - -TODO: mention R inheritance (John ?) - -### Extending `Rcpp::as` and `Rcpp::wrap` - -Sometimes it is necessary to extend `Rcpp::as` or `Rcpp::wrap` for -classes that are also exposed using Rcpp modules. Instead of using the -general methods described in the _Rcpp Extending_ vignette, one can -use the `RCPP_EXPOSED_AS` or `RCPP_EXPOSED_WRAP` macros. -Alternatively the `RCPP_EXPOSED_CLASS` macro defines both `Rcpp::as` -and `Rcpp::wrap` specializations. Do not use these macros together -with the generic extension mechanisms. Note that opposesd to the -generic methods, these macros can be used _after_ `Rcpp.h` has been -loaded. Here an example of a pair of Rcpp modules exposed classes -where one of them has a method taking an instance of the other class -as argument. In this case it is suffcient to use `RCPP_EXPOSED_AS` to -enable the transparent conversion from \proglang{R} to \proglang{C++}: - -```cpp -#include - -class Foo { -public: - Foo() = default; -}; - -class Bar { -public: - Bar() = default; - void handleFoo(Foo foo) { - Rcpp::Rcout << "Got a Foo!" << std::endl; - }; -}; - -RCPP_EXPOSED_AS(Foo) - -RCPP_MODULE(Foo){ - Rcpp::class_("Foo") - .constructor(); -} - -RCPP_MODULE(Barl){ - Rcpp::class_("Bar") - .constructor() - .method("handleFoo", &Bar::handleFoo); -} -``` - -```{r, eval=FALSE} -foo <- new(Foo) -bar <- new(Bar) -bar$handleFoo(foo) -#> Got a Foo! -``` - -### Full example - - - -The following example illustrates how to use Rcpp modules to expose -the class `std::vector` from the STL. - -```cpp -typedef std::vector vec; -void vec_assign(vec* obj, - Rcpp::NumericVector data) { - obj->assign(data.begin(), data.end()); -} -void vec_insert(vec* obj, int position, - Rcpp::NumericVector data) { - vec::iterator it = obj->begin() + position; - obj->insert(it, data.begin(), data.end()); -} -Rcpp::NumericVector vec_asR( vec* obj ) { - return Rcpp::wrap( *obj ); -} -void vec_set(vec* obj, int i, double value) { - obj->at( i ) = value; -} - -RCPP_MODULE(mod_vec) { - using namespace Rcpp; - - // we expose class std::vector - // as "vec" on the R side - class_("vec") - - // exposing constructors - .constructor() - .constructor() - - // exposing member functions - .method("size", &vec::size) - .method("max_size", &vec::max_size) - .method("resize", &vec::resize) - .method("capacity", &vec::capacity) - .method("empty", &vec::empty) - .method("reserve", &vec::reserve) - .method("push_back", &vec::push_back) - .method("pop_back", &vec::pop_back) - .method("clear", &vec::clear) - - // exposing const member functions - .const_method("back", &vec::back) - .const_method("front", &vec::front) - .const_method("at", &vec::at ) - - // exposing free functions taking a - // std::vector* as their first - // argument - .method("assign", &vec_assign) - .method("insert", &vec_insert) - .method("as.vector", &vec_asR) - - // special methods for indexing - .const_method("[[", &vec::at) - .method("[[<-", &vec_set) - ; -} -``` - -```{r, eval=FALSE} -# for code compiled on the fly using -# cxxfunction() into 'fx_vec', we use -mod_vec <- Module("mod_vec", - getDynLib(fx_vec), - mustStart = TRUE) -vec <- mod_vec$vec -# and that is not needed in a package -# setup as e.g. one created -# via Rcpp.package.skeleton(..., module=TRUE) -v <- new(vec) -v$reserve(50L) -v$assign(1:10) -v$push_back(10) -v$size() -v$capacity() -v[[ 0L ]] -v$as.vector() -``` - -# Using modules in other packages {#sec:package} - -## Namespace import/export - -### Import all functions and classes - -When using \pkg{Rcpp} modules in a packages, the client package needs to -import \pkg{Rcpp}'s namespace. This is achieved by adding the -following line to the `NAMESPACE` file. - -```{r, echo=FALSE,eval=TRUE} -options( prompt = " ", continue = " " ) -``` - -```{r, eval=FALSE} -import(Rcpp) -``` - -In some case we have found that explicitly naming a symbol can be preferable: - -```{r, eval=FALSE} -import(Rcpp, evalCpp) -``` - -## Load the module - -### Deprecated older method using loadRcppModules - -Note: This approach is deprecated as of Rcpp 0.12.5, and now triggers a warning -message. Eventually this function will be withdrawn. - -The simplest way to load all functions and classes from a module directly -into a package namespace used to be to use the `loadRcppModules` function -within the `.onLoad` body. - -```{r, eval=FALSE} -.onLoad <- function(libname, pkgname) { - loadRcppModules() -} -``` - -This will look in the package's DESCRIPTION file for the `RcppModules` -field, load each declared module and populate their contents into the -package's namespace. For example, both the \pkg{testRcppModule} package -(which is part of large unit test suite for \pkg{Rcpp}) and the package -created via `Rcpp.package.skeleton("somename", module=TRUE)` have this -declaration: - -``` -RcppModules: yada, stdVector, NumEx -``` - -The `loadRcppModules` function has a single argument `direct` -with a default value of `TRUE`. With this default value, all content -from the module is exposed directly in the package namespace. If set to -`FALSE`, all content is exposed as components of the module. - -### Preferred current method using loadModule - -Starting with release 0.9.11, an alternative is provided by the -`loadModule()` function which takes the module name as an argument. -It can be placed in any `.R` file in the package. This is useful as it allows to load -the module from the same file as some auxiliary \proglang{R} functions using the -module. For the example module, the equivalent code to the `.onLoad()` -use shown above then becomes - -```{r, eval=FALSE} -loadModule("yada") -loadModule("stdVector") -loadModule("NumEx") -``` - -This feature is also used in the new Rcpp Classes introduced with Rcpp 0.9.11. - -### Just expose the module - -Alternatively, it is possible to just expose the module to the user of the package, -and let them extract the functions and classes as needed. This uses lazy loading -so that the module is only loaded the first time the user attempts to extract -a function or a class with the dollar extractor. - -```{r, eval=FALSE} -yada <- Module( "yada" ) - -.onLoad <- function(libname, pkgname) { - # placeholder -} -``` - -```{r, echo=FALSE,eval=TRUE} -options(prompt = "> ", continue = "+ ") -``` - - -## Support for modules in skeleton generator - -The `Rcpp.package.skeleton` function has been improved to help -\pkg{Rcpp} modules. When the `module` argument is set to `TRUE`, -the skeleton generator installs code that uses a simple module. - -```{r, eval=FALSE} -Rcpp.package.skeleton("testmod", module = TRUE) -``` - -Creating a new package using \textsl{Rcpp modules} is easiest via the call to -`Rcpp.package.skeleton()` with argument `module=TRUE` as a working -package with three example Modules results. - -## Module documentation - -\pkg{Rcpp} defines a `prompt` method for the -`Module` class, allowing generation of a skeleton of an Rd -file containing some information about the module. - -```{r, eval=FALSE} -yada <- Module("yada") -prompt(yada, "yada-module.Rd") -``` - -We strongly recommend using a package when working with Modules. But in case a -manually compiled shared library has to loaded, the return argument of the -`getDynLib()` function can be supplied as the `PACKAGE` argument to -the `Module()` function as well. - - -# Future extensions {#sec:future} - -`Boost.Python` has many more features that we would like to port -to Rcpp modules : class inheritance, default arguments, enum -types, ... - -# Known shortcomings {#sec:misfeatures} - -There are some things \textsl{Rcpp modules} is not good at: - -- serialization and deserialization of objects: modules are - implemented via an external pointer using a memory location, which is - non-constant and varies between session. Objects have to be re-created, - which is different from the (de-)serialization that R offers. So these - objects cannot be saved from session to session. -- mulitple inheritance: currently, only simple class structures are - representable via \textsl{Rcpp modules}. - -# Summary - -This note introduced \textsl{Rcpp modules} and illustrated how to expose -\proglang{C++} function and classes more easily to \proglang{R}. -We hope that \proglang{R} and \proglang{C++} programmers -find \textsl{Rcpp modules} useful. - - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-modules.Rnw rcpp-1.0.3/inst/doc/Rcpp-modules.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-modules.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-modules.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-modules} +%\VignetteKeywords{Rcpp, modules, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-modules.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-package.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-package.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-package.Rmd rcpp-1.0.3/inst/doc/Rcpp-package.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-package.Rmd 2017-11-04 19:04:52.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-package.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,491 +0,0 @@ ---- -title: Writing a package that uses \pkg{Rcpp} - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document provides a short overview of how to use - \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} when writing - an \proglang{R} package. It shows how usage of the function - \rdoc{Rcpp}{Rcpp.package.skeleton} which creates a complete and - self-sufficient example package using \pkg{Rcpp}. All components of the - directory tree created by \rdoc{Rcpp}{Rcpp.package.skeleton} are discussed - in detail. This document thereby complements the \textsl{Writing R - Extensions} manual \citep{R:Extensions} which is the authoritative source - on how to extend \proglang{R} in general. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - package - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - -vignette: > - %\VignetteIndexEntry{Rcpp-package} - %\VignetteKeywords{Rcpp, package, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -# Introduction - -\pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} is an extension -package for \proglang{R} which offers an easy-to-use yet featureful interface -between \proglang{C++} and \proglang{R}. However, it is somewhat different -from a traditional \proglang{R} package because its key component is a -\proglang{C++} library. A client package that wants to make use of the -\pkg{Rcpp} features must link against the library provided by \pkg{Rcpp}. - -It should be noted that \proglang{R} has only limited support for -\proglang{C(++)}-level dependencies between packages \citep{R:Extensions}. The -`LinkingTo` declaration in the package `DESCRIPTION` file -allows the client package to retrieve the headers of the target package (here -\pkg{Rcpp}), but support for linking against a library is not provided by -\proglang{R} and has to be added manually. - -This document follows the steps of the \rdoc{Rcpp}{Rcpp.package.skeleton} -function to illustrate a recommended way of using \pkg{Rcpp} from a client -package. We illustrate this using a simple \proglang{C++} function -which will be called by an \proglang{R} function. - -We strongly encourage the reader to become familiar with the material in the -\textsl{Writing R Extensions} manual \citep{R:Extensions}, as well as with other -documents on \proglang{R} package creation such as \cite{Leisch:2008:Tutorial}. Given -a basic understanding of how to create \proglang{R} package, the present -document aims to provide the additional information on how to use \pkg{Rcpp} -in such add-on packages. - -# Using `Rcpp.package.skeleton` - -## Overview - -\pkg{Rcpp} provides a function \rdoc{Rcpp}{Rcpp.package.skeleton}, modeled -after the base \proglang{R} function \rdoc{utils}{package.skeleton}, which -facilitates creation of a skeleton package using \pkg{Rcpp}. - -\rdoc{Rcpp}{Rcpp.package.skeleton} has a number of arguments documented on -its help page (and similar to those of \rdoc{utils}{package.skeleton}). The -main argument is the first one which provides the name of the package one -aims to create by invoking the function. An illustration of a call using an -argument `mypackage` is provided below. - -```r -Rcpp.package.skeleton("mypackage") -``` - -\begin{ShadedResult} -\begin{verbatim} -$ ls -1R mypackage/ -DESCRIPTION -NAMESPACE -R -Read-and-delete-me -man -src - -mypackage/R: -RcppExports.R - -mypackage/man: -mypackage-package.Rd -rcpp_hello_world.Rd - -mypackage/src: -Makevars # until Rcpp 0.10.6, see below -Makevars.win # until Rcpp 0.10.6, see below -RcppExports.cpp -rcpp_hello_world.cpp -$ -\end{verbatim} -\end{ShadedResult} - -Using \rdoc{Rcpp}{Rcpp.package.skeleton} is by far the simplest approach -as it fulfills two roles. It creates the complete set of files needed for a -package, and it also includes the different components needed for using -\pkg{Rcpp} that we discuss in the following sections. - -## \proglang{C++} code - -If the `attributes` argument is set to `TRUE`[^1], the -following \proglang{C++} file is included in the `src/` directory: - -```cpp -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List rcpp_hello_world() { - - CharacterVector x = - CharacterVector::create("foo", "bar"); - NumericVector y = - NumericVector::create( 0.0, 1.0 ) ; - List z = List::create( x, y ) ; - - return z ; -} -``` - -The file defines the simple `rcpp_hello_world` function that -uses a few \pkg{Rcpp} classes and returns a `List`. - -This function is preceded by the `Rcpp::export` attribute to automatically -handle argument conversion because \proglang{R} has to be taught how to -e.g. handle the `List` class. - -\rdoc{Rcpp}{Rcpp.package.skeleton} then invokes \rdoc{Rcpp}{compileAttributes} -on the package, which generates the `RcppExports.cpp` file (where we indented -the first two lines for the more compact display here): - -```rcpp -// Generated by using Rcpp::compileAttributes() \ -// -> do not edit by hand -// Generator token: \ -// 10BE3573-1514-4C36-9D1C-5A225CD40393 - -#include - -using namespace Rcpp; - -// rcpp_hello_world -List rcpp_hello_world(); -RcppExport SEXP mypackage_rcpp_hello_world() { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - rcpp_result_gen = - Rcpp::wrap(rcpp_hello_world()); - return rcpp_result_gen; -END_RCPP -} -``` - -This file defines a function with the appropriate calling convention, suitable for -\rdoc{base}{.Call}. It needs to be regenerated each time functions -exposed by attributes are modified. This is the task of the -\rdoc{Rcpp}{compileAttributes} function. A discussion on attributes is -beyond the scope of this document and more information is available -in the attributes vignette \citep{CRAN:Rcpp:Attributes}. - -## \proglang{R} code - -The \rdoc{Rcpp}{compileAttributes} also generates \proglang{R} code -that uses the \proglang{C++} function. - -```r -# Generated by using Rcpp::compileAttributes() \ -# -> do not edit by hand -# Generator token: \ -# 10BE3573-1514-4C36-9D1C-5A225CD40393 - -rcpp_hello_world <- function() { - .Call('mypackage_rcpp_hello_world', - PACKAGE = 'mypackage') -} -``` - -This is also a generated file so it should not be modified manually, rather -regenerated as needed by \rdoc{Rcpp}{compileAttributes}. - -## `DESCRIPTION` - -The skeleton generates an appropriate `DESCRIPTION` file, using -both `Imports:` and `LinkingTo` for \pkg{Rcpp}: - -\begin{ShadedResult} -\begin{verbatim} -Package: mypackage -Type: Package -Title: What the package does (short line) -Version: 1.0 -Date: 2013-09-17 -Author: Who wrote it -Maintainer: Who -Description: More about what it does (maybe - more than one line) -License: What Licence is it under ? -Imports: Rcpp (>= 0.11.0) -LinkingTo: Rcpp -\end{verbatim} -\end{ShadedResult} - - -\rdoc{Rcpp}{Rcpp.package.skeleton} adds the three last lines to the -`DESCRIPTION` file generated by \rdoc{utils}{package.skeleton}. - -The `Imports` declaration indicates \proglang{R}-level dependency -between the client package and \pkg{Rcpp}; code from the latter is being -imported into the package described here. The `LinkingTo` declaration -indicates that the client package needs to use header files exposed by -\pkg{Rcpp}. - -## Now optional: `Makevars` and `Makevars.win` - -This behaviour changed with \pkg{Rcpp} release 0.11.0. These files used to be -mandatory, now they are merely optional. - -We will describe the old setting first as it was in use for a few years. The -new standard, however, is much easier and is described below. - -## Releases up until 0.10.6 - -Unfortunately, the `LinkingTo` declaration in itself was not -enough to link to the user \proglang{C++} library of \pkg{Rcpp}. Until more -explicit support for libraries is added to \proglang{R}, ones needes to manually -add the \pkg{Rcpp} library to the `PKG_LIBS` variable in the -`Makevars` and `Makevars.win` files. (This has now changed with -release 0.11.0; see below). -\pkg{Rcpp} provides the unexported function `Rcpp:::LdFlags()` to ease the process: - -```sh -## Use the R_HOME indirection to support -## installations of multiple R version -## -## NB: No longer needed, see below -PKG_LIBS = `$(R_HOME)/bin/Rscript -e \ - "Rcpp:::LdFlags()"` - -``` - -The `Makevars.win` is the equivalent, targeting windows. - -```sh -## Use the R_HOME indirection to support -## installations of multiple R version -## -## NB: No longer needed, see below -PKG_LIBS = $(shell \ - "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" \ - -e "Rcpp:::LdFlags()") -``` - -## Releases since 0.11.0 - -As of release 0.11.0, this is no longer needed as client packages obtain the -required code from \pkg{Rcpp} via explicit function registration. The user -does not have to do anything. - -This means that `PKG_LIBS` can now be empty---unless some client -libraries are needed. For example, \pkg{RcppCNPy} needs compression support -and hence uses `PKG_LIBS= -lz`. Similarly, when a third-party library is -required, it can and should be set here. - -## `NAMESPACE` - -The \rdoc{Rcpp}{Rcpp.package.skeleton} function also creates a file -`NAMESPACE`. - -```sh -useDynLib(mypackage) -exportPattern("^[[:alpha:]]+") -importFrom(Rcpp, evalCpp) -``` - -This file serves three purposes. First, it ensure that the dynamic library -contained in the package we are creating via -\rdoc{Rcpp}{Rcpp.package.skeleton} will be loaded and thereby made -available to the newly created \proglang{R} package. - -Second, it declares which functions should be globally visible from the -namespace of this package. As a reasonable default, we export all functions. - -Third, it instructs R to import a symbol from \pkg{Rcpp}. This sets up the -import of all registered function and, together with the `Imports:` -statement in `DESCRIPTION`, provides what is needed for client packages -to access \pkg{Rcpp} functionality. - -## Help files - -Also created is a directory `man` containing two help files. One is -for the package itself, the other for the (single) \proglang{R} function -being provided and exported. - -The \textsl{Writing R Extensions} manual \citep{R:Extensions} provides the complete -documentation on how to create suitable content for help files. - -## `mypackage-package.Rd` - -The help file `mypackage-package.Rd` can be used to describe -the new package (and we once again indented some lines): - -```sh -\name{mypackage-package} -\alias{mypackage-package} -\alias{mypackage} -\docType{package} -\title{ -What the package does (short line) -} -\description{ -More about what it does (maybe more than one line) -~~ A concise (1-5 lines) description of the -package ~~ -} -\details{ -\tabular{ll}{ -Package: \tab mypackage\cr -Type: \tab Package\cr -Version: \tab 1.0\cr -Date: \tab 2013-09-17\cr -License: \tab What license is it under?\cr -} -~~ An overview of how to use the package, -including the most important functions ~~ -} -\author{ -Who wrote it - -Maintainer: Who -} -\references{ -~~ Literature or other references for -background information ~~ -} -~~ Optionally other standard keywords, one per -line, from file KEYWORDS in the R -documentation directory ~~ -\keyword{ package } -\seealso{ -~~ Optional links to other man pages, e.g. ~~ -~~ \code{\link[:-package]{}} ~~ -} -\examples{ -%% ~~ simple examples of the most important -%% functions ~~ -} -``` - -## `rcpp_hello_world.Rd` - -The help file `rcpp_hello_world.Rd` serves as documentation for the -example \proglang{R} function. - -```sh -\name{rcpp_hello_world} -\alias{rcpp_hello_world} -\docType{package} -\title{ -Simple function using Rcpp -} -\description{ -Simple function using Rcpp -} -\usage{ -rcpp_hello_world() -} -\examples{ -\dontrun{ -rcpp_hello_world() -} -} -``` - -# Using modules - -This document does not cover the use of the `module` argument -of \rdoc{Rcpp}{Rcpp.package.skeleton}. It is covered -in the modules vignette \citep{CRAN:Rcpp:Modules}. - -# Further examples - -The canonical example of a package that uses \pkg{Rcpp} is the -\pkg{RcppExamples} \citep{CRAN:RcppExamples} package. \pkg{RcppExamples} -contains various examples of using \pkg{Rcpp}. Hence, the \pkg{RcppExamples} -package is provided as a template for employing \pkg{Rcpp} in packages. - -Other CRAN packages using the \pkg{Rcpp} package are \pkg{RcppArmadillo} -\citep{CRAN:RcppArmadillo}, -and \pkg{minqa} \citep{CRAN:minqa}. Several other packages follow older (but still supported -and appropriate) instructions. They can serve examples on how to get data to -and from \proglang{C++} routines, but should not be considered templates for -how to connect to \pkg{Rcpp}. The full list of packages using \pkg{Rcpp} can -be found at the [CRAN page](http://CRAN.R-project.org/package=Rcpp) of -\pkg{Rcpp}. - -# Other compilers - -Less experienced \proglang{R} users on the Windows platform frequently ask -about using \pkg{Rcpp} with the Visual Studio toolchain. That is simply not -possible as \proglang{R} is built with the \pkg{gcc} compiler. Different -compilers have different linking conventions. These conventions are -particularly hairy when it comes to using \proglang{C++}. In short, it is -not possible to simply drop sources (or header files) from \pkg{Rcpp} into a -\proglang{C++} project built with Visual Studio, and this note makes no -attempt at claiming otherwise. - -\pkg{Rcpp} is fully usable on Windows provided the standard Windows -toolchain for \proglang{R} is used. See the \textsl{Writing R Extensions} -manual \citep{R:Extensions} for details. - -# Summary - -This document described how to use the \pkg{Rcpp} package for \proglang{R} -and \proglang{C++} integration when writing an \proglang{R} extension -package. The use of the \rdoc{Rcpp}{Rcpp.package.skeleton} was shown in -detail, and references to further examples were provided. - -[^1]: Setting `attributes` to `TRUE` is the default. This document - does not cover the behavior of `Rcpp.package.skeleton` when `attributes` is set - to `FALSE` as we try to encourage package developpers to use - attributes. diff -Nru rcpp-1.0.2/inst/doc/Rcpp-package.Rnw rcpp-1.0.3/inst/doc/Rcpp-package.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-package.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-package.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-package} +%\VignetteKeywords{Rcpp, package, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-package.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-quickref.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-quickref.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-quickref.R rcpp-1.0.3/inst/doc/Rcpp-quickref.R --- rcpp-1.0.2/inst/doc/Rcpp-quickref.R 2019-07-20 14:39:49.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-quickref.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -## ---- eval = FALSE------------------------------------------------------- -# ## Note - this is R code. -# ## cppFunction in Rcpp allows rapid testing. -# require(Rcpp) -# -# cppFunction(" -# NumericVector exfun(NumericVector x, int i){ -# x = x*i; -# return x; -# }") -# -# exfun(1:5, 3) -# -# ## Use evalCpp to evaluate C++ expressions -# evalCpp("std::numeric_limits::max()") - -## ---- eval = FALSE------------------------------------------------------- -# # In R, create a package shell. For details, -# # see the "Writing R Extensions" manual and -# # the "Rcpp-package" vignette. -# -# Rcpp.package.skeleton("myPackage") -# -# # Add R code to pkg R/ directory. Call C++ -# # function. Do type-checking in R. -# -# myfunR <- function(Rx, Ry) { -# ret = .Call("myCfun", Rx, Ry, -# package="myPackage") -# return(ret) -# } - -## ---- eval=FALSE--------------------------------------------------------- -# require(myPackage) -# -# aa <- 1.5 -# bb <- 1.5 -# cc <- myfunR(aa, bb) -# aa == bb -# # FALSE, C++ modifies aa -# -# aa <- 1:2 -# bb <- 1:2 -# cc <- myfunR(aa, bb) -# identical(aa, bb) -# # TRUE, R/C++ types don't match -# # so a copy was made - -## ---- eval=FALSE--------------------------------------------------------- -# Rcpp::sourceCpp("path/to/file/Rcpp_example.cpp") -# x <- 1:5 -# all.equal(muRcpp(x), mean(x)) -# all.equal(var(x),varRcpp(x)) - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-quickref.Rmd rcpp-1.0.3/inst/doc/Rcpp-quickref.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-quickref.Rmd 2018-12-26 11:59:01.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-quickref.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,554 +0,0 @@ ---- -title: \pkg{Rcpp} Quick Reference Guide - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document provides short code snippets that are helpful for using the - \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - quickref - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - -vignette: > - %\VignetteIndexEntry{Rcpp-quickref} - %\VignetteKeywords{Rcpp, quickref, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Important Notes - -```cpp -// If you experience compiler errors, please check -// that you have an appropriate version of g++. -// See `Rcpp-FAQ' for more information. - -// Many of the examples here imply the following: -#include -using namespace Rcpp; -// The cppFunction will automatically add this. - -// Or, prefix Rcpp objects with the Rcpp namespace -// as e.g. in: -Rcpp::NumericVector xx(10); -``` - -# Create simple vectors - -```cpp -SEXP x; std::vector y(10); - -// from SEXP -NumericVector xx(x); - -// of a given size (filled with 0) -NumericVector xx(10); -// ... with a default for all values -NumericVector xx(10, 2.0); - -// range constructor -NumericVector xx(y.begin(), y.end()); - -// using create -NumericVector xx = - NumericVector::create(1.0, 2.0, 3.0, 4.0); -NumericVector yy = - NumericVector::create(Named("foo") = 1.0, - _["bar"] = 2.0); - // _ short for Named -``` - -# Extract and set single elements - -```cpp -// extract single values -double x0 = xx[0]; -double x1 = xx(1); - -double y0 = yy["foo"]; -double y1 = yy["bar"]; - -// set single values -xx[0] = 2.1; -xx(1) = 4.2; - -yy["foo"] = 3.0; - -// grow the vector -yy["foobar"] = 10.0; -``` - -# Using matrices - -```cpp -// Initializing from SEXP, -// dimensions handled automatically -SEXP x; -NumericMatrix xx(x); - -// Matrix of 4 rows & 5 columns (filled with 0) -NumericMatrix xx(4, 5); - -// Fill with value -int xsize = xx.nrow() * xx.ncol(); -for (int i = 0; i < xsize; i++) { - xx[i] = 7; -} -// Same as above, using STL fill -std::fill(xx.begin(), xx.end(), 8); - -// Assign this value to single element -// (1st row, 2nd col) -xx(0,1) = 4; - -// Reference the second column -// Changes propagate to xx (same applies for Row) -NumericMatrix::Column zzcol = xx( _, 1); -zzcol = zzcol * 2; - -// Copy the second column into new object -NumericVector zz1 = xx( _, 1); -// Copy submatrix (top left 3x3) into new object -NumericMatrix zz2 = xx( Range(0,2), Range(0,2)); -``` - -# Inline C++ Compile in R - -```{r, eval = FALSE} -## Note - this is R code. -## cppFunction in Rcpp allows rapid testing. -require(Rcpp) - -cppFunction(" -NumericVector exfun(NumericVector x, int i){ - x = x*i; - return x; -}") - -exfun(1:5, 3) - -## Use evalCpp to evaluate C++ expressions -evalCpp("std::numeric_limits::max()") -``` - -# Interface with R - -## First step in R - -```{r, eval = FALSE} -# In R, create a package shell. For details, -# see the "Writing R Extensions" manual and -# the "Rcpp-package" vignette. - -Rcpp.package.skeleton("myPackage") - -# Add R code to pkg R/ directory. Call C++ -# function. Do type-checking in R. - -myfunR <- function(Rx, Ry) { - ret = .Call("myCfun", Rx, Ry, - package="myPackage") - return(ret) -} -``` - -## Additional C++ - -```cpp -// Add C++ code to pkg src/ directory. -using namespace Rcpp; -// Define function as extern with RcppExport -RcppExport SEXP myCfun( SEXP x, SEXP y) { - // If R/C++ types match, use pointer to x. - // Pointer is faster, but changes to xx - // propagate to R ( xx -> x == Rx). - NumericVector xx(x); - - // clone is slower and uses extra memory. - // Safe. No side effects. - NumericVector yy(clone(y)); - - xx[0] = yy[0] = -1.5; - int zz = xx[0]; - - // use wrap() to return non-SEXP objects, e.g: - // return(wrap(zz)); - // Build and return a list - List ret; - ret["x"] = xx; - ret["y"] = yy; - return(ret); -} -``` - -## On the command-line - -```sh -# From shell, above package directory -R CMD build myPackage -R CMD check myPackage_1.0.tar.gz ## Optional -R CMD INSTALL myPackage_1.0.tar.gz -``` - -## Back in R - -```{r, eval=FALSE} -require(myPackage) - -aa <- 1.5 -bb <- 1.5 -cc <- myfunR(aa, bb) -aa == bb -# FALSE, C++ modifies aa - -aa <- 1:2 -bb <- 1:2 -cc <- myfunR(aa, bb) -identical(aa, bb) -# TRUE, R/C++ types don't match -# so a copy was made -``` - -# STL interface - -```cpp -// sum a vector from beginning to end -double s = std::accumulate(x.begin(), - x.end(), 0.0); -// prod of elements from beginning to end -int p = std::accumulate(vec.begin(), - vec.end(), 1, - std::multiplies()); -// inner_product to compute sum of squares -double s2 = std::inner_product(res.begin(), - res.end(), - res.begin(), 0.0); -``` - -# Rcpp Attributes - -## In C++ - -```cpp -// Add code below into C++ file Rcpp_example.cpp - -#include -using namespace Rcpp; - -// Place the 'Rcpp::export' tag -// right above function declaration. - -// [[Rcpp::export]] -double muRcpp(NumericVector x){ - int n = x.size(); // Size of vector - double sum = 0; // Sum value - - // For loop, note cpp index shift to 0 - for(int i = 0; i < n; i++){ - // Shorthand for sum = sum + x[i] - sum += x[i]; - } - - return sum/n; // Obtain and return the Mean -} - -// Place dependent functions above call or -// declare the function definition with: -double muRcpp(NumericVector x); - -// [[Rcpp::export]] -double varRcpp(NumericVector x, bool bias = true){ - // Calculate the mean using C++ function - double mean = muRcpp(x); - double sum = 0; - int n = x.size(); - - for(int i = 0; i < n; i++){ - sum += pow(x[i] - mean, 2.0); // Square - } - - return sum/(n-bias); // Return variance -} -``` - -## In R: - -```{r, eval=FALSE} -Rcpp::sourceCpp("path/to/file/Rcpp_example.cpp") -x <- 1:5 -all.equal(muRcpp(x), mean(x)) -all.equal(var(x),varRcpp(x)) -``` - -# Rcpp Extensions - -```cpp -// Enable C++11 -// [[Rcpp::plugins(cpp11)]] - -// Enable OpenMP (excludes macOS) -// [[Rcpp::plugins(openmp)]] - -// Use the RcppArmadillo package -// Requires different header file from Rcpp.h -#include -// [[Rcpp::depends(RcppArmadillo)]] -``` - -# Rcpp sugar - -```cpp -NumericVector x = - NumericVector::create(-2.0,-1.0,0.0,1.0,2.0); -IntegerVector y = - IntegerVector::create(-2, -1, 0, 1, 2); - -NumericVector xx = abs( x ); -IntegerVector yy = abs( y ); - -bool b = all( x < 3.0 ).is_true() ; -bool b = any( y > 2 ).is_true(); - -NumericVector xx = ceil( x ); -NumericVector xx = ceiling( x ); -NumericVector yy = floor( y ); -NumericVector yy = floor( y ); - -NumericVector xx = exp( x ); -NumericVector yy = exp( y ); - -NumericVector xx = head( x, 2 ); -IntegerVector yy = head( y, 2 ); - -IntegerVector xx = seq_len( 10 ); -IntegerVector yy = seq_along( y ); - -NumericVector xx = rep( x, 3 ); -NumericVector xx = rep_len( x, 10 ); -NumericVector xx = rep_each( x, 3 ); - -IntegerVector yy = rev( y ); -``` - -# Random Number Generation functions} - -```cpp -// Set seed -RNGScope scope; - -// For details see Section 6.7.1--Distribution -// functions of the `Writing R Extensions' manual. -// In some cases (e.g. rnorm), dist-specific -// arguments can be omitted; when in doubt, -// specify all dist-specific arguments. The use -// of doublesrather than integers for dist- -// specific arguments is recommended. Unless -// explicitly specified, log=FALSE. - -// Equivalent to R calls -NumericVector xx = runif(20); -NumericVector xx1 = rnorm(20); -NumericVector xx1 = rnorm(20, 0); -NumericVector xx1 = rnorm(20, 0, 1); - -// Example vector of quantiles -NumericVector quants(5); -for (int i = 0; i < 5; i++) { - quants[i] = (i-2); -} - -// in R, dnorm(-2:2) -NumericVector yy = dnorm(quants) ; -NumericVector yy = dnorm(quants, 0.0, 1.0) ; - -// in R, dnorm(-2:2, mean=2, log=TRUE) -NumericVector yy = dnorm(quants, 2.0, true) ; - -// Note - cannot specify sd without mean -// in R, dnorm(-2:2, mean=0, sd=2, log=TRUE) -NumericVector yy = dnorm(quants, 0.0, 2.0, true) ; - -// To get original R api, use Rf_* -double zz = Rf_rnorm(0, 2); -``` - - -# Environment - -```cpp -// Special environments -Environment::Rcpp_namespace(); -Environment::base_env(); -Environment::base_namespace(); -Environment::global_env(); -Environment::empty_env(); - -// Obtain an R environment -Environment stats("package:stats"); -Environment env( 2 ); // by position -Environment glob = Environment::global_env(); - -// Extract function from specific environment -Function rnorm = stats["rnorm"]; - -// Assign into the environment -glob["x"] = "foo"; -glob["y"] = 3; - -// Retrieve information from environment -std::string x = glob["x"]; -glob.assign( "foo" , 3 ); -int foo = glob.get( "foo" ); -int foo = glob.find( "foo" ); -CharacterVector names = glob.ls(TRUE) -bool b = glob.exists( "foo" ); -glob.remove( "foo" ); - -// Administration -glob.lockBinding("foo"); -glob.unlockBinding("foo"); -bool b = glob.bindingIsLocked("foo"); -bool b = glob.bindingIsActive("foo"); - -// Retrieve related environments -Environment e = stats.parent(); -Environment e = glob.new_child(); -``` - -# Calling Functions in R - -```cpp -// Do NOT expect to have a performance gain -// when calling R functions from R! - -// Retrieve functions from default loaded env. -Function rnorm("rnorm"); -rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 ); - -// Passing in an R function and obtaining results -// Make sure function conforms with return type! -NumericVector callFunction(NumericVector x, - Function f) { - NumericVector res = f(x); - return res; -} - -/*** R -# The following is R code executed -# by sourceCpp() as a convenience. -x = 1:5 -callFunction(x, sum) -*/ -``` - -# Modules - -```cpp -// Warning -- Module-based objects do not persist -// across quit(save="yes")/reload cycles. To be -// safe, save results to R objects and remove -// module objects before exiting R. - -// To create a module-containing package from R: -// Rcpp.package.skeleton("mypackage", module=TRUE) - -class Bar { - public: - Bar(double x_) : x(x_), nread(0), nwrite(0) {} - - double get_x( ) { - nread++; - return x; - } - - void set_x( double x_) { - nwrite++; - x = x_; - } - - IntegerVector stats() const { - return - IntegerVector::create(_["read"] = nread, - _["write"] = nwrite); - } - private: - double x; int nread, nwrite; -}; - -RCPP_MODULE(mod_bar) { - class_( "Bar" ) - .constructor() - .property( "x", &Bar::get_x, &Bar::set_x, - "Docstring for x" ) - .method( "stats", &Bar::stats, - "Docstring for stats") -;} - -/*** R -## The following is R code. -require(mypackage) s -how(Bar) -b <- new(Bar, 10) -b$x <- 10 -b_persist <- list(stats=b$stats(), x=b$x) -rm(b) -*/ -``` diff -Nru rcpp-1.0.2/inst/doc/Rcpp-quickref.Rnw rcpp-1.0.3/inst/doc/Rcpp-quickref.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-quickref.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-quickref.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-quickref} +%\VignetteKeywords{Rcpp, quickref, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-quickref.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/inst/doc/Rcpp-sugar.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/inst/doc/Rcpp-sugar.pdf differ diff -Nru rcpp-1.0.2/inst/doc/Rcpp-sugar.R rcpp-1.0.3/inst/doc/Rcpp-sugar.R --- rcpp-1.0.2/inst/doc/Rcpp-sugar.R 2019-07-20 14:39:54.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-sugar.R 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -## ---- eval = FALSE------------------------------------------------------- -# foo <- function(x, y) { -# ifelse(x < y, x * x, -(y * y)) -# } - diff -Nru rcpp-1.0.2/inst/doc/Rcpp-sugar.Rmd rcpp-1.0.3/inst/doc/Rcpp-sugar.Rmd --- rcpp-1.0.2/inst/doc/Rcpp-sugar.Rmd 2018-09-02 19:06:26.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-sugar.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,835 +0,0 @@ ---- -title: \pkg{Rcpp} syntactic sugar - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note describes \sugar which has been introduced in version - 0.8.3 of \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp}. \sugar brings a - higher-level of abstraction to \proglang{C++} code written using the - \pkg{Rcpp} API. \sugar is based on expression templates - \citep{Abrahams+Gurtovoy:2004:TemplateMetaprogramming,Vandevoorde+Josuttis:2003:Templates} - and provides some 'syntactic sugar' facilities directly in - \pkg{Rcpp}. This is similar to how \pkg{RcppArmadillo} - \citep{CRAN:RcppArmadillo} offers linear algebra \proglang{C++} - classes based on \pkg{Armadillo} \citep{Sanderson:2010:Armadillo}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - sugar - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - \newcommand{\ith}{\textsl{i}-\textsuperscript{th}} - -vignette: > - %\VignetteIndexEntry{Rcpp-sugar} - %\VignetteKeywords{Rcpp, sugar, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Motivation - -\pkg{Rcpp} facilitates development of internal compiled code in an \proglang{R} -package by abstracting low-level details of the \proglang{R} API \citep{R:Extensions} -into a consistent set of \proglang{C++} classes. - -Code written using \pkg{Rcpp} classes is easier to read, write and maintain, -without loosing performance. Consider the following code example which -provides a function `foo` as a \proglang{C++} extension to -\proglang{R} by using the \pkg{Rcpp} API: - -```cpp -RcppExport SEXP foo(SEXP x, SEXP y) { - Rcpp::NumericVector xx(x), yy(y); - int n = xx.size(); - Rcpp::NumericVector res(n); - double x_ = 0.0, y_ = 0.0; - for (int i=0; i y; -LogicalVector res = x <= y; -LogicalVector res = x >= y; -LogicalVector res = x == y; -LogicalVector res = x != y; - -// one vector, one single value -LogicalVector res = x < 2; -LogicalVector res = 2 > x; -LogicalVector res = y <= 2; -LogicalVector res = 2 != y; - -// two expressions -LogicalVector res = (x + y) < (x*x); -LogicalVector res = (x + y) >= (x*x); -LogicalVector res = (x + y) == (x*x); -``` - -## Unary operators - -The unary `operator-` can be used to negate a (numeric) sugar expression. -whereas the unary `operator!` negates a logical sugar expression: - -```cpp -// a numeric vector -NumericVector x; - -// negate x -NumericVector res = -x; - -// use it as part of a numerical expression -NumericVector res = -x * (x + 2.0); - -// two integer vectors of the same size -NumericVector y; -NumericVector z; - -// negate the logical expression "y < z" -LogicalVector res = !(y < z); -``` - -# Functions - -\sugar defines functions that closely match the behavior of \proglang{R} -functions of the same name. - -## Functions producing a single logical result - -Given a logical sugar expression, the `all` function identifies if all -the elements are `TRUE`. Similarly, the `any` function -identifies if any the element is `TRUE` when -given a logical sugar expression. - - -```cpp -IntegerVector x = seq_len(1000); -all(x*x < 3); -any(x*x < 3); -``` - -Either call to `all` and `any` creates an object of a class -that has member functions `is_true`, `is_false`, -`is_na` and a conversion to `SEXP` operator. - -One important thing to highlight is that `all` is lazy. Unlike -\proglang{R}, there is no need to fully evaluate the expression. In the -example above, the result of `all` is fully resolved after evaluating -only the two first indices of the expression \verb|x * x < 3|. `any` -is lazy too, so it will only need to resolve the first element of the example -above. - -### Conversion to bool - -One important thing to note concerns the conversion to the `bool` -type. In order to respect the concept of missing values (`NA`) in -\proglang{R}, expressions generated by `any` or `all` can not -be converted to `bool`. Instead one must use `is_true`, -`is_false` or `is_na`: - -```cpp -// wrong: will generate a compile error -bool res = any(x < y); - -// ok -bool res = is_true(any( x < y )); -bool res = is_false(any( x < y )); -bool res = is_na(any( x < y )); -``` - - - - -## Functions producing sugar expressions - -### is_na - -Given a sugar expression of any type, \verb|is_na| (just like the other -functions in this section) produces a logical sugar expression of the same -length. Each element of the result expression evaluates to `TRUE` if -the corresponding input is a missing value, or `FALSE` otherwise. - -```cpp -IntegerVector x = - IntegerVector::create(0, 1, NA_INTEGER, 3); - -is_na(x) -all(is_na( x )) -any(!is_na( x )) -``` - -### seq_along - -Given a sugar expression of any type, `seq_along` creates an -integer sugar expression whose values go from 1 to the size of the input. - -```cpp -IntegerVector x = - IntegerVector::create( 0, 1, NA_INTEGER, 3 ); - -IntegerVector y = seq_along(x); -IntegerVector z = seq_along(x * x * x * x * x * x); -``` - -This is the most lazy function, as it only needs to call the `size` -member function of the input expression. The input expression need not to be -resolved. The two examples above gives the same result with the same efficiency -at runtime. The compile time will be affected by the complexity of the -second expression, since the abstract syntax tree is built at compile time. - -### seq_len - -`seq_len` creates an integer sugar expression whose -\ith\ element expands to `i`. `seq_len` is particularly useful in -conjunction with `sapply` and `lapply`. - -```cpp -// 1, 2, ..., 10 -IntegerVector x = seq_len(10); - -List y = lapply(seq_len(10), seq_len); -``` - -### pmin and pmax - -Given two sugar expressions of the same type and size, or one expression and -one primitive value of the appropriate type, `pmin` (`pmax`) -generates a sugar expression of the same type whose \ith\ element expands to -the lowest (highest) value between the \ith\ element of the first expression -and the \ith element of the second expression. - -```cpp -IntegerVector x = seq_len(10); - -pmin(x, x*x); -pmin(x*x, 2); - -pmin(x, x*x); -pmin(x*x, 2); -``` - -### ifelse - -Given a logical sugar expression and either : -\begin{itemize} -\item two compatible sugar expression (same type, same size) -\item one sugar expression and one compatible primitive -\end{itemize} -`ifelse` expands to a sugar expression whose \ith\ -element is the \ith\ element of the first expression -if the \ith\ element of the condition expands to `TRUE` -or the \ith\ of the second expression if -the \ith\ element of the condition expands to `FALSE`, -or the appropriate missing value otherwise. - -```cpp -IntegerVector x; -IntegerVector y; - -ifelse(x < y, x, (x+y)*y) -ifelse(x > y, x, 2) -``` - -### sapply - -`sapply` applies a \proglang{C++} function to each element -of the given expression to create a new expression. The type of the -resulting expression is deduced by the compiler from the result type of -the function. - -The function can be a free \proglang{C++} function such as the overload -generated by the template function below: - -```cpp -template -T square(const T& x){ - return x * x; -} -sapply(seq_len(10), square); -``` - -Alternatively, the function can be a functor whose type has a nested type -called `result_type` - -```cpp -template -struct square : std::unary_function { - T operator()(const T& x){ - return x * x; - } -} -sapply(seq_len(10), square()); -``` - -### lapply - -`lapply` is similar to `sapply` except that the result is -allways an list expression (an expression of type `VECSXP`). - -### sign - -Given a numeric or integer expression, `sign` expands to an expression -whose values are one of 1, 0, -1 or `NA`, depending on the sign -of the input expression. - -```cpp -IntegerVector xx; - -sign(xx) -sign(xx * xx) -``` - -### diff - -The \ith\ element of the result of `diff` is -the difference between the $(i+1)^{\text{th}}$ and the -\ith\ element of the input expression. Supported types are -integer and numeric. - -```cpp -IntegerVector xx; - -diff(xx) -``` - -## Mathematical functions - -For the following set of functions, generally speaking, the \ith\ element of -the result of the given function (say, `abs`) is the result of -applying that function to this \ith\ element of the input expression. -Supported types are integer and numeric. - -```cpp -IntegerVector x; - -abs(x) -exp(x) -floor(x) -ceil(x) -pow(x, z) // x to the power of z -``` - - - -## The d/q/p/r statistical functions - -The framework provided by \sugar also permits easy and efficient access the -density, distribution function, quantile and random number generation -functions function by \proglang{R} in the \code{Rmath} library. - -Currently, most of these functions are vectorised for the first element which -denote size. Consequently, these calls works in \proglang{C++} just as they -would in \proglang{R}: - -```cpp -x1 = dnorm(y1, 0, 1); // density of y1 at m=0, sd=1 -x2 = qnorm(y2, 0, 1); // quantiles of y2 -x3 = pnorm(y3, 0, 1); // distribution of y3 -x4 = rnorm(n, 0, 1); // 'n' RNG draws of N(0, 1) -``` - -Similar d/q/p/r functions are provided for the most common distributions: -beta, binom, cauchy, chisq, exp, f, gamma, geom, hyper, lnorm, logis, nbeta, -nbinom, nbinom_mu, nchisq, nf, norm, nt, pois, t, unif, and weibull. - -Note that the parameterization used in these sugar functions may differ between -the top-level functions exposed in an \proglang{R} session. For example, -the internal \code{rexp} is parameterized by \code{scale}, -whereas the R-level \code{stats::rexp} is parameterized by \code{rate}. -Consult \href{http://cran.r-project.org/doc/manuals/r-release/R-exts.html#Distribution-functions}{Distribution Functions} -for more details on the parameterization used for these sugar functions. - -One point to note is that the programmer using these functions needs to -initialize the state of the random number generator as detailed in Section -6.3 of the `Writing R Extensions' manual \citep{R:Extensions}. A nice -\proglang{C++} solution for this is to use a \textsl{scoped} class that sets -the random number generatator on entry to a block and resets it on exit. We -offer the \code{RNGScope} class which allows code such as - -```cpp -RcppExport SEXP getRGamma() { - RNGScope scope; - NumericVector x = rgamma(10, 1, 1); - return x; -} -``` - -As there is some computational overhead involved in using \code{RNGScope}, we -are not wrapping it around each inner function. Rather, the user of these -functions (\textsl{i.e.} you) should place an \code{RNGScope} at the -appropriate level of your code. - - -# Performance -\label{sec:performance} - -TBD - -# Implementation - -This section details some of the techniques used in the implementation of -\sugar. Note that the user need not to be familiar with the implementation -details in order to use \sugar, so this section can be skipped upon a first -read of the paper. - -Writing \sugar functions is fairly repetitive and follows a well-structured -pattern. So once the basic concepts are mastered (which may take time given -the inherent complexities in template programming), it should be possible to -extend the set of function further following the established pattern. - -## The curiously recurring template pattern - -Expression templates such as those used by \sugar use a technique -called the _Curiously Recurring Template Pattern_ (CRTP). The general -form of CRTP is: - -```cpp -// The Curiously Recurring Template Pattern (CRTP) -template -struct base { - // ... -}; -struct derived : base { - // ... -}; -``` - -The `base` class is templated by the class that derives from it : -`derived`. This shifts the relationship between a base class and a -derived class as it allows the base class to access methods of the derived -class. - -## The VectorBase class - -The CRTP is used as the basis for \sugar with the `VectorBase` -class template. All sugar expression derive from one class generated by the -`VectorBase` template. The current definition of `VectorBase` -is given here: - -```cpp -template -class VectorBase { -public: - struct r_type : - traits::integral_constant{}; - struct can_have_na : - traits::integral_constant{}; - - typedef typename - traits::storage_type::type - stored_type; - - VECTOR& get_ref(){ - return static_cast(*this); - } - - inline stored_type operator[](int i) const { - return static_cast( - this)->operator[](i); - } - - inline int size() const { - return static_cast( - this)->size(); - } - - /* definition ommited here */ - class iterator; - - inline iterator begin() const { - return iterator(*this, 0); - } - inline iterator end() const { - return iterator(*this, size()); - } -} -``` - -The `VectorBase` template has three parameters: - - -- `RTYPE`: This controls the type of expression (INTSXP, REALSXP, ...) -- `na`: This embeds in the derived type information about whether - instances may contain missing values. \pkg{Rcpp} vector types - (`IntegerVector`, ...) derive from `VectorBase` with this - parameter set to `true` because there is no way to know at - compile-time if the vector will contain missing values at run-time. - However, this parameter is set to `false` for types that are - generated by sugar expressions as these are guaranteed to produce - expressions that are without missing values. An example is the - `is_na` function. This parameter is used in several places as part - of the compile time dispatch to limit the occurence of redundant - operations. -- `VECTOR`: This parameter is the key of \sugar. This is the - manifestation of CRTP. The indexing operator and the `size` method - of `VectorBase` use a static cast of `this` to the - `VECTOR` type to forward calls to the actual method of the derived - class. - -## Example: sapply - -As an example, the current implementation of `sapply`, supported by -the template class `Rcpp::sugar::Sapply` is given below: - -```cpp -template -class Sapply : public VectorBase< - Rcpp::traits::r_sexptype_traits< typename - ::Rcpp::traits::result_of::type - >::rtype, - true, - Sapply -> { -public: - typedef typename - ::Rcpp::traits::result_of::type; - - const static int RESULT_R_TYPE = - Rcpp::traits::r_sexptype_traits< - result_type>::rtype; - - typedef Rcpp::VectorBase VEC; - - typedef typename - Rcpp::traits::r_vector_element_converter< - RESULT_R_TYPE>::type - converter_type; - - typedef typename Rcpp::traits::storage_type< - RESULT_R_TYPE>::type STORAGE; - - Sapply(const VEC& vec_, Function fun_) : - vec(vec_), fun(fun_){} - - inline STORAGE operator[]( int i ) const { - return converter_type::get(fun(vec[i])); - } - - inline int size() const { - return vec.size(); - } - -private: - const VEC& vec; - Function fun; -}; - -// sugar - -template -inline sugar::Sapply -sapply(const Rcpp::VectorBase& t, - Function fun) { - - return - sugar::Sapply(t, fun); -} -``` - -### The sapply function - -`sapply` is a template function that takes two arguments. - -- The first argument is a sugar expression, which we recognize because of - the relationship with the `VectorBase` class template. -- The second argument is the function to apply. - -The `sapply` function itself does not do anything, it is just used -to trigger compiler detection of the template parameters that will be used -in the `sugar::Sapply` template. - -### Detection of return type of the function - -In order to decide which kind of expression is built, the `Sapply` -template class queries the template argument via the `Rcpp::traits::result_of` -template. - -```cpp -typedef typename - ::Rcpp::traits::result_of::type - result_type; -``` - -The `result_of` type trait is implemented as such: - -```{Rcpp, eval = FALSE} -template -struct result_of{ - typedef typename T::result_type type; -}; - -template -struct result_of { - typedef RESULT_TYPE type; -}; -``` - -The generic definition of `result_of` targets functors -with a nested `result_type` type. - -The second definition is a partial specialization targetting -function pointers. - -### Indentification of expression type - -Based on the result type of the function, the `r_sexptype_traits` -trait is used to identify the expression type. - -```cpp -const static int RESULT_R_TYPE = - Rcpp::traits::r_sexptype_traits< - result_type>::rtype; -``` - -### Converter - -The `r_vector_element_converter` class is used to convert an -object of the function's result type to the actual storage type suitable -for the sugar expression. - -```cpp -typedef typename - Rcpp::traits::r_vector_element_converter< - RESULT_R_TYPE>::type - converter_type; -``` - -### Storage type - -The `storage_type` trait is used to get access to the storage type -associated with a sugar expression type. For example, the storage type -of a `REALSXP` expression is `double`. - -```cpp -typedef typename - Rcpp::traits::storage_type::type - STORAGE; -``` - -### Input expression base type - -The input expression --- the expression over which `sapply` runs --- is -also typedef'ed for convenience: - -```cpp -typedef Rcpp::VectorBase VEC; -``` - -### Output expression base type - -In order to be part of the \sugar system, the type generated by the -`Sapply` class template must inherit from `VectorBase`. - -```cpp -template -class Sapply : public VectorBase< - Rcpp::traits::r_sexptype_traits< - typename - ::Rcpp::traits::result_of::type - >::rtype, - true, - Sapply -> -``` - -The expression built by `Sapply` depends on the result type -of the function, may contain missing values, and the third argument -is the manifestation of the _CRTP_. - -### Constructor - -The constructor of the `Sapply` class template is straightforward, it -simply consists of holding the reference to the input expression and the -function. - -```cpp -Sapply(const VEC& vec_, Function fun_): - vec(vec_), fun(fun_){} - -private: - const VEC& vec; - Function fun; -``` - -### Implementation - -The indexing operator and the `size` member function is what -the `VectorBase` expects. The size of the result expression is -the same as the size of the input expression and the $i^{\text{th}}$ -element of the result is simply retrieved by applying the function -and the converter. Both these methods are inline to maximize performance: - -```cpp -inline STORAGE operator[](int i) const { - return converter_type::get(fun(vec[i])); -} -inline int size() const { - return vec.size(); -} -``` - -# Summary - -TBD diff -Nru rcpp-1.0.2/inst/doc/Rcpp-sugar.Rnw rcpp-1.0.3/inst/doc/Rcpp-sugar.Rnw --- rcpp-1.0.2/inst/doc/Rcpp-sugar.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/inst/doc/Rcpp-sugar.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-sugar} +%\VignetteKeywords{Rcpp, sugar, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-sugar.pdf} +\end{document} diff -Nru rcpp-1.0.2/inst/include/Rcpp/api/meat/is.h rcpp-1.0.3/inst/include/Rcpp/api/meat/is.h --- rcpp-1.0.2/inst/include/Rcpp/api/meat/is.h 2015-10-15 13:33:57.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/api/meat/is.h 2019-10-02 22:09:52.000000000 +0000 @@ -148,6 +148,8 @@ return TYPEOF(x) == REALSXP && Rf_inherits(x, "POSIXt"); } +#ifndef RCPP_NO_MODULES + inline bool is_module_object_internal(SEXP obj, const char* clazz){ Environment env(obj); SEXP sexp = env.get(".cppclass"); @@ -161,6 +163,8 @@ return is_module_object_internal(x, typeid(CLASS).name()); } +#endif + } // namespace internal } // namespace Rcpp diff -Nru rcpp-1.0.2/inst/include/Rcpp/api/meat/meat.h rcpp-1.0.3/inst/include/Rcpp/api/meat/meat.h --- rcpp-1.0.2/inst/include/Rcpp/api/meat/meat.h 2014-09-04 00:24:05.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/api/meat/meat.h 2019-10-02 22:09:52.000000000 +0000 @@ -42,6 +42,8 @@ #include #include +#ifndef RCPP_NO_MODULES #include +#endif #endif diff -Nru rcpp-1.0.2/inst/include/Rcpp/config.h rcpp-1.0.3/inst/include/Rcpp/config.h --- rcpp-1.0.2/inst/include/Rcpp/config.h 2019-07-20 13:49:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/config.h 2019-11-08 12:26:52.000000000 +0000 @@ -27,10 +27,10 @@ // the currently released version #define RCPP_VERSION Rcpp_Version(1,0,2) -#define RCPP_VERSION_STRING "1.0.2" +#define RCPP_VERSION_STRING "1.0.3" // the current source snapshot #define RCPP_DEV_VERSION RcppDevVersion(1,0,2,0) -#define RCPP_DEV_VERSION_STRING "1.0.2.0" +#define RCPP_DEV_VERSION_STRING "1.0.3.0" #endif diff -Nru rcpp-1.0.2/inst/include/Rcpp/DataFrame.h rcpp-1.0.3/inst/include/Rcpp/DataFrame.h --- rcpp-1.0.2/inst/include/Rcpp/DataFrame.h 2018-07-20 10:24:54.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/DataFrame.h 2019-11-03 14:16:02.000000000 +0000 @@ -101,7 +101,7 @@ if( ::Rf_inherits( x, "data.frame" )){ Parent::set__( x ) ; } else{ - SEXP y = internal::convert_using_rfunction( x, "as.data.frame" ) ; + Shield y(internal::convert_using_rfunction( x, "as.data.frame" )) ; Parent::set__( y ) ; } } @@ -130,7 +130,7 @@ obj.erase(strings_as_factors_index) ; names.erase(strings_as_factors_index) ; obj.attr( "names") = names ; - Shield call( Rf_lang3(as_df_symb, obj, wrap( strings_as_factors ) ) ) ; + Shield call( Rf_lang3(as_df_symb, obj, Rf_ScalarLogical(strings_as_factors) ) ) ; SET_TAG( CDDR(call), strings_as_factors_symb ) ; Shield res(Rcpp_fast_eval(call, R_GlobalEnv)); DataFrame_Impl out( res ) ; diff -Nru rcpp-1.0.2/inst/include/Rcpp/Environment.h rcpp-1.0.3/inst/include/Rcpp/Environment.h --- rcpp-1.0.2/inst/include/Rcpp/Environment.h 2018-07-20 10:24:54.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/Environment.h 2019-11-04 12:18:15.000000000 +0000 @@ -2,8 +2,8 @@ // // Environment.h: Rcpp R/C++ interface class library -- access R environments // -// Copyright (C) 2009 - 2013 Dirk Eddelbuettel and Romain Francois -// Copyright (C) 2014 Dirk Eddelbuettel, Romain Francois and Kevin Ushey +// Copyright (C) 2009 - 2013 Dirk Eddelbuettel and Romain Francois +// Copyright (C) 2014 - 2019 Dirk Eddelbuettel, Romain Francois and Kevin Ushey // // This file is part of Rcpp. // @@ -246,9 +246,8 @@ we have to go back to R to do this operation */ SEXP internalSym = Rf_install( ".Internal" ); SEXP removeSym = Rf_install( "remove" ); - Shield call( Rf_lang2(internalSym, - Rf_lang4(removeSym, Rf_mkString(name.c_str()), Storage::get__(), Rf_ScalarLogical( FALSE )) - ) ); + Shield str(Rf_mkString(name.c_str())); + Shield call(Rf_lang2(internalSym, Rf_lang4(removeSym, str, Storage::get__(), Rf_ScalarLogical(FALSE)))); Rcpp_fast_eval( call, R_GlobalEnv ) ; } } else{ @@ -374,7 +373,8 @@ try{ SEXP getNamespaceSym = Rf_install("getNamespace"); Shield package_str( Rf_mkString(package.c_str()) ); - env = Rcpp_fast_eval(Rf_lang2(getNamespaceSym, package_str), R_GlobalEnv); + Shield call( Rf_lang2(getNamespaceSym, package_str) ); + env = Rcpp_fast_eval(call, R_GlobalEnv); } catch( ... ){ throw no_such_namespace( package ) ; } diff -Nru rcpp-1.0.2/inst/include/Rcpp/exceptions.h rcpp-1.0.3/inst/include/Rcpp/exceptions.h --- rcpp-1.0.2/inst/include/Rcpp/exceptions.h 2018-11-03 00:20:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/exceptions.h 2019-10-14 11:51:00.000000000 +0000 @@ -318,7 +318,11 @@ template inline SEXP exception_to_condition_template( const Exception& ex, bool include_call) { +#ifndef RCPP_NO_RTTI std::string ex_class = demangle( typeid(ex).name() ) ; +#else + std::string ex_class = ""; +#endif std::string ex_msg = ex.what() ; Rcpp::Shelter shelter; @@ -369,7 +373,10 @@ } std::string demangle( const std::string& name) ; +#ifndef RCPP_NO_RTTI #define DEMANGLE(__TYPE__) demangle( typeid(__TYPE__).name() ).c_str() +#endif + inline void forward_exception_to_r(const std::exception& ex){ SEXP stop_sym = Rf_install( "stop" ) ; diff -Nru rcpp-1.0.2/inst/include/Rcpp/proxy/FieldProxy.h rcpp-1.0.3/inst/include/Rcpp/proxy/FieldProxy.h --- rcpp-1.0.2/inst/include/Rcpp/proxy/FieldProxy.h 2018-06-17 11:58:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/proxy/FieldProxy.h 2019-11-04 12:18:15.000000000 +0000 @@ -41,12 +41,14 @@ const std::string& field_name ; SEXP get() const { - Shield call( Rf_lang3( R_DollarSymbol, parent, Rf_mkString(field_name.c_str()) ) ) ; + Shield str(Rf_mkString(field_name.c_str())); + Shield call(Rf_lang3(R_DollarSymbol, parent, str)); return Rcpp_fast_eval( call, R_GlobalEnv ) ; } void set(SEXP x ) { SEXP dollarGetsSym = Rf_install( "$<-"); - Shield call( Rf_lang4( dollarGetsSym, parent, Rf_mkString(field_name.c_str()) , x ) ) ; + Shield str(Rf_mkString(field_name.c_str())); + Shield call(Rf_lang4(dollarGetsSym, parent, str, x)); parent.set__( Rcpp_fast_eval( call, R_GlobalEnv ) ); } } ; @@ -66,7 +68,8 @@ const std::string& field_name ; SEXP get() const { - Shield call( Rf_lang3( R_DollarSymbol, parent, Rf_mkString(field_name.c_str()) ) ) ; + Shield str(Rf_mkString(field_name.c_str())); + Shield call(Rf_lang3(R_DollarSymbol, parent, str)); return Rcpp_fast_eval( call, R_GlobalEnv ) ; } } ; diff -Nru rcpp-1.0.2/inst/include/Rcpp/r/headers.h rcpp-1.0.3/inst/include/Rcpp/r/headers.h --- rcpp-1.0.2/inst/include/Rcpp/r/headers.h 2019-07-14 22:17:42.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/r/headers.h 2019-10-14 11:51:00.000000000 +0000 @@ -1,7 +1,7 @@ // headers.h: Rcpp R/C++ interface class library -- R headers // // Copyright (C) 2008 - 2009 Dirk Eddelbuettel -// Copyright (C) 2009 - 2013 Dirk Eddelbuettel and Romain Francois +// Copyright (C) 2009 - 2019 Dirk Eddelbuettel and Romain Francois // // This file is part of Rcpp. // @@ -26,6 +26,7 @@ #define R_NO_REMAP // until September 2019, define RCPP_NO_STRICT_R_HEADERS for transition +// (that goal was too optimistic, reverse depency checks showed too much breakage) #ifndef RCPP_NO_STRICT_R_HEADERS # define RCPP_NO_STRICT_R_HEADERS #endif @@ -36,6 +37,13 @@ # endif #endif +// no rtti implies no modules +#ifdef RCPP_NO_RTTI +# ifndef RCPP_NO_MODULES +# define RCPP_NO_MODULES +# endif +#endif + // prevent some macro pollution when including R headers // in particular, on Linux, gcc 'leaks' the 'major', // 'minor' and 'makedev' macros on Linux; we prevent diff -Nru rcpp-1.0.2/inst/include/Rcpp/r_cast.h rcpp-1.0.3/inst/include/Rcpp/r_cast.h --- rcpp-1.0.2/inst/include/Rcpp/r_cast.h 2018-07-20 12:01:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/r_cast.h 2019-11-03 14:16:02.000000000 +0000 @@ -31,7 +31,8 @@ Armor res; try{ SEXP funSym = Rf_install(fun); - res = Rcpp_fast_eval(Rf_lang2(funSym, x), R_GlobalEnv); + Shield call(Rf_lang2(funSym, x)); + res = Rcpp_fast_eval(call, R_GlobalEnv); } catch( eval_error& e) { const char* fmt = "Could not convert using R function: %s."; throw not_compatible(fmt, fun); diff -Nru rcpp-1.0.2/inst/include/Rcpp/Reference.h rcpp-1.0.3/inst/include/Rcpp/Reference.h --- rcpp-1.0.2/inst/include/Rcpp/Reference.h 2018-06-17 11:58:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/Reference.h 2019-11-04 12:18:15.000000000 +0000 @@ -2,7 +2,7 @@ // // Reference.h: Rcpp R/C++ interface class library -- Reference class objects // -// Copyright (C) 2010 - 2015 Dirk Eddelbuettel and Romain Francois +// Copyright (C) 2010 - 2019 Dirk Eddelbuettel and Romain Francois // // This file is part of Rcpp. // @@ -58,7 +58,8 @@ */ Reference_Impl( const std::string& klass ) { SEXP newSym = Rf_install("new"); - Shield call( Rf_lang2( newSym, Rf_mkString( klass.c_str() ) ) ); + Shield str(Rf_mkString(klass.c_str())); + Shield call(Rf_lang2(newSym, str)); Storage::set__( Rcpp_fast_eval( call , Rcpp::internal::get_Rcpp_namespace()) ); } diff -Nru rcpp-1.0.2/inst/include/Rcpp/XPtr.h rcpp-1.0.3/inst/include/Rcpp/XPtr.h --- rcpp-1.0.2/inst/include/Rcpp/XPtr.h 2017-08-05 17:46:22.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp/XPtr.h 2019-11-08 12:17:46.000000000 +0000 @@ -58,6 +58,35 @@ typedef StoragePolicy Storage; +#if defined(RCPP_USING_CXX11) + + /** + * constructs a XPtr wrapping the external pointer (EXTPTRSXP SEXP) + * + * @param xp external pointer to wrap + */ + explicit XPtr(SEXP x) { + if (TYPEOF(x) != EXTPTRSXP) { + const char* fmt = "Expecting an external pointer: [type=%s]."; + throw ::Rcpp::not_compatible(fmt, Rf_type2char(TYPEOF(x))); + } + Storage::set__(x); + }; + + /** + * constructs a XPtr wrapping the external pointer (EXTPTRSXP SEXP) + * + * @param xp external pointer to wrap + * @param tag tag to assign to external pointer + * @param prot protected data to assign to external pointer + */ + explicit XPtr(SEXP x, SEXP tag, SEXP prot) : XPtr(x) { + R_SetExternalPtrTag( x, tag); + R_SetExternalPtrProtected(x, prot); + }; + +#else + /** * constructs a XPtr wrapping the external pointer (EXTPTRSXP SEXP) * @@ -74,6 +103,8 @@ R_SetExternalPtrProtected(x, prot); }; +#endif + /** * creates a new external pointer wrapping the dumb pointer p. * diff -Nru rcpp-1.0.2/inst/include/Rcpp.h rcpp-1.0.3/inst/include/Rcpp.h --- rcpp-1.0.2/inst/include/Rcpp.h 2019-04-25 02:44:25.000000000 +0000 +++ rcpp-1.0.3/inst/include/Rcpp.h 2019-10-02 22:09:52.000000000 +0000 @@ -63,8 +63,10 @@ #include +#ifndef RCPP_NO_MODULES #include #include +#endif #include diff -Nru rcpp-1.0.2/inst/NEWS.Rd rcpp-1.0.3/inst/NEWS.Rd --- rcpp-1.0.2/inst/NEWS.Rd 2019-07-20 13:19:05.000000000 +0000 +++ rcpp-1.0.3/inst/NEWS.Rd 2019-11-08 12:38:54.000000000 +0000 @@ -3,6 +3,45 @@ \newcommand{\ghpr}{\href{https://github.com/RcppCore/Rcpp/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/RcppCore/Rcpp/issues/#1}{##1}} +\section{Changes in Rcpp version 1.0.3 (2019-11-08)}{ + \itemize{ + \item Changes in Rcpp API: + \itemize{ + \item Compilation can be sped up by skipping Modules headers via a + toggle \code{RCPP_NO_MODULES} (Kevin in \ghpr{995} for \ghit{993}). + \item Compilation can be sped up by toggling \code{RCPP_NO_RTTI} which + implies \code{RCPP_NO_MODULES} (Dirk in \ghpr{998} fixing \ghit{998}). + \item \code{XPtr} tags are now preserved in \code{as<>} (Stephen Wade + in \ghpr{1003} fixing \ghit{986}, plus Dirk in \ghpr{1012}). + \item A few more temporary allocations are now protected from garbage + collection (Romain Francois in \ghpr{1010}, and Dirk in \ghpr{1011}). + } + \item Changes in Rcpp Modules: + \itemize{ + \item Improved initialization via explicit \code{Rcpp::} prefix + (Riccardo Porreca in \ghpr{980}). + } + \item Changes in Rcpp Deployment: + \itemize{ + \item A unit test for Rcpp Class exposure was updated to not fail under + r-devel (Dirk in \ghpr{1008} fixing \ghit{1006}). + } + \item Changes in Rcpp Documentation: + \itemize{ + \item The \code{Rcpp-modules} vignette received a major review and + edit (Riccardo Porreca in \ghpr{982}). + \item Minor whitespace alignments and edits were made in three + vignettes following the new \pkg{pinp} release (Dirk). + \item New badges for DOI and CRAN and BioConductor reverse dependencies + have been added to README.md (Dirk). + \item Vignettes are now included pre-made (Dirk in \ghpr{1005} + addressing \ghit{1004})). + \item The Rcpp FAQ has two new entries on 'no modules / no rtti' and + exceptions across shared libraries (Dirk in \ghpr{1009}). + } + } +} + \section{Changes in Rcpp version 1.0.2 (2019-07-20)}{ \itemize{ \item Changes in Rcpp API: @@ -16,7 +55,7 @@ \itemize{ \item The second END wrapper macro also gets \code{UNPROTECT} and a variable reference suppressing compiler warnings (Dirk in - \ghpr{953}) fixing \ghit{951}). + \ghpr{953} fixing \ghit{951}). \item Default function arguments are parsed correctly (Pierrick Roger in \ghpr{977} fixing \ghit{975}) } @@ -34,7 +73,7 @@ \itemize{ \item The \code{Rcpp-modules} vignette now covers the \code{RCPP_EXPOSED_*} macros, and the \code{Rcpp-extending} vignette - references it (Ralf Stubner in \ghpr{959} fixing \ghit{952}) + references it (Ralf Stubner in \ghpr{959} fixing \ghit{952}). } } } diff -Nru rcpp-1.0.2/inst/unitTests/cpp/XPtr.cpp rcpp-1.0.3/inst/unitTests/cpp/XPtr.cpp --- rcpp-1.0.2/inst/unitTests/cpp/XPtr.cpp 2015-02-03 16:40:03.000000000 +0000 +++ rcpp-1.0.3/inst/unitTests/cpp/XPtr.cpp 2019-10-20 14:29:37.000000000 +0000 @@ -47,6 +47,17 @@ } // [[Rcpp::export]] +void xptr_self_tag( XPtr< std::vector > p ){ + XPtr< std::vector > self_tag(wrap(p), wrap(p), R_NilValue) ; +} + +// [[Rcpp::export]] +bool xptr_has_self_tag( XPtr< std::vector > p ){ + return wrap(p) == R_ExternalPtrTag(p); +} + + +// [[Rcpp::export]] bool xptr_release( XPtr< std::vector > p) { p.release(); return !p; diff -Nru rcpp-1.0.2/inst/unitTests/runit.exposeClass.R rcpp-1.0.3/inst/unitTests/runit.exposeClass.R --- rcpp-1.0.2/inst/unitTests/runit.exposeClass.R 2018-07-25 19:12:20.000000000 +0000 +++ rcpp-1.0.3/inst/unitTests/runit.exposeClass.R 2019-10-27 20:36:16.000000000 +0000 @@ -46,8 +46,14 @@ ## create package Rcpp.package.skeleton(pkg_name, path=path, environment = environment(), example_code = FALSE, module = TRUE) + ## R 4.0.0 (currently in development) is stricter about the NAMESPACE and wants + ## - an actual function behind the export declaration we end up with here + ## - an export declaration for the class exposed and check below + ## so we provide both to comply (and also no longer delete from src/ and R/) + cat("Rcpp.fake.fun <- function() {}", file=file.path(path, pkg_name, "R", "fakefun.R")) + cat("export(\"fooR\")", append=TRUE, file=file.path(path, pkg_name, "NAMESPACE")) + on.exit(unlink(pkg_path, recursive=TRUE)) - file.remove(list.files(c(src_path, R_path), full.names = TRUE)) cat(foo_header, file = file.path(src_path, "foo.h")) ## check that result of exposeClass compiles and runs properly diff -Nru rcpp-1.0.2/inst/unitTests/runit.XPTr.R rcpp-1.0.3/inst/unitTests/runit.XPTr.R --- rcpp-1.0.2/inst/unitTests/runit.XPTr.R 2016-03-05 14:08:43.000000000 +0000 +++ rcpp-1.0.3/inst/unitTests/runit.XPTr.R 2019-11-08 12:17:46.000000000 +0000 @@ -20,17 +20,24 @@ .runThisTest <- Sys.getenv("RunAllRcppTests") == "yes" +isWindows <- Sys.info()[["sysname"]] == "Windows" + if (.runThisTest) { .setUp <- Rcpp:::unitTestSetup("XPtr.cpp") - + test.XPtr <- function(){ xp <- xptr_1() checkEquals(typeof( xp ), "externalptr", msg = "checking external pointer creation" ) - + front <- xptr_2(xp) checkEquals( front, 1L, msg = "check usage of external pointer" ) + if (!isWindows) { + xptr_self_tag(xp) + checkEquals(xptr_has_self_tag(xp), T, msg = "check external pointer tag preserved") + } + checkTrue(xptr_release(xp), msg = "check release of external pointer") checkTrue(xptr_access_released(xp), msg = "check access of released external pointer") diff -Nru rcpp-1.0.2/MD5 rcpp-1.0.3/MD5 --- rcpp-1.0.2/MD5 2019-07-25 10:10:05.000000000 +0000 +++ rcpp-1.0.3/MD5 2019-11-08 23:15:32.000000000 +0000 @@ -1,12 +1,12 @@ -09116ab740545e35cbc9ab9e181f2365 *ChangeLog -7211aa554f700b88cb901bfaa155d845 *DESCRIPTION +a1795ff760de869ffa241c277b3c73ed *ChangeLog +b8fcaabdb1ec3b4f9edd8389741c3963 *DESCRIPTION f53ecd48407d7485920c4f3caaf187e0 *NAMESPACE ad57518c2d1d3d66fc26b6c214ed13e1 *R/00_classes.R f9a4ffb4d0fcec3eec6ef6c229ff1bba *R/01_show.R 5ad59a1671fd934a15f614a96331c56a *R/02_completion.R 3eafac927ff4e744b84675639ff48078 *R/03_prompt.R d9c3ef55af80891b856a4a91fa9816bc *R/Attributes.R -eb9739feac4aec22022b2ef80a849977 *R/Module.R +276dbd9dcacd1d0b3689468b881dd8f9 *R/Module.R e370122b2dd714f010068ba5010bfa96 *R/Rcpp.package.skeleton.R ebc4b0f592a5bdaf5dbdd303de33a5b0 *R/RcppClass.R 7d60098efca205c55a55632ed7cbf8d7 *R/RcppLdpath.R @@ -21,47 +21,38 @@ a7677d0b8631d443c4ad44014780439b *R/tools.R 4bf79abf213d048d344510ba58bff662 *R/unit.tests.R e82268e95d8f2d3a1759620eb1bc6664 *R/zzz.R -6fd1749bc7ae0d48606001e722da10a7 *README.md +ab40ea37ac1f17527ef5bc4a47737d68 *README.md dcfe968628d24168fc5bb54a66631158 *TODO -1ce779857fbdd349300113f555cb385a *build/vignette.rds -1918c105d26e9bedd2a6af3277bf0e15 *cleanup +e9d315e907c3734b972b359ccfc85513 *build/vignette.rds +1b6b2d1ce7cb507b4b0db45926c79886 *cleanup 25a5891b4f43e3a5075e0ba42ef9038f *inst/CITATION -e1de765a30ccaa98e3edf3182225e33a *inst/NEWS.Rd +58335f24f7fedd797fb05f40b2738de8 *inst/NEWS.Rd 7a9967333ad85931cc6d2051f4dff76e *inst/announce/ANNOUNCE-0.10.0.txt 734d037a2ac31af4659fb3b2e1a778ad *inst/announce/ANNOUNCE-0.11.0.txt 7d85af8d096e473821a3f001d3128b01 *inst/announce/ANNOUNCE-0.6.0.txt f61c7e9e1460eac25702b24c1af30442 *inst/announce/ANNOUNCE-0.7.0.txt a198e05a9b004dfc1f8ea67629f2f6c7 *inst/announce/ANNOUNCE-0.8.0.txt 3e8a171f22548f5da208b58e66b48e6c *inst/announce/ANNOUNCE-0.9.0.txt -571da9900e590625ef4834055fdbbb4a *inst/bib/Rcpp.bib +8cff6c1d650e7312a6d0520fabd81dd0 *inst/bib/Rcpp.bib 6f1e3b1f4f75e04af65bb9daf94e9630 *inst/discovery/cxx0x.R -ebc22ff5dfae5865c545dc4a2bf6c4d6 *inst/doc/Rcpp-FAQ.R -9f66aaa1d65534b63230a2f676cb4801 *inst/doc/Rcpp-FAQ.Rmd -6d60b599d15f2c2b267af23a1aeb7fe5 *inst/doc/Rcpp-FAQ.pdf -b1157589ff4b4bacfc87b241fdc0606d *inst/doc/Rcpp-attributes.R -a278225621df1aa072f9348166812480 *inst/doc/Rcpp-attributes.Rmd -5a3e8418aef3e0348d7f7c858b9d5d0b *inst/doc/Rcpp-attributes.pdf -b6e0f1cc037ab16647b82d1e71ac1617 *inst/doc/Rcpp-extending.R -eb54bf86409788a9265abf4ed891f39a *inst/doc/Rcpp-extending.Rmd -d6a3d7fa732e18b63dee337b6e8d50b7 *inst/doc/Rcpp-extending.pdf -1197a3955d4dea583d2ebd95f1e7c98e *inst/doc/Rcpp-introduction.R -8b26a9444aad4052447641cc740264e5 *inst/doc/Rcpp-introduction.Rmd -ee164651698c66cf38542918810113bb *inst/doc/Rcpp-introduction.pdf -d2b93db47ce0e0b2e16567ce6c5f6e6e *inst/doc/Rcpp-jss-2011.R -0e54f1a6c5efb98f3c9ccde370ef6376 *inst/doc/Rcpp-jss-2011.Rnw -cf9e2384623d2e972ac24a885201cdef *inst/doc/Rcpp-jss-2011.pdf -aa313807eb4acd95a026949cece3b4f3 *inst/doc/Rcpp-modules.R -b959784a2242f812d34cd9f95e428d21 *inst/doc/Rcpp-modules.Rmd -34f9589a201c2d43af7678bfe86d43e3 *inst/doc/Rcpp-modules.pdf -7b4b5a4dc5fd5c88fb7745d9eca2806b *inst/doc/Rcpp-package.Rmd -8a0a4f042ab30521e90e7afdda69696a *inst/doc/Rcpp-package.pdf -b0db896621d7b77ebc2a41feb5d9ab0d *inst/doc/Rcpp-quickref.R -f5d660cdaed01cfaf91e1ba24ff5795d *inst/doc/Rcpp-quickref.Rmd -64192b1b219ac145a0e5345a915bad8a *inst/doc/Rcpp-quickref.pdf -a2c19629ad1cdf95042e634683766007 *inst/doc/Rcpp-sugar.R -bbca23801eda4033fe290d2374e3ac66 *inst/doc/Rcpp-sugar.Rmd -357da4b09e336afe6d9a8fdb986a752b *inst/doc/Rcpp-sugar.pdf -571da9900e590625ef4834055fdbbb4a *inst/doc/Rcpp.bib +2baf167ce452976b0fcb43e44f566af7 *inst/doc/Rcpp-FAQ.Rnw +c83eaf06b58fd392ec6d24212d10b0f4 *inst/doc/Rcpp-FAQ.pdf +887250b7e0675b4a70d6eb1a4689080c *inst/doc/Rcpp-attributes.Rnw +ece219d173c8c2ff240b76ee84e4a248 *inst/doc/Rcpp-attributes.pdf +37f50a136d1350e8e864c9265cc88ad8 *inst/doc/Rcpp-extending.Rnw +a1e686c983b5766360d54c409ad333ad *inst/doc/Rcpp-extending.pdf +90eade7bfffa82f250510759bc9a7f36 *inst/doc/Rcpp-introduction.Rnw +b56e1aea586e856e33f342fb521e4428 *inst/doc/Rcpp-introduction.pdf +e6cf1d12ce4e3a2fed6eddf6290d393f *inst/doc/Rcpp-jss-2011.Rnw +45fac4d24f0ae1c7cf01a1401b510e1b *inst/doc/Rcpp-jss-2011.pdf +a96bcf4153b795bff19ddc36a17ca435 *inst/doc/Rcpp-modules.Rnw +321d056f0bb0e05b43bd6eb803bf03cc *inst/doc/Rcpp-modules.pdf +835d0e2dd365e4621663bd03ae219758 *inst/doc/Rcpp-package.Rnw +eebe65fdee8150f4a909d1a6117985d6 *inst/doc/Rcpp-package.pdf +d76adfdc4e68c69c5ff632e234db6a85 *inst/doc/Rcpp-quickref.Rnw +917df5502be2f291be680098baac1341 *inst/doc/Rcpp-quickref.pdf +929a1aad762b7354b6875a35093ec477 *inst/doc/Rcpp-sugar.Rnw +a830cbd050344f4f708155e9fa8d1538 *inst/doc/Rcpp-sugar.pdf 35fa971232b8c9fb0bbb9dfc2ad3de7a *inst/examples/Attributes/Depends.cpp a9aa3aceea0b49525155a2c43296318b *inst/examples/Attributes/Export.cpp c6c9969e0067a1321827369cba1cc566 *inst/examples/Attributes/cppFunction.R @@ -117,13 +108,13 @@ f55a0d78225fef3970fc5f54fddb5801 *inst/examples/functionCallback/newApiExample.r 2b3ff26140686d910b4fe51505b817a3 *inst/examples/performance/extractors.R 33c7adefe3137cae65b189490c958c6a *inst/examples/performance/performance.R -30b4798a7bda4addd03c8e23a5b7e280 *inst/include/Rcpp.h +e4a82daa3c36100e5e5fdf9600b73a54 *inst/include/Rcpp.h 7acf90ededacb240b082c50653a1fe05 *inst/include/Rcpp/Benchmark/Timer.h -b0724e8d002c43603aec7ea479d9be0c *inst/include/Rcpp/DataFrame.h +c79cfd5b4dbc08e6649c4f1f563d22c2 *inst/include/Rcpp/DataFrame.h e4195b2fee650b67d709d7bd529f3de6 *inst/include/Rcpp/Dimension.h bed24a03d2f346377d351327e6ead507 *inst/include/Rcpp/DottedPair.h 8ae8df6f92f7d17625b543348c9c035c *inst/include/Rcpp/DottedPairImpl.h -6f170fd8a954172992af3c08d12116d2 *inst/include/Rcpp/Environment.h +764724d506d79dee5546941271c60abf *inst/include/Rcpp/Environment.h 719d99509ff3398d24d31a4964dc6beb *inst/include/Rcpp/Extractor.h 0e673291cac4bf839157946880772c1d *inst/include/Rcpp/Fast.h 1836fe44282438109267ce447debae1a *inst/include/Rcpp/Formula.h @@ -141,7 +132,7 @@ c299955262d228fc372294633ecb10a9 *inst/include/Rcpp/Promise.h c7c202116cb2d8f9993f2d2879a48339 *inst/include/Rcpp/RNGScope.h 19d73d0c48066eab27b7e21f016aca39 *inst/include/Rcpp/RObject.h -309a1410ef45e09d6a73dd310edde650 *inst/include/Rcpp/Reference.h +0708f78d2a5868bd0036bdffc92557eb *inst/include/Rcpp/Reference.h 577707408edc19445de29e2fd4182292 *inst/include/Rcpp/Rmath.h 4a8bc08de01a68edf476065293076bc9 *inst/include/Rcpp/S4.h b479ccd53c1917ce1140ee0a17bb3d21 *inst/include/Rcpp/StretchyList.h @@ -150,7 +141,7 @@ 016374544bddc85df03012bf1e70377c *inst/include/Rcpp/Symbol.h 6370b5966cc98d3e684862425576275b *inst/include/Rcpp/Vector.h eed9bf9af10a68be9cd55e5a5cdaa36a *inst/include/Rcpp/WeakReference.h -1833b739afe31ccbff8a9b055d979459 *inst/include/Rcpp/XPtr.h +ef8c0402cedddd5aa88c28ca789585e8 *inst/include/Rcpp/XPtr.h 2eff8a753ede96fbcf538eab9eb22889 *inst/include/Rcpp/algo.h 8945b9daf79dc522161d4738be104e8e *inst/include/Rcpp/algorithm.h 3fa2caaea31d12b63d0a049c1da3c878 *inst/include/Rcpp/api/bones/Date.h @@ -169,8 +160,8 @@ eded8a0a95dd5ecdcae8aa70aceb795c *inst/include/Rcpp/api/meat/Vector.h a3e8a42322f0e644f1d6b6d4f55425e7 *inst/include/Rcpp/api/meat/as.h f1b2b53b2851bbd3afb878ef3829f58f *inst/include/Rcpp/api/meat/export.h -ee1558eb2fe010d34a140397ceb5254b *inst/include/Rcpp/api/meat/is.h -fa071e7b4746e47fb8179365d4c96c79 *inst/include/Rcpp/api/meat/meat.h +cc1991e18d0c1d1e3470285fec935c36 *inst/include/Rcpp/api/meat/is.h +9ce33f68f2a0bd91f063dafd5e1981a6 *inst/include/Rcpp/api/meat/meat.h 71c33d73cde9cdf7368627a9b00a8e7d *inst/include/Rcpp/api/meat/module/Module.h d3e14b929d0b6cd092f52d1ced57b573 *inst/include/Rcpp/api/meat/protection.h c9af45da88ea151bb2f8cd27900257e8 *inst/include/Rcpp/api/meat/proxy.h @@ -179,7 +170,7 @@ 90c153091bc3fb1e123fef9dc40394e6 *inst/include/Rcpp/barrier.h fa7b26bbe19f908b9c00ead2fe2717ac *inst/include/Rcpp/clone.h 1b3b2bee1fc9bd3f231c2a33ca572281 *inst/include/Rcpp/complex.h -29ffb8318d23eb549521dec821d783d9 *inst/include/Rcpp/config.h +0599d382813a7756c2e64c51adeccc6b *inst/include/Rcpp/config.h b90e19134c5d4a4c0652f956c022d1e4 *inst/include/Rcpp/date_datetime/Date.h e75130fc77dac6243e5c88639c940dea *inst/include/Rcpp/date_datetime/Datetime.h 0d754f1a9266c3e1bbc6946ba1304ab5 *inst/include/Rcpp/date_datetime/date_datetime.h @@ -187,7 +178,7 @@ 1c84cd464c857eadab9323be5772ef2b *inst/include/Rcpp/date_datetime/newDatetimeVector.h eeaacae019fe68c8acbd3e9fbea29a3d *inst/include/Rcpp/date_datetime/oldDateVector.h a2bcdcb2cc9e096bfb46106875462a13 *inst/include/Rcpp/date_datetime/oldDatetimeVector.h -6b1ffcd99c40e9ecb40865252690ffaa *inst/include/Rcpp/exceptions.h +754402dfeca86d248da30b6bde017747 *inst/include/Rcpp/exceptions.h fabe6bb18d2e4714327930f192754072 *inst/include/Rcpp/exceptions/cpp11/exceptions.h 4f3d1575c7468c08aff9caf2029b5262 *inst/include/Rcpp/exceptions/cpp98/exceptions.h 7dc521891bf0b250105c08f84806dedf *inst/include/Rcpp/generated/DataFrame_generated.h @@ -263,7 +254,7 @@ 9b71f44a9870eaee5c63de664e5db4f1 *inst/include/Rcpp/proxy/AttributeProxy.h d1800f7df6f83a017e0501af64551239 *inst/include/Rcpp/proxy/Binding.h 2767ffc2e7c0e7832e7223cd8da38be1 *inst/include/Rcpp/proxy/DottedPairProxy.h -65d7e7aa82ea868bdb7c2286063b0788 *inst/include/Rcpp/proxy/FieldProxy.h +59d09bb7d953413d5452a45616fca92f *inst/include/Rcpp/proxy/FieldProxy.h bb4b32da96533b2cae35b524cf796d04 *inst/include/Rcpp/proxy/GenericProxy.h e34b2baf18b2684fe26743c96f78b3c6 *inst/include/Rcpp/proxy/NamesProxy.h e6ffa94de4d38f34d9b363785fbdf1ff *inst/include/Rcpp/proxy/ProtectedProxy.h @@ -271,8 +262,8 @@ 9e412a44a35eb570fe422b00c15dc84e *inst/include/Rcpp/proxy/SlotProxy.h 16583a2ce9f3f158d32a59bc69dc6045 *inst/include/Rcpp/proxy/TagProxy.h 5b3488834c9e483325dc45493deaf0d4 *inst/include/Rcpp/proxy/proxy.h -4c862302afb82afcb1da5dcabfc6ca63 *inst/include/Rcpp/r/headers.h -a6b8e0bbb496eb48ea9938196e49d497 *inst/include/Rcpp/r_cast.h +166f7552afdf7d445bacbf7e0c3045a3 *inst/include/Rcpp/r/headers.h +3623ef6f3fa8a62ec1f67dbe2f86e51b *inst/include/Rcpp/r_cast.h a0559271da8ee5ec875573d72896cbd5 *inst/include/Rcpp/routines.h 5c5eddabb61b11f1e2aa1dfd3b7dfcc6 *inst/include/Rcpp/sprintf.h 652b362ffc5b25dc354e2f94ccf775df *inst/include/Rcpp/stats/beta.h @@ -525,7 +516,7 @@ bf2f556311ef8884928d6db63fccf112 *inst/unitTests/cpp/Subset.cpp 9e43515f6d1955c9bd0457c962db4338 *inst/unitTests/cpp/Vector.cpp 2834dfe1270c0e1cc24aba14721c09da *inst/unitTests/cpp/VectorOld.cpp -883ac0fb1f6427b1c5789ecce66c5f6c *inst/unitTests/cpp/XPtr.cpp +aa3497bfcf9b9d14f35e9558a19fc1b4 *inst/unitTests/cpp/XPtr.cpp d19479e6aab83b12124389782f4bf739 *inst/unitTests/cpp/algorithm.cpp 219e1d71106fb3bb1253ce60affbb398 *inst/unitTests/cpp/as.cpp 12c4f9c7f7323095f118fc9c11ace5da *inst/unitTests/cpp/attributes.cpp @@ -566,7 +557,7 @@ 5763c8fa41ecdd44ba9fbaedee9b7106 *inst/unitTests/runit.String.R 911dcc0822d7590a2c65599e5f4f13d0 *inst/unitTests/runit.Vector.R 2982da95e99677f66e7c0ae07743d2ec *inst/unitTests/runit.VectorOld.R -3f571d70d028a84ffa2ba7d569819cfd *inst/unitTests/runit.XPTr.R +fed8ed4da592c9b27b955a60b3ec0d61 *inst/unitTests/runit.XPTr.R 96ca46cdd33bc463a18a4fd91ba96cd8 *inst/unitTests/runit.algorithm.R c900795c44fa64fa17017d74781a6336 *inst/unitTests/runit.as.R 236cfb63718f861178334db870cd15f8 *inst/unitTests/runit.attributes.R @@ -576,7 +567,7 @@ 706eae34e6bc4220b10a20ee3bad1b59 *inst/unitTests/runit.embeddedR.R 1c23067386c47ed0bc18dc449d8f4c8c *inst/unitTests/runit.environments.R 78c2017571525d41de5a18d37a993891 *inst/unitTests/runit.exceptions.R -87c0df0cecdcb600d8ab0b57b72f44d0 *inst/unitTests/runit.exposeClass.R +5b60cc16ac6f8c4e16b1880d3099c208 *inst/unitTests/runit.exposeClass.R a58a42ac5c983dcefd232eafb36d3566 *inst/unitTests/runit.interface.R c764dcb5fc96a7d08f8cdb6110164981 *inst/unitTests/runit.misc.R b7846b7f02127205c9f46da71202eabe *inst/unitTests/runit.modref.R @@ -689,19 +680,22 @@ eef4c2f0e1abd787b8fd62d289ed5961 *src/internal.h 162e25bdcd86f0b858d832ab31dd2d93 *src/module.cpp 8a6cc9f18853ede2e3901e5b7dfb34f2 *src/rcpp_init.cpp -7084f702614a944a63aa3c3ca4ce12cd *tests/doRUnit.R -9f66aaa1d65534b63230a2f676cb4801 *vignettes/Rcpp-FAQ.Rmd -a278225621df1aa072f9348166812480 *vignettes/Rcpp-attributes.Rmd -eb54bf86409788a9265abf4ed891f39a *vignettes/Rcpp-extending.Rmd -8b26a9444aad4052447641cc740264e5 *vignettes/Rcpp-introduction.Rmd -0e54f1a6c5efb98f3c9ccde370ef6376 *vignettes/Rcpp-jss-2011.Rnw -b959784a2242f812d34cd9f95e428d21 *vignettes/Rcpp-modules.Rmd -7b4b5a4dc5fd5c88fb7745d9eca2806b *vignettes/Rcpp-package.Rmd -f5d660cdaed01cfaf91e1ba24ff5795d *vignettes/Rcpp-quickref.Rmd -bbca23801eda4033fe290d2374e3ac66 *vignettes/Rcpp-sugar.Rmd -1ff499f807825e7b2cc00a9d6367ba4b *vignettes/Rcpp-unitTests.pdf -571da9900e590625ef4834055fdbbb4a *vignettes/Rcpp.bib -5a3a712f27dd747d0da481ed445526be *vignettes/figures/bootstrap.pdf -80b507d5b500d5fd7135d71eca9557c6 *vignettes/figures/dist_graphs-1.pdf -6b2608bdcc856f4aaed8be1a0db315e7 *vignettes/figures/function_annotation_cpp.png -b1e52c8afdcf8bd9229a0733e623eae0 *vignettes/figures/samplePkg-files-light-bg.png +591a07a49f93c42b109aaaa74c76c03b *tests/doRUnit.R +2baf167ce452976b0fcb43e44f566af7 *vignettes/Rcpp-FAQ.Rnw +887250b7e0675b4a70d6eb1a4689080c *vignettes/Rcpp-attributes.Rnw +37f50a136d1350e8e864c9265cc88ad8 *vignettes/Rcpp-extending.Rnw +90eade7bfffa82f250510759bc9a7f36 *vignettes/Rcpp-introduction.Rnw +e6cf1d12ce4e3a2fed6eddf6290d393f *vignettes/Rcpp-jss-2011.Rnw +a96bcf4153b795bff19ddc36a17ca435 *vignettes/Rcpp-modules.Rnw +835d0e2dd365e4621663bd03ae219758 *vignettes/Rcpp-package.Rnw +d76adfdc4e68c69c5ff632e234db6a85 *vignettes/Rcpp-quickref.Rnw +929a1aad762b7354b6875a35093ec477 *vignettes/Rcpp-sugar.Rnw +14f68ba28e03f07ae1ec10d0d4ac3554 *vignettes/pdf/Rcpp-FAQ.pdf +a456c3a3e3e563bf4ac3f55a9993bd95 *vignettes/pdf/Rcpp-attributes.pdf +f59befb6e430ee07f968c4d8962ea0f9 *vignettes/pdf/Rcpp-extending.pdf +9ee99ba7d16151abc02a276371484af0 *vignettes/pdf/Rcpp-introduction.pdf +61be227a4a789920771b65a723d79d12 *vignettes/pdf/Rcpp-jss-2011.pdf +666f97a3b4d82ff0287ca292dcd0d9b9 *vignettes/pdf/Rcpp-modules.pdf +39a08ea1ff289367534cb2ec951d96d9 *vignettes/pdf/Rcpp-package.pdf +e4c478bf181bae73e3c3398a12ea2c51 *vignettes/pdf/Rcpp-quickref.pdf +60ba1d2f9ceac0d01d36561b2b4c466a *vignettes/pdf/Rcpp-sugar.pdf diff -Nru rcpp-1.0.2/R/Module.R rcpp-1.0.3/R/Module.R --- rcpp-1.0.2/R/Module.R 2018-03-31 17:34:39.000000000 +0000 +++ rcpp-1.0.3/R/Module.R 2019-07-21 18:04:44.000000000 +0000 @@ -230,11 +230,11 @@ .self <- .refClassDef <- NULL generator$methods(initialize = if(cpp_hasDefaultConstructor(CLASS)) - function(...) cpp_object_initializer(.self,.refClassDef, ...) + function(...) Rcpp::cpp_object_initializer(.self,.refClassDef, ...) else function(...) { - if(nargs()) cpp_object_initializer(.self,.refClassDef, ...) - else cpp_object_dummy(.self, .refClassDef) + if(nargs()) Rcpp::cpp_object_initializer(.self,.refClassDef, ...) + else Rcpp::cpp_object_dummy(.self, .refClassDef) } ) rm( .self, .refClassDef ) diff -Nru rcpp-1.0.2/README.md rcpp-1.0.3/README.md --- rcpp-1.0.2/README.md 2018-11-04 19:13:31.000000000 +0000 +++ rcpp-1.0.3/README.md 2019-10-14 11:57:00.000000000 +0000 @@ -1,6 +1,19 @@ -## Rcpp [![Build Status](https://travis-ci.org/RcppCore/Rcpp.svg)](https://travis-ci.org/RcppCore/Rcpp) [![License](https://eddelbuettel.github.io/badges/GPL2+.svg)](http://www.gnu.org/licenses/gpl-2.0.html) [![CRAN](http://www.r-pkg.org/badges/version/Rcpp)](https://cran.r-project.org/package=Rcpp) [![Dependencies](https://tinyverse.netlify.com/badge/Rcpp)](https://cran.r-project.org/package=Rcpp) [![Downloads](http://cranlogs.r-pkg.org/badges/Rcpp?color=brightgreen)](http://www.r-pkg.org/pkg/Rcpp) [![Coverage Status](https://codecov.io/gh/RcppCore/Rcpp/graph/badge.svg)](https://codecov.io/github/RcppCore/Rcpp?branch=master) +## Rcpp: Seamless R and C++ Integration -### Seamless R and C++ Integration +[![Build Status](https://travis-ci.org/RcppCore/Rcpp.svg)](https://travis-ci.org/RcppCore/Rcpp) +[![License](https://eddelbuettel.github.io/badges/GPL2+.svg)](http://www.gnu.org/licenses/gpl-2.0.html) +[![CRAN](http://www.r-pkg.org/badges/version/Rcpp)](https://cran.r-project.org/package=Rcpp) +[![Dependencies](https://tinyverse.netlify.com/badge/Rcpp)](https://cran.r-project.org/package=Rcpp) +[![Coverage Status](https://codecov.io/gh/RcppCore/Rcpp/graph/badge.svg)](https://codecov.io/github/RcppCore/Rcpp?branch=master) +[![Downloads](http://cranlogs.r-pkg.org/badges/Rcpp?color=brightgreen)](http://www.r-pkg.org/pkg/Rcpp) +[![CRAN use](https://jangorecki.gitlab.io/rdeps/Rcpp/CRAN_usage.svg?sanitize=true)](https://cran.r-project.org/package=Rcpp) +[![BioConductor use](https://jangorecki.gitlab.io/rdeps/Rcpp/BioC_usage.svg?sanitize=true)](https://cran.r-project.org/package=Rcpp) +[![StackOverflow](https://img.shields.io/badge/stackoverflow-rcpp-orange.svg)](https://stackoverflow.com/questions/tagged/rcpp) +[![JSS](https://img.shields.io/badge/JSS-10.18637%2Fjss.v040.i08-brightgreen)](http://dx.doi.org/10.18637/jss.v040.i08) +[![Springer useR!](https://img.shields.io/badge/Springer%20useR!-10.1007%2F978--1--4614--6868--4-brightgreen)](https://www.springer.com/gp/book/9781461468677) +[![TAS](https://img.shields.io/badge/TAS-10.1080%2F00031305.2017.1375990-brightgreen)](http://dx.doi.org/10.1080/00031305.2017.1375990) + +### Synopsis The [Rcpp package](https://cran.r-project.org/package=Rcpp) provides R functions and a (header-only for client packages) C++ library greatly @@ -82,9 +95,9 @@ available for code relying on the older interface. New development should always use this Rcpp package instead. -Other usage examples are provided by packages using Rcpp. As of November 2018, -there are 1490 [CRAN](https://cran.r-project.org) packages using Rcpp, a further -150 [BioConductor](http://www.bioconductor.org) packages in its current release +Other usage examples are provided by packages using Rcpp. As of September 2019, +there are 1790 [CRAN](https://cran.r-project.org) packages using Rcpp, a further +176 [BioConductor](http://www.bioconductor.org) packages in its current release as well as an unknown number of GitHub, Bitbucket, R-Forge, ... repositories using Rcpp. All these packages provide usage examples for Rcpp. diff -Nru rcpp-1.0.2/tests/doRUnit.R rcpp-1.0.3/tests/doRUnit.R --- rcpp-1.0.2/tests/doRUnit.R 2019-03-20 00:05:31.000000000 +0000 +++ rcpp-1.0.3/tests/doRUnit.R 2019-11-08 12:17:46.000000000 +0000 @@ -60,9 +60,11 @@ Sys.setenv("RunAllRcppTests"="yes") } - tests <- runTestSuite(testSuite) # Run tests + tests <- runTestSuite(testSuite) # Run tests printTextProtocol(tests) # Print results + if (Sys.info()[["sysname"]] != "Windows") + printTextProtocol(tests, file="/tmp/RcppTestLog.txt") ## Return success or failure to R CMD CHECK if (getErrors(tests)$nFail > 0) stop("TEST FAILED!") Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/figures/bootstrap.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/figures/bootstrap.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/figures/dist_graphs-1.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/figures/dist_graphs-1.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/figures/function_annotation_cpp.png and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/figures/function_annotation_cpp.png differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/figures/samplePkg-files-light-bg.png and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/figures/samplePkg-files-light-bg.png differ diff -Nru rcpp-1.0.2/vignettes/.install_extras rcpp-1.0.3/vignettes/.install_extras --- rcpp-1.0.2/vignettes/.install_extras 2013-12-17 01:24:15.000000000 +0000 +++ rcpp-1.0.3/vignettes/.install_extras 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Rcpp.bib -rcpp.index.html Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-attributes.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-attributes.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-extending.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-extending.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-FAQ.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-FAQ.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-introduction.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-introduction.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-jss-2011.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-jss-2011.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-modules.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-modules.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-package.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-package.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-quickref.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-quickref.pdf differ Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/pdf/Rcpp-sugar.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/pdf/Rcpp-sugar.pdf differ diff -Nru rcpp-1.0.2/vignettes/Rcpp-attributes.Rmd rcpp-1.0.3/vignettes/Rcpp-attributes.Rmd --- rcpp-1.0.2/vignettes/Rcpp-attributes.Rmd 2018-09-18 22:45:39.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-attributes.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,846 +0,0 @@ ---- -title: \pkg{Rcpp} Attributes - -# Use letters for affiliations -author: - - name: J.J. Allaire - affiliation: a - - name: Dirk Eddelbuettel - affiliation: b - - name: Romain François - affiliation: c - -address: - - code: a - address: \url{https://rstudio.com} - - code: b - address: \url{http://dirk.eddelbuettel.com} - - code: c - address: \url{https://romain.rbind.io/} - -# For footer text TODO(fold into template, allow free form two-authors) -lead_author_surname: Allaire, Eddelbuettel, François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - \textsl{Rcpp attributes} provide a high-level syntax for declaring \proglang{C++} - functions as callable from \proglang{R} and automatically generating the code - required to invoke them. Attributes are intended to facilitate both interactive use - of \proglang{C++} within \proglang{R} sessions as well as to support \proglang{R} - package development. The implementation of attributes is based on previous - work in the \pkg{inline} package \citep{CRAN:inline}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - attributes - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-attributes} - %\VignetteKeywords{Rcpp, attributes, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -Attributes are a new feature of \pkg{Rcpp} version 0.10.0 \citep{CRAN:Rcpp,JSS:Rcpp} -that provide infrastructure for seamless language bindings between \proglang{R} and -\proglang{C++}. The motivation for attributes is several-fold: - -1. Reduce the learning curve associated with using C++ and R together -1. Eliminate boilerplate conversion and marshaling code wherever - possible -1. Seamless use of C++ within interactive R sessions -1. Unified syntax for interactive work and package development - -The core concept is to add annotations to \proglang{C++} source -files that provide the context required to automatically generate \proglang{R} -bindings to \proglang{C++} functions. Attributes and their supporting -functions include: - -- `Rcpp::export` attribute to export a \proglang{C++} function - to \proglang{R} -- `sourceCpp` function to source exported functions from a file -- `cppFunction` and `evalCpp` functions for inline - declarations and execution -- `Rcpp::depends` attribute for specifying additional build - dependencies for `sourceCpp` - -Attributes can also be used for package development via the -`compileAttributes` function, which automatically generates -`extern "C"` and `.Call` wrappers for \proglang{C++} -functions within packages. - -# Using Attributes - -Attributes are annotations that are added to C++ source files to provide -additional information to the compiler. \pkg{Rcpp} supports attributes -to indicate that C++ functions should be made available as R functions, -as well as to optionally specify additional build dependencies for source files. - -\proglang{C++11} specifies a standard syntax for attributes -\citep{Maurer+Wong:2008:AttributesInC++}. Since this standard isn't yet -fully supported across all compilers, \pkg{Rcpp} attributes are included in -source files using specially formatted comments. - -## Exporting C++ Functions - -The `sourceCpp` function parses a \proglang{C++} file and looks for -functions marked with the `Rcpp::export` attribute. A shared -library is then built and its exported functions are made available as R -functions in the specified environment. For example, this source file -contains an implementation of convolve (note the `Rcpp::export` -attribute in the comment above the function): - -```{Rcpp, eval = FALSE} -#include -using namespace Rcpp; - -// [[Rcpp::export]] -NumericVector convolveCpp(NumericVector a, - NumericVector b) { - - int na = a.size(), nb = b.size(); - int nab = na + nb - 1; - NumericVector xab(nab); - - for (int i = 0; i < na; i++) - for (int j = 0; j < nb; j++) - xab[i + j] += a[i] * b[j]; - - return xab; -} -``` - -The addition of the export attribute allows us to do this from the \proglang{R} -prompt: - -```{r, eval = FALSE} -sourceCpp("convolve.cpp") -convolveCpp(x, y) -``` - -We can now write \proglang{C++} functions using built-in \proglang{C++} types -and \pkg{Rcpp} wrapper types and then source them just as we would an -\proglang{R} script. - -The `sourceCpp` function performs caching based on the last -modified date of the source file and it's local dependencies so as -long as the source does not change the compilation will occur only -once per R session. - -## Specifying Argument Defaults - -If default argument values are provided in the C++ function definition -then these defaults are also used for the exported R function. For example, -the following C++ function: - -```{Rcpp, eval = FALSE} -DataFrame readData(CharacterVector file, - CharacterVector colNames = - CharacterVector::create(), - std::string comment = "#", - bool header = true) -``` - -Will be exported to R as: - -```{r, eval = FALSE} -function(file, colNames=character(), - comment="#", header=TRUE) -``` - -Note that C++ rules for default arguments still apply: they must occur -consecutively at the end of the function signature and (unlike R) can't rely -on the values of other arguments. - -Not all \proglang{C++} default argument values can be parsed into their -\proglang{R} equivalents, however the most common cases are supported, including: - -- String literals delimited by quotes (e.g. `"foo"`) -- Decimal numeric values (e.g. `10` or `4.5`) -- Pre-defined constants including `true`, `false`, - `R_NilValue`, `NA_STRING`, `NA_INTEGER`, - `NA_REAL`, and `NA_LOGICAL`. -- Selected vector types (`CharacterVector`, `IntegerVector`, - and `NumericVector`) instantiated using the `::create` - static member function. -- `Matrix` types instantiated using the `rows`, - `cols` constructor. - -## Signaling Errors - -Within \proglang{R} code the `stop` function is typically used to signal -errors. Within \proglang{R} extensions written in \proglang{C} the `Rf_error` function is typically used. However, within \proglang{C++} code you cannot -safely use `Rf_error` because it results in a `longjmp` over -any \proglang{C++} destructors on the stack. - -The correct way to signal errors within \proglang{C++} functions is to throw an `Rcpp::exception`. For example: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - throw Rcpp::exception("Unexpected " - "condition occurred"); -``` - -There is also an `Rcpp::stop` function that is shorthand for throwing -an `Rcpp::exception`. For example: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - Rcpp::stop("Unexpected condition occurred"); -``` - -In both cases the \proglang{C++} exception will be caught by \pkg{Rcpp} -prior to returning control to \proglang{R} and converted into the correct -signal to \proglang{R} that execution should stop with the specified message. - -You can similarly also signal warnings with the `Rcpp::warning` -function: - -```{Rcpp, eval = FALSE} -if (unexpectedCondition) - Rcpp::warning("Unexpected condition occurred"); -``` - -## Supporting User Interruption - -If your function may run for an extended period of time, users will appreciate -the ability to interrupt it's processing and return to the REPL. This is -handled automatically for R code (as R checks for user interrupts periodically -during processing) however requires explicit accounting for in C and C++ -extensions to R. To make computations interrupt-able, you should periodically -call the `Rcpp::checkUserInterrupt` function, for example: - -```{Rcpp, eval = FALSE} -for (int i=0; i<1000000; i++) { - // check for interrupt every 1000 iterations - if (i % 1000 == 0) - Rcpp::checkUserInterrupt(); - - // ...do some expensive work... -} -``` - -A good guideline is to call `Rcpp::checkUserInterrupt` every 1 or 2 -seconds that your computation is running. In the above code, if the user -requests an interrupt then an exception is thrown and the attributes wrapper -code arranges for the user to be returned to the REPL. - -Note that R provides a \proglang{C} API for the same purpose -(`R_CheckUserInterrupt`) however this API is not safe to use in -\proglang{C++} code as it uses `longjmp` to exit the current scope, -bypassing any C++ destructors on the stack. The `Rcpp::checkUserInterrupt` -function is provided as a safe alternative for \proglang{C++} code. - -## Embedding R Code - -Typically \proglang{C++} and \proglang{R} code are kept in their own source -files. However, it's often convenient to bundle code from both languages into -a common source file that can be executed using single call to `sourceCpp`. - -To embed chunks of \proglang{R} code within a \proglang{C++} -source file you include the \proglang{R} code within a block comment that -has the prefix of `/*** R`. For example: - -```{Rcpp, eval = FALSE} -/*** R - -# Call the fibonacci function defined in C++ -fibonacci(10) - -*/ -``` - -Multiple \proglang{R} code chunks can be included in a \proglang{C++} file. The -`sourceCpp` function will first compile the \proglang{C++} code into a -shared library and then source the embedded \proglang{R} code. - -## Modifying Function Names - -You can change the name of an exported function as it appears to \proglang{R} by -adding a name parameter to `Rcpp::export`. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::export(name = ".convolveCpp")]] -NumericVector convolveCpp(NumericVector a, - NumericVector b) -``` - -Note that in this case since the specified name is prefaced by a \code{.} the -exported R function will be hidden. You can also use this method to provide -implementations of S3 methods (which wouldn't otherwise be possible because -C++ functions can't contain a '.' in their name). - -## Function Requirements - -Functions marked with the `Rcpp::export` attribute must meet several -requirements to be correctly handled: - -- Be defined in the global namespace (i.e. not within a C++ namespace declaration) -- Have a return type that is either void or compatible with `Rcpp::wrap` - and parameter types that are compatible with `Rcpp::as` (see sections - 3.1 and 3.2 of the '\textsl{Rcpp-jss-2011}' vignette for more details). -- Use fully qualified type names for the return value and all parameters. - Rcpp types may however appear without a namespace qualifier (i.e. - `DataFrame` is okay as a type name but `std::string` must be - specified fully). - -## Random Number Generation - -\proglang{R} functions implemented in \proglang{C} or \proglang{C++} need -to be careful to surround use of internal random number generation routines -(e.g. `unif_rand`) with calls to `GetRNGstate` and -`PutRNGstate`. - -Within \pkg{Rcpp}, this is typically done using the `RNGScope` class. -However, this is not necessary for \proglang{C++} functions exported using -attributes because an `RNGScope` is established for them automatically. -Note that \pkg{Rcpp} implements `RNGScope` using a counter, so it's -still safe to execute code that may establish it's own `RNGScope` (such -as the \pkg{Rcpp} sugar functions that deal with random number generation). - -The overhead associated with using `RNGScope` is negligible (only a -couple of milliseconds) and it provides a guarantee that all C++ code -will inter-operate correctly with R's random number generation. If you are -certain that no C++ code will make use of random number generation and the -2ms of execution time is meaningful in your context, you can disable the -automatic injection of `RNGScope` using the `rng` parameter -of the `Rcpp::export` attribute. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::export(rng = false)]] -double myFunction(double input) { - // ...code that never uses the - // R random number generation... -} -``` - -## Importing Dependencies - -It's also possible to use the `Rcpp::depends` attribute to declare -dependencies on other packages. For example: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(RcppArmadillo)]] - -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List fastLm(NumericVector yr, NumericMatrix Xr) { - - int n = Xr.nrow(), k = Xr.ncol(); - - arma::mat X(Xr.begin(), n, k, false); - arma::colvec y(yr.begin(), yr.size(), false); - - arma::colvec coef = arma::solve(X, y); - arma::colvec rd = y - X*coef; - - double sig2 = - arma::as_scalar(arma::trans(rd)*rd/(n-k)); - arma::colvec sderr = arma::sqrt(sig2 * - arma::diagvec(arma::inv(arma::trans(X)*X))); - - return List::create(Named("coef") = coef, - Named("sderr")= sderr); -} -``` - -The inclusion of the `Rcpp::depends` attribute causes `sourceCpp` -to configure the build environment to correctly compile and link against the -\pkg{RcppArmadillo} package. Source files can declare more than one dependency -either by using multiple `Rcpp::depends` attributes or with syntax like this: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(Matrix, RcppArmadillo)]] -``` - -Dependencies are discovered both by scanning for package include directories -and by invoking \pkg{inline} plugins if they are available for a package. - -Note that while the `Rcpp::depends` attribute establishes dependencies -for `sourceCpp`, it's important to note that if you include the same -source file in an \proglang{R} package these dependencies must still be -listed in the `Imports` and/or `LinkingTo` fields of the package -`DESCRIPTION` file. - -## Sharing Code - -The core use case for `sourceCpp` is the compilation of a single -self-contained source file. Code within this file can import other C++ code -by using the `Rcpp::depends` attribute as described above. - -The recommended practice for sharing C++ code across many uses of -`sourceCpp` is therefore to create an R package to wrap the C++ -code. This has many benefits not the least of which is easy distribution of -shared code. More information on creating packages that contain C++ code -is included in the Package Development section below. - -### Shared Code in Header Files - -If you need to share a small amount of C++ code between source files -compiled with `sourceCpp` and the option of creating a package -isn't practical, then you can also share code using local includes of C++ -header files. To do this, create a header file with the definition of -shared functions, classes, enums, etc. For example: - -```{Rcpp, eval = FALSE} -#ifndef __UTILITIES__ -#define __UTILITIES__ - -inline double timesTwo(double x) { - return x * 2; -} - -#endif // __UTILITIES__ -``` - -Note the use of the `#ifndef` include guard, this is important to ensure -that code is not included more than once in a source file. You should -use an include guard and be sure to pick a unique name for the corresponding -`#define`. - -Also note the use of the \code{inline} keyword preceding the function. This -is important to ensure that there are not multiple definitions of -functions included from header files. Classes fully defined in header files -automatically have inline semantics so don't require this treatment. - -To use this code in a source file you'd just include -it based on it's relative path (being sure to use `"` as the -delimiter to indicate a local file reference). For example: - -```{Rcpp, eval = FALSE} -#include "shared/utilities.hpp" - -// [[Rcpp::export]] -double transformValue(double x) { - return timesTwo(x) * 10; -} -``` - -### Shared Code in C++ Files - -When scanning for locally included header files \code{sourceCpp} also checks -for a corresponding implementation file and automatically includes it in the -compilation if it exists. - -This enables you to break the shared code entirely into it's own source file. -In terms of the above example, this would mean having only a function -declaration in the header: - -```{Rcpp, eval = FALSE} -#ifndef __UTILITIES__ -#define __UTILITIES__ - -double timesTwo(double x); - -#endif // __UTILITIES__ -``` - -Then actually defining the function in a separate source file with the -same base name as the header file but with a .cpp extension (in the above -example this would be \code{utilities.cpp}): - -```{Rcpp, eval = FALSE} -#include "utilities.hpp" - -double timesTwo(double x) { - return x * 2; -} -``` - -It's also possible to use attributes to declare dependencies and exported -functions within shared header and source files. This enables you to take -a source file that is typically used standalone and include it when compiling -another source file. - -Note that since additional source files are processed as separate translation -units the total compilation time will increase proportional to the number of -files processed. From this standpoint it's often preferable to use shared -header files with definitions fully inlined as demonstrated above. - -Note also that embedded R code is only executed for the main source file not -those referenced by local includes. - -## Including C++ Inline - -Maintaining C++ code in it's own source file provides several benefits including -the ability to use \proglang{C++} aware text-editing tools and straightforward -mapping of compilation errors to lines in the source file. However, it's also -possible to do inline declaration and execution of C++ code. - -There are several ways to accomplish this, including passing a code -string to `sourceCpp` or using the shorter-form `cppFunction` -or `evalCpp` functions. For example: - -```{r, eval = FALSE} -cppFunction(' - int fibonacci(const int x) { - if (x < 2) - return x; - else - return (fibonacci(x-1)) + fibonacci(x-2); - } -') - -evalCpp('std::numeric_limits::max()') -``` - -You can also specify a depends parameter to `cppFunction` or `evalCpp`: - -```{r, eval = FALSE} -cppFunction(depends='RcppArmadillo', code='...') -``` - -# Package Development - -One of the goals of \pkg{Rcpp} attributes is to simultaneously facilitate -ad-hoc and interactive work with \proglang{C++} while also making it very easy to -migrate that work into an \proglang{R} package. There are several benefits of -moving code from a standalone \proglang{C++} source file to a package: - -1. Your code can be made available to users without \proglang{C++} development - tools (at least on Windows or Mac OS X where binary packages are common) -1. Multiple source files and their dependencies are handled automatically - by the \proglang{R} package build system -1. Packages provide additional infrastructure for testing, documentation - and consistency - -## Package Creation - -To create a package that is based on \pkg{Rcpp} you should follow the -guidelines in the '\textsl{Rcpp-package}' vignette. For a new package this -is most conveniently done using the `Rcpp.package.skeleton` function. - -To generate a new package with a simple hello, world function that uses -attributes you can do the following: - -```{r, eval = FALSE} -Rcpp.package.skeleton("NewPackage", - attributes = TRUE) -``` - -To generate a package based on \proglang{C++} files that you've been using -with `sourceCpp` you can use the `cpp_files` parameter: - -```{r, eval = FALSE} -Rcpp.package.skeleton("NewPackage", - example_code = FALSE, - cpp_files = c("convolve.cpp")) -``` - -## Specifying Dependencies - -Once you've migrated \proglang{C++} code into a package, the dependencies for -source files are derived from the `Imports` and `LinkingTo` fields -in the package `DESCRIPTION` file rather than the `Rcpp::depends` -attribute. Some packages also require the addition of an entry to the package -`NAMESPACE` file to ensure that the package's shared library is loaded -prior to callers using the package. For every package you import C++ code from -(including \pkg{Rcpp}) you need to add these entries. - -Packages that provide only C++ header files (and no shared library) need only -be referred to using `LinkingTo`. You should consult the documentation -for the package you are using for the requirements particular to that package. - -For example, if your package depends on \pkg{Rcpp} you'd have the following -entries in the `DESCRIPTION` file: - -```{bash, eval = FALSE} -Imports: Rcpp (>= 0.11.4) -LinkingTo: Rcpp -``` - -And the following entry in your `NAMESPACE` file: - -```{bash, eval = FALSE} -importFrom(Rcpp, evalCpp) -``` - -If your package additionally depended on the \pkg{BH} (Boost headers) package -you'd just add an entry for \pkg{BH} to the `LinkingTo` field since -\pkg{BH} is a header-only package: - -```{bash, eval = FALSE} -Imports: Rcpp (>= 0.11.4) -LinkingTo: Rcpp, BH -``` - - -## Exporting R Functions - -Within interactive sessions you call the `sourceCpp` function -on individual files to export \proglang{C++} functions into the global -environment. However, for packages you call a single utility function to -export all \proglang{C++} functions within the package. - -The `compileAttributes` function scans the source files within a package -for export attributes and generates code as required. For example, executing -this from within the package working directory: - -```{r, eval = FALSE} -compileAttributes() -``` - -Results in the generation of the following two source files: - -- `src/RcppExports.cpp` -- The `extern "C"` wrappers required - to call exported \proglang{C++} functions within the package. -- `R/RcppExports.R` -- The `.Call` wrappers required to call - the `extern "C"` functions defined in `RcppExports.cpp`. - -You should re-run `compileAttributes` whenever functions are added, -removed, or have their signatures changed. Note that if you are using either -RStudio or \pkg{devtools} to build your package then the -`compileAttributes` function is called automatically whenever your -package is built. - -The `compileAttributes` function deals only with exporting -\proglang{C++} functions to \proglang{R}. If you want the functions to -additionally be publicly available from your package's namespace another -step may be required. Specifically, if your package `NAMESPACE` file -does not use a pattern to export functions then you should add an explicit -entry to `NAMESPACE` for each R function you want publicly available. - -## Package Init Functions - -Rcpp attribute compilation will automatically generate a package R_init function that does native routine registration as described here: . - -You may however want to add additional C++ code to the package initialization sequence. To do this, you can add the `[[Rcpp::init]]` attribute to functions within your package. For example: - -```{cpp, eval = FALSE} -// [[Rcpp::init]] -void my_package_init(DllInfo *dll) { - // initialization code here -} -``` - -In this case, a call to `my_package_init()` will be added to the end of the automatically generated R_init function within RcppExports.cpp. For example: - -```{cpp, eval = FALSE} -void my_package_init(DllInfo *dll); -RcppExport void R_init_pkgname(DllInfo *dll) { - R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); - R_useDynamicSymbols(dll, FALSE); - my_package_init(dll); -} -``` - -## Types in Generated Code - -In some cases the signatures of the C++ functions that are generated within -`RcppExports.cpp` may have additional type requirements beyond the core -standard library and \pkg{Rcpp} types (e.g. `CharacterVector`, -`NumericVector`, etc.). Examples might include convenience typedefs, -as/wrap handlers for marshaling between custom types and SEXP, or types -wrapped by the Rcpp `XPtr` template. - -In this case, you can create a header file that contains these type definitions -(either defined inline or by including other headers) and have this header -file automatically included in `RcppExports.cpp`. Headers named with -the convention `pkgname_types` are automatically included along with -the generated C++ code. For example, if your package is named \pkg{fastcode} -then any of the following header files would be automatically included in -`RcppExports.cpp`: - -```{Rcpp, eval = FALSE} -src/fastcode_types.h -src/fastcode_types.hpp -inst/include/fastcode_types.h -inst/include/fastcode_types.hpp -``` - -There is one other mechanism for type visibility in `RcppExports.cpp`. -If your package provides a master include file for consumption by C++ clients -then this file will also be automatically included. For example, if the -\pkg{fastcode} package had a C++ API and the following header file: - -```{Rcpp, eval = FALSE} -inst/include/fastcode.h -``` - -This header file will also automatically be included in -`RcppExports.cpp`. Note that the convention of using `.h` for -header files containing C++ code may seem unnatural, but this comes from the -recommended practices described in '\textsl{Writing R Extensions}' -\citep{R:Extensions}. - -## Roxygen Comments - -The \pkg{roxygen2} package \citep{CRAN:roxygen2} provides a facility for -automatically generating \proglang{R} documentation files based on specially -formatted comments in \proglang{R} source code. - -If you include roxygen comments in your \proglang{C++} source file with a -`//'` prefix then `compileAttributes` will transpose them -into R roxygen comments within `R/RcppExports.R`. For example the -following code in a \proglang{C++} source file: - -```{Rcpp, eval = FALSE} -//' The length of a string (in characters). -//' -//' @param str input character vector -//' @return characters in each element of the vector -// [[Rcpp::export]] -NumericVector strLength(CharacterVector str) -``` - -Results in the following code in the generated \proglang{R} source file: - -```{r, eval = FALSE} -#' The length of a string (in characters). -#' -#' @param str input character vector -#' @return characters in each element of the vector -strLength <- function(str) -``` - -## Providing a C++ Interface - -The interface exposed from \proglang{R} packages is most typically a set of -\proglang{R} functions. However, the \proglang{R} package system also provides -a mechanism to allow the exporting of \proglang{C} and \proglang{C++} -interfaces using package header files. This is based on the -`R_RegisterCCallable` and `R_GetCCallable` functions described in -'\textsl{Writing R Extensions}' \citep{R:Extensions}. - -\proglang{C++} interfaces to a package are published within the -top level `include` directory of the package (which within the package -source directory is located at `inst/include`). The \proglang{R} build -system automatically adds the required `include` directories for all -packages specified in the `LinkingTo` field of the package -`DESCRIPTION` file. - -### Interfaces Attribute - -The `Rcpp::interfaces` attribute can be used to automatically -generate a header-only interface to your \proglang{C++} functions -within the `include` directory of your package. - -The `Rcpp::interfaces` attribute is specified on a per-source -file basis, and indicates which interfaces (\proglang{R}, \proglang{C++}, -or both) should be provided for exported functions within the file. - -For example, the following specifies that both R and \proglang{C++} interfaces -should be generated for a source file: - -```{Rcpp, eval = FALSE} -// [[Rcpp::interfaces(r, cpp)]] -``` - -Note that the default behavior if an `Rcpp::interfaces` attribute -is not included in a source file is to generate an R interface only. - -### Generated Code - -If you request a `cpp` interface for a source file then -`compileAttributes` generates the following header files -(substituting \emph{Package} with the name of the package code is being -generated for): - -```{bash, eval = FALSE} -inst/include/Package.h -inst/include/Package_RcppExports.h -``` - -The `Package_RcppExports.h` file has inline definitions for all -exported \proglang{C++} functions that enable calling them using the -`R_GetCCallable` mechanism. - -The `Package.h` file does nothing other than include the -`Package_RcppExports.h` header. This is done so -that package authors can replace the `Package.h` header with -a custom one and still be able to include the automatically generated exports -(details on doing this are provided in the next section). - -The exported functions are defined within a \proglang{C++} namespace that matches -the name of the package. For example, an exported \proglang{C++} function -`bar` could be called from package `MyPackage` as follows: - -```{Rcpp, eval = FALSE} -// [[Rcpp::depends(MyPackage)]] - -#include - -void foo() { - MyPackage::bar(); -} -``` - -### Including Additional Code - -You might wish to use the `Rcpp::interfaces` attribute to generate -a part of your package's \proglang{C++} interface but also provide -additional custom \proglang{C++} code. In this case you -should replace the generated `Package.h` file with one of your own. - -Note that the way \pkg{Rcpp} distinguishes user verses generated files is by checking -for the presence a special token in the file (if it's present then it's known -to be generated and thus safe to overwrite). You'll see this token at the top -of the generated `Package.h` file, be sure to remove it if you want -to provide a custom header. - -Once you've established a custom package header file, you need only include the -`Package_RcppExports.h` file within your header to make available -the automatically generated code alongside your own. - -If you need to include code from your custom header files within the -compilation of your package source files, you will also need to add the -following entry to `Makevars` and `Makevars.win` (both are -in the `src` directory of your package): - -```{bash, eval = FALSE} -PKG_CPPFLAGS += -I../inst/include/ -``` - -Note that the R package build system does not automatically force a rebuild -when headers in `inst/include` change, so you should be sure to perform a -full rebuild of the package after making changes to these headers. diff -Nru rcpp-1.0.2/vignettes/Rcpp-attributes.Rnw rcpp-1.0.3/vignettes/Rcpp-attributes.Rnw --- rcpp-1.0.2/vignettes/Rcpp-attributes.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-attributes.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-attributes} +%\VignetteKeywords{Rcpp, attributes, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-attributes.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp.bib rcpp-1.0.3/vignettes/Rcpp.bib --- rcpp-1.0.2/vignettes/Rcpp.bib 2019-07-20 13:50:10.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp.bib 1970-01-01 00:00:00.000000000 +0000 @@ -1,857 +0,0 @@ -@String{CRAN = "http://CRAN.R-Project.org/" } -@String{manuals = CRAN # "doc/manuals/" } -@String{RCoreTeam = "{R Core Team}" } -@String{RFoundation = "R Foundation for Statistical Computing" } -@String{R-Forge = "http://R-Forge.R-Project.org/" } - -@manual{Abrahams+Grosse-Kunstleve:2003:Boost.Python, - author = { David Abrahams and Ralf W. Grosse-Kunstleve }, - organization = "Boost Consulting", - title = "Building Hybrid Systems with Boost.Python", - year = 2003, - url = "http://www.boostpro.com/writing/bpl.pdf" -} - -@Book{Abrahams+Gurtovoy:2004:TemplateMetaprogramming, - author = {David Abrahams and Aleksey Gurtovoy}, - title = {{C++} {T}emplate {M}etaprogramming: Concepts, Tools - and Techniques from {B}oost and Beyond}, - publisher = {Addison-Wesley}, - year = 2004, - address = {Boston} -} - -@book{Anderson:1990:UGLAPACK, - author = {Anderson, E. and Bai, Z. and Bischof, C. and - Blackford, S. and Demmel, J. and Dongarra, J. and Du - Croz, J. and Greenbaum, A. and Hammarling, S. and - McKenney, A. and Sorensen, D.}, - title = {{LAPACK} Users' Guide}, - edition = {Third}, - publisher = {Society for Industrial and Applied Mathematics}, - year = 1999, - address = {Philadelphia, PA}, - isbn = {0-89871-447-8 (paperback)} -} - -@Manual{Armstrong:2009:RAbstraction, - title = {{RAbstraction}: {C++} abstraction for {R} objects}, - author = {Whit Armstrong}, - year = 2009, - note = {Code repository last updated 2009-07-22.}, - url = {http://github.com/armstrtw/rabstraction} -} - -@Manual{Armstrong:2009:RObjects, - title = {{RObjects}: {C++} wrapper for R objects (a better - implementation of {RAbstraction}}, - author = {Whit Armstrong}, - year = 2009, - note = {Code repository last updated 2009-11-28.}, - url = {http://github.com/armstrtw/RObjects} -} - -@InProceedings{Bates+DebRoy:2001:C++Classes, - author = {Douglas M. Bates and Saikat DebRoy}, - title = {{C++} Classes for {R} Objects}, - booktitle = {Proceedings of the 2nd International Workshop on Distributed - Statistical Computing, March 15--17, 2001, Technische - Universit\"at Wien, Vienna, Austria}, - editor = {Kurt Hornik and Friedrich Leisch}, - year = {2001}, - url = {http://www.ci.tuwien.ac.at/Conferences/DSC-2001/Proceedings/}, - note = {ISSN 1609-395X} -} - - -@Misc{Brokken:2011:Cpp, - author = {Frank B. Brokken}, - title = {C++ Annotations}, - howpublished = {Electronic book, University of Groningen}, - year = 2011, - url = {http://www.icce.rug.nl/documents/cplusplus/} -} - -@Manual{CRAN:Matrix, - title = {\pkg{Matrix}: Sparse and Dense Matrix Classes and Methods}, - author = {Douglas Bates and Martin Maechler}, - year = 2019, - note = {R package version 1.2-17}, - url = CRAN # "package=Matrix" -} - -@Manual{CRAN:RInside, - title = {RInside: C++ classes to embed R in C++ applications}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2019, - note = {R package version 0.2.15}, - url = CRAN # "package=RInside" -} - -@Manual{CRAN:RProtoBuf, - title = {RProtoBuf: R Interface to the Protocol Buffers API}, - author = {Romain Fran\c{c}ois and Dirk Eddelbuettel and Murray Stokely and Jeroen Ooms}, - year = 2019, - note = {R package version 0.4.14}, - url = CRAN # "package=RProtoBuf" -} - -@Manual{CRAN:RQuantLib, - title = {RQuantLib: {R} interface to the {QuantLib} library}, - author = {Dirk Eddelbuettel and Khanh Nguyen and Terry Leitch}, - year = 2019, - note = {R package version 0.4.9}, - url = CRAN # "package=RQuantLib" -} - -@Manual{CRAN:RUnit, - title = {RUnit: R Unit Test Framework}, - author = {Matthias Burger and Klaus Juenemann and Thomas - Koenig}, - year = 2015, - note = {R package version 0.4.31}, - url = {https://CRAN.R-project.org/package=RUnit}, -} - -@Manual{CRAN:Rcpp, - title = {{Rcpp}: Seamless {R} and {C++} Integration}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois and JJ - Allaire and Kevin Ushey and Qiang Kou and - Nathan Russel and John Chambers and Douglas Bates}, - year = 2019, - note = {R package version 1.0.2}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Attributes, - crossref = {CRAN:Rcpp}, - author = {J. J. Allaire and Dirk Eddelbuettel and Romain - Fran\c{c}ois}, - title = {{Rcpp} Attributes}, - year = 2018, - note = {Vignette included in R package Rcpp}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:FAQ, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Frequently Asked Questions About {Rcpp}}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Modules, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Exposing {C++} functions and classes with {Rcpp} modules}, - year = 2018, - note = {Vignette included in R package Rcpp}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Package, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Writing a package that uses {Rcpp}}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:Rcpp:Sugar, - crossref = {CRAN:Rcpp}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - title = {Rcpp syntactic sugar}, - year = 2018, - note = {Vignette included in R package {Rcpp}}, - url = CRAN # "package=Rcpp" -} - -@Manual{CRAN:RcppArmadillo, - title = {RcppArmadillo: Rcpp integration for Armadillo - templated linear algebra library}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois and - Douglas Bates and Binxiang Ni}, - year = 2019, - note = {R package version 0.9.600.4.0}, - url = CRAN # "package=RcppArmadillo" -} - -@Manual{CRAN:RcppClassic, - title = {RcppClassic: Deprecated 'classic' Rcpp API}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.9.11}, - url = CRAN # "package=RcppClassic" -} - -@Manual{CRAN:RcppDE, - title = {RcppDE: Global optimization by differential evolution in C++}, - author = {Dirk Eddelbuettel}, - year = 2018, - note = {R package version 0.1.6}, - url = CRAN # "package=RcppDE" -} - -@Manual{CRAN:RcppEigen, - title = {RcppEigen: Rcpp integration for the Eigen templated linear - algebra library}, - author = {Douglas Bates and Dirk Eddelbuettel and Romain Fran\c{c}ois and Yixuan Qiu}, - year = 2018, - note = {{R} package version 0.3.3.5.0}, - url = CRAN # "package=RcppEigen" -} - -@Manual{CRAN:RcppExamples, - title = {RcppExamples: Examples using {Rcpp} to interface {R} - and {C++}}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2016, - note = {R package version 0.1.8}, - url = CRAN # "package=RcppExamples" -} - -@Manual{CRAN:RcppGSL, - title = {RcppGSL: Rcpp integration for GNU GSL vectors and matrices}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.3.6}, - url = CRAN # "package=RcppGSL" -} - -@Manual{CRAN:RcppZiggurat, - title = {RcppZiggurat: Rcpp Integration of Different Ziggurat Normal RNG Implementations}, - author = {Dirk Eddelbuettel}, - year = 2018, - note = {R package version 0.1.5}, - url = CRAN # "package=RcppZiggurat" -} - -@Manual{CRAN:Rserve, - title = {Rserve: Binary R server}, - author = {Simon Urbanek}, - year = 2019, - note = {R package version 1.7-3.1}, - url = CRAN # "package=Rserve" -} - -@Manual{CRAN:cxxPack, - title = {cxxpack: {R/C++} Tools for Literate Statistical - Practice}, - author = {Dominick Samperi}, - year = 2010, - note = {R package version 7.0.6}, - url = CRAN # "package=cxxPack" -} - -@Manual{CRAN:devtools, - title = {devtools: Tools to Make Developing R Packages - Easier}, - author = {Hadley Wickham and Winston Chang}, - year = 2016, - note = {R package version 1.12.0}, - url = {https://CRAN.R-project.org/package=devtools}, -} - -@Manual{CRAN:highlight, - title = {highlight: Syntax highlighter}, - author = {Romain Fran\c{c}ois}, - year = 2017, - note = {R package with version 0.4.7.2}, - url = CRAN # "package=highlight" -} - -@Manual{CRAN:inline, - title = {inline: Inline C, C++, Fortran function calls from - R}, - author = {Oleg Sklyar and Duncan Murdoch and Mike Smith and - Dirk Eddelbuettel and Romain Fran\c{c}ois}, - year = 2018, - note = {R package version 0.3.15}, - url = CRAN # "package=inline" -} - -@Manual{CRAN:littler, - title = {littler: {R} at the {Command-Line} via r}, - author = {Dirk Eddelbuettel and Jeffrey Horner}, - year = 2017, - note = {R package version 0.3.2}, - url = CRAN # "package=littler" -} - -@Manual{CRAN:microbenchmark, - title = {microbenchmark: Accurate Timing Functions}, - author = {Olaf Mersmann}, - year = 2015, - note = {R package version 1.4-2.1}, - url = {https://CRAN.R-project.org/package=microbenchmark} -} - -@Manual{CRAN:minqa, - title = {minqa: Derivative-free optimization algorithms by - quadratic approximation}, - author = {Douglas Bates and Katharine M. Mullen and John - C. Nash and Ravi Varadhan}, - year = 2014, - note = {R package version 1.2.4}, - url = CRAN # "package=minqa" -} - -@Manual{CRAN:profvis, - title = {profvis: Interactive Visualizations for Profiling R Code}, - author = {Winston Chang and Javier Luraschi}, - year = 2017, - note = {R package version 0.3.3}, - url = {https://CRAN.R-project.org/package=profvis}, -} - -@Manual{CRAN:rbenchmark, - title = {\pkg{rbenchmark}: Benchmarking routine for R}, - author = {Wacek Kusnierczyk}, - year = 2012, - note = {R package version 1.0.0}, - url = CRAN # "package=rbenchmark" -} - -@Manual{CRAN:roxygen2, - title = {roxygen2: In-source documentation for R}, - author = {Hadley Wickham and Peter Danenberg and Manuel Eugster}, - year = 2017, - note = {R package version 6.0.1}, - url = CRAN # "package=roxygen2" -} - -@Article{CRAN:testthat, - author = {Hadley Wickham}, - title = {testthat: Get Started with Testing}, - journal = {The R Journal}, - year = 2011, - volume = 3, - pages = {5--10}, -} - -@Book{Chambers:1998:PwD, - author = {John M. Chambers}, - title = {Programming with Data: {A} Guide to the {S} Language}, - publisher = {Springer-Verlag}, - year = 1998, - address = {Heidelberg}, - note = {{ISBN} 978-0387985039} -} - -@Book{Chambers:2008:SoDA, - author = {John M. Chambers}, - title = {Software for Data Analysis: Programming with {R}}, - publisher = {Springer-Verlag}, - year = 2008, - series = {Statistics and Computing}, - address = {Heidelberg}, - note = {{ISBN} 978-0-387-75935-7} -} - -@Book{Chambers:2016:ExtR, - author = {John M. Chambers}, - title = {Extending R}, - publisher = {Chapman and Hall/CRC}, - year = 2016, - series = {{The R Series}}, - address = {London}, - note = {{ISBN} 9781498775717} -} - -@Misc{Cpp11, - author = "ISO/IEC", - organization = "{International Organization for Standardization}", - title = "\proglang{C++} 2011 Standard Document 14882:2011", - howpublished = {ISO/IEC Standard Group for Information Technology / Programming Languages / C++}, - year = 2011, - url = "http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372", - urlansi = "http://webstore.ansi.org/RecordDetail.aspx?sku=ISO/IEC%2014882:2011" -} - -@book{Dongarra:1979:UGLINPACK, - title = {LINPACK users' guide}, - author = {Dongarra, Jack J and Moler, Cleve B and Bunch, James - R and Stewart, Gilbert W}, - year = 1979, - publisher = {SIAM} -} - -@Article{Eddelbuettel+Sanderson:2013:RcppArmadillo, - title = {{RcppArmadillo}: Accelerating {R} with High-Performance {C++} Linear Algebra}, - author = {Dirk Eddelbuettel and Conrad Sanderson}, - journal = {Computational Statistics and Data Analysis}, - year = 2014, - volume = 71, - month = {March}, - pages = {1054--1063}, - doi = {10.1016/j.csda.2013.02.005}, - url = {http://dx.doi.org/10.1016/j.csda.2013.02.005} -} - -@Article{Eddelbuettel+Sanderson:2014:RcppArmadillo, - title = {{RcppArmadillo}: Accelerating {R} with High-Performance {C++} Linear Algebra}, - author = {Dirk Eddelbuettel and Conrad Sanderson}, - journal = {Computational Statistics and Data Analysis}, - year = 2014, - volume = 71, - month = {March}, - pages = {1054--1063}, - doi = {10.1016/j.csda.2013.02.005}, - url = {http://dx.doi.org/10.1016/j.csda.2013.02.005} -} - -@Book{Eddelbuettel:2013:Rcpp, - author = {Dirk Eddelbuettel}, - title = {Seamless R and C++ Integration with Rcpp}, - publisher = {Springer}, - series = {Use R!}, - year = 2013, - address = {New York}, - isbn = {978-1-4614-6867-7} -} - -@article{Efron:1979:Bootstrap, - URL = {http://www.jstor.org/stable/2958830}, - author = {Efron, B.}, - journal = {The Annals of Statistics}, - number = {1}, - pages = {1-26}, - publisher = {Institute of Mathematical Statistics}, - title = {Bootstrap Methods: Another Look at the Jackknife}, - volume = {7}, - year = {1979} -} - -@MISC{Eigen:Web, - author = {Ga\"{e}l Guennebaud and Beno\^{i}t Jacob and others}, - title = {Eigen v3}, - year = 2012, - url = {http://eigen.tuxfamily.org}, -} -; see http://eigen.tuxfamily.org/index.php?title=BibTeX -; replaced 'howpublished' with 'url' and updated year to 2011, and again to 2012 - -@Manual{GSL, - title = {{GNU} {S}cientific {L}ibrary {R}eference {M}anual}, - author = {Mark Galassi and Jim Davies and James Theiler and Brian Gough and Gerard Jungman and Patrick Alken and Michael Booth and Fabrice Rossi}, - year = {2010}, - edition = {3rd}, - note = {Version 1.14. {ISBN} 0954612078}, - url = {http://www.gnu.org/software/gsl} -} - -@Book{Gentleman:2009:RProgramming, - author = {Robert Gentleman}, - title = {R Programming for Bioinformatics}, - publisher = {Chapman \& Hall/CRC}, - year = 2009, - series = {Computer Science and Data Analysis}, - address = {Boca Raton, FL} -} - -@Manual{GitHub:Rperform, - title = {Rperform: Rperform - Performance testing for R packages}, - author = {Akash Tandon and Toby Dylan Hocking}, - year = {2015}, - note = {R package version 0.0.0.9000}, -} - -@Article{Gropp+Lusk+Doss+Skjellum:1996:MPI, - author = {William Gropp and Ewing Lusk and Nathan Doss and Anthony Skjellum}, - title = {A high-performance, portable implementation of the {MPI} message passing interface standard}, - journal = {Parallel Computing}, - year = 1996, - url = {http://dx.doi.org/10.1016/0167-8191(96)00024-5}, - volume = 22, - number = 6, - pages = {789--828} -} - -@Book{Gropp+Lusk+Skjellum:1999:MPI, - author = {William Gropp and Ewing Lusk and Anthony Skjellum}, - title = {Using {MPI}: Portable Parallel Programming with the Message Passing Interface}, - publisher = {MIT Press}, - year = 1999, - series = {Scientific and Engineering Computation Series}, - edition = {2nd}, - month = {November}, - note = {{ISBN} 978-0-262-57132-6} -} - -@article{Ihaka:1996, - Author = {Ihaka, Ross and Gentleman, Robert}, - Journal = {Journal of Computational and Graphical Statistics}, - Number = 3, - Pages = {299--314}, - Title = {R: A Language for Data Analysis and Graphics}, - Volume = 5, - Year = 1996 -} - -@article{JOSS:RcppCNPy, - doi = {10.21105/joss.00055}, - url = {https://doi.org/10.21105/joss.00055}, - year = {2016}, - month = {sep}, - publisher = {The Open Journal}, - volume = {1}, - number = {5}, - author = {Dirk Eddelbuettel and Wush Wu}, - title = {{RcppCNPy}: Read-Write Support for {NumPy} Files in R}, - journal = {The Journal of Open Source Software} -} - -@Article{JSS:RProtoBuf, - title = {{RProtoBuf}: Efficient Cross-Language Data Serialization in - {R}}, - author = {Dirk Eddelbuettel and Murray Stokely and Jeroen Ooms}, - journal = {Journal of Statistical Software}, - year = {2016}, - volume = {71}, - number = {2}, - pages = {1--24}, - doi = {10.18637/jss.v071.i02}, -} - -@Article{JSS:Rcpp, - title = {{Rcpp}: Seamless {R} and {C++} Integration}, - author = {Dirk Eddelbuettel and Romain Fran\c{c}ois}, - journal = {Journal of Statistical Software}, - year = 2011, - volume = 40, - number = 8, - pages = {1--18}, - url = {http://www.jstatsoft.org/v40/i08/}, -} - -@Article{JSS:RcppEigen, - title = {Fast and Elegant Numerical Linear Algebra Using the - {RcppEigen} Package}, - author = {Douglas Bates and Dirk Eddelbuettel}, - journal = {Journal of Statistical Software}, - year = {2013}, - volume = {52}, - number = {5}, - pages = {1--24}, - url = {http://www.jstatsoft.org/v52/i05/}, -} - -@Unpublished{Java+Gaile+Manly:2007:RCpp, - author = {James J. Java and Daniel P. Gaile and Kenneth - E. Manly}, - title = {{R/Cpp}: Interface Classes to Simplify Using {R} - Objects in {C++} Extensions}, - note = {Unpublished manuscript, University at Buffalo}, - url = - {http://sphhp.buffalo.edu/biostat/research/techreports/UB_Biostatistics_TR0702.pdf}, - month = {July}, - year = 2007 -} - -@misc{KDE-TechBase:2012, - author = {KDE-TechBase}, - title = {Binary Compatibility Issues With {C++}}, - url = "http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++", - year = 2012, - note = "[Online; accessed 24-November-2012]" -} - -@InProceedings{Leisch:2008:Tutorial, - author = {Friedrich Leisch}, - title = {Tutorial on {C}reating \proglang{R} {P}ackages}, - booktitle = {COMPSTAT 2008 -- Proceedings in Computational - Statistics}, - year = 2008, - editor = {Paula Brito}, - address = {Heidelberg}, - publisher = {Physica Verlag}, - url = CRAN # "doc/contrib/Leisch-CreatingPackages.pdf" -} - -@Manual{Liang:2008:rcppbind, - title = {rcppbind: {A} template library for R/C++ developers}, - author = {Gang Liang}, - year = 2008, - note = {R package version 1.0}, - url = R-Forge # "projects/rcppbind" -} - -@Book{Lippman+Lajoie+Moo:2005:Cpp_Primer, - author = {Stanley B. Lippman and Jos\'{e}e Lajoie and Barbara E. Moo}, - title = {The C++ Primer}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 2005, - edition = {4th} -} - -@Book{Matloff:2011:ArtOfR, - author = {Norman Matloff}, - title = {The Art of R Programming: A Tour of Statistical Software Design}, - publisher = {No Starch Press}, - address = {San Francisco, CA}, - year = 2011 -} - -@InProceedings{Maurer+Wong:2008:AttributesInC++, - author = {Jens Maurer and Michael Wong}, - title = {Towards support for attributes in {C++} (Revision - 6)}, - booktitle = {JTC1/SC22/WG21 - The C++ Standards Committee}, - year = {2008}, - url = - {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf}, - note = {{N2761=08-0271}} -} - -@book{Meyers:1995:MoreEffectiveC++, - author = {Scott Meyers}, - title = {More Effective C++: 35 New Ways to Improve Your - Programs and Designs}, - year = 1995, - note = {{ISBN} 020163371X}, - publisher = {Addison-Wesley}, - address = {Boston} -} - -@book{Meyers:2001:EffectiveSTL, - author = {Scott Meyers}, - title = {Effective STL: 50 specific ways to improve your use - of the standard template library}, - year = 2001, - note = {{ISBN} 0-201-74962-9}, - publisher = {Addison-Wesley}, - address = {Essex} -} - -@book{Meyers:2005:EffectiveC++, - author = {Scott Meyers}, - title = {Effective C++: 55 Specific Ways to Improve Your - Programs and Designs}, - year = 2005, - note = {{ISBN} 978-0321334879}, - publisher = {Addison-Wesley}, - address = {Boston}, - edition = {3rd}, -} - -@Article{PeerJ:Rcpp, - author = {Dirk Eddelbuettel and James Joseph Balamuta}, - title = {Extending R with C++: A Brief Introduction to Rcpp}, - journal = {PeerJ Preprints}, - volume = 5, - issue = {e3188v1}, - year = 2017, - month = {August}, - doi = {10.7287/peerj.preprints.3188v1/}, -} - -@Book{Plauger+Et+Al:2000:STL, - author = {P.J. Plauger and Alexander Stepanov and Meng Lee and - David R. Musser}, - title = {The {C++} Standard Template Library}, - publisher = {Prentice Hall PTR}, - year = 2000, - note = {{ISBN} 978-0134376332}, -} - -@manual{R:Administration, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R Installation and Administration", - annote = {{ISBN} 3-900051-09-7}, - url = manuals # "R-admin.html" -} - -@manual{R:Extensions, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "Writing R extensions", - annote = {{ISBN} 3-900051-11-9}, - url = manuals # "R-exts.html" -} - -@manual{R:Internals, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R internals", - annote = {{ISBN} 3-900051-14-3}, - url = manuals # "R-ints.html" -} - -@manual{R:Language, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - title = "R language", - annote = {{ISBN} 3-900051-13-5}, - url = manuals # "R-lang.html" -} - -@Manual{R:Main, - title = {R: A Language and Environment for Statistical - Computing}, - author = RCoreTeam, - organization = RFoundation, - address = {Vienna, Austria}, - year = 2018, - url = {https://www.R-project.org/} -} - -@InProceedings{Runnalls:2009:CXXR, - author = {Andrew Runnalls}, - title = {Aspects of {CXXR} internals}, - booktitle = {Directions in Statistical Computing}, - address = {University of Copenhagen, Denmark}, - year = 2009 -} - -@Manual{Samperi:2009:RcppTemplate, - title = {RcppTemplate: Rcpp {R/C++} Object Mapping Library - and Package Template}, - author = {Dominick Samperi}, - year = 2009, - note = {(Archived) R package version 6.1}, - url = CRAN # "/src/contrib/Archive/RcppTemplate" -} - -@article{Sanderson+Curtin:2016, - doi = {10.21105/joss.00026}, - url = {http://dx.doi.org/10.21105/joss.00026}, - year = 2016, - month = {{June}}, - publisher = {The Open Journal}, - volume = 1, - number = 2, - author = {Conrad Sanderson and Ryan Curtin}, - title = {Armadillo: {A Template-Based C++ Library for Linear - Algebra}}, - journal = {{JOSS}} -} - -@TechReport{Sanderson:2010:Armadillo, - author = {Conrad Sanderson}, - title = {{Armadillo}: {An} open source {C++} Algebra Library - for Fast Prototyping and Computationally Intensive - Experiments }, - institution = {{NICTA}}, - year = 2010, - url = "http://arma.sf.net" -} - -@Book{Stroustrup:1997:Cpp, - author = {Bjarne Stroustrup}, - title = {The C++ Programming Language}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 1997, - edition = {3rd} -} - -@Book{Stroustrup:2013:Cpp, - author = {Bjarne Stroustrup}, - title = {The C++ Programming Language}, - publisher = {Addison-Wesley}, - address = {Boston}, - year = 2013, - pages = 1368, - edition = {4th} -} - -@Article{TAS:Rcpp, - author = {Dirk Eddelbuettel and James Joseph Balamuta}, - title = {Extending R with C++: A Brief Introduction to Rcpp}, - journal = {The American Statistician}, - volume = 72, - number = 1, - year = 2018, - month = {August}, - doi = {10.1080/00031305.2017.1375990} -} - -@Article{TempleLang:2009:ModestProposal, - author = {Duncan {Temple Lang}}, - title = {A modest proposal: an approach to making the - internal {R} system extensible}, - journal = {Computational Statistics}, - year = 2009, - volume = 24, - number = 2, - pages = {271-281}, - month = {May} -} - -@Article{TempleLang:2009:RGCCTranslationUnit, - author = {Duncan {Temple Lang}}, - title = {Working with meta-data from {C/C++} code in {R}: the - {RGCCTranslationUnit} package}, - journal = {Computational Statistics}, - year = 2009, - volume = 24, - number = 2, - pages = {283-293}, - month = {May} -} - -@InProceedings{Urbanek:2003:Rserve, - author = {Simon Urbanek}, - title = {{Rserve}: A Fast Way to Provide {R} Functionality to - Applications}, - booktitle = {Proceedings of the 3rd International Workshop on Distributed - Statistical Computing, Vienna, Austria}, - editor = {Kurt Hornik and Friedrich Leisch and Achim Zeileis}, - year = {2003}, - url = {http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/}, - note = {{ISSN 1609-395X}} -} - -@Book{Vandevoorde+Josuttis:2003:Templates, - author = {David Vandevoorde and Nicolai M. Josuttis}, - title = {{C++} {T}emplates: The Complete Guide}, - publisher = {Addison-Wesley}, - year = 2003, - address = {Boston} -} - -@inproceedings{Veldhuizen:1998:Blitz, - author = {Todd L. Veldhuizen}, - title = {Arrays in {Blitz++}}, - booktitle = {ISCOPE '98: Proceedings of the Second International - Symposium on Computing in Object-Oriented Parallel - Environments}, - note = {{ISBN} 3-540-65387-2}, - year = 1998, - pages = {223--230}, - publisher = {Springer-Verlag}, - address = {London}, -} - -@Book{Venables+Ripley:2000:SProgramming, - author = {Willian N. Venables and Brian D. Ripley}, - title = {S Programming}, - publisher = {Springer-Verlag}, - year = 2000, - series = {Statistics and Computing}, - address = {New York} -} - -@Book{Venables+Ripley:2002:MASS, - title = {Modern Applied Statistics with S}, - author = {W. N. Venables and B. D. Ripley}, - publisher = {Springer}, - edition = {Fourth}, - address = {New York}, - year = 2002, - note = {ISBN 0-387-95457-0}, - url = {http://www.stats.ox.ac.uk/pub/MASS4}, -} diff -Nru rcpp-1.0.2/vignettes/Rcpp-extending.Rmd rcpp-1.0.3/vignettes/Rcpp-extending.Rmd --- rcpp-1.0.2/vignettes/Rcpp-extending.Rmd 2019-03-27 10:06:05.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-extending.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,383 +0,0 @@ ---- -title: \pkg{Rcpp} Extending - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note provides an overview of the steps programmers should follow to - extend \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp} for use with their own classes. This document - is based on our experience in extending \pkg{Rcpp} to work with the - \pkg{Armadillo} \citep{Sanderson:2010:Armadillo} classes, available in the separate package - \pkg{RcppArmadillo} \citep{CRAN:RcppArmadillo}. This document assumes - knowledge of \pkg{Rcpp} as well as some knowledge of \proglang{C++} - templates \citep{Abrahams+Gurtovoy:2004:TemplateMetaprogramming}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - extending - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-extending} - %\VignetteKeywords{Rcpp, extending, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Introduction - -\pkg{Rcpp} facilitates data interchange between \proglang{R} and -\proglang{C++} through the templated functions `Rcpp::as` (for -conversion of objects from \proglang{R} to \proglang{C++}) and -`Rcpp::wrap` (for conversion from \proglang{C++} to \proglang{R}). In -other words, we convert between the so-called \proglang{S}-expression -pointers (in type `SEXP`) to a templated \proglang{C++} type, and vice -versa. The corresponding function declarations are as follows: - -```{Rcpp, eval = FALSE} -// conversion from R to C++ -template T as(SEXP x); - -// conversion from C++ to R -template SEXP wrap(const T& object); -``` - -These converters are often used implicitly, as in the following code chunk: - -```{Rcpp} -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List fx(List input) { // we get a list from R -// pull std::vector from R list -// this is achieved through an implicit -// call to Rcpp::as -std::vector x = input["x"]; - -// return an R list; this is achieved -// through an implicit call to Rcpp::wrap -return List::create(_["front"] = x.front(), - _["back"] = x.back()); -} -``` - -Example: - -```{r} -# Run sourceCpp compilation to include file -# Rcpp::sourceCpp(file= "code.cpp") -input <- list( x = seq(1, 10, by = 0.5) ) -fx(input) -``` - -The \pkg{Rcpp} converter function `Rcpp::as` and `Rcpp::wrap` have been -designed to be extensible to user-defined types and third-party types. - -# Extending `Rcpp::wrap` - -The \pkg{Rcpp::wrap} converter is extensible in essentially two ways : intrusive -and non-intrusive. - -## Intrusive extension - -When extending \pkg{Rcpp} with your own data type, the recommended way is to -implement a conversion to `SEXP`. This lets `Rcpp::wrap` know -about the new data type. The template meta programming (or TMP) dispatch is able to -recognize that a type is convertible to a `SEXP` and -`Rcpp::wrap` will use that conversion. - -The caveat is that the type must be declared before the main header -file `Rcpp.h` is included. - -```{Rcpp, eval = FALSE} -#include - -class Foo { -public: - Foo(); - - // this operator enables implicit Rcpp::wrap - operator SEXP(); -} - -#include -``` - -This is called \emph{intrusive} because the conversion to `SEXP` -operator has to be declared within the class. - -## Non-intrusive extension - -It is often desirable to offer automatic conversion to third-party types, over -which the developer has no control and can therefore not include a conversion -to `SEXP` operator in the class definition. - -To provide automatic conversion from \proglang{C++} to \proglang{R}, one must -declare a specialization of the `Rcpp::wrap` template between the -includes of `RcppCommon.h` and `Rcpp.h`. - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares class Bar -#include - -// declaring the specialization -namespace Rcpp { - template <> SEXP wrap(const Bar&); -} - -// this must appear after the specialization, -// otherwise the specialization will not be -// seen by Rcpp types -#include -``` - -It should be noted that only the declaration is required. The implementation -can appear after the `Rcpp.h` file is included, and therefore take -full advantage of the \pkg{Rcpp} type system. - -Another non-intrusive option is to expose an external pointer. The macro -`RCPP_EXPOSED_WRAP` provides an easy way to expose a \proglang{C++} class -to \proglang{R} as an external pointer. It can be used instead of specializing -`Rcpp::wrap`, and should not be used simultaneously. Note that the -\proglang{C++} class has to use Rcpp modules. See the Rcpp modules vignette for -more details. - -```{Rcpp, eval = FALSE} -#include -#include - -RCPP_EXPOSED_WRAP(Bar) -``` - -## Templates and partial specialization - -It is perfectly valid to declare a partial specialization for the -`Rcpp::wrap` template. The compiler will identify the appropriate -overload: - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares -// a template class Bling -#include - -// declaring the partial specialization -namespace Rcpp { - namespace traits { - - template - SEXP wrap(const Bling&); - - } -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include - -``` - - -# Extending `Rcpp::as` - -Conversion from \proglang{R} to \proglang{C++} is also possible -in both intrusive and non-intrusive ways. - -## Intrusive extension - -As part of its template meta programming dispatch logic, `Rcpp::as` -will attempt to use the constructor of the target class taking a `SEXP`. - -```{Rcpp, eval = FALSE} -#include - -class Foo{ - public: - Foo(); - - // this ctor enables implicit Rcpp::as - Foo(SEXP); -} - - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -## Non-intrusive extension - -It is also possible to fully specialize `Rcpp::as` to enable -non-intrusive implicit conversion capabilities. - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares class Bar -#include - -// declaring the specialization -namespace Rcpp { - template <> Bar as(SEXP); -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -Furthermore, another non-intrusive option is to opt for sharing an R -external pointer. The macro `RCPP_EXPOSED_AS` provides an easy way to -extend `Rcpp::as` to expose \proglang{R} external pointers to -\proglang{C++}. It can be used instead of specializing `Rcpp::as`, and -should not be used simultaneously. Note that the \proglang{C++} class -has to use Rcpp modules. See the Rcpp modules vignette for more details. - -```{Rcpp, eval = FALSE} -#include -#include - -RCPP_EXPOSED_AS(Bar) -``` - -With this being said, there is one additional macro that can be used to -simultaneously define both `Rcpp::wrap` and `Rcpp::as` -specialization for an external pointer. The macro `RCPP_EXPOSED_CLASS` -can be use to transparently exchange a class between \proglang{R} and -\proglang{C++} as an external pointer. Do not simultaneously use it alongside -`RCPP_EXPOSED_AS`, `RCPP_EXPOSED_WRAP`, `Rcpp::wrap`, or -`Rcpp::as`. - - -## Templates and partial specialization - -The signature of `Rcpp::as` does not allow partial specialization. -When exposing a templated class to `Rcpp::as`, the programmer must -specialize the \pkg{Rcpp::traits::Exporter} template class. The TMP dispatch -will recognize that a specialization of `Exporter` is available -and delegate the conversion to this class. \pkg{Rcpp} defines -the `Rcpp::traits::Exporter` template class as follows : - -```{Rcpp, eval = FALSE} -namespace Rcpp { - namespace traits { - - template class Exporter{ - public: - Exporter(SEXP x) : t(x){} - inline T get() { return t; } - - private: - T t; - }; - } -} -``` - -This is the reason why the default behavior of `Rcpp::as` is to -invoke the constructor of the type `T` taking a `SEXP`. - -Since partial specialization of class templates is allowed, we can expose -a set of classes as follows: - -```{Rcpp, eval = FALSE} -#include - -// third party library that declares -// a template class Bling -#include - -// declaring the partial specialization -namespace Rcpp { - namespace traits { - template - class Exporter< Bling >; - } -} - -// this must appear after the specialization, or -// specialization will not be seen by Rcpp types -#include -``` - -Using this approach, the requirements for the -`Exporter< Bling >` class are: - -- it should have a constructor taking a `SEXP` -- it should have a methods called `get` that returns an instance - of the `Bling` type. - -# Summary - -The \pkg{Rcpp} package greatly facilitates the transfer of objects between -\proglang{R} and \proglang{C++}. This note has shown how to extend \pkg{Rcpp} -to either user-defined or third-party classes via the `Rcpp::as` and -`Rcpp::wrap` template functions. Both intrusive and non-intrusive -approaches were discussed. diff -Nru rcpp-1.0.2/vignettes/Rcpp-extending.Rnw rcpp-1.0.3/vignettes/Rcpp-extending.Rnw --- rcpp-1.0.2/vignettes/Rcpp-extending.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-extending.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-extending} +%\VignetteKeywords{Rcpp, extending, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-extending.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp-FAQ.Rmd rcpp-1.0.3/vignettes/Rcpp-FAQ.Rmd --- rcpp-1.0.2/vignettes/Rcpp-FAQ.Rmd 2018-09-21 16:24:39.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-FAQ.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,1722 +0,0 @@ ---- -title: \pkg{Rcpp} FAQ - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document attempts to answer the most Frequently Asked - Questions (FAQ) regarding the \pkg{Rcpp} - \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} package. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - FAQ - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - -vignette: > - %\VignetteIndexEntry{Rcpp-FAQ} - %\VignetteKeywords{Rcpp, FAQ, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -\tableofcontents - -```{r setup, include=FALSE} -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -library(inline) -options("width"=50, digits=5) -``` - -# Getting started - -## How do I get started - -If you have \pkg{Rcpp} installed, please execute the following command -in \proglang{R} to access the introductory vignette (which is a -variant of the \citet{JSS:Rcpp} and \citet{PeerJ:Rcpp,TAS:Rcpp} papers) for a -detailed introduction, ideally followed by at least the Rcpp -Attributes \citep{CRAN:Rcpp:Attributes} vignette: - -```{r, eval=FALSE} -vignette("Rcpp-jss-2011") -vignette("Rcpp-introduction") -vignette("Rcpp-attributes") -``` - -If you do not have \pkg{Rcpp} installed, these documents should also be available -whereever you found this document, \textsl{i.e.,} on every mirror site of CRAN. - -## What do I need - -Obviously, \proglang{R} must be installed. \pkg{Rcpp} provides a -\proglang{C++} API as an extension to the \proglang{R} system. As such, it -is bound by the choices made by \proglang{R} and is also influenced by how -\proglang{R} is configured. - -In general, the standard environment for building a CRAN package from source -(particularly when it contains \proglang{C} or \proglang{C++} code) is required. This -means one needs: - -- a development environment with a suitable compiler (see - below), header files and required libraries; -- \proglang{R} should be built in a way that permits linking and possibly - embedding of \proglang{R}; this is typically ensured by the - `--enable-shared-lib` option; -- standard development tools such as `make` etc. - -Also see the [RStudio documentation](http://www.rstudio.com/ide/docs/packages/prerequisites) -on pre-requisites for R package development. - -## What compiler can I use - -On almost all platforms, the GNU Compiler Collection (or `gcc`, which -is also the name of its \proglang{C} language compiler) has to be used along -with the corresponding `g++` compiler for the \proglang{C++} language. -A minimal suitable version is a final 4.2.* release; earlier 4.2.* were -lacking some \proglang{C++} features (and even 4.2.1, still used on OS X as the -last gcc release), has issues). - -Generally speaking, the default compilers on all the common platforms are suitable. - -Specific per-platform notes: - -\begin{description} - \item[Windows] users need the \texttt{Rtools} package from the site maintained by - Duncan Murdoch which contains all the required tools in a single package; - complete instructions specific to Windows are in the `R Administration' - manual \citep[Appendix D]{R:Administration}. As of August 2014, it still - installs the \texttt{gcc/g++} 4.6.* compiler which limits the ability to use - modern C++ standards so only \code{s-std=c++0x} is supported. R 3.1.0 and - above detect this and set appropriate flags. - \item[OS X] users, as noted in the `R Administration' manual \citep[Appendix - C.4]{R:Administration}, need to install the Apple Developer Tools - (\textsl{e.g.}, \href{https://itunes.apple.com/us/app/xcode/id497799835?mt=12}{Xcode} (OS X $\le 10.8$) or \href{https://developer.apple.com/library/ios/technotes/tn2339/_index.html}{Xcode Command Line Tools} (OS X $\ge 10.9$) (as well as \texttt{gfortran} if \proglang{R} or - Fortran-using packages are to be built); also see \faq{q:OSX} and - \faq{q:OSXArma} below. Depending on whether on OS X release before or after - Mavericks is used, different additional installation may be needed. Consult - the \code{r-sig-mac} list (and its archives) for (current) details. - \item[Linux] user need to install the standard developement packages. Some - distributions provide helper packages which pull in all the required - packages; the \texttt{r-base-dev} package on Debian and Ubuntu is an example. -\end{description} - -The `clang` and `clang++` compilers from the LLVM project can -also be used. On Linux, they are inter-operable with `gcc` et al. On -OS X, they are unfortunately not ABI compatible. The `clang++` -compiler is interesting as it emits much more comprehensible error messages -than `g++` (though `g++` 4.8 and 4.9 have caught up). - -The Intel `icc` family has also been used successfully as its output -files can also be combined with those from `gcc`. - -## What other packages are useful - -Additional packages that we have found useful are: - -\begin{description} -\item[\pkg{inline}] which is invaluable for direct compilation, linking and loading - of short code snippets---but now effectively superseded by the Rcpp - Attributes (see \faq{using-attributes} and - \faq{prototype-using-attributes}) feature provided by \pkg{Rcpp}; -\item[\pkg{RUnit}] is used for unit testing; the package is recommended and - will be needed to re-run some of our tests but it is not strictly required - during use of \pkg{Rcpp}; -\item[\pkg{rbenchmark}] to run simple timing comparisons and benchmarks; it is also - recommended but not required. -\item[\pkg{microbenchmark}] is an alternative for benchmarking. -\item[\pkg{devtools}] can help the process of building, compiling and testing - a package but it too is entirely optional. -\end{description} - -## What licenses can I choose for my code - -The \pkg{Rcpp} package is licensed under the terms of the -[GNU GPL 2 or later](http://www.gnu.org/licenses/gpl-2.0.html), just like -\proglang{R} itself. A key goal of the \pkg{Rcpp} package is to make -extending \proglang{R} more seamless. But by \textsl{linking} your code against -\proglang{R} (as well as \pkg{Rcpp}), the combination is bound by the GPL as -well. This is very clearly -stated at the -[FSF website](https://www.gnu.org/licenses/gpl-faq.html#GPLStaticVsDynamic): - -> Linking a GPL covered work statically or dynamically with other modules is -> making a combined work based on the GPL covered work. Thus, the terms and -> conditions of the GNU General Public License cover the whole combination. - -So you are free to license your work under whichever terms you find suitable -(provided they are GPL-compatible, see the -[FSF site for details](http://www.gnu.org/licenses/licenses.html)). However, -the combined work will remain under the terms and conditions of the GNU General -Public License. This restriction comes from both \proglang{R} which is GPL-licensed -as well as from \pkg{Rcpp} and whichever other GPL-licensed components you may -be linking against. - - -# Compiling and Linking - -## How do I use \pkg{Rcpp} in my package {#make-package} - -\pkg{Rcpp} has been specifically designed to be used by other packages. -Making a package that uses \pkg{Rcpp} depends on the same mechanics that are -involved in making any \proglang{R} package that use compiled code --- so -reading the \textsl{Writing R Extensions} manual \citep{R:Extensions} is a required -first step. - -Further steps, specific to \pkg{Rcpp}, are described in a separate vignette. - -```{r, eval=FALSE} -vignette("Rcpp-package") -``` - -## How do I quickly prototype my code - -There are two toolchains which can help with this: - -- The older one is provided by the \pkg{inline} package and described in - Section~\ref{using-inline}. -- Starting with \pkg{Rcpp} 0.10.0, the Rcpp Attributes feature (described - in Section~\ref{using-attributes}) offered an even easier alternative via - the function \rdoc{Rcpp}{evalCpp}, \rdoc{Rcpp}{cppFunction} and - \rdoc{Rcpp}{sourceCpp}. - -The next two subsections show an example each. - -### Using inline - -The \pkg{inline} package \citep{CRAN:inline} provides the functions -\rdoc{inline}{cfunction} and \rdoc{inline}{cxxfunction}. Below is a simple -function that uses `accumulate` from the (\proglang{C++}) Standard -Template Library to sum the elements of a numeric vector. - -```{r} -fx <- cxxfunction(signature(x = "numeric"), - 'NumericVector xx(x); - return wrap( - std::accumulate(xx.begin(), - xx.end(), - 0.0) - );', - plugin = "Rcpp") -res <- fx(seq(1, 10, by=0.5)) -res -``` - -One might want to use code that lives in a \proglang{C++} file instead of writing -the code in a character string in R. This is easily achieved by using -\rdoc{base}{readLines}: - -```{r, eval=FALSE} -fx <- cxxfunction(signature(), - paste(readLines("myfile.cpp"), - collapse="\n"), - plugin = "Rcpp") -``` - -The `verbose` argument of \rdoc{inline}{cxxfunction} is very -useful as it shows how \pkg{inline} runs the show. - -### Using Rcpp Attributes {#using-attributes} - -Rcpp Attributes \citep{CRAN:Rcpp:Attributes}, and also discussed in -\faq{prototype-using-attributes} below, permits an even easier -route to integrating R and C++. It provides three key functions. -First, \rdoc{Rcpp}{evalCpp} provide a means to evaluate simple C++ -expression which is often useful for small tests, or to simply check -if the toolchain is set up correctly. Second, \rdoc{Rcpp}{cppFunction} -can be used to create C++ functions for R use on the fly. Third, -`Rcpp::sourceCpp` can integrate entire files in order to define -multiple functions. - -The example above can now be rewritten as: - -```{r} -cppFunction('double accu(NumericVector x) { - return( - std::accumulate(x.begin(), x.end(), 0.0) - ); -}') -res <- accu(seq(1, 10, by=0.5)) -res -``` - -The \rdoc{Rcpp}{cppFunction} parses the supplied text, extracts the desired -function names, creates the required scaffolding, compiles, links and loads -the supplied code and makes it available under the selected identifier. - -Similarly, \rdoc{Rcpp}{sourceCpp} can read in a file and compile, link and load -the code therein. - -## How do I convert my prototyped code to a package {#from-inline-to-package} - -Since release 0.3.5 of \pkg{inline}, one can combine \faq{using-inline} and -\faq{make-package}. See `help("package.skeleton-methods")` once -\pkg{inline} is loaded and use the skeleton-generating functionality to -transform a prototyped function into the minimal structure of a package. -After that you can proceed with working on the package in the spirit of -\faq{make-package}. - -Rcpp Attributes \citep{CRAN:Rcpp:Attributes} also offers a means to convert -functions written using Rcpp Attributes into a function via the -\rdoc{Rdoc}{compileAttributes} function; see the vignette for details. - -## How do I quickly prototype my code in a package {#using-a-package} - -The simplest way may be to work directly with a package. Changes to both the -\proglang{R} and \proglang{C++} code can be compiled and tested from the -command line via: - -```{bash, eval = FALSE} -$ R CMD INSTALL mypkg && \ - Rscript --default-packages=mypkg -e \ - 'someFunctionToTickle(3.14)' -``` - -This first installs the packages, and then uses the command-line tool -\rdoc{utils}{Rscript} (which ships with `R`) to load the package, and execute -the \proglang{R} expression following the `-e` switch. Such an -expression can contain multiple statements separated by semicolons. -\rdoc{utils}{Rscript} is available on all three core operating systems. - -On Linux, one can also use `r` from the `littler` package by Horner -and Eddelbuettel which is an alternative front end to \proglang{R} designed -for both `#!` (hashbang) scripting and command-line use. It has slightly -faster start-up times than \rdoc{utils}{Rscript}; and both give a guaranteed clean -slate as a new session is created. - -The example then becomes - -```{bash, eval = FALSE} -$ R CMD INSTALL mypkg && \ - r -l mypkg -e 'someFunctionToTickle(3.14)' -``` - -The `-l` option calls 'suppressMessages(library(mypkg))' before executing the -\proglang{R} expression. Several packages can be listed, separated by a comma. - -More choice are provide by the \pkg{devtools} package, and by using -RStudio. See the respective documentation for details. - -## But I want to compile my code with R CMD SHLIB {#using-r-cmd-shlib} - -The recommended way is to create a package and follow \faq{make-package}. The -alternate recommendation is to use \pkg{inline} and follow \faq{using-inline} -because it takes care of all the details. - -However, some people have shown that they prefer not to follow recommended -guidelines and compile their code using the traditional `R CMD SHLIB`. To -do so, we need to help `SHLIB` and let it know about the header files -that \pkg{Rcpp} provides and the \proglang{C++} library the code must link -against. - -On the Linux command-line, you can do the following: - -```{bash, eval = FALSE} -$ # if Rcpp older than 0.11.0 -$ export PKG_LIBS=`Rscript -e "Rcpp:::LdFlags()"` -$ export PKG_CXXFLAGS=\ - `Rscript -e "Rcpp:::CxxFlags()"` -$ R CMD SHLIB myfile.cpp -``` - -which first defines and exports two relevant environment variables which -`R CMD SHLIB` then relies on. On other operating systems, appropriate -settings may have to be used to define the environment variables. - -This approach corresponds to the very earliest ways of building programs and -can still be found in some deprecated documents (as _e.g._ some of -Dirk's older 'Intro to HPC with R' tutorial slides). It is still not -recommended as there are tools and automation mechanisms that can do the work -for you. - -\pkg{Rcpp} versions 0.11.0 or later can do with the definition of -`PKG_LIBS` as a user-facing library is no longer needed (and hence no -longer shipped with the package). One still needs to set `PKG_CXXFLAGS` -to tell R where the \pkg{Rcpp} headers files are located. - -Once `R CMD SHLIB` has created the dyanmically-loadable file (with -extension `.so` on Linux, `.dylib` on OS X or `.dll` on -Windows), it can be loaded in an R session via \rdoc{base}{dyn.load}, and the -function can be executed via \rdoc{base}{.Call}. Needless to say, we -\emph{strongly} recommend using a package, or at least Rcpp Attributes as -either approach takes care of a lot of these tedious and error-prone manual -steps. - - -## But R CMD SHLIB still does not work - -We have had reports in the past where build failures occurred when users had -non-standard code in their `~/.Rprofile` or `Rprofile.site` (or -equivalent) files. - -If such code emits text on `stdout`, the frequent and implicit -invocation of `Rscript -e "..."` (as in \faq{using-r-cmd-shlib} -above) to retrieve settings directly from \pkg{Rcpp} will fail. - -You may need to uncomment such non-standard code, or protect it by wrapping -it inside `if (interactive())`, or possibly try to use -`Rscript --vanilla` instead of plain `Rscript`. - -## What about `LinkingTo ` - -\proglang{R} has only limited support for cross-package linkage. - -We now employ the `LinkingTo` field of the `DESCRIPTION` file -of packages using \pkg{Rcpp}. But this only helps in having \proglang{R} -compute the location of the header files for us. - -The actual library location and argument still needs to be provided by the -user. How to do so has been shown above, and we recommned you use either -\faq{make-package} or \faq{using-inline} both which use the \pkg{Rcpp} -function `Rcpp:::LdFlags()`. - -If and when `LinkingTo` changes and lives up to its name, we will be -sure to adapt \pkg{Rcpp} as well. - -An important change arrive with \pkg{Rcpp} release 0.11.0 and concern the -automatic registration of functions; see Section~\ref{function-registration} below. - - -## Does \pkg{Rcpp} work on windows - -Yes of course. See the Windows binaries provided by CRAN. - -## Can I use \pkg{Rcpp} with Visual Studio - -Not a chance. - -And that is not because we are meanies but because \proglang{R} and Visual -Studio simply do not get along. As \pkg{Rcpp} is all about extending -\proglang{R} with \proglang{C++} interfaces, we are bound by the available -toolchain. And \proglang{R} simply does not compile with Visual Studio. Go -complain to its vendor if you are still upset. - -## I am having problems building Rcpp on macOS, any help {#q:OSX} - -There are three known issues regarding Rcpp build problems on macOS. If you are -building packages with RcppArmadillo, there is yet another issue that is -addressed separately in \faq{q:OSXArma} below. - -### Lack of a Compiler - -By default, macOS does not ship with an active compiler. Depending on the -\proglang{R} version being used, there are different development environment -setup procedures. For the current \proglang{R} version, we recommend observing -the official procedure used in -[Section 6.3.2 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS-packages) -and [Section C.3 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) -of the [R Installation and Administration](https://cran.r-project.org/doc/manuals/r-release/R-admin.html) -manual. - -### Differing macOS R Versions Leading to Binary Failures - -There are currently _three_ distinct versions of R for macOS. -The first version is a legacy version meant for macOS 10.6 (Snow Leopard) - -10.8 (Mountain Lion). The second version is for more recent system -macOS 10.9 (Mavericks) and 10.10 (Yosemite). Finally, the third and most -up-to-date version supports macOS 10.11 (El Capitan), 10.12 (Sierra), and 10.13 (High Sierra). -The distinction comes as a result of a change in the compilers shipped with the -operating system as highlighted previously. As a result, avoid sending -\textbf{package binaries} to collaborators if they are working on older -operating systems as the \proglang{R} binaries for these versions will not be -able to mix. In such cases, it is better to provide collaborators with the -\textbf{package source} and allow them to build the package locally. - -### OpenMP Support - -By default, the macOS operating environment lacks the ability to parallelize -sections of code using the \proglang{[OpenMP](http://openmp.org/wp/)} -standard. Within \proglang{R} 3.4.*, the default developer environment was -_changed_ to allow for \proglang{OpenMP} to be used on macOS by using -a non-default toolchain provided by R Core Team maintainers for macOS. -Having said this, it is still important to protect any reference to -\proglang{OpenMP} as some users may not yet have the ability to -use \proglang{OpenMP}. - -To setup the appropriate protection for using \proglang{OpenMP}, the process -is two-fold. First, protect the inclusion of headers with: - -```cpp -#ifdef _OPENMP - #include -#endif -``` - -Second, when parallelizing portions of code use: - -```cpp -#ifdef _OPENMP - // multithreaded OpenMP version of code -#else - // single-threaded version of code -#endif -``` - -Under this approach, the code will be _safely_ parallelized when -support exists for \proglang{OpenMP} on Windows, macOS, and Linux. - -### Additional Information and Help - -Below are additional resources that provide information regarding compiling Rcpp code on macOS. - -1. A helpful post was provided by Brian Ripley regarding the use of - compiling R code with macOS in April 2014 - [on the `r-sig-mac` list](https://stat.ethz.ch/pipermail/r-sig-mac/2014-April/010835.html), - which is generally recommended for OS X-specific questions and further consultation. -2. Another helpful write-up for installation / compilation on OS X Mavericks is provided - [by the BioConductor project](http://www.bioconductor.org/developers/how-to/mavericks-howto/). -3. Lastly, another resource that exists for installation / compilation - help is provided at - . - -\textbf{Note:} If you are running into trouble compiling code with \pkg{RcppArmadillo}, please also see \faq{q:OSXArma} listed below. - - - -## Does \pkg{Rcpp} work on solaris/suncc - -Yes, it generally does. But as we do not have access to such systems, some -issues persist on the CRAN test systems. - -## Does \pkg{Rcpp} work with Revolution R - -We have not tested it yet. \pkg{Rcpp} might need a few tweaks to work -with the compilers used by Revolution R (if those differ from the defaults). - -## Is it related to Rho (formerly CXXR) - -Rho, previously known as CXXR, is an ambitious project that aims to -totally refactor the \proglang{R} interpreter in \proglang{C++}. There -are a few similaritites with \pkg{Rcpp} but the projects are -unrelated. - -Rho / CXXR and \pkg{Rcpp} both want \proglang{R} to make more use of \proglang{C++} -but they do it in very different ways. - -## How do I quickly prototype my code using Attributes {#prototype-using-attributes} - -\pkg{Rcpp} version 0.10.0 and later offer a new feature 'Rcpp Attributes' -which is described in detail in its own vignette -\citep{CRAN:Rcpp:Attributes}. In short, it offers functions \rdoc{Rcpp}{evalCpp}, -\rdoc{Rcpp}{cppFunction} and \rdoc{Rcpp}{sourceCpp} which extend the functionality of the -\rdoc{Rcpp}{cxxfunction} function. - - -## What about the new 'no-linking' feature {#function-registration} - -Starting with \pkg{Rcpp} 0.11.0, functionality provided by \pkg{Rcpp} and -used by packages built with \pkg{Rcpp} accessed via the registration facility -offered by R (and which is used by \pkg{lme4} and \pkg{Matrix}, as well as by -\pkg{xts} and \pkg{zoo}). This requires no effort from the user / -programmer, and even frees us from explicit linking instruction. In most -cases, the files `src/Makevars` and `src/Makevars.win` can now be -removed. Exceptions are the use of \pkg{RcppArmadillo} (which needs an entry -`PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)`) and packages linking -to external libraries they use. - -But for most packages using \pkg{Rcpp}, only two things are required: - -- an entry in `DESCRIPTION` such as `Imports: Rcpp` (which may - be versioned as in `Imports: Rcpp (>= 0.11.0)`), and -- an entry in `NAMESPACE` to ensure \pkg{Rcpp} is correctly - instantiated, for example `importFrom(Rcpp, evalCpp)`. - -The name of the symbol does not really matter; once one symbol is imported all -symbols should be available. - -## I am having problems building RcppArmadillo on macOS, any help {#q:OSXArma} - -Odds are your build failures are due to the absence of `gfortran` -and its associated libraries. The errors that you may receive are related to either -`-lgfortran` or `-lquadmath`. - -To rectify the root of these errors, there are two options available. The first -option is to download and use a fixed set of `gfortran` binaries that are -used to compile R for macOS (e.g. given by the maintainers of the macOS build). -The second option is to either use pre-existing `gfortran` binaries on -your machine or download the latest. These options are described in-depth -in [Section C.3 macOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) -of the [R Installation and Administration](https://cran.r-project.org/doc/manuals/r-release/R-admin.html) -manual. Please consult this manual for up-to-date information regarding `gfortran` -binaries on macOS. We have also documented _other_ common macOS compile -issues in Section \faq{q:OSX}. - -# Examples - -The following questions were asked on the -[Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list, which is our preferred place to ask questions as it guarantees -exposure to a number of advanced Rcpp users. The -[StackOverflow tag for rcpp](http://stackoverflow.com/questions/tagged/rcpp) -is an alternative; that site is also easily searchable. - -Several dozen fully documented examples are provided at the -[Rcpp Gallery](http://gallery.rcpp.org) -- which is also open for new contributions. - - -## Can I use templates with \pkg{Rcpp} - -> I'm curious whether one can provide a class definition inline in an R -> script and then initialize an instance of the class and call a method on -> the class, all inline in R. - -This question was initially about using templates with \pkg{inline}, and we -show that (older) answer first. It is also easy with Rcpp Attributes which is -what we show below. - - -### Using inline with Templated Code -Most certainly, consider this simple example of a templated class -which squares its argument: - -```{r} -inc <- 'template - class square : - public std::unary_function { - public: - T operator()( T t) const { - return t*t; - } - }; - ' - -src <- ' - double x = Rcpp::as(xs); - int i = Rcpp::as(is); - square sqdbl; - square sqint; - return Rcpp::DataFrame::create( - Rcpp::Named("x", sqdbl(x)), - Rcpp::Named("i", sqint(i))); - ' -fun <- cxxfunction(signature(xs="numeric", - is="integer"), - body=src, include=inc, - plugin="Rcpp") - -fun(2.2, 3L) -``` - -### Using Rcpp Attributes with Templated Code - -We can also use 'Rcpp Attributes' \citep{CRAN:Rcpp:Attributes}---as described -in \faq{using-attributes} and \faq{prototype-using-attributes} above. Simply -place the following code into a file and use \rdoc{Rcpp}{sourceCpp} on it. It -will even run the R part at the end. - -```cpp -#include - -template class square : - public std::unary_function { - public: - T operator()( T t) const { - return t*t ; - } -}; - -// [[Rcpp::export]] -Rcpp::DataFrame fun(double x, int i) { - square sqdbl; - square sqint; - return Rcpp::DataFrame::create( - Rcpp::Named("x", sqdbl(x)), - Rcpp::Named("i", sqint(i))); -} - -/*** R -fun(2.2, 3L) -*/ -``` - -## Can I do matrix algebra with Rcpp {#matrix-algebra} - - -> \pkg{Rcpp} allows element-wise operations on vector and matrices through -> operator overloading and STL interface, but what if I want to multiply a -> matrix by a vector, etc ... - -\noindent Currently, \pkg{Rcpp} does not provide binary operators to allow operations -involving entire objects. Adding operators to \pkg{Rcpp} would be a major -project (if done right) involving advanced techniques such as expression -templates. We currently do not plan to go in this direction, but we would -welcome external help. Please send us a design document. - -However, we have developed the \pkg{RcppArmadillo} package -\citep{CRAN:RcppArmadillo,Eddelbuettel+Sanderson:2014:RcppArmadillo} that -provides a bridge between \pkg{Rcpp} and \pkg{Armadillo} -\citep{Sanderson:2010:Armadillo}. \pkg{Armadillo} -supports binary operators on its types in a way that takes full advantage of -expression templates to remove temporaries and allow chaining of -operations. That is a mouthful of words meaning that it makes the code go -faster by using fiendishly clever ways available via the so-called template -meta programming, an advanced \proglang{C++} technique. -Also, the \pkg{RcppEigen} package \citep{JSS:RcppEigen} provides an alternative using the -[Eigen](http://eigen.tuxfamily.org) template library. - -### Using inline with RcppArmadillo {#using-inline-armadillo} - -The following example is adapted from the examples available at the project -page of Armadillo. It calculates $x' \times Y^{-1} \times z$ - -```{r, eval = FALSE} -lines = '// copy the data to armadillo structures -arma::colvec x = Rcpp::as (x_); -arma::mat Y = Rcpp::as(Y_) ; -arma::colvec z = Rcpp::as(z_) ; - -// calculate the result -double result = arma::as_scalar( - arma::trans(x) * arma::inv(Y) * z - ); - -// return it to R -return Rcpp::wrap( result );' - -writeLines(a, file = "myfile.cpp") -``` - -If stored in a file `myfile.cpp`, we can use it via \pkg{inline}: - -```{r, eval = FALSE} -fx <- cxxfunction(signature(x_="numeric", - Y_="matrix", - z_="numeric" ), - paste(readLines("myfile.cpp"), - collapse="\n"), - plugin="RcppArmadillo" ) -fx(1:4, diag(4), 1:4) -``` - -The focus is on the code `arma::trans(x) * arma::inv(Y) * z`, which -performs the same operation as the R code `t(x) %*% solve(Y) %*% z`, -although Armadillo turns it into only one operation, which makes it quite fast. -Armadillo benchmarks against other \proglang{C++} matrix algebra libraries -are provided on [the Armadillo website](http://arma.sourceforge.net/speed.html). - -It should be noted that code below depends on the version `0.3.5` of -\pkg{inline} and the version `0.2.2` of \pkg{RcppArmadillo}. - -### Using Rcpp Attributes with RcppArmadillo - -We can also write the same example for use with Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::depends(RcppArmadillo)]] - -// [[Rcpp::export]] -double fx(arma::colvec x, arma::mat Y, - arma::colvec z) { - // calculate the result - double result = arma::as_scalar( - arma::trans(x) * arma::inv(Y) * z - ); - return result; -} - -/*** R -fx(1:4, diag(4), 1:4) -*/ -``` - -Here, the additional `Rcpp::depends(RcppArmadillo)` ensures that code -can be compiled against the \pkg{RcppArmadillo} header, and that the correct -libraries are linked to the function built from the supplied code example. - -Note how we do not have to concern ourselves with conversion; R object -automatically become (Rcpp)Armadillo objects and we can focus on the single -computing a (scalar) result. - -## Can I use code from the Rmath header and library with \pkg{Rcpp} - -> Can I call functions defined in the Rmath header file and the -> standalone math library for R--as for example the random number generators? - -\noindent Yes, of course. This math library exports a subset of R, but \pkg{Rcpp} has -access to much more. Here is another simple example. Note how we have to use -and instance of the `RNGScope` class to set and re-set the -random-number generator. This also illustrates Rcpp sugar as we are using a -vectorised call to `rnorm`. Moreover, because the RNG is reset, the -two calls result in the same random draws. If we wanted to control the draws, -we could explicitly set the seed after the `RNGScope` object has been -instantiated. - -```{r} -fx <- cxxfunction(signature(), - 'RNGScope(); - return rnorm(5, 0, 100);', - plugin="Rcpp") -set.seed(42) -fx() -fx() -``` - -Newer versions of Rcpp also provide the actual Rmath function in the `R` -namespace, \textsl{i.e.} as `R::rnorm(m,s)` to obtain a scalar -random variable distributed as $N(m,s)$. - -Using Rcpp Attributes, this can be as simple as - -```{r} -cppFunction('Rcpp::NumericVector ff(int n) { - return rnorm(n, 0, 100); }') -set.seed(42) -ff(5) -ff(5) -set.seed(42) -rnorm(5, 0, 100) -rnorm(5, 0, 100) -``` - -This illustrates the Rcpp Attributes adds the required `RNGScope` object -for us. It also shows how setting the seed from R affects draws done via C++ -as well as R, and that identical random number draws are obtained. - -## Can I use `NA` and `Inf` with \pkg{Rcpp} - -> R knows about `NA` and `Inf`. How do I use them from C++? - -\noindent Yes, see the following example: - -```{r} -src <- 'Rcpp::NumericVector v(4); - v[0] = R_NegInf; // -Inf - v[1] = NA_REAL; // NA - v[2] = R_PosInf; // Inf - v[3] = 42; // c.f. Hitchhiker Guide - return Rcpp::wrap(v);' -fun <- cxxfunction(signature(), src, plugin="Rcpp") -fun() -``` - -Similarly, for Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::export]] -Rcpp::NumericVector fun(void) { - Rcpp::NumericVector v(4); - v[0] = R_NegInf; // -Inf - v[1] = NA_REAL; // NA - v[2] = R_PosInf; // Inf - v[3] = 42; // c.f. Hitchhiker Guide - return v; -} -``` - -## Can I easily multiply matrices - -> Can I multiply matrices easily? - -\noindent Yes, via the \pkg{RcppArmadillo} package which builds upon \pkg{Rcpp} and the -wonderful Armadillo library described above in \faq{matrix-algebra}: - -```{r, eval = FALSE} -txt <- 'arma::mat Am = Rcpp::as< arma::mat >(A); - arma::mat Bm = Rcpp::as< arma::mat >(B); - return Rcpp::wrap( Am * Bm );' -mmult <- cxxfunction(signature(A="numeric", - B="numeric"), - body=txt, - plugin="RcppArmadillo") -A <- matrix(1:9, 3, 3) -B <- matrix(9:1, 3, 3) -C <- mmult(A, B) -C -``` - -Armadillo supports a full range of common linear algebra operations. - -The \pkg{RcppEigen} package provides an alternative using the -[Eigen](http://eigen.tuxfamily.org) template library. - -Rcpp Attributes, once again, makes this even easier: - -```cpp - -#include - -// [[Rcpp::depends(RcppArmadillo)]] - -// [[Rcpp::export]] -arma::mat mult(arma::mat A, arma::mat B) { - return A*B; -} - -/*** R -A <- matrix(1:9, 3, 3) -B <- matrix(9:1, 3, 3) -mult(A,B) -*/ -``` - -which can be built, and run, from R via a simple \rdoc{Rcpp}{sourceCpp} -call---and will also run the small R example at the end. - -## How do I write a plugin for \pkg{inline} and/or Rcpp Attributes - -> How can I create my own plugin for use by the \pkg{inline} package? - -Here is an example which shows how to it using GSL libraries as an -example. This is merely for demonstration, it is also not perfectly general -as we do not detect locations first---but it serves as an example: - -```{r, eval = FALSE} -# simple example of seeding RNG and -# drawing one random number -gslrng <- ' -int seed = Rcpp::as(par) ; -gsl_rng_env_setup(); -gsl_rng *r = gsl_rng_alloc (gsl_rng_default); -gsl_rng_set (r, (unsigned long) seed); -double v = gsl_rng_get (r); -gsl_rng_free(r); -return Rcpp::wrap(v);' - -plug <- Rcpp::Rcpp.plugin.maker( - include.before = "#include ", - libs = paste( -"-L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp", -"-Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib", -"-L/usr/lib -lgsl -lgslcblas -lm") -) -registerPlugin("gslDemo", plug ) -fun <- cxxfunction(signature(par="numeric"), - gslrng, plugin="gslDemo") -fun(0) -``` - -Here the \pkg{Rcpp} function `Rcpp.plugin.maker` is used to create a -plugin 'plug' which is then registered, and subsequently used by \pkg{inline}. - -The same plugins can be used by Rcpp Attributes as well. - -## How can I pass one additional flag to the compiler - -> How can I pass another flag to the `g++` compiler without writing a new plugin? - -The quickest way is to modify the return value from an existing plugin. Here -we use the default one from \pkg{Rcpp} itself in order to pass the new flag -`-std=c++0x`. As it does not set the `PKG_CXXFLAGS` variable, we -simply assign this. For other plugins, one may need to append to the existing -values instead. - -```{r, eval=FALSE} -myplugin <- getPlugin("Rcpp") -myplugin$env$PKG_CXXFLAGS <- "-std=c++11" -f <- cxxfunction(signature(), - settings = myplugin, body = ' - // fails without -std=c++0x - std::vector x = { 1.0, 2.0, 3.0 }; - return Rcpp::wrap(x); -') -f() -``` - -For Rcpp Attributes, the attributes `Rcpp::plugin()` can be -used. Currently supported plugins are for C++11 as well as for OpenMP. - -## How can I set matrix row and column names - -> Ok, I can create a matrix, but how do I set its row and columns names? - -Pretty much the same way as in \proglang{R} itself: We define a list with two -character vectors, one each for row and column names, and assign this to the -`dimnames` attribute: - -```{r, eval = FALSE} -src <- ' - Rcpp::NumericMatrix x(2,2); - x.fill(42); // or another value - Rcpp::List dimnms = // list with 2 vecs - Rcpp::List::create( // with static names - Rcpp::CharacterVector::create("cc", "dd"), - Rcpp::CharacterVector::create("ee", "ff") - ); - // and assign it - x.attr("dimnames") = dimnms; - return(x); -' -fun <- cxxfunction(signature(), - body=src, plugin="Rcpp") -fun() -``` - -The same logic, but used with Rcpp Attributes: - -```cpp -#include - -// [[Rcpp::export]] -Rcpp::List fun(void) { - Rcpp::NumericMatrix x(2,2); - x.fill(42); // or another value - Rcpp::List dimnms = // list with 2 vecs - Rcpp::List::create( // with static names - Rcpp::CharacterVector::create("cc", "dd"), - Rcpp::CharacterVector::create("ee", "ff")); - // and assign it - x.attr("dimnames") = dimnms; - return(x); -} -``` - -## Why can long long types not be cast correctly - -That is a good and open question. We rely on the basic \proglang{R} types, -notably `integer` and `numeric`. These can be cast to and from -\proglang{C++} types without problems. But there are corner cases. The -following example, contributed by a user, shows that we cannot reliably cast -`long` types (on a 64-bit machines). - -```{r, eval = FALSE} -BigInts <- cxxfunction(signature(), - 'std::vector bigints; - bigints.push_back(12345678901234567LL); - bigints.push_back(12345678901234568LL); - Rprintf("Difference of %ld\\n", - 12345678901234568LL - 12345678901234567LL); - return wrap(bigints);', - plugin="Rcpp", includes="#include ") - -retval <- BigInts() - -# Unique 64-bit integers were cast to identical -# lower precision numerics behind my back with -# no warnings or errors whatsoever. Error. - -stopifnot(length(unique(retval)) == 2) -``` - -While the difference of one is evident at the \proglang{C++} level, it is no -longer present once cast to \proglang{R}. The 64-bit integer values get cast -to a floating point types with a 53-bit mantissa. We do not have a good -suggestion or fix for casting 64-bit integer values: 32-bit integer values -fit into `integer` types, up to 53 bit precision fits into -`numeric` and beyond that truly large integers may have to converted -(rather crudely) to text and re-parsed. Using a different representation as -for example from the [GNU Multiple Precision Arithmetic Library](http://gmplib.org/) -may be an alternative. - -## What LaTeX packages do I need to typeset the vignettes - -> I would like to typeset the vignettes. What do I need? - -The [TeXLive](https://www.tug.org/texlive/) distribution seems to get -bigger and bigger. What you need to install may depend on your operating -system. - -Specific per-platform notes: - -- **Windows** users probably want the [MiKTeX](http://miktex.org/). - Suggestions for a more detailed walk through would be appreciated. -- **OS X** users seem to fall into camps which like or do not like brew / - homebrew. One suggestion was to install - [MacTeX](https://tug.org/mactex/mactex-download.html) but at - approximately 2.5gb (as of January 2016) this is not lightweight. -- **Linux** users probably want the full - [TeXLive](https://www.tug.org/texlive/) set from their distribution. On - [Debian](http://www.debian.org) these packages are installed to build - the R package itself: `texlive-base, texlive-latex-base, - texlive-generic-recommended, texlive-fonts-recommended, - texlive-fonts-extra, texlive-extra-utils, texlive-latex-recommended, - texlive-latex-extra`. Using `texlive-full` may be a shortcut. - Fedora and other distributions should have similar packages. - -## Why is there a limit of 20 on some constructors - -> Ok, I would like to pass $N$ object but you only allow 20. How come? - -In essence, and in order to be able to compile it with the largest number of -compilers, \pkg{Rcpp} is constrained by the older C++ standards which do not -support variadic function arguments. So we actually use macros and code -generator scripts to explicitly enumerate arguments, and that number has to stop -at some limit. We chose 20. - -A good discussion is available at -[this StackOverflow question](http://stackoverflow.com/questions/27371543) -concering data.frame creation with \pkg{Rcpp}. One solution offers a custom -`ListBuilder` class to circumvent the limit; another suggests to simply -nest lists. - -## Can I use default function parameters with \pkg{Rcpp} - -Yes, you can use default parameters with _some_ limitations. -The limitations are mainly related to string literals and empty vectors. -This is what is currently supported: - -- String literals delimited by quotes (e.g. `"foo"`) -- Integer and Decimal numeric values (e.g. `10` or `4.5`) -- Pre-defined constants including: - - Booleans: `true` and `false` - - Null Values: `R_NilValue`, `NA_STRING`, `NA_INTEGER`, `NA_REAL`, and `NA_LOGICAL`. -- Selected vector types can be instantiated using the empty form of the - `::create` static member function. - - `CharacterVector`, `IntegerVector`, and `NumericVector` -- Matrix types instantiated using the rows, cols constructor - `Rcpp::Matrix n(rows,cols)` - - `CharacterMatrix`, `IntegerMatrix`, and `NumericMatrix` - -To illustrate, please consider the following example that provides a short -how-to: - -```cpp -#include - -// [[Rcpp::export]] -void sample_defaults( - NumericVector x = - NumericVector::create(), // Size 0 vector - bool bias = true, // Set to true - std::string method = - "rcpp rules!") { // Set string - - Rcpp::Rcout << "x size: " << x.size() << ", "; - Rcpp::Rcout << "bias value: " << bias << ", "; - Rcpp::Rcout << "method value: " << "."; - -} - -/*** R -sample_defaults() # all defaults -sample_defaults(1:5) # supply x values - -sample_defaults(bias = FALSE, # supply bool - method = "Rlang") # and string -*/ -``` - -Note: In `cpp`, the default `bool` values are `true` and -`false` whereas in R the valid types are `TRUE` or `FALSE`. - -## Can I use C++11, C++14, C++17, ... with \pkg{Rcpp} - -But of course. In a nutshell, this boils down to \emph{what your compiler - supports}, and also \emph{what R supports}. We expanded a little on this in -[Rcpp Gallery article](http://gallery.rcpp.org/articles/rcpp-and-c++11-c++14-c++17/) providing more detail. What follows in an abridged summary. - -You can always \emph{locally} set appropriate `PKG_CXXFLAGS` as an -environment variable, or via `~/.R/Makevars`. You can also plugins and/or R -support from `src/Makevars`: - -- _C++11_: has been supported since early 2013 via a plugin selecting - the language standard which is useful for `sourceCpp()` etc. For - packages, R has supported it since R 3.1.0 which added the option to select - the language standard via `CXX_STD = CXX11`. As of early 2017, over 120 - packages on CRAN use this. -- _C++14_: has been supported since early 2016 via a plugin selecting - the language standard which is useful for `sourceCpp()` etc. For - packages, R supports it since R 3.4.0 adding the option to select the language - standard via `CXX_STD = CXX14`. -- _C++17_: is itself more experimental now, but if you have a compiler - supporting (at least parts of) it, you can use it via plugin (starting with - Rcpp 0.12.10) for use via `sourceCpp()`, or via `PKG_CXXFLAGS` or - other means to set compiler options. R support may be available at a later - date. - -## How do I use it within (Python's) Conda setup? - -In a comment to [issue ticket #770](https://github.com/RcppCore/Rcpp/issues/770#issuecomment-346716808) it is stated that running - -```sh -conda install gxx_linux-64 -``` - -helps within this environment as it installs the corresponding -`x86_64-conda_cos6-linux-gnu-c++` compiler. Documentation for this and other -systems is provided -[at this page](https://conda.io/docs/user-guide/tasks/build-packages/compiler-tools.html). - -# Support - -## Is the API documented - -You bet. We use \proglang{doxygen} to generate html, latex and man page -documentation from the source. The html documentation is available for -[browsing](http://dirk.eddelbuettel.com/code/rcpp/html/index.html), as a -[very large pdf file](http://dirk.eddelbuettel.com/code/rcpp/Rcpp_refman.pdf), -and all three formats are also available a zip-archives: -[html](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-html.zip), -[latex](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-latex.zip), and -[man](http://dirk.eddelbuettel.com/code/rcpp/rcpp-doc-man.zip). - -## Does it really work - -We take quality seriously and have developped an extensive unit test suite to -cover many possible uses of the \pkg{Rcpp} API. - -We are always on the look for more coverage in our testing. Please let us know -if something has not been tested enough. - -## Where can I ask further questions - -The -[Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list hosted at R-forge is by far the best place. You may also want -to look at the list archives to see if your question has been asked before. - -You can also use [StackOverflow via its 'rcpp' tag](http://stackoverflow.com/questions/tagged/rcpp). - -## Where can I read old questions and answers - -The normal [Rcpp-devel](https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel) -mailing list hosting at R-forge contains an archive, which can be -[searched via swish](http://lists.r-forge.r-project.org/mailman/swish.cgi?query=listname=rcpp-devel). - -Alternatively, one can also use -[Mail-Archive on Rcpp-devel](http://www.mail-archive.com/rcpp-devel@lists.r-forge.r-project.org/info.html) -which offers web-based interfaces, including searching. - -## I like it. How can I help {#helping} - -We maintain a list of -[open issues in the Github repository](https://github.com/RcppCore/Rcpp/issues?state=open). -We welcome pull requests and suggest that code submissions -come corresponding unit tests and, if applicable, documentation. - -If you are willing to donate time and have skills in C++, let us know. If you are -willing to donate money to sponsor improvements, let us know too. - -You can also spread the word about \pkg{Rcpp}. There are many packages on CRAN -that use \proglang{C++}, yet are not using \pkg{Rcpp}. You could blog about -it, or get the word out otherwise. - -Last but not least the [Rcpp Gallery](http://gallery.rcpp.org) is open -for user contributions. - -## I don't like it. How can I help {#dont-like-help} - -It is very generous of you to still want to help. Perhaps you can tell us -what it is that you dislike. We are very open to \emph{constructive} criticism. - -## Can I have commercial support for \pkg{Rcpp} - -Sure you can. Just send us an email, and we will be happy to discuss the -request. - -## I want to learn quickly. Do you provide training courses - -Yes. Just send us an email. - -## Where is the code repository - -From late 2008 to late 2013, we used the -[Subversion repository at R-Forge](https://r-forge.r-project.org/scm/?group_id=155) -which contained \pkg{Rcpp} and a number of related packages. It still has the full -history as well as number of support files. - -We have since switched to a [Git repository at Github](http://github.com/RcppCore/Rcpp) -for \pkg{Rcpp} (as well as for \pkg{RcppArmadillo} and \pkg{RcppEigen}). - -# Known Issues - -Contained within this section is a list of known issues regarding \pkg{Rcpp}. -The issues listed here are either not able to be fixed due to breaking -application binary interface (ABI), would impact the ability to reproduce -pre-existing results, or require significant work. Generally speaking, these -issues come to light only when pushing the edge capabilities of \pkg{Rcpp}. - -## \pkg{Rcpp} changed the (const) object I passed by value - -\pkg{Rcpp} objects are wrappers around the underlying \proglang{R} objects' `SEXP`, -or S-expression. The `SEXP` is a pointer variable that holds the location -of where the \proglang{R} object data has been stored \citep[][Section 1.1]{R:Internals}. -That is to say, the `SEXP` does _not_ hold the actual data of the -\proglang{R} object but merely a reference to where the data resides. When creating a new -\pkg{Rcpp} object for an \proglang{R} object to enter \proglang{C++}, this object will -use the same `SEXP` that powers the original \proglang{R} object if the types match -otherwise a new `SEXP` must be created to be type safe. In essence, the -underlying `SEXP` objects are passed by reference without explicit copies -being made into \proglang{C++}. We refer to this arrangement as a -_proxy model_. - -As for the actual implementation, there are a few consequences of the proxy -model. The foremost consequence within this paradigm is that pass by value is -really a pass by reference. In essence, the distinction between the following -two functions is only visual sugar: - -```cpp -void implicit_ref(NumericVector X); -void explicit_ref(NumericVector& X); -``` - -In particular, when one is passing by value what occurs is the instantiation of -the new \pkg{Rcpp} object that uses the same `SEXP` for the \proglang{R} object. -As a result, the \pkg{Rcpp} object is ``linked'' to the original \proglang{R} object. -Thus, if an operation is performed on the \pkg{Rcpp} object, such as adding 1 -to each element, the operation also updates the \proglang{R} object causing the change to be propagated to \proglang{R}'s interactive environment. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void implicit_ref(Rcpp::NumericVector X) { - X = X + 1.0; -} - -// [[Rcpp::export]] -void explicit_ref(Rcpp::NumericVector& X) { - X = X + 1.0; -} -``` - -R use - -```{r} -a <- 1.5:4.5 -b <- 1.5:4.5 -implicit_ref(a) -a -explicit_ref(b) -b -``` - -There are two exceptions to this rule. The first exception is that a deep copy -of the object can be made by explicit use of `Rcpp:clone()`. In this case, -the cloned object has no link to the original \proglang{R} object. However, there is a -time cost associated with this procedure as new memory must be allocated and -the previous values must be copied over. The second exception, which was -previously foreshadowed, is encountered when \pkg{Rcpp} and \proglang{R} object types -do not match. One frequent example of this case is when the \proglang{R} object generated -from `seq()` or `a:b` reports a class of `"integer"` while the -\pkg{Rcpp} object is setup to receive the class of `"numeric"` as its -object is set to `NumericVector` or `NumericMatrix`. In such cases, -this would lead to a new `SEXP` object being created behind the scenes -and, thus, there would _not_ be a link between the \pkg{Rcpp} object -and \proglang{R} object. So, any changes in \proglang{C++} would not be propagated to -\proglang{R} unless otherwise specified. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void int_vec_type(Rcpp::IntegerVector X) { - X = X + 1.0; -} - -// [[Rcpp::export]] -void num_vec_type(Rcpp::NumericVector X) { - X = X + 1.0; -} -``` - -R use: - -```{r} -a <- 1:5 -b <- 1:5 -class(a) -int_vec_type(a) -a # variable a changed as a side effect -num_vec_type(b) -b # b unchanged as copy was made for numeric -``` - -With this being said, there is one last area of contention with the proxy model: -the keyword `const`. The `const` declaration indicates that an object -is not allowed to be modified by any action. Due to the way the proxy -model paradigm works, there is a way to "override" the `const` designation. -Simply put, one can create a new \pkg{Rcpp} object without the `const` -declaration from a pre-existing one. As a result, the new \pkg{Rcpp} object -would be allowed to be modified by the compiler and, thus, modifying the initial -`SEXP` object. Therefore, the initially secure \proglang{R} object would be altered. -To illustrate this phenomenon, consider the following scenario: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::IntegerVector const_override_ex( - const Rcpp::IntegerVector& X) { - - Rcpp::IntegerVector Y(X); // Create object - // from SEXP - - Y = Y * 2; // Modify new object - - return Y; // Return new object -} -``` - -R use: - -```{r} -x <- 1:10 # an integer sequence -# returning an altered value -const_override_ex(x) -# but the original value is altered too! -x -``` - -So we see that with `SEXP` objects, the `const` declaration can be -circumvented as it is really a pointer to the underlying R object. - - -## Issues with implicit conversion from an \pkg{Rcpp} object to a scalar or other \pkg{Rcpp} object - -Not all \pkg{Rcpp} expressions are directly compatible with -`operator=`. Compability issues stem from many \pkg{Rcpp} objects and -functions returning an intermediary result which requires an explicit -conversion. In such cases, the user may need to assist the compiler -with the conversion. - -There are two ways to assist with the conversion. The first is to construct -storage variable for a result, calculate the result, and then store a value -into it. This is typically what is needed when working with -`Character` and `String` in \pkg{Rcpp} due to the -`Rcpp::internal::string_proxy` class. Within the following code snippet, -the aforementioned approach is emphasized: - -```cpp -#include - -// [[Rcpp::export]] -std::string explicit_string_conv( - Rcpp::CharacterVector X) { - - std::string s; // define storage - s = X[0]; // assign from CharacterVector - - return s; -} -``` - -If one were to use a direct allocation and assignment strategy, -e.g. `std::string s = X[0]`, this would result in the compiler triggering -a conversion error on _some_ platforms. The error would be similar to: - -```{bash, eval = FALSE} -error: no viable conversion from 'Proxy' -(aka 'string_proxy<16>') to 'std::string' -(aka 'basic_string, -allocator >') -``` - -The second way to help the compiler is to use an explicit \pkg{Rcpp} type conversion -function, if one were to exist. Examples of \pkg{Rcpp} type conversion functions -include `as()`, `.get()` for `cumsum()`, `is_true()` -and `is_false()` for `any()` or `all()`. - - -## Using `operator=` with a scalar replaced the object instead of filling element-wise - -Assignment using the `operator=` with either `Vector` and -`Matrix` classes will not elicit an element-wise fill. If you seek an -element-wise fill, then use the `.fill()` member method to propagate a -single value throughout the object. With this being said, the behavior of -`operator=` differs for the `Vector` and `Matrix` classes. - -The implementation of the `operator=` for the `Vector` class will -replace the existing vector with the assigned value. This behavior is valid -even if the assigned value is a scalar value such as 3.14 or 25 as the object -is cast into the appropriate \pkg{Rcpp} object type. Therefore, if a -`Vector` is initialized to have a length of 10 and a scalar is assigned -via `operator=`, then the resulting `Vector` would have a length of -1. See the following code snippet for the aforementioned behavior. - -```{Rcpp} -#include - -// [[Rcpp::export]] -void vec_scalar_assign(int n, double fill_val) { - Rcpp::NumericVector X(n); - Rcpp::Rcout << "Value of Vector " << - "on Creation: " << - std::endl << X << std::endl; - - X = fill_val; - - Rcpp::Rcout << "Value of Vector " << - "after Assignment: " << - std::endl << X << std::endl; -} -``` - -R use: - -```{r} -vec_scalar_assign(5L, 3.14) -``` - - -Now, the `Matrix` class does not define its own `operator=` but -instead uses the `Vector` class implementation. This leads to unexpected -results while attempting to use the assignment operator with a scalar. In -particular, the scalar will be coerced into a square `Matrix` and then -assigned. For an example of this behavior, consider the following code: - -```{Rcpp} -#include - -// [[Rcpp::export]] -void mat_scalar_assign(int n, double fill_val) { - Rcpp::NumericMatrix X(n, n); - Rcpp::Rcout << "Value of Matrix " << - "on Creation: " << - std::endl << X << std::endl; - - X = fill_val; - - Rcpp::Rcout << "Value of Matrix " << - "after Assignment: " << - std::endl << X << std::endl; -} -``` - -R use: - -```{r} -mat_scalar_assign(2L, 3.0) -``` - -## Long Vector support on Windows - -Prior to \proglang{R}'s 3.0.0, the largest vector one could obtain was at most $2^{31} - 1$ -elements. With the release of \proglang{R}'s 3.0.0, long vector support was added to -allow for largest vector possible to increase up to $2^{52}$ elements on x64 bit -operating systems (c.f. [Long Vectors help entry](https://stat.ethz.ch/R-manual/R-devel/library/base/html/LongVectors.html)). -Once this was established, support for long vectors within the \pkg{Rcpp} paradigm -was introduced with \pkg{Rcpp} version 0.12.0 (c.f [\pkg{Rcpp} 0.12.0 annoucement](http://dirk.eddelbuettel.com/blog/2015/07/25/)). - -However, the requirement for using long vectors in \pkg{Rcpp} necessitates the -presence of compiler support for the `R_xlen_t`, which is platform -dependent on how `ptrdiff_t` is implemented. Unfortunately, this means -that on the Windows platform the definition of `R_xlen_t` is of type -`long` instead of `long long` when compiling under the -\proglang{C++98} specification. Therefore, to solve this issue one must compile -under the specification for \proglang{C++11} or later version. - -There are three options to trigger compilation with \proglang{C++11}. -The first -- and most likely option to use -- will be the plugin support offered -by \pkg{Rcpp} attributes. This is engaged by adding -`// [[Rcpp::plugins(cpp11)]]` to the top of the \proglang{C++} script. -For diagnostic and illustrativative purposes, consider the following code -which checks to see if `R_xlen_t` is available on your platform: - -```{Rcpp} -#include -// Force compilation mode to C++11 -// [[Rcpp::plugins(cpp11)]] - -// [[Rcpp::export]] -bool test_long_vector_support() { -#ifdef RCPP_HAS_LONG_LONG_TYPES - return true; -#else - return false; -#endif -} -``` - -R use: - -```{r} -test_long_vector_support() -``` - -The remaining two options are for users who have opted to embed \pkg{Rcpp} code -within an \proglang{R} package. In particular, the second option requires adding -`CXX_STD = CXX11` to a `Makevars` file found in the `/src` -directory. Finally, the third option is to add `SystemRequirements:C++11` -in the package's `DESCRIPTION` file. - -Please note that the support for \proglang{C++11} prior to \proglang{R} v3.3.0 on Windows -is limited. Therefore, plan accordingly if the goal is to support older -versions of \proglang{R}. - -## Sorting with STL on a `CharacterVector` produces problematic results - -The Standard Template Library's (STL) `std::sort` algorithm performs -adequately for the majority of \pkg{Rcpp} data types. The notable exception -that makes what would otherwise be a universal quantifier into an existential -quantifier is the `CharacterVector` data type. Chiefly, the issue with -sorting strings is related to how the `CharacterVector` relies upon the -use of `Rcpp::internal::string_proxy`. -In particular, `Rcpp::internal::string_proxy` is _not_ MoveAssignable since the -left hand side of `operator=(const string_proxy \&rhs)` is _not_ -viewed as equivalent to the right hand side before the -operation \citep[][p. 466, Table 22]{Cpp11}. This further complicates matters -when using `CharacterVector` with `std::swap`, `std::move`, -`std::copy` and their variants. - -To avoid unwarranted pain with sorting, the preferred approach is to use the -`.sort()` member function of \pkg{Rcpp} objects. The member function -correctly applies the sorting procedure to \pkg{Rcpp} objects regardless of -type. Though, sorting is slightly problematic due to locale as explained in the -next entry. In the interim, the following code example illustrates the preferred -approach alongside the problematic STL approach: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::CharacterVector preferred_sort( - Rcpp::CharacterVector x) { - - Rcpp::CharacterVector y = Rcpp::clone(x); - y.sort(); - - return y; -} - -// [[Rcpp::export]] -Rcpp::CharacterVector stl_sort( - Rcpp::CharacterVector x) { - - Rcpp::CharacterVector y = Rcpp::clone(x); - std::sort(y.begin(), y.end()); - - return y; -} -``` - -R use: - -```{r} -set.seed(123) -(X <- sample(c(LETTERS[1:5], letters[1:6]), 11)) -preferred_sort(X) -stl_sort(X) -``` - -In closing, the results of using the STL approach do change depending on -whether `libc++` or `libstdc++` standard library is used to compile -the code. When debugging, this does make the issue particularly complex to -sort out. Principally, compilation with `libc++` and STL has been shown -to yield the correct results. However, it is not wise to rely upon this library -as a majority of code is compiled against `libstdc++` as it more complete. - -## Lexicographic order of string sorting differs due to capitalization - -Comparing strings within \proglang{R} hinges on the ability to process the locale or -native-language environment of the string. In \proglang{R}, there is a function called -`Scollate` that performs the comparison on locale. Unfortunately, this -function has not been made publicly available and, thus, \pkg{Rcpp} does -_not_ have access to it within its implementation of `StrCmp`. -As a result, strings that are sorted under the `.sort()` member function -are ordered improperly. Specifically, if capitalization is present, then -capitalized words are sorted together followed by the sorting of lowercase -words instead of a mixture of capitalized and lowercase words. The issue is -illustrated by the following code example: - -```{Rcpp} -#include - -// [[Rcpp::export]] -Rcpp::CharacterVector rcpp_sort( - Rcpp::CharacterVector X) { - X.sort(); - return X; -} -``` - -R use: - -```{r} -x <- c("B", "b", "c", "A", "a") -sort(x) -rcpp_sort(x) -``` - -## Package building fails with 'symbols not found' - -R 3.4.0 and later strongly encourage registering dynamically loadable -symbols. In the stronger form (where `.registration=TRUE` is added to the -`useDynLib()` statement in `NAMESPACE`), only registered symbols can be -loaded. This is fully supported by Rcpp 0.12.12 and later, and the required code -is added to `src/RcppExports.cpp`. - -However, the transition from the previously generated file `src/RcppExports.cpp` -to the new one may require running `compileAttributes()` twice (which does not -happen when, _e.g._, devtools is used). When `Rcpp::compileAttributes()` is -called, it also calls `tools::package_native_routine_registration_skeleton()`, -which crawls through usages of `.Call()` in the `R/` source files of the package to -figure out what routines need to be registered. If an older `RcppExports.R` file -is discovered, its out-of-date symbol names get picked up, and registration -rules for those symbols get written as well. This will register more symbols for -the package than are actually defined, leading to an error. This point has been -discussed at some length both in the GitHub issue tickes, on StackOverflow and -elsewhere. - -So if your autogenerated file fails, and a `symbols not found` error is reported -by the linker, consider running `compileAttributes()` twice. Deleting -`R/RcppExports.R` and `src/RcppExports.cpp` may also work. diff -Nru rcpp-1.0.2/vignettes/Rcpp-FAQ.Rnw rcpp-1.0.3/vignettes/Rcpp-FAQ.Rnw --- rcpp-1.0.2/vignettes/Rcpp-FAQ.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-FAQ.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-FAQ} +%\VignetteKeywords{Rcpp, FAQ, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-FAQ.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp-introduction.Rmd rcpp-1.0.3/vignettes/Rcpp-introduction.Rmd --- rcpp-1.0.2/vignettes/Rcpp-introduction.Rmd 2018-07-27 12:39:57.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-introduction.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,921 +0,0 @@ ---- -title: | - | Extending \rlang with C++: - | A Brief Introduction to Rcpp - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: James Joseph Balamuta - affiliation: b -address: - - code: a - address: Debian and R Projects; Chicago, IL, USA; \url{edd@debian.org} - - code: b - address: Depts of Informatics and Statistics, Univ. of Illinois at Urbana-Champaign; Champaign, IL, USA; \url{balamut2@illinois.edu} - -# For footer text TODO(fold into template, allow free form two-authors) -lead_author_surname: Eddelbuettel and Balamuta - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - \rlang has always provided an application programming interface (API) for extensions. - Based on the \clang language, it uses a number of macros and other low-level constructs - to exchange data structures between the \rlang process and any dynamically-loaded component - modules authors added to it. With the introduction of the \rcpp package, and its later - refinements, this process has become considerably easier yet also more robust. By now, \rcpp has - become the most popular extension mechanism for \rlangns. This article introduces \rcppns, and - illustrates with several examples how the _Rcpp Attributes_ mechanism in particular - eases the transition of objects between \rlang and \cpp code. - -# Acknowledgements -acknowledgements: | - We thank Bob Rudis and Lionel Henry for excellent comments and suggestion on an earlier - draft of this manuscript. Furthermore, we appreciate the improved \cpp annotated function - graphic provided by Bob Rudis. This version is a pre-print of \citet{PeerJ:Rcpp,TAS:Rcpp}. - -# One or more keywords -keywords: - - applications and case studies - - statistical computing - - computationally intensive methods - - simulation - -# Bibliography -bibliography: Rcpp - -# Enable a watermark on the document -watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: - pinp::pinp: - collapse: true - -# Local additiona of a few definitions we use -header-includes: > - \newcommand{\TODO}{\marginnote{TODO}} - \newcommand{\rlang}{\textit{R }} - \newcommand{\rlangns}{\textit{R}} - \newcommand{\slang}{\textit{S }} - \newcommand{\rcpp}{\textit{Rcpp }} - \newcommand{\rcppns}{\textit{Rcpp}} - \newcommand{\clang}{\textit{C }} - \newcommand{\clangns}{\textit{C}} - \newcommand{\cpp}{\textit{C++ }} - \newcommand{\cppns}{\textit{C++}} - \newcommand{\fortran}{\textit{Fortran }} - \newcommand{\fortranns}{\textit{Fortran}} - \newcommand{\python}{\textit{Python}} - \newcommand{\julia}{\textit{Julia}} - \newcommand{\pkg}[1]{\textbf{#1}} - -vignette: > - %\VignetteIndexEntry{Rcpp-introduction} - %\VignetteKeywords{Rcpp, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r setup, include=FALSE} -knitr::opts_chunk$set(cache=TRUE) -library(Rcpp) -options("width"=50, digits=5) -``` - - -# Introduction - -The \rlang language and environment \citep{R:main} has established itself as -both an increasingly dominant facility for data analysis, and the -*lingua franca* for statistical computing in both research and -application settings. - -Since the beginning, and as we argue below, "by design", -the \rlang system has always provided an application programming interface (API) -suitable for extending \rlang with code written in \clang or \fortranns. Being -implemented chiefly in \rlang and \clang (with a generous sprinkling of \fortran -for well-established numerical subroutines), \rlang has always been -extensible via a \clang interface. Both the actual -implementation and the \clang interface use a number of macros and other -low-level constructs to exchange data structures between the \rlang process -and any dynamically-loaded component modules authors added to it. - -A \clang interface will generally also be accessible to other languages. -Particularly noteworthy here is the \cpp language, developed originally as a -'better \clangns', which is by its design very interoperable with -\clangns. And with the introduction of the \rcpp package -\citep{JSS:Rcpp,Eddelbuettel:2013:Rcpp,CRAN:Rcpp}, and its later refinements, this -process of extending \rlang has become considerably easier yet also more robust. -To date, \rcpp has become the most popular extension system for -\rlangns. This article introduces \rcppns, and illustrates with several -examples how the _Rcpp Attributes_ mechanism -\citep{CRAN:Rcpp:Attributes} in particular eases the transition of -objects between \rlang and \cpp code. - - -## Background - -\citet[p. 3]{Chambers:2008:SoDA} provides a very thorough discussion of -desirable traits for a system designed to _program with data_, -and the \rlang system in particular. Two key themes motivate the introductory -discussion. First, the _Mission_ is to aid exploration in order to -provide the best platform to analyse data: "to boldly go where no one -has gone before." Second, the _Prime Directive_ is that the software -systems we build must be _trustworthy_: "the many computational steps -between original data source and displayed result must all be -trustful." The remainder of the book then discusses \rlangns, leading -to two final chapters on interfaces. - -\citet[p. 4]{Chambers:2016:ExtR} builds and expands on this theme. Two core -facets of what "makes" \rlang are carried over from the previous book. The -first states what \rlang is composed of: _Everything that exists in \rlang is -an object_. The second states how these objects are created or -altered: _Everything that happens in \rlang is a function call_. A third -statement is now added: _Interfaces to other software are part of \rlangns_. - -This last addition is profound. If and when suitable and performant -software for a task exists, it is in fact desirable to have a (preferably -also perfomant) interface to this software from \rlangns. -\cite{Chambers:2016:ExtR} discusses several possible approaches for simpler -interfaces and illustrates them with reference implementations to both \python\ and -\julia. However, the most performant interface for \rlang is provided at the -subroutine level, and rather than discussing the older \clang interface for -\rlangns, \cite{Chambers:2016:ExtR} prefers to discuss \rcppns. This article -follows the same school of thought and aims to introduce \rcpp to -analysts and data scientists, aiming to enable them to use---and -create--- further _interfaces_ for \rlang which aid the _mission_ while -staying true to the _prime directive_. Adding interfaces in such a way is in -fact a natural progression from the earliest designs for its predecessor -\slang which was after all designed to provide a more useable 'interface' to -underlying routines in \fortranns. - -The rest of the paper is structured as follows. We start by discussing -possible first steps, chiefly to validate correct installations. This -is followed by an introduction to simple \cpp functions, comparison to -the \clang API, a discussion of packaging with \rcpp and a linear algebra -example. The appendix contains some empirical illustrations of the -adoption of \rcppns. - - -# First Steps with \rcpp - -\rcpp is a CRAN package and can be installed -by using `install.packages('Rcpp')` just like any other \rlang package. On -some operating systems this will download _pre-compiled_ binary packages; on -others an installation from source will be attempted. But \rcpp is a little -different from many standard \rlang packages in one important aspect: it helps the user -to _write C(++) programs more easily_. The key aspect to note here is \cpp -programs: to operate, \rcpp needs not only \rlang but also an additional -_toolchain_ of a compiler, linker and more in order to be able to create _binary_ object -code extending \rlangns. - -We note that this requirement is no different from what is needed with base \rlang when -compilation of extensions is attempted. How to achieve this using only base \rlang is described in -some detail in the _Writing R Extensions_ manual \citep{R:Extensions} that is included -with \rlangns. As for the toolchain requirements, on Linux and macOS, all required -components are likely to be present. The macOS can offer additional challenges as toolchain -elements can be obtained in different ways. Some of these are addressed in the _Rcpp FAQ_ -\citep{CRAN:Rcpp:FAQ} in sections 2.10 and 2.16. On Windows, users will have to install -the Rtools kit provided by R Core available at . -Details of these installation steps are beyond the scope of this -paper. However, many external resources exist that provide detailed -installation guides for \rlang toolschains in -[Windows](http://thecoatlessprofessor.com/programming/rcpp/install-rtools-for-rcpp/) -and -[macOS](http://thecoatlessprofessor.com/programming/r-compiler-tools-for-rcpp-on-os-x/). - -As a first step, and chiefly to establish that the toolchain is set up correctly, consider -a minimal use case such as the following: - -```{r evalCpp} -library("Rcpp") -evalCpp("2 + 2") -``` - -Here the \rcpp package is loaded first via the `library()` function. Next, we deploy one -of its simplest functions, `evalCpp()`, which is described in the _Rcpp Attributes_ vignette -\citep{CRAN:Rcpp:Attributes}. It takes the first (and often only) argument---a character -object---and evaluates it as a minimal \cpp expression. The value assignment and return -are implicit, as is the addition of a trailing semicolon and more. In fact, `evalCpp()` -surrounds the expression with the required 'glue' to make it a minimal source file which -can be compiled, linked and loaded. The exact details behind this process -are available in-depth when the `verbose` option of the function is set. -If everything is set up correctly, the newly-created \rlang function will be -returned. - -While such a simple expression is not interesting in itself, it serves a -useful purpose here to unequivocally establish whether \rcpp is correctly -set up. Having accomplished that, we can proceed to the next step of -creating simple functions. - -# A first \cpp function using \rcpp - -As a first example, consider the determination of whether a number is odd or even. The -default practice is to use modular arithmetic to check if a remainder exists under $x -\bmod 2$. Within \rlangns, this can be implemented as follows: - -```{r isOddR, cache=TRUE} -isOddR <- function(num = 10L) { - result <- (num %% 2L == 1L) - return(result) -} -isOddR(42L) -``` - -The operator `%%` implements the $\bmod$ operation in \rlangns. For the default -(integer) argument of ten used in the example, $10 \bmod 2$ results in zero, which is then -mapped to `FALSE` in the context of a logical expression. - -Translating this implementation into \cppns, several small details have to be -considered. First and foremost, as \cpp is a _statically-typed language_, there needs to -be additional (compile-time) information provided for each of the variables. Specifically, -a *type*, _i.e._ the kind of storage used by a variable must be explicitly -defined. Typed languages generally offer benefits in terms of both correctness -(as it is harder to accidentally assign to an ill-matched type) and -performance (as the compiler can optimize code based on the storage and cpu -characteristics). Here we have an `int` argument, but return a logical, or -`bool` for short. Two more smaller differences are that each statement -within the body must be concluded with a semicolon, and that `return` does -not require parentheses around its argument. A graphical breakdown of all -aspects of a corresponding \cpp function is given in Figure \ref{fig:cpp-function-annotation}. - -\begin{figure*} - \begin{center} - \includegraphics[width=5.5in]{figures/function_annotation_cpp.png} - \caption{Graphical annotation of the \texttt{is\_odd\_cpp} function.} - \label{fig:cpp-function-annotation} - \end{center} -\end{figure*} - -When using \rcppns, such \cpp functions can be directly embedded and compiled in an \rlang -script file through the use of the `cppFunction()` provided by _Rcpp Attributes_ -\citep{CRAN:Rcpp:Attributes}. The first parameter of the function accepts string input -that represents the \cpp code. Upon calling the `cppFunction()`, and similarly to the -earlier example involving `evalCpp()`, the \cpp code is both _compiled_ and _linked_, and -then _imported_ into \rlang under the name of the function supplied (_e.g._ here `isOddCpp()`). - -```{r isOddRcpp} -library("Rcpp") -cppFunction(" -bool isOddCpp(int num = 10) { - bool result = (num % 2 == 1); - return result; -}") -isOddCpp(42L) -``` - -# Extending \rlang via its \clang API - -Let us first consider the case of 'standard \rlangns', _i.e._ the API as -defined in the core \rlang documentation. Extending \rlang with routines written -using the \clang language requires the use of internal macros and functions -documented in Chapter 5 of _Writing R Extensions_ \citep{R:Extensions}. - -```{Rcpp convolutionC, eval = FALSE} -#include -#include - -SEXP convolve2(SEXP a, SEXP b) { - int na, nb, nab; - double *xa, *xb, *xab; - SEXP ab; - - a = PROTECT(coerceVector(a, REALSXP)); - b = PROTECT(coerceVector(b, REALSXP)); - na = length(a); nb = length(b); - nab = na + nb - 1; - ab = PROTECT(allocVector(REALSXP, nab)); - xa = REAL(a); xb = REAL(b); xab = REAL(ab); - for (int i = 0; i < nab; i++) - xab[i] = 0.0; - for (int i = 0; i < na; i++) - for (int j = 0; j < nb; j++) - xab[i + j] += xa[i] * xb[j]; - UNPROTECT(3); - return ab; -} -``` - -This function computes a _convolution_ of two vectors supplied on input, $a$ and -$b$, which is defined to be ${ab_{k + 1}} = \sum\limits_{i + j == k} {{a_i} \cdot {b_j}}$. -Before computing the convolution (which is really just the three lines involving two -nested for loops with indices $i$ and $j$), a total of ten lines of mere housekeeping -are required. Vectors $a$ and $b$ are coerced to `double`, and a results vector `ab` is -allocated. This expression involves three calls to the `PROTECT` macro for which a _precisely_ -matching `UNPROTECT(3)` is required as part of the interfacing of internal memory -allocation. The vectors are accessed through pointer equivalents `xa`, `xb` and `xab`; and -the latter has to be explicitly zeroed prior to the convolution calculation involving -incremental summary at index $i+j$. - - -# Extending \rlang via the \cpp API of \rcpp - -Using the idioms of \rcppns, the above example can be written in a much more -compact fashion---leading to code that is simpler to read and -maintain. - -```{Rcpp convolutionRcpp, eval = FALSE} -#include "Rcpp.h" -using namespace Rcpp; - -// [[Rcpp::export]] -NumericVector -convolve_cpp(const NumericVector& a, - const NumericVector& b) { - - // Declare loop counters, and vector sizes - int i, j, - na = a.size(), nb = b.size(), - nab = na + nb - 1; - - // Create vector filled with 0 - NumericVector ab(nab); - - // Crux of the algorithm - for(i = 0; i < na; i++) { - for(j = 0; j < nb; j++) { - ab[i + j] += a[i] * b[j]; - } - } - - // Return result - return ab; -} -``` - -To deploy such code from within an \rlang script or session, first save it into a new -file---which could be called **convolve.cpp**---in either the working directory, a -temporary directoy or a project directory. Then from within the \rlang session, -use `Rcpp::sourceCpp("convolve.cpp")` (possibly using a path as well as the filename). This -not only compiles, links and loads the code within the external file but also adds the -necessary "glue" to make the \rcpp function available in the \rlang environment. Once the -code is compiled and linked, call the newly-created `convolve_cpp()` function with the -appropriate parameters as done in previous examples. - -What is notable about the \rcpp version is that it has no `PROTECT` or `UNPROTECT` -which not only frees the programmer from a tedious (and error-prone) step but -more importantly also shows that memory management can be handled automatically. -The result vector is already initialized at zero as well, -reducing the entire function to just the three lines for the two nested loops, -plus some variable declarations and the `return` statement. The resulting code is -shorter, easier to read, comprehend and maintain. Furthermore, the \rcpp code -is more similar to traditional \rlang code, which reduces -the barrier of entry. - - -# Data Driven Performance Decisions with \rcpp - -When beginning to implement an idea, more so an algorithm, there are many ways -one is able to correctly implement it. Prior to the routine being used in -production, two questions must be asked: - -1. Does the implementation produce the _correct_ results? -2. What implementation of the routine is the _best_? - -The first question is subject to a binary pass-fail unit test verification -while the latter question is where the details of an implementation are scrutinized -to extract maximal efficiency from the routine. The quality of the _best_ routine -follows first and foremost from its correctness. To that end, -\rlang offers many different unit testing frameworks such as \pkg{RUnit} by -\cite{CRAN:RUnit}, which is used to construct \rcppns's 1385+ unit tests, and -\pkg{testthat} by \cite{CRAN:testthat}. Only when correctness is -achieved is it wise to begin the procedure of optimizing the efficiency of -the routine and, in turn, selecting the best routine. - -Optimization of an algorithm involves performing a quantitative analysis of the -routine's properties. There are two main approaches to analyzing the behavior -of a routine: theoretical analysis\footnote{ -Theoretical analysis is often directed to describing -the limiting behavior of a function through asymptotic notation, -commonly referred to as Big O and denoted as $\mathcal{O}(\cdot)$.} -or an empirical examination using profiling tools.\footnote{ -Within base \rlangns, profiling can be activated by \code{utils::Rprof()} -for individual command timing information, \code{utils::Rprofmem()} for memory -information, and \code{System.time(\{\})} for a quick overall execution timing. -Additional profiling \rlang packages such as \pkg{profvis} by -\cite{CRAN:profvis}, \pkg{Rperform} by \cite{GitHub:Rperform}, and -benchmarking packages have extended the ability to analyze performance.} -Typically, the latter option is more prominently used -as the routine's theoretical properties are derived prior to an implementation -being started. Often the main concern regarding an implementation in \rlang relates -to the speed of the algorithm as it impacts how quickly analyses -can be done and reports can be provided to decision makers. Coincidentally, the -speed of code is one of the key governing use cases of \rcppns. Profiling \rlang -code will reveal shortcomings related to loops, _e.g._ `for`, `while`, and `repeat`; -conditional statements, _e.g._ `if`-`else if`-`else` and `switch`; -and recursive functions, _i.e._ a function written in terms of itself such that the -problem is broken down on each call in a reduced state until an answer can be -obtained. In contrast, the overhead for such operations is significantly less -in \cppns. Thus, critical components of a given routine should be written -in \rcpp to capture maximal efficiency. - -Returning to the second question, to decide which -implementation works the best, one needs to employ a benchmark -to obtain _quantifiable results_. Benchmarks are an ideal way to quantify how -well a method performs because they have the ability to show the amount of time the -code has been running and where bottlenecks exist within functions. -This does not imply that benchmarks are completely infallible as user error -can influence the end results. For example, if a user decides -to benchmark code in one \rlang session and in another session performs a heavy -computation, then the benchmark will be biased (if "wall clock" is measured). - -There are different levels of magnification that a benchmark can provide. For a more macro -analysis, one should benchmark data using `benchmark(test = func(), test2 = func2())`, -a function from the \pkg{rbenchmark} \rlang package by \cite{CRAN:rbenchmark}. This form of -benchmarking will be used when the computation is more intensive. -The motivating example `isOdd()` -(which is only able to accept a single `integer`) warrants a much more -microscopic timing comparison. In cases such as this, the objective -is to obtain precise results in the amount of nanoseconds elapsed. Using the -`microbenchmark` function from the \pkg{microbenchmark} \rlang package by -\cite{CRAN:microbenchmark} is more helpful to obtain timing information. -To perform the benchmark: - -```{r microbenchmark_isOdd, dependson=c("isOddR", "isOddRcpp"), eval=FALSE} -library("microbenchmark") -results <- microbenchmark(isOddR = isOddR(12L), - isOddCpp = isOddCpp(12L)) -print(summary(results)[, c(1:7)],digits=1) -``` - -By looking at the summary of 100 evaluations, we note that the -\rcpp function performed better than the equivalent in \rlang by achieving -a lower run time on average. The lower run time in this part is not necessarily -critical as the difference is nanoseconds on a trivial computation. -However, each section of code does contribute to a faster overall runtime. - -# Random Numbers within \rcppns: An Example of _Rcpp Sugar_ - -\rcpp connects \rlang with \cppns. Only the former is vectorized: \cpp is not. -_Rcpp Sugar_, however, provides a convenient way to work with high-performing -\cpp functions in a similar way to how \rlang offers vectorized operations. -The _Rcpp Sugar_ vignette \citep{CRAN:Rcpp:Sugar} details these, as well as -many more functions directly accessible to \rcpp in a way that should feel -familiar to \rlang users. Some examples of _Rcpp Sugar_ functions -include special math functions like gamma and beta, statistical distributions -and random number generation. - -We will illustrate a case of random number generation. Consider drawing one -or more $N(0,1)$-distributed random variables. The very -simplest case can just use `evalCpp()`: - -```{r rnormScalar} -evalCpp("R::rnorm(0, 1)") -``` - -By setting a seed, we can make this reproducible: - -```{r normWithSeed} -set.seed(123) -evalCpp("R::rnorm(0, 1)") -``` - -One important aspect of the behind-the-scenes code generation for the single expression -(as well as all code created via _Rcpp Attributes_) is the automatic preservation of the -state of the random nunber generators in \rlangns. This means that from a given seed, we will -receive _identical_ draws of random numbers whether we access them from \rlang or via \cpp code -accessing the same generators (via the \rcpp interfaces). To illustrate, the -same number is drawn via \rlang code after resetting the seed: - -```{r rnormWithSeedFromR} -set.seed(123) -# Implicit mean of 0, sd of 1 -rnorm(1) -``` - -We can make the _Rcpp Sugar_ -function `rnorm()` accessible from \rlang in the same way to return a vector of values: - -```{r rnormExCpp} -set.seed(123) -evalCpp("Rcpp::rnorm(3)") -``` - -Note that we use the `Rcpp::` namespace explicitly here to -contrast the vectorised `Rcpp::rnorm()` with the scalar `R::rnorm()` -also provided as a convenience wrapper for the \clang API of \rlangns. - -And as expected, this too replicates from \rlang as the very -same generators are used in both cases along with consistent handling -of generator state permitting to alternate: - -```{r rnormExR} -set.seed(123) -rnorm(3) -``` - -# Translating Code from \rlang into \rcppns: Bootstrap Example - -Statistical inference relied primarily upon asymptotic theory until -\cite{Efron:1979:Bootstrap} proposed the bootstrap. Bootstrapping is known -to be computationally intensive due to the need to use loops. Thus, it is an ideal candidate to use as an -example. Before starting to write \cpp code using \rcpp, prototype the code in \rlangns. - -```{r bootstrap_in_r} -# Function declaration -bootstrap_r <- function(ds, B = 1000) { - - # Preallocate storage for statistics - boot_stat <- matrix(NA, nrow = B, ncol = 2) - - # Number of observations - n <- length(ds) - - # Perform bootstrap - for(i in seq_len(B)) { - # Sample initial data - gen_data <- ds[ sample(n, n, replace=TRUE) ] - # Calculate sample data mean and SD - boot_stat[i,] <- c(mean(gen_data), - sd(gen_data)) - } - - # Return bootstrap result - return(boot_stat) -} -``` - -Before continuing, check that the initial prototype \rlang code works. To -do so, write a short \rlang script. Note the use of `set.seed()` to ensure -reproducible draws. - -```{r bootstrap_example} -# Set seed to generate data -set.seed(512) -# Generate data -initdata <- rnorm(1000, mean = 21, sd = 10) -# Set a new _different_ seed for bootstrapping -set.seed(883) -# Perform bootstrap -result_r <- bootstrap_r(initdata) -``` - -Figure \ref{fig:bootstrap-graphs} shows that the bootstrap procedure worked well! - -```{r dist_graphs, echo = FALSE, results = "hide"} -make_boot_graph <- function(ds, actual, type, ylim){ - hist(ds, main = paste(type, "Bootstrap"), xlab = "Samples", - col = "lightblue", lwd = 2, prob = TRUE, ylim = ylim, cex.axis = .85, cex.lab = .90) - abline(v = actual, col = "orange2", lwd = 2) - lines(density(ds)) -} -pdf("figures/bootstrap.pdf", width=6.5, height=3.25) -par(mfrow=c(1,2)) -make_boot_graph(result_r[,1], 21, "Mean", c(0, 1.23)) -make_boot_graph(result_r[,2], 10, "SD", c(0, 1.85)) -dev.off() -``` - -\begin{figure*} - \begin{center} - \includegraphics[width=6.5in, height=3.25in]{figures/bootstrap} - \caption{Results of the bootstrapping procedure for sample mean and variance.} - \label{fig:bootstrap-graphs} - \end{center} -\end{figure*} - -With reassurances that the method to be implemented within \rcpp works -appropriately in \rlangns, proceed to translating the code -into \rcppns. As indicated previously, there are many convergences between \rcpp -syntax and base \rlang via \rcpp Sugar. - - -```{Rcpp bootstrap_in_cpp} -#include - -// Function declaration with export tag -// [[Rcpp::export]] -Rcpp::NumericMatrix -bootstrap_cpp(Rcpp::NumericVector ds, - int B = 1000) { - - // Preallocate storage for statistics - Rcpp::NumericMatrix boot_stat(B, 2); - - // Number of observations - int n = ds.size(); - - // Perform bootstrap - for(int i = 0; i < B; i++) { - // Sample initial data - Rcpp::NumericVector gen_data = - ds[ floor(Rcpp::runif(n, 0, n)) ]; - // Calculate sample mean and std dev - boot_stat(i, 0) = mean(gen_data); - boot_stat(i, 1) = sd(gen_data); - } - - // Return bootstrap results - return boot_stat; -} -``` - -In the \rcpp version of the bootstrap function, there are a few additional -changes that occurred during the translation. In particular, the use of -`Rcpp::runif(n, 0, n)` enclosed by `floor()`, which rounds down to the nearest integer, -in place of `sample(n, n, replace = TRUE)` to sample row ids. This is an -equivalent substitution since equal weight is being placed upon all row ids and -replacement is allowed.\footnote{For more flexibility in sampling see Christian Gunning's -Sample extension for \pkg{RcppArmadillo} and -\href{http://gallery.rcpp.org/articles/using-the-Rcpp-based-sample-implementation/}{Rcpp Gallery: Using the \pkg{RcppArmadillo}-based Implementation of R's sample()} or consider using the \code{Rcpp::sample()} sugar function added in 0.12.9 by Nathan Russell.} -Note that the upper bound of the interval, `n`, will never be reached. While -this may seem flawed, it is important to note that vectors and matrices in -\cpp use a zero-based indexing system, meaning that they begin at 0 instead of 1 -and go up to $n-1$ instead of $n$, which is unlike \rlangns's system. Thus, an -out of bounds error would be triggered if `n` was used as that point does _not_ -exist within the data structure. The application of this logic can be seen -in the span the `for` loop takes in \cpp when compared to \rlangns. Another -syntactical change is the use of `()` in place of `[]` -while accessing the matrix. This change is due to the governance of \cpp -and its comma operator making it impossible to place multiple indices inside -the square brackets. - -To validate that the translation was successful, first run the \cpp function -under the _same_ data and seed as was given for the \rlang function. - -```{r bootstrap_cpp} -# Use the same seed use in R and C++ -set.seed(883) -# Perform bootstrap with C++ function -result_cpp <- bootstrap_cpp(initdata) -``` - -Next, check the output between the functions using \rlang's `all.equal()` function -that allows for an $\varepsilon$-neighborhood around a number. - -```{r check_r_to_cpp} -# Compare output -all.equal(result_r, result_cpp) -``` - -Lastly, make sure to benchmark the newly translated \rcpp function against the -\rlang implementation. As stated earlier, data is paramount to making a decision -related to which function to use in an analysis or package. - -```{r benchmark_r_to_cpp} -library(rbenchmark) - -benchmark(r = bootstrap_r(initdata), - cpp = bootstrap_cpp(initdata))[, 1:4] -``` - -# Using \rcpp as an Interface to External Libraries: Exploring Linear Algebra Extensions - -Many of the previously illustrated \rcpp examples were directed primarily to -show the gains in computational efficiency that are possible by implementing -code directly in \cppns; however, this is only one potential application of \rcppns. -Perhaps one of the most understated features of \rcpp is its ability to -enable \cite{Chambers:2016:ExtR}'s third statement of -_Interfaces to other software are part of \rlangns_. In particular, \rcpp is -designed to facilitate interfacing libraries written in \cpp or \clang to \rlangns. -Hence, if there is a specific feature within a \cpp or \clang library, -then one can create a bridge to it using \rcpp to enable it from within \rlangns. - -An example is the use of \cpp matrix algebra libraries like -\pkg{Armadillo} \citep{Sanderson:2010:Armadillo} - -or \pkg{Eigen} \citep{Eigen:Web}. By outsourcing complex linear -algebra operations to matrix libraries, the need to directly call -functions within \pkg{Linear Algebra PACKage (LAPACK)} -\citep{Anderson:1990:UGLAPACK} is negated. Moreover, the \rcpp design -allows for seamless transfer between object types by using automatic -converters governed by `wrap()`, \cpp to \rlang, and `as()`, \rlang -to \cpp with the `T` indicating the type of object being cast into. -These two helper functions provide a non-invasive way to work with an -external object. Thus, a further benefit to using external \cpp -libraries is the ability to have a portable code base that can be -implemented within a standalone \cpp program or within another -computational language. - - -## Compute RNG draws from a multivariate Normal - -A common application in statistical computing is simulating from a multivariate normal distribution. -The algorithm relies on a linear transformation of the -standard Normal distribution. -Letting $\boldsymbol{Y}_{m \times 1} = \boldsymbol{A}_{m\times n}\boldsymbol{Z}_{n\times 1} + \boldsymbol{b}_{m\times 1}$, -where $\boldsymbol{A}$ is a $m \times n$ matrix, $\boldsymbol{b} \in \mathbb{R}^m$, $\boldsymbol{Z} \sim N(\boldsymbol{0}_{n},\boldsymbol{I}_n)$, -and $\boldsymbol{I}_n$ is the identity matrix, then ${\boldsymbol{Y}} \sim N_{m}\left({\boldsymbol{\mu} = \boldsymbol{b}, \boldsymbol{\Sigma} = \boldsymbol{A}\boldsymbol{A}^T}\right)$. -To obtain the matrix $\boldsymbol{A}$ from $\boldsymbol{\Sigma}$, either a Cholesky or Eigen decomposition -is required. As noted in \citet{Venables+Ripley:2002:MASS}, the Eigen decomposition is more -stable in addition to being more computationally demanding compared to -the Cholesky decomposition. For simplicity and speed, we have opted to implement -the sampling procedure using a Cholesky decomposition. Regardless, there -is a need to involve one of the above matrix libraries to make the sampling -viable in \cppns. - -Here, we demonstrate how to take advantage of the *Armadillo* linear algebra template -classes \citep{Sanderson+Curtin:2016} via the \pkg{RcppArmadillo} package -\citep{Eddelbuettel+Sanderson:2013:RcppArmadillo, CRAN:RcppArmadillo}. Prior to -running this example, the \pkg{RcppArmadillo} package must be installed using -`install.packages('RcppArmadillo')`.\footnote{macOS users may encounter `-lgfortran` -and `-lquadmath` errors on compilations with this package if the development environment -is not appropriately set up. \href{https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-FAQ.pdf}{Section 2.16 of the Rcpp FAQ} provides details regarding the necessary `gfortran` binaries.} -One important caveat when using additional packages -within the \rcpp ecosystem is the correct header file may not be `Rcpp.h`. -In a majority of cases, the additional package ships a dedicated header -(as _e.g._ `RcppArmadillo.h` here) which not only declares data -structures from both systems, but may also add complementary integration and conversion -routines. It typically needs to be listed in an `include` statement along with a -`depends()` attribute to tell \rlang where to find the additional header files: - -```{Rcpp armaDepends, eval = F} -// Use the RcppArmadillo package -// Requires different header file from Rcpp.h -#include -// [[Rcpp::depends(RcppArmadillo)]] -``` - -With this in mind, sampling from a multivariate normal distribution can -be obtained in a straightforward manner. Using only _Armadillo_ -data types and values: - -```{Rcpp rmvnorm, eval = FALSE} -#include -// [[Rcpp::depends(RcppArmadillo)]] - -// Sample N x P observations from a Standard -// Multivariate Normal given N observations, a -// vector of P means, and a P x P cov matrix -// [[Rcpp::export]] -arma::mat rmvnorm(int n, - const arma::vec& mu, - const arma::mat& Sigma) { - unsigned int p = Sigma.n_cols; - - // First draw N x P values from a N(0,1) - Rcpp::NumericVector draw = Rcpp::rnorm(n*p); - - // Instantiate an Armadillo matrix with the - // drawn values using advanced constructor - // to reuse allocated memory - arma::mat Z = arma::mat(draw.begin(), n, p, - false, true); - - // Simpler, less performant alternative - // arma::mat Z = Rcpp::as(draw); - - // Generate a sample from the Transformed - // Multivariate Normal - arma::mat Y = arma::repmat(mu, 1, n).t() + - Z * arma::chol(Sigma); - - return Y; -} -``` - -As a result of using a random number generation (RNG), there is an -additional requirement to ensure reproducible results: the necessity -to explicitly set a seed (as shown above). Because of the -(programmatic) interface provided by \rlang to its own RNGs, this setting of the -seed has to occur at the \rlang level -via the `set.seed()` function as no (public) interface is provided by -the \rlang header files. - - -## Faster linear model fits - -As a second example, consider the problem of estimating a common -linear model repeatedly. One use case might be the -simulation of size and power of standard tests. Many users of \rlang would -default to using `lm()`, however, the overhead associated with this function -greatly impacts speed with which an estimate can be obtained. Another approach -would be to take the base \rlang function `lm.fit()`, which is called by `lm()`, -to compute estimated $\hat{\beta}$ in just about the fastest time possible. -However, this approach is also not viable as it does not report the estimated -standard errors. As a result, we cannot use any default -\rlang functions in the context of simulating finite sample population -effects on inference. - -One alternative is provided by the `fastLm()` function in -\pkg{RcppArmadillo} \citep{CRAN:RcppArmadillo}. - -```{Rcpp fastLm, eval = FALSE} -#include -// [[Rcpp::depends(RcppArmadillo)]] - -// Compute coefficients and their standard error -// during multiple linear regression given a -// design matrix X containing N observations with -// P regressors and a vector y containing of -// N responses -// [[Rcpp::export]] -Rcpp::List fastLm(const arma::mat& X, - const arma::colvec& y) { - // Dimension information - int n = X.n_rows, p = X.n_cols; - // Fit model y ~ X - arma::colvec coef = arma::solve(X, y); - // Compute the residuals - arma::colvec res = y - X*coef; - // Estimated variance of the random error - double s2 = - std::inner_product(res.begin(), res.end(), - res.begin(), 0.0) - / (n - p); - - // Standard error matrix of coefficients - arma::colvec std_err = arma::sqrt(s2 * - arma::diagvec(arma::pinv(X.t()*X))); - - // Create named list with the above quantities - return Rcpp::List::create( - Rcpp::Named("coefficients") = coef, - Rcpp::Named("stderr") = std_err, - Rcpp::Named("df.residual") = n - p ); -} -``` - -The interface is very simple: a matrix $X_{n \times p}$ of regressors, and a -dependent variable $y_{n \times 1}$ as a vector. We invoke the standard Armadillo -function `solve()` to fit the model `y ~ X`.\footnote{We should note -that this will use the standard \pkg{LAPACK} functionality via Armadillo whereas R -uses an internal refinement of \pkg{LINPACK} \citep{Dongarra:1979:UGLINPACK} via pivoting, -rendering the operation numerically more stable. That is an important -robustness aspect---though common datasets on current hardware almost -never lead to actual differences. That said, if in doubt, stick with -the R implementation. What is shown here is mostly for exposition of -the principles.} We then compute residuals, and extract the -(appropriately scaled) diagonal of the covariance matrix, also taking -its square root, in order to return both estimates $\hat{\beta}$ and $\hat{\sigma}$. - -# \rcpp in Packages - -Once a project containing compiled code has matured to the point of sharing it with -collaborators\footnote{It is sometimes said that every project has two collaborators: -self, and future self. Packaging code is \textsl{best practices} even for code not -intended for public uploading.} or using it within a parallel computing environments, the -ideal way forward is to embed the code within an \rlang package. Not only does an \rlang -package provide a way to automatically compile source code, but also enables the use of -the \rlang help system to document how the written functions should be used. As a further -benefit, the package format enables the use of unit tests to ensure that the functions are -producing the correct output. Lastly, having a package provides the option of uploading -to a repository such as CRAN for wider dissemination. - -To facilitate package building, \rcpp provides a function `Rcpp.package.skeleton()` that -is modeled after the base \rlang function `package.skeleton()`. This function automates -the creation of a skeleton package appropriate for distributing \rcppns: - -```{r skeleton, eval = FALSE} -library("Rcpp") -Rcpp.package.skeleton("samplePkg") -``` - -\begin{figure} - \begin{center} - \includegraphics[width=3in]{figures/samplePkg-files-light-bg.png} - \caption{Graphical annotation of the \texttt{is\_odd\_cpp} function.} - \label{fig:package-files} - \end{center} -\end{figure} - - -This shows how distinct directories `man`, `R`, `src` are created for, -respectively, the help pages, files with \rlang code and files with -\cpp code. Generally speaking, all compiled code, be it from \clangns, -\cpp or \fortran sources, should be placed within the `src/` -directory. - -Alternatively, one can achieve similar results to using -`Rcpp.package.skeleton()` by using a feature of the -RStudio IDE. Specifically, while creating a new package project there -is an option to select the type of package by engaging a dropdown menu -to select "Package w/ Rcpp" in RStudio versions prior to v1.1.0. In RStudio -versions later than v1.1.0, support for package templates has been added -allowing users to directly create \rcppns-based packages that use Eigen or Armadillo. - -Lastly, one more option exists for users who are familiar with the \pkg{devtools} -\rlang package. To create the \rlang package skeleton -use `devtools::create("samplePkg")`. From here, part of the -structure required by \rcpp can be added by using `devtools::use_rcpp()`. -The remaining aspects needed by \rcpp must be manually copied from -the roxygen tags written to console and pasted into one of the package's \rlang -files to successfully incorporate the dynamic library and link to \rcppns's -headers. - -All of these methods take care of a number of small settings one would have to enable -manually otherwise. These include an 'Imports:' and 'LinkingTo:' declaration in file -DESCRIPTION, as well as 'useDynLib' and 'importFrom' in NAMESPACE. For _Rcpp Attributes_ -use, the `compileAttributes()` function has to be called. Similarly, to take advantage of -its documentation-creation feature, the `roxygenize()` function from \pkg{roxygen2} has to -be called.\footnote{The \pkg{littler} package \citep{CRAN:littler} has a helper script `roxy.r` -for this.} Additional details on using \rcpp within a package scope are detailed in -\citet{CRAN:Rcpp:Package}. - -# Conclusion - -\rlang has always provided mechanisms to extend it. The bare-bones \clang API is already used -to great effect by a large number of packages. By taking advantage of a number of \cpp -features, \rcpp has been able to make extending \rlang easier, offering a combination of -both speed _and_ ease of use that has been finding increasingly widespread utilization by -researchers and data scientists. We are thrilled about this adoption, and look forward to -seeing more exciting extensions to \rlang being built. diff -Nru rcpp-1.0.2/vignettes/Rcpp-introduction.Rnw rcpp-1.0.3/vignettes/Rcpp-introduction.Rnw --- rcpp-1.0.2/vignettes/Rcpp-introduction.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-introduction.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,11 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-introduction} +%\VignetteKeywords{Rcpp, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-introduction.pdf} +\end{document} + diff -Nru rcpp-1.0.2/vignettes/Rcpp-jss-2011.Rnw rcpp-1.0.3/vignettes/Rcpp-jss-2011.Rnw --- rcpp-1.0.2/vignettes/Rcpp-jss-2011.Rnw 2018-05-05 12:58:40.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-jss-2011.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -1,1079 +1,11 @@ -%% use JSS class -- use 'nojss' to turn off header -\documentclass[shortnames,nojss,article]{jss} -\usepackage{booktabs,flafter,thumbpdf} +\documentclass{article} +\usepackage{pdfpages} %\VignetteIndexEntry{Rcpp-JSS-2011} %\VignetteKeywords{Rcpp, foreign function interface, .Call, C++, R} -%\VignetteDepends{Rcpp} -\SweaveOpts{concordance=FALSE} - -\author{Dirk Eddelbuettel\\Debian Project \And Romain Fran\c{c}ois\\\proglang{R} Enthusiasts} -\Plainauthor{Dirk Eddelbuettel, Romain Fran\c{c}ois} - -\title{\pkg{Rcpp}: Seamless \proglang{R} and \proglang{C++} Integration} -\Plaintitle{Rcpp: Seamless R and C++ Integration} - -\Abstract{ - The \pkg{Rcpp} package simplifies integrating \proglang{C++} code with \proglang{R}. It - provides a consistent \proglang{C++} class hierarchy that maps various types of \proglang{R} - objects (vectors, matrices, functions, environments, \dots) to dedicated \proglang{C++} - classes. Object interchange between \proglang{R} and \proglang{C++} is managed by - simple, flexible and extensible concepts which include broad support for - \proglang{C++} Standard Template Library idioms. \proglang{C++} code can both be - compiled, linked and loaded on the fly, or added via packages. - Flexible error and exception code handling is provided. - \pkg{Rcpp} substantially lowers the barrier for programmers wanting to - combine \proglang{C++} code with \proglang{R}. -} - -\Keywords{\proglang{R}, \proglang{C++}, foreign function interface, \code{.Call}} -\Plainkeywords{R, C++, foreign function interface, .Call} - -\Volume{40} -\Issue{8} -\Month{April} -\Year{2011} -\Submitdate{2010-11-15} -\Acceptdate{2011-03-21} - -\Address{ - Dirk Eddelbuettel \\ - Debian Project \\ - River Forest, IL, United States of America\\ - E-mail: \email{edd@debian.org}\\ - URL: \url{http://dirk.eddelbuettel.com/}\\ - - Romain Fran\c{c}ois\\ - Professional \proglang{R} Enthusiast\\ - 1 rue du Puits du Temple\\ - 34 000 Montpellier, France \\ - E-mail: \email{romain@r-enthusiasts.com}\\ - URL: \url{http://romainfrancois.blog.free.fr/} -} - -%% need no \usepackage{Sweave.sty} - -<>= -library(Rcpp) -rcpp.version <- packageDescription("Rcpp")$Version -rcpp.date <- packageDescription("Rcpp")$Date -now.date <- strftime(Sys.Date(), "%B %d, %Y") -@ -% - +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} \begin{document} - -\vspace*{-0.25cm} - -\section{Introduction} - -\proglang{R} \citep{R:Main} is an extensible system. -The `Writing \proglang{R} Extensions' manual \citep{R:Extensions} -describes in detail how to augment \proglang{R} with compiled code, -focusing mostly on the \proglang{C} language, but also mentioning -\proglang{C++} and \proglang{Fortran}. The \proglang{R} application programming -interface (API) described in `Writing \proglang{R} Extensions' is -based on a set of functions and macros operating on \code{SEXP} (pointers to -\code{SEXPREC} or `\proglang{S} expression' structures, see the `\proglang{R} Language' -manual \citealp{R:Language} for details) which are the internal -representation of \proglang{R} objects. -In this article, we discuss the functionality of the \pkg{Rcpp} -package \citep{CRAN:Rcpp}, which simplifies the usage of \proglang{C++} code -in \proglang{R}. Combining \proglang{R} and \proglang{C++} is not a new idea, so we start with -a short review of other approaches and give some historical -background on the development of \pkg{Rcpp}. - -The \pkg{Rcpp} package provides a consistent API for seamlessly accessing, -extending or modifying \proglang{R} objects at the \proglang{C++} level. The API is a rewritten -and extended version of an earlier API which we refer to as the `classic -\pkg{Rcpp} API'. It is still provided in the \pkg{RcppClassic} package \citep{CRAN:RcppClassic} -to ensure compatibility, but its use is otherwise deprecated. -All new development should use the richer second API which -is enclosed in the \pkg{Rcpp} \proglang{C++} -namespace, and corresponds to the redesigned code base. -This article highlights some of the key design and implementation choices of -the new API: Lightweight encapsulation of \proglang{R} objects in \proglang{C++} classes, automatic -garbage collection strategy, code inlining, data interchange between \proglang{R} and -\proglang{C++}, and error handling. - -Several examples are included to illustrate the benefits of using \pkg{Rcpp} -as opposed to the traditional \proglang{R} API. Many more examples are available within -the package, both as explicit examples and as part of the numerous unit tests. -% -The \pkg{Rcpp} package is available from the Comprehensive \proglang{R} Archive Network (CRAN) -at \url{http://CRAN.R-project.org/package=Rcpp}. - -\makeatletter -\if@nojss - This vignette corresponds to the paper published in the \textsl{Journal of - Statistical Software} (and is still mostly identical to the published paper). - It had been distributed with the \pkg{Rcpp} package as file - \textsf{Rcpp-introduction.pdf} for several years but has now been superceded by - an updated introduction \citep{PeerJ:Rcpp,TAS:Rcpp}. - - For citations, please use the \cite{JSS:Rcpp} or - \cite{Eddelbuettel:2013:Rcpp}; details are also provided in \proglang{R} via - \texttt{citation("Rcpp")}. - - This version corresponds to \pkg{Rcpp} version \Sexpr{rcpp.version} and was - typeset on \Sexpr{now.date}. -\fi -\makeatother - - -\subsection{Historical context} - -\pkg{Rcpp} first appeared in 2005 as a contribution (by Dominick Samperi) to the -\pkg{RQuantLib} package \citep{CRAN:RQuantLib} and became a CRAN package -in early 2006. Several releases (all by Samperi) followed in quick succession -under the name \pkg{Rcpp}. The package was then renamed to -\pkg{RcppTemplate}; several more releases followed during 2006 under the new -name. However, no further releases were made during 2007, 2008 or most of -2009. Following a few updates in late 2009, it was withdrawn from CRAN. - -Given the continued use of the package, Eddelbuettel decided to revitalize it. New -releases, using the initial name \pkg{Rcpp}, started in November 2008. These -included an improved build and distribution process, additional -documentation, and new functionality---while retaining the existing -`classic \pkg{Rcpp}' interface. While not described here, this API will -be provided for the foreseeable future via the \pkg{RcppClassic} package. - -Reflecting evolving \proglang{C++} coding standards \citep[see][]{Meyers:2005:EffectiveC++}, -Eddelbuettel and Fran\c{c}ois started a significant redesign of the -code base in 2009. This added numerous new features several of which are described -in this article as well as in multiple -vignettes included with the package. This new API is our current focus, -and we intend to both extend and support the API in future development of the -\pkg{Rcpp} package. - -\subsection{Related work} - -Integration of \proglang{C++} and \proglang{R} has been addressed by several authors; the earliest -published reference is probably \cite{Bates+DebRoy:2001:C++Classes}. -An unpublished paper by \cite{Java+Gaile+Manly:2007:RCpp} expresses several ideas -that are close to some of our approaches, though not yet fully fleshed out. -The \pkg{Rserve} package \citep{Urbanek:2003:Rserve,CRAN:Rserve} acts as a -socket server for \proglang{R}. On the server side, \pkg{Rserve} translates \proglang{R} data -structures into a binary serialization format and uses TCP/IP for -transfer. On the client side, objects are reconstructed as instances of \proglang{Java} -or \proglang{C++} classes that emulate the structure of \proglang{R} objects. - -The packages \pkg{rcppbind} \citep{Liang:2008:rcppbind}, \pkg{RAbstraction} -\citep{Armstrong:2009:RAbstraction} and \pkg{RObjects} -\citep{Armstrong:2009:RObjects} are all implemented using \proglang{C++} templates. -None of them have matured to the point of a CRAN release. -\pkg{CXXR} \citep{Runnalls:2009:CXXR} approaches this topic from the other direction: -Its aim is to completely refactor \proglang{R} on a stronger \proglang{C++} foundation. -\pkg{CXXR} is therefore concerned with all aspects of the \proglang{R} interpreter, -read-eval-print loop (REPL), and threading; object interchange between \proglang{R} and \proglang{C++} is but one -part. A similar approach is discussed by \cite{TempleLang:2009:ModestProposal} -who suggests making low-level internals extensible by package developers in -order to facilitate extending \proglang{R}. -\cite{TempleLang:2009:RGCCTranslationUnit}, using compiler output for -references on the code in order to add bindings and wrappers, offers -a slightly different angle. - -\subsection[Rcpp use cases]{\pkg{Rcpp} use cases} -\label{sec:classic_rcpp} - -The core focus of \pkg{Rcpp} has always been on helping the -programmer to more easily add \proglang{C++}-based functions. -Here, we use `function' in the standard mathematical sense of providing -results (output) given a set of parameters or data (input). -This was -facilitated from the earliest releases using \proglang{C++} classes for receiving -various types of \proglang{R} objects, converting them to \proglang{C++} objects and allowing the -programmer to return the results to \proglang{R} with relative ease. - -This API therefore supports two typical use cases. First, existing \proglang{R} code -may be replaced by equivalent \proglang{C++} code in order to reap -performance gains. This case is conceptually easy when there are -(built- or run-time) dependencies on other \proglang{C} or \proglang{C++} libraries. It typically -involves setting up data and parameters---the right-hand side components of a -function call---before making the call in order to provide the result that is -to be assigned to the left-hand side. Second, \pkg{Rcpp} facilitates calling -functions provided by other libraries. The use resembles the first case but -with an additional level of abstraction: data -and parameters are passed via \pkg{Rcpp} to a function set-up to call code -from an external library. - -Apart from this `vertical mode' of calling \proglang{C++} from \proglang{R}, additional -features in the new API also support a more `horizontal mode' of directly -calling \pkg{Rcpp} objects. This was motivated by the needs of other -projects such as \pkg{RInside} \citep{CRAN:RInside} for easy embedding of \proglang{R} -in \proglang{C++} applications and \pkg{RProtoBuf} \citep{CRAN:RProtoBuf} to -interface with the Protocol Buffers library. This use will be touched upon -in the next section, but a more detailed discussion is outside the scope of -this paper. Lastly, the more recent additions `\pkg{Rcpp} modules' and `\pkg{Rcpp} sugar' -also expand the use cases; see Section~\ref{sec:ongoing} below. - -\section[The Rcpp API]{The \pkg{Rcpp} API} -\label{sec:new_rcpp} - -\subsection{A first example} - -We can illustrate the \pkg{Rcpp} API by revisiting the convolution example -from the `Writing \proglang{R} Extensions' manual \citep[Chapter 5]{R:Extensions}. Using -\pkg{Rcpp}, this function can be written as follows: -% -\begin{Code} -#include - -RcppExport SEXP convolve3cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a); - Rcpp::NumericVector xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - int nab = n_xa + n_xb - 1; - Rcpp::NumericVector xab(nab); - - for (int i = 0; i < n_xa; i++) - for (int j = 0; j < n_xb; j++) - xab[i + j] += xa[i] * xb[j]; - - return xab; -} -\end{Code} -% -We can highlight several aspects. -\begin{enumerate} -\item Only a single header file - \code{Rcpp.h} is needed to use the \pkg{Rcpp} API. -\item \code{RcppExport} is a convenience macro helping with calling a - \proglang{C} function from \proglang{C++}. -\item Given two - arguments of type \code{SEXP}, a third is returned (as using only - \code{SEXP} types for input and output is prescribed by the \code{.Call()} - interface of the \proglang{R} API). -\item Both inputs are - converted to \proglang{C++} vector types provided by \pkg{Rcpp} (and we have more to say about these - conversions below). -\item The - usefulness of these classes can be seen when we query the vectors directly - for their size---using the \code{size()} member function---in order to - reserve a new result type of appropriate length, - and with the use of the - \verb|operator[]| to extract and set individual elements of the vector. -\item The computation itself is - straightforward embedded looping just as in the original examples in the - `Writing \proglang{R} Extensions' manual \citep{R:Extensions}. -\item The return conversion - from the \code{NumericVector} to the \code{SEXP} type is also automatic. -\end{enumerate} - -We argue that this \pkg{Rcpp}-based usage is much easier to read, write and debug than the -\proglang{C} macro-based approach supported by \proglang{R} itself. - - - -\subsection[Rcpp class hierarchy]{\pkg{Rcpp} class hierarchy} - -The \code{Rcpp::RObject} class is the basic class of the new \pkg{Rcpp} API. -An instance of the \code{RObject} class encapsulates an \proglang{R} object -(itself represented by the \proglang{R} type \code{SEXP}), exposes methods that are appropriate for all types -of objects and transparently manages garbage collection. - -The most important aspect of the \code{RObject} class is that it is -a very thin wrapper around the \code{SEXP} it encapsulates. The -\code{SEXP} is indeed the only data member of an \code{RObject}. The -\code{RObject} class does not interfere with the way \proglang{R} manages its -memory and does not perform copies of the object into a suboptimal -\proglang{C++} representation. Instead, it merely acts as a proxy to the -object it encapsulates so that methods applied to the \code{RObject} -instance are relayed back to the \code{SEXP} in terms of the standard -\proglang{R} API. - -The \code{RObject} class takes advantage of the explicit life cycle of -\proglang{C++} objects to manage exposure of the underlying \proglang{R} object to the -garbage collector. The \code{RObject} effectively treats -its underlying \code{SEXP} as a resource. -The constructor of the \code{RObject} class takes -the necessary measures to guarantee that the underlying \code{SEXP} -is protected from the garbage collector, and the destructor -assumes the responsibility to withdraw that protection. - -By assuming the entire responsibility of garbage collection, \pkg{Rcpp} -relieves the programmer from writing boiler plate code to manage -the protection stack with \code{PROTECT} and \code{UNPROTECT} macros. - -The \code{RObject} class defines a set of member functions applicable -to any \proglang{R} object, regardless of its type. This ranges from -querying properties of the object (\texttt{isNULL}, \texttt{isObject}, -\texttt{isS4}), management of the attributes -(\texttt{attributeNames}, \texttt{hasAttribute}, \texttt{attr}) to -handling of slots\footnote{Member functions dealing with slots -are only applicable to \proglang{S}4 objects; otherwise an exception is thrown.} -(\texttt{hasSlot}, \texttt{slot}). - -\subsection{Derived classes} - -Internally, an \proglang{R} object must have one type amongst the set of -predefined types, commonly referred to as SEXP types. The `\proglang{R} Internals' -manual \citep{R:Internals} documents these various types. -\pkg{Rcpp} associates a dedicated \proglang{C++} class for most SEXP types, and -therefore only exposes functionality that is relevant to the \proglang{R} object -that it encapsulates. - -For example \code{Rcpp::Environment} contains -member functions to manage objects in the associated environment. -Similarly, classes related to vectors---\code{IntegerVector}, \code{NumericVector}, -\code{RawVector}, \code{LogicalVector}, \code{CharacterVector}, -\code{GenericVector} (also known as \code{List}) and -\code{ExpressionVector}---expose functionality to extract and set values from the vectors. - -The following sections present typical uses of \pkg{Rcpp} classes in -comparison with the same code expressed using functions and macros of the \proglang{R} API. - -\subsection{Numeric vectors} - -The next code snippet is taken from `Writing \proglang{R} Extensions' -\citep[Section 5.9.1]{R:Extensions}. It allocates a \code{numeric} vector of two elements -and assigns some values to it using the \proglang{R} API. -% -\begin{Code} -SEXP ab; -PROTECT(ab = allocVector(REALSXP, 2)); -REAL(ab)[0] = 123.45; -REAL(ab)[1] = 67.89; -UNPROTECT(1); -\end{Code} -% -Although this is one of the simplest examples in `Writing \proglang{R} Extensions', -it seems verbose and yet it is not obvious at first sight what is happening. -Memory is allocated by \code{allocVector}; we must also supply it with -the type of data (\code{REALSXP}) and the number of elements. Once -allocated, the \code{ab} object must be protected from garbage -collection. -Lastly, the \code{REAL} macro returns a pointer to the -beginning of the actual array; its indexing does not resemble either \proglang{R} or -\proglang{C++}. - -The code can be simplified using the \code{Rcpp::NumericVector} class: -% -\begin{Code} -Rcpp::NumericVector ab(2); -ab[0] = 123.45; -ab[1] = 67.89; -\end{Code} -% -The code contains fewer idiomatic decorations. The \code{NumericVector} -constructor is given the number of elements the vector contains (2), which -hides the call to the \code{allocVector} in the original code example. Also hidden is -protection of the object from garbage collection, which is a behavior that -\code{NumericVector} inherits from \code{RObject}. Values are assigned to -the first and second elements of the vector as \code{NumericVector} overloads -the \code{operator[]}. - -The snippet can also be written more concisely as a single statement using the \code{create} -static member function of the \code{NumericVector} class: -% -\begin{Code} -Rcpp::NumericVector ab = Rcpp::NumericVector::create(123.45, 67.89); -\end{Code} - - -\subsection{Character vectors} - -A second example deals with character vectors and emulates this \proglang{R} code: -% -\begin{CodeInput} -R> c("foo", "bar") -\end{CodeInput} -% -Using the traditional \proglang{R} API, the vector can be allocated and filled as such: -% -\begin{Code} -SEXP ab; -PROTECT(ab = allocVector(STRSXP, 2)); -SET_STRING_ELT( ab, 0, mkChar("foo") ); -SET_STRING_ELT( ab, 1, mkChar("bar") ); -UNPROTECT(1); -\end{Code} -% -This imposes on the programmer knowledge of \code{PROTECT}, \code{UNPROTECT}, -\code{SEXP}, \code{allocVector}, \code{SET\_STRING\_ELT}, and \code{mkChar}. -% -Using the \code{Rcpp::CharacterVector} class, we can express the same -code more concisely: -% -\begin{Code} -Rcpp::CharacterVector ab(2); -ab[0] = "foo"; -ab[1] = "bar"; -\end{Code} - -\section[R and C++ data interchange]{\proglang{R} and \proglang{C++} data interchange} - -In addition to classes, the \pkg{Rcpp} package contains two -functions to perform conversion of \proglang{C++} objects to \proglang{R} objects and back. - -\subsection[C++ to R: wrap]{\proglang{C++} to \proglang{R}: \code{wrap}} - -The \proglang{C++} to \proglang{R} conversion is performed by the \code{Rcpp::wrap} templated -function. It uses advanced template metaprogramming techniques\footnote{A - discussion of template metaprogramming - \citep{Vandevoorde+Josuttis:2003:Templates,Abrahams+Gurtovoy:2004:TemplateMetaprogramming} is beyond the - scope of this article.} to convert a wide and extensible set of types and -classes to the most appropriate type of \proglang{R} object. The signature of the -\code{wrap} template is as follows: -% -\begin{Code} -template SEXP wrap(const T& object); -\end{Code} -% -The templated function takes a reference to a `wrappable' -object and converts this object into a \code{SEXP}, which is what \proglang{R} expects. -Currently wrappable types are: -\begin{itemize} -\item primitive types: \code{int}, \code{double}, \code{bool}, \dots which are converted -into the corresponding atomic \proglang{R} vectors; -\item \code{std::string} objects which are converted to \proglang{R} atomic character vectors; -\item Standard Template Library (STL) containers such as \code{std::vector} or \code{std::map}, -as long as the template parameter type \code{T} is itself wrappable; -\item STL maps which use \code{std::string} for keys -({e.g.}, \code{std::map}); as long as -the type \code{T} is wrappable; -\item any type that implements implicit conversion to \code{SEXP} through the -\code{operator SEXP()}; -\item any type for which the \code{wrap} template is -fully specialized. -\end{itemize} - -Wrappability of an object type is resolved at compile time using -modern techniques of template meta programming and class traits. The -\code{Rcpp-extending} vignette in the \pkg{Rcpp} package discusses in depth how to extend \code{wrap} -to third-party types. The \pkg{RcppArmadillo} -\citep*{CRAN:RcppArmadillo} and \pkg{RcppGSL} \citep{CRAN:RcppGSL} packages -feature several examples. -The following segment of code illustrates that the design allows -composition: - -\begin{Code} -RcppExport SEXP someFunction() { - std::vector > v; - std::map m1; - std::map m2; - - m1["foo"]=1; - m1["bar"]=2; - m2["foo"]=1; - m2["bar"]=2; - m2["baz"]=3; - - v.push_back( m1 ); - v.push_back( m2 ); - return Rcpp::wrap( v ); -} -\end{Code} -% -In this example, the STL types \verb+vector+ and \verb+map+ are used to -create a list of two named vectors. The member function \verb+push_back+ -insert a given element into a vector. This example is equivalent to the -result of this \proglang{R} statement: -% -\begin{Code} -list(c(bar = 2L, foo = 1L), c(bar = 2L, baz = 3L, foo = 1L)) -\end{Code} - - -\subsection[R to C++: as]{\proglang{R} to \proglang{C++}: \code{as}} - -The reverse conversion from an \proglang{R} object to a \proglang{C++} object is implemented by variations of the -\code{Rcpp::as} template whose signature is: -% -\begin{Code} -template T as(SEXP x); -\end{Code} -% -It offers less flexibility and currently -handles conversion of \proglang{R} objects into primitive types ({e.g.}, \code{bool}, \code{int}, \code{std::string}, \dots), -STL vectors of primitive types ({e.g.}, \code{std::vector}, -\code{std::vector}, \dots) and arbitrary types that offer -a constructor that takes a \code{SEXP}. In addition \code{as} can -be fully or partially specialized to manage conversion of \proglang{R} data -structures to third-party types as can be seen for example in the -\pkg{RcppArmadillo} package which eases transfer of \proglang{R} matrices and vectors to -the optimised data structures in the \pkg{Armadillo} linear algebra library \citep{Sanderson:2010:Armadillo}. - - -\subsection{Implicit use of converters} - -The converters offered by \code{wrap} and \code{as} provide a very -useful framework to implement code logic in terms of \proglang{C++} -data structures and then explicitly convert data back to \proglang{R}. - -In addition, the converters are also used implicitly -in various places in the \code{Rcpp} API. -Consider the following code that uses the \code{Rcpp::Environment} class to -interchange data between \proglang{C++} and \proglang{R}. It accesses a vector -\texttt{x} from the global environment, creates an STL \texttt{map} of string -types and pushes this back to \proglang{R}: -% -\begin{Code} -Rcpp::Environment global = Rcpp::Environment::global_env(); -std::vector vx = global["x"]; - -std::map map; -map["foo"] = "oof"; -map["bar"] = "rab"; - -global["y"] = map; -\end{Code} -% -In the first part of the example, the code extracts a -\code{std::vector} from the global environment. In order to achieve this, -the \code{operator[]} of \code{Environment} uses the proxy pattern -\citep{Meyers:1995:MoreEffectiveC++} -to distinguish between left hand side (LHS) and right hand side (RHS) use. - -The output of the \code{operator[]} is an instance of the nested class -\code{Environment::Binding}. This class defines a templated implicit conversion -operator. It is this conversion operator which allows a \code{Binding} -object to be assigned to any type that \code{Rcpp::as} is able to handle. - -In the last part of the example, the LHS use of the \code{Binding} instance is -implemented through its assignment operator. This is also templated and uses -\code{Rcpp::wrap} to perform the conversion to a \code{SEXP} that can be -assigned to the requested symbol in the global environment. - -The same mechanism is used throughout the API. Examples include access/modification -of object attributes, slots, elements of generic vectors (lists), -function arguments, nodes of dotted pair lists, language calls and more. - -\section{Function calls} -\label{sec:functions} - -\begin{table}[t!] - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Environment: Using the \pkg{Rcpp} API}} - \begin{Code} -Environment stats("package:stats"); -Function rnorm = stats["rnorm"]; -return rnorm(10, - Named("sd", 100.0)); - \end{Code} -\end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Environment: Using the \proglang{R} API}} - \begin{Code} -SEXP stats = PROTECT( - R_FindNamespace( - mkString("stats"))); -SEXP rnorm = PROTECT( - findVarInFrame(stats, - install("rnorm"))); -SEXP call = PROTECT( - LCONS( rnorm, - CONS(ScalarInteger(10), - CONS(ScalarReal(100.0), - R_NilValue)))); -SET_TAG(CDDR(call),install("sd")); -SEXP res = PROTECT(eval(call, - R_GlobalEnv)); -UNPROTECT(4); -return res; - \end{Code} - \end{minipage} - -\bigskip - - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Language: Using the \pkg{Rcpp} API}} - \begin{Code} -Language call("rnorm", 10, - Named("sd",100.0)); -return call.eval(); - \end{Code} - \end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Language: Using the \proglang{R} API}} - \begin{Code} -SEXP call = PROTECT( - LCONS(install("rnorm"), - CONS(ScalarInteger(10), - CONS(ScalarReal(100.0), - R_NilValue)))); -SET_TAG(CDDR(call),install("sd")); -SEXP res = PROTECT(eval(call, - R_GlobalEnv)); -UNPROTECT(2); -return res; - \end{Code} - \end{minipage} - -\bigskip - - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Sugar: Using the \pkg{Rcpp} API}} - \begin{Code} -RNGScope scope; -return rnorm(10, 0, 100); - \end{Code} -\end{minipage} - \begin{minipage}{0.06\linewidth} - \phantom{XXX} - \end{minipage} - \begin{minipage}[t]{0.465\linewidth} - \centering{\underline{Sugar: Using the \proglang{R} API}} - - \medskip - (not applicable) - \end{minipage} - -\bigskip - - \caption{\pkg{Rcpp} versus the \proglang{R} API: Five ways of calling - \code{rnorm(10L, sd = 100)} in \proglang{C}/\proglang{C++}.} - \label{fig:rnormCode} - \medskip \small - Note that we have removed the \code{Rcpp::} prefix for readability; this corresponds to adding a directive - \texttt{using namespace Rcpp;} in the code. The versions that use callbacks to \proglang{R} do not require handling - of the state of the random number generator. The version that uses \pkg{Rcpp} sugar requires it, which - is done via the instantiation of the \code{RNGScope} variable. -\end{table} - -The next example shows how to use \pkg{Rcpp} to emulate the \proglang{R} code -\code{rnorm(10L, sd = 100.0)}. -As shown in Table~\ref{fig:rnormCode}, the code can be expressed in several -ways in either \pkg{Rcpp} or the standard \proglang{R} API. The first version shows the -use of the \code{Environment} and \code{Function} classes by -\pkg{Rcpp}. -The second version shows the use of the \code{Language} class, which -manages calls (LANGSXP). -For comparison, we also show both versions using the standard \proglang{R} API. -Finally, we also show a variant using `\pkg{Rcpp} sugar', a topic which is -discussed in Sections~\ref{sec:perfcomp} and \ref{sec:ongoing} below. - -This example illustrates that the \pkg{Rcpp} API permits us to work with code -that is easier to read, write and maintain. More examples are available as -part of the documentation included in the \pkg{Rcpp} package, as well as -among its over seven hundred and fifty unit tests. - -\section{Using code `inline'} -\label{sec:inline} - -Extending \proglang{R} with compiled code requires a mechanism for reliably compiling, -linking, and loading the code. While using a package is preferable in the long run, -it may be too involved for quick explorations. An alternative is -provided by the \pkg{inline} package \citep{CRAN:inline} which compiles, -links and loads a \proglang{C}, \proglang{C++} or \proglang{Fortran} function---directly from the \proglang{R} prompt -using simple functions \code{cfunction} and \code{cxxfunction}. The latter provides an extension which -works particularly well with \pkg{Rcpp} via so-called `plugins' which provide -information about additional header file and -library locations. - -The use of \pkg{inline} is possible as \pkg{Rcpp} can be installed and -updated just like any other \proglang{R} package using, for examples, the -\code{install.packages()} function for initial installation as well as -\code{update.packages()} for upgrades. So even though \proglang{R}/\proglang{C++} interfacing -would otherwise require source code, the \pkg{Rcpp} library is always provided -ready for use as a pre-built library through the CRAN package -mechanism.\footnote{This presumes a platform for which pre-built binaries are - provided. \pkg{Rcpp} is available in binary form for Windows and OS~X users from - CRAN, and as a \code{.deb} package for Debian and Ubuntu users. For other systems, the - \pkg{Rcpp} library is automatically built from source during installation - or upgrades.} - -The library and header files provided by \pkg{Rcpp} for use by other packages -are installed along with the \pkg{Rcpp} package. The \code{LinkingTo:}~\code{Rcpp} -directive in the \code{DESCRIPTION} file lets \proglang{R} properly reference the header files. -The \pkg{Rcpp} package provides appropriate information for the \code{-L} -switch needed for linking via the function \code{Rcpp:::LdFlags()}. -It can be used by \code{Makevars} files of other -packages, and \pkg{inline} makes use of it internally so that all of this is -done behind the scenes without the need for explicitly setting compiler or -linker options. - -The convolution example provided above can be rewritten for use by -\pkg{inline} as shown below. The function body is provided by the \proglang{R} character -variable \code{src}, the function header is defined by the argument -\code{signature}, and we only need to enable \code{plugin = "Rcpp"} to obtain a -new \proglang{R} function \code{fun} based on the \proglang{C++} code in \code{src}: -% -\begin{CodeChunk} -\begin{CodeInput} -R> src <- ' -+ Rcpp::NumericVector xa(a); -+ Rcpp::NumericVector xb(b); -+ int n_xa = xa.size(), n_xb = xb.size(); -+ -+ Rcpp::NumericVector xab(n_xa + n_xb - 1); -+ for (int i = 0; i < n_xa; i++) -+ for (int j = 0; j < n_xb; j++) -+ xab[i + j] += xa[i] * xb[j]; -+ return xab; -+ ' -R> fun <- cxxfunction(signature(a = "numeric", b = "numeric"), -+ src, plugin = "Rcpp") -R> fun(1:3, 1:4) -\end{CodeInput} -\begin{CodeOutput} -[1] 1 4 10 16 17 12 -\end{CodeOutput} -\end{CodeChunk} -% -With one assignment to the \proglang{R} variable \code{src}, and one call of the \proglang{R} function -\code{cxxfunction} (provided by the \pkg{inline} package), we have created a new \proglang{R} -function \code{fun} that uses the \proglang{C++} code we assigned to -\code{src}---and all this functionality can be used directly from the \proglang{R} -prompt making prototyping with \proglang{C++} functions straightforward. - -\textsl{Update}: \pkg{Rcpp} version 0.10.0 and later contain new and powerful feature -called 'Rcpp Attributes' which provides an even more powerful mechanism; see -\cite{CRAN:Rcpp:Attributes} for more details. - -\section{Using Standard Template Library algorithms} - -The STL offers a variety of generic -algorithms designed to be used on ranges of elements -\citep{Plauger+Et+Al:2000:STL}. A range is any sequence of objects that can be -accessed through iterators or pointers. All \pkg{Rcpp} classes from the new -API representing vectors (including lists) can produce ranges through their -member functions \code{begin()} and \code{end()}, effectively supporting -iterating over elements of an \proglang{R} vector. - -The following code illustrates how \pkg{Rcpp} might be used -to emulate a -simpler\footnote{The version of \code{lapply} does not allow use of the -ellipsis (\code{...}).} version of \code{lapply} -using the \code{transform} algorithm from the STL. -% -\begin{CodeChunk} -\begin{CodeInput} -R> src <- ' -+ Rcpp::List input(data); -+ Rcpp::Function f(fun); -+ Rcpp::List output(input.size()); -+ std::transform(input.begin(), input.end(), output.begin(), f); -+ output.names() = input.names(); -+ return output; -+ ' -R> cpp_lapply <- cxxfunction(signature(data = "list", fun = "function"), -+ src, plugin = "Rcpp") -\end{CodeInput} -\end{CodeChunk} -% -We can now use this \code{cpp_lapply} function to calculate a summary of each -column of the \code{faithful} data set included with \proglang{R}. -% -\begin{CodeInput} -R> cpp_lapply(faithful, summary) -\end{CodeInput} -\begin{CodeOutput} -$eruptions - Min. 1st Qu. Median Mean 3rd Qu. Max. -1.600 2.163 4.000 3.488 4.454 5.100 - -$waiting - Min. 1st Qu. Median Mean 3rd Qu. Max. - 43.0 58.0 76.0 70.9 82.0 96.0 -\end{CodeOutput} - - -\section{Error handling} - -Code that uses both \proglang{R} and \proglang{C++} has to deal with two distinct -error handling models. \pkg{Rcpp} simplifies this and allows both -systems to work together. - -\subsection[C++ exceptions in R]{\proglang{C++} exceptions in \proglang{R}} - -The internals of the \proglang{R} condition mechanism and the implementation of -\proglang{C++} exceptions are both based on a layer above POSIX jumps. These layers -both assume total control over the call stack and should not be used together -without extra precaution. \pkg{Rcpp} contains facilities to combine both systems -so that \proglang{C++} exceptions are caught and recycled into the \proglang{R} condition -mechanism. - -\pkg{Rcpp} defines the \code{BEGIN\_RCPP} and \code{END\_RCPP} macros that should -be used to bracket code that might throw \proglang{C++} exceptions. -% -\begin{Code} -RcppExport SEXP fun( SEXP x ) { -BEGIN_RCPP - int dx = Rcpp::as(x); - if( dx > 10 ) - throw std::range_error("too big"); - return Rcpp::wrap( dx * dx); -END_RCPP -} -\end{Code} -% -The macros are simply defined to avoid code repetition. They expand to -simple \code{try}/\code{catch} blocks so that the above example becomes: -% -\begin{Code} -RcppExport SEXP fun( SEXP x ) { - try { - int dx = Rcpp::as(x); - if( dx > 10 ) - throw std::range_error("too big"); - return Rcpp::wrap( dx * dx); - } catch( std::exception& __ex__ ) { - forward_exception_to_r( __ex__ ); - } catch(...) { - ::Rf_error( "c++ exception (unknown reason)" ); - } -} -\end{Code} -% -Using \code{BEGIN\_RCPP} and \code{END\_RCPP}---or the expanded -versions---guarantees that the stack is first unwound in terms of \proglang{C++} -exceptions, before the problem is converted to the standard \proglang{R} error -management system using the function \code{Rf\_error} of the \proglang{R} API. - -The \code{forward\_exception\_to\_r} function uses run-time type information to -extract information about the class of the \proglang{C++} exception and its message so that -dedicated handlers can be installed on the \proglang{R} side. -% -\begin{CodeChunk} -\begin{CodeInput} -R> f <- function(x) .Call("fun", x) -R> tryCatch(f(12), "std::range_error" = function(e) { conditionMessage(e) }) -\end{CodeInput} -\begin{CodeOutput} -[1] "too big" -\end{CodeOutput} -\begin{CodeInput} -R> tryCatch(f(12), "std::range_error" = function(e) { class(e) }) -\end{CodeInput} -\begin{CodeOutput} -[1] "std::range_error" "C++Error" "error" "condition" -\end{CodeOutput} -\end{CodeChunk} -% -A serious limitation of this approach is the lack of support for calling -handlers. \proglang{R} calling handlers are also based on POSIX jumps, and using both -calling handlers from the \proglang{R} engine as well \proglang{C++} exception forwarding might -lead to undetermined results. Future versions of \pkg{Rcpp} might attempt to -to improve this issue. - -\subsection[R errors in C++]{\proglang{R} errors in \proglang{C++}} - -\proglang{R} itself currently does not offer \proglang{C}-level mechanisms to deal with errors. To -overcome this problem, \pkg{Rcpp} uses the \code{Rcpp\_eval} -function to evaluate an \proglang{R} expression in an R-level \code{tryCatch} -block. The error, if any, that occurs while evaluating the -function is then translated into an \proglang{C++} exception that can be dealt with using -regular \proglang{C++} \code{try}/\code{catch} syntax. - -An open (and rather hard) problem, however, is posed by the fact that calls -into the \proglang{C} API offered by \proglang{R} cannot be reliably protected. Such -calls can always encounter an error condition of their own triggering a call -to \code{Rf_error} which will lead to a sudden death of the program. In -particular, neither \proglang{C++} class destructors nor \code{catch} parts of outer -\code{try}/\code{catch} blocks will be called. This leaves the potential for -memory or resource leakage. So while newly written code can improve on this -situation via use of \proglang{C++} exception handling, existing code calling -into the \proglang{C} API of \proglang{R} cannot be amended just by having an outer layer -of exception handling around it. - - -\section{Performance comparison} -\label{sec:perfcomp} - -In this section, we present several different ways to leverage \pkg{Rcpp} to -rewrite the convolution example from `Writing \proglang{R} Extensions' \citep[Chapter 5]{R:Extensions} -first discussed in Section~\ref{sec:new_rcpp}. -As part of the redesign of \pkg{Rcpp}, data copy is kept to the -absolute minimum: The \code{RObject} class and all its derived -classes are just a container for a \code{SEXP} object. We let \proglang{R} perform -all memory management and access data though the macros or functions -offered by the standard \proglang{R} API. - -The implementation of the \code{operator[]} is designed to be as -efficient as possible, using both inlining and caching, -but even this implementation is still less efficient than the -reference \proglang{C} implementation described in \cite{R:Extensions}. - -\pkg{Rcpp} follows design principles from the STL, and classes such -as \code{NumericVector} expose iterators that can be used for -sequential scans of the data. Algorithms using iterators are -usually more efficient than those that operate on objects using the -\code{operator[]}. The following version of the convolution function -illustrates the use of the \code{NumericVector::iterator}. -% -\begin{Code} -#include - -RcppExport SEXP convolve4cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a), xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - Rcpp::NumericVector xab(n_xa + n_xb - 1); - - typedef Rcpp::NumericVector::iterator vec_iterator; - vec_iterator ia = xa.begin(), ib = xb.begin(); - vec_iterator iab = xab.begin(); - for (int i = 0; i < n_xa; i++) - for (int j = 0; j < n_xb; j++) - iab[i + j] += ia[i] * ib[j]; - - return xab; -} -\end{Code} -% -One of the focuses of recent developments of \pkg{Rcpp} is called `\pkg{Rcpp} sugar', -and aims to provide R-like syntax in \proglang{C++}. While a fuller discussion of \pkg{Rcpp} sugar is -beyond the scope of this article, we have included -another version of the convolution algorithm based on \pkg{Rcpp} sugar for illustrative purposes here: -% -\begin{Code} -#include - -RcppExport SEXP convolve11cpp(SEXP a, SEXP b) { - Rcpp::NumericVector xa(a), xb(b); - int n_xa = xa.size(), n_xb = xb.size(); - Rcpp::NumericVector xab(n_xa + n_xb-1, 0.0); - - Rcpp::Range r( 0, n_xb-1 ); - for (int i=0; i} & 683 & 3.13 \\ - \bottomrule - \end{tabular} - \end{small} - \caption{Run-time performance of the different convolution examples.} - \label{tab:benchmark} - \end{center} -\end{table} - -The first implementation, written in \proglang{C} and using the traditional \proglang{R} API, -provides our base case. It takes advantage of pointer arithmetics and therefore -does not to pay the price of \proglang{C++} object encapsulation or operator overloading. - -The slowest solution illustrates the price of object encapsulation. Calling an overloaded -\code{operator[]} as opposed to using direct pointer arithmetics as in the -reference case costs about 29\% in performance. - -The next implementation uses iterators rather than indexing. Its performance -is indistinguishable from the base case. -This also shows that the use of \proglang{C++} may not necessarily imply any performance -penalty. Further, \proglang{C++} \code{iterators} can be used to achieve the performance -of \proglang{C} pointers, but without the potential dangers of direct memory -access via pointers. - -Finally, the fastest implementation uses \pkg{Rcpp} sugar. It performs -significantly better than the base case. Explicit loop unrolling provides us with -vectorization at the \proglang{C++} level which is responsible for this particular speedup. - -\section{On-going development} -\label{sec:ongoing} - -\pkg{Rcpp} is in very active development: Current work in the -package (and in packages such as \pkg{RcppArmadillo}) -focuses on further improving interoperability between \proglang{R} and \proglang{C++}. -Two core themes for on-going development are `\pkg{Rcpp} sugar' as well as `\pkg{Rcpp} modules', both of which are -also discussed in more detail in specific vignettes in the \pkg{Rcpp} package. - -`\pkg{Rcpp} sugar' offers syntactic -sugar at the \proglang{C++} level, including optimized binary operators and many -\proglang{R} functions such as \code{ifelse}, \code{sapply}, \code{any}, \code{head}, -\code{tail}, and more. -The main technique used in \pkg{Rcpp} sugar is -expression templates pioneered by the \pkg{Blitz++} library \citep{Veldhuizen:1998:Blitz} -and since adopted -by projects such as \pkg{Armadillo} \citep{Sanderson:2010:Armadillo}. -Access to most of the d/p/q/r-variants of the statistical distribution -functions has also been added, enabling the use of expressions such as -\code{dnorm(X, m, s)} for a numeric vector \code{X} and scalars \code{m} and -\code{s}. This was shown in Table~\ref{fig:rnormCode} in -Section~\ref{sec:functions} above where -the \proglang{R} expression \code{rnorm(10L, sd = 100)} -was rewritten in \proglang{C++} as \code{rnorm(10, 0, 100)}. Note that -\proglang{C++} semantics require the second parameter to be used here, which is -different from the \proglang{R} case. - -`\pkg{Rcpp} modules' allows programmers to expose \proglang{C++} functions and classes at the -\proglang{R} level. This offers access to \proglang{C++} code from \proglang{R} using even less interface -code than by writing accessor functions. Modules are inspired by the -\pkg{Boost.Python} library -\citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python} which provides similar -functionality for \proglang{Python}. \proglang{C++} classes exposed by \pkg{Rcpp} modules are -shadowed by reference classes which have been introduced in \proglang{R} 2.12.0. - -\textsl{Update}: Besides the vignettes for '\pkg{Rcpp} Sugar' -\citep{CRAN:Rcpp:Sugar} and '\pkg{Rcpp} Modules' \citep{CRAN:Rcpp:Modules}, -the aforementioned vignette for '\pkg{Rcpp} Attributes' -\citep{CRAN:Rcpp:Attributes} describes a new possibility for even more direct -integration between \proglang{Rcpp} and \proglang{C++}. - -\section{Summary} - -The \pkg{Rcpp} package presented in this paper greatly simplifies integration of -compiled \proglang{C++} code with \proglang{R}. -\pkg{Rcpp} provides a \proglang{C++} class hierarchy which allows manipulation of \proglang{R} data structures in \proglang{C++} -using member functions and operators directly related to the type -of object being used, thereby reducing the level of expertise -required to master the various functions and macros offered by the -internal \proglang{R} API. The classes assume the entire -responsibility of garbage collection of objects, relieving the -programmer from book-keeping operations with the protection stack -and enabling him/her to focus on the underlying problem. - -Data interchange between \proglang{R} and \proglang{C++} code is performed by the \code{wrap()} and -\code{as()} template functions. They allow the programmer to write logic in terms -of \proglang{C++} data structures, and facilitate use of modern libraries such as the -Standard Template Library (STL) and its containers and algorithms. The -\code{wrap()} and \code{as()} template functions are extensible by -design. They are also used either explicitly or implicitly throughout the API. -By using only thin wrappers around \code{SEXP} objects and adopting \proglang{C++} -idioms such as iterators, the footprint of the \pkg{Rcpp} API -is very lightweight, and does not incur a significant performance penalty. - -The \pkg{Rcpp} API offers opportunities to dramatically reduce the complexity -of code, which should lower the initial cost of writing code and improve code readability, maintainability, and -reuse---without incurring noticeable penalties in run-time performance. - -\section*{Acknowledgments} - -Detailed comments and suggestions by editors as well as anonymous referees -are gratefully acknowledged. We are also thankful for code contributions by -Douglas Bates and John Chambers, as well as for very helpful suggestions by Uwe -Ligges, Brian Ripley and Simon Urbanek concerning the build systems for different -platforms. Last but not least, several users provided very fruitful -ideas for new or extended features via the \code{rcpp-devel} mailing list. - -\bibliography{\Sexpr{Rcpp:::bib()}} - -\vspace*{-0.35cm} - +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-jss-2011.pdf} \end{document} -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: diff -Nru rcpp-1.0.2/vignettes/Rcpp-modules.Rmd rcpp-1.0.3/vignettes/Rcpp-modules.Rmd --- rcpp-1.0.2/vignettes/Rcpp-modules.Rmd 2019-03-27 10:06:05.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-modules.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,1233 +0,0 @@ ---- -title: | - | Exposing \proglang{C++} functions and classes - | with \pkg{Rcpp} modules - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note discusses \textsl{Rcpp modules}. \textsl{Rcpp modules} allow programmers to - expose \proglang{C++} functions and classes to \proglang{R} with relative - ease. \textsl{Rcpp modules} are inspired from the \pkg{Boost.Python} - \proglang{C++} library \citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python} - which provides similar features for \proglang{Python}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - modules - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - \newcommand{\ith}{\textsl{i}-\textsuperscript{th}} - -vignette: > - %\VignetteIndexEntry{Rcpp-modules} - %\VignetteKeywords{Rcpp, modules, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Motivation - -Exposing \proglang{C++} functionality to \proglang{R} is greatly facilitated -by the \pkg{Rcpp} package and its underlying \proglang{C++} library -\citep{CRAN:Rcpp,JSS:Rcpp}. \pkg{Rcpp} smoothes many of the rough edges in -\proglang{R} and \proglang{C++} integration by replacing the traditional -\proglang{R} Application Programming Interface (API) described in -'\textsl{Writing R Extensions}' \citep{R:Extensions} with a consistent set of \proglang{C++} -classes. The '\textsl{Rcpp-jss-2011}' vignette \citep{CRAN:Rcpp,JSS:Rcpp} describes the API and -provides an introduction to using \pkg{Rcpp}. - -These \pkg{Rcpp} facilities offer a lot of assistance to the programmer -wishing to interface \proglang{R} and \proglang{C++}. At the same time, these -facilities are limited as they operate on a function-by-function basis. The -programmer has to implement a `.Call` compatible function (to -conform to the \proglang{R} API) using classes of the \pkg{Rcpp} API as -described in the next section. - -## Exposing functions using \pkg{Rcpp} - -Exposing existing \proglang{C++} functions to \proglang{R} through \pkg{Rcpp} -usually involves several steps. One approach is to write an additional wrapper -function that is responsible for converting input objects to the appropriate -types, calling the actual worker function and converting the results back to -a suitable type that can be returned to \proglang{R} (`SEXP`). -Consider the `norm` function below: - -```cpp -double norm( double x, double y ) { - return sqrt( x*x + y*y ); -} -``` - -This simple function does not meet the requirements set by the `.Call` -convention, so it cannot be called directly by \proglang{R}. Exposing the -function involves writing a simple wrapper function -that does match the `.Call` requirements. \pkg{Rcpp} makes this easy. - -```cpp -using namespace Rcpp; -RcppExport SEXP norm_wrapper(SEXP x_, SEXP y_) { - // step 0: convert input to C++ types - double x = as(x_), y = as(y_); - - // step 1: call the underlying C++ function - double res = norm(x, y); - - // step 2: return the result as a SEXP - return wrap(res); -} -``` - -Here we use the (templated) \pkg{Rcpp} converter `as()` which can -transform from a `SEXP` to a number of different \proglang{C++} and -\pkg{Rcpp} types. The \pkg{Rcpp} function `wrap()` offers the opposite -functionality and converts many known types to a `SEXP`. - -This process is simple enough, and is used by a number of CRAN packages. -However, it requires direct involvement from the programmer, which quickly -becomes tiresome when many functions are involved. \textsl{Rcpp modules} -provides a much more elegant and unintrusive way to expose \proglang{C++} -functions such as the `norm` function shown above to \proglang{R}. - -We should note that \pkg{Rcpp} now has \textsl{Rcpp attributes} which extends -certain aspect of \textsl{Rcpp modules} and makes binding to simple functions -such as this one even easier. With \textsl{Rcpp attribues} we can just write - -```cpp -# include - -// [[Rcpp::export]] -double norm(double x, double y) { - return sqrt(x*x + y*y); -} -``` - -See the corresponding vignette \citep{CRAN:Rcpp:Attributes} for details, but -read on for \textsl{Rcpp modules} which contains to provide features not -covered by \textsl{Rcpp attributes}, particularly when it comes to binding -entire C++ classes and more. - -## Exposing classes using Rcpp - -Exposing \proglang{C++} classes or structs is even more of a challenge because it -requires writing glue code for each member function that is to be exposed. - -Consider the simple `Uniform` class below: - -```cpp -class Uniform { -public: - Uniform(double min_, double max_) : - min(min_), max(max_) {} - - NumericVector draw(int n) { - RNGScope scope; - return runif(n, min, max); - } - -private: - double min, max; -}; -``` - -To use this class from R, we at least need to expose the constructor and -the `draw` method. External pointers -\citep{R:Extensions} are the perfect vessel for this, and using the -`Rcpp:::XPtr` template from \pkg{Rcpp} we can expose the class -with these two functions: - -```cpp -using namespace Rcpp; - -/// create external pointer to a Uniform object -RcppExport SEXP Uniform__new(SEXP min_, - SEXP max_) { - // convert inputs to appropriate C++ types - double min = as(min_), - max = as(max_); - - // create pointer to an Uniform object and - // wrap it as an external pointer - Rcpp::XPtr - ptr( new Uniform( min, max ), true ); - - // return the external pointer to the R side - return ptr; -} - -/// invoke the draw method -RcppExport SEXP Uniform__draw(SEXP xp, SEXP n_) { - // grab the object as a XPtr (smart pointer) - // to Uniform - Rcpp::XPtr ptr(xp); - - // convert the parameter to int - int n = as(n_); - - // invoke the function - NumericVector res = ptr->draw( n ); - - // return the result to R - return res; -} -``` - -As it is generally a bad idea to expose external pointers `as is', -they usually get wrapped as a slot of an S4 class. - -Using `cxxfunction()` from the \pkg{inline} package, we can build this -example on the fly. Suppose the previous example code assigned to a text variable -`unifModcode`, we could then do - - - -```{r, eval=FALSE} -f1 <- cxxfunction( , "", includes = unifModCode, - plugin = "Rcpp" ) -getDynLib(f1) ## will display info about 'f1' -``` - -The following listing shows some \textsl{manual} wrapping to access the code, -we will see later how this can be automated: - -```{r, eval=FALSE} -setClass("Uniform", - representation( pointer = "externalptr")) - -# helper -Uniform_method <- function(name) { - paste("Uniform", name, sep = "__") -} - -# syntactic sugar to allow object$method( ... ) -setMethod("$", "Uniform", function(x, name) { - function(...) - .Call(Uniform_method(name) , - x@pointer, ...) -} ) -# syntactic sugar to allow new( "Uniform", ... ) -setMethod("initialize", "Uniform", - function(.Object, ...) { - .Object@pointer <- - .Call(Uniform_method("new"), ...) - .Object -} ) - -u <- new("Uniform", 0, 10) -u$draw( 10L ) -``` - -\pkg{Rcpp} considerably simplifies the code that would -be involved for using external pointers with the traditional \proglang{R} API. -Yet this still involves a lot of mechanical code that quickly -becomes hard to maintain and error prone. -\textsl{Rcpp modules} offer an elegant way to expose the `Uniform` -class in a way that makes both the internal -\proglang{C++} code and the \proglang{R} code easier. - - - -# Rcpp modules - -The design of Rcpp modules has been influenced by \proglang{Python} modules which are generated by the -`Boost.Python` library \citep{Abrahams+Grosse-Kunstleve:2003:Boost.Python}. -Rcpp modules provide a convenient and easy-to-use way -to expose \proglang{C++} functions and classes to \proglang{R}, grouped -together in a single entity. - -A Rcpp module is created in a `cpp` file using the `RCPP_MODULE` -macro, which then provides declarative code of what the module -exposes to \proglang{R}. - -## Exposing \proglang{C++} functions using Rcpp modules - -Consider the `norm` function from the previous section. -We can expose it to \proglang{R} : - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm); -} -``` - -The code creates an Rcpp module called `mod` -that exposes the `norm` function. \pkg{Rcpp} automatically -deduces the conversions that are needed for input and output. This alleviates -the need for a wrapper function using either \pkg{Rcpp} or the \proglang{R} API. - -On the \proglang{R} side, the module is retrieved by using the -`Module` function from \pkg{Rcpp} - -```{r, eval=FALSE} -inc <- ' -using namespace Rcpp; - -double norm( double x, double y ) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm); -} -' - -fx <- cxxfunction(signature(), - plugin="Rcpp", include=inc) -mod <- Module("mod", getDynLib(fx)) -``` - -Note that this example assumed that the previous code segment defining the -module was returned by the `cxxfunction()` (from the \pkg{inline} -package) as callable R function `fx` from which we can extract the -relevant pointer using `getDynLib()`. In the case of using Rcpp modules -via a package (which is detailed in Section \ref{sec:package} below), modules -are actually loaded differently and we would have used - -```{r, eval=FALSE} -require(nameOfMyModulePackage) -mod <- new( mod ) -mod$norm( 3, 4 ) -``` - -where the module is loaded upon startup and we use the constructor -directly. More details on this aspect follow below. - -A module can contain any number of calls to `function` to register -many internal functions to \proglang{R}. For example, these 6 functions : - -```cpp -std::string hello() { - return "hello"; -} - -int bar( int x) { - return x*2; -} - -double foo( int x, double y) { - return x * y; -} - -void bla( ) { - Rprintf("hello\\n"); -} - -void bla1( int x) { - Rprintf("hello (x = %d)\\n", x); -} - -void bla2( int x, double y) { - Rprintf("hello (x = %d, y = %5.2f)\\n", x, y); -} -``` - -can be exposed with the following minimal code: - -```cpp -RCPP_MODULE(yada) { - using namespace Rcpp; - - function("hello" , &hello); - function("bar" , &bar ); - function("foo" , &foo ); - function("bla" , &bla ); - function("bla1" , &bla1 ); - function("bla2" , &bla2 ); -} -``` - -which can then be used from \proglang{R}: - -```{r, eval=FALSE} -require(Rcpp) - -yd <- Module("yada", getDynLib(fx)) -yd$bar(2L) -yd$foo(2L, 10.0) -yd$hello() -yd$bla() -yd$bla1(2L) -yd$bla2(2L, 5.0) -``` - -In the case of a package (as for example the one created by -`Rcpp.package.skeleton()` with argument `module=TRUE`; more on that -below), we can use - -```{r, eval=FALSE} -require(myModulePackage) ## if another name - -bar(2L) -foo(2L, 10.0) -hello() -bla() -bla1(2L) -bla2(2L, 5.0) -``` - - -The requirements for a function to be exposed to \proglang{R} via Rcpp modules -are: - -- The function takes between 0 and 65 parameters. -- The type of each input parameter must be manageable by the `Rcpp::as` template. -- The return type of the function must be either `void` or any type that - can be managed by the `Rcpp::wrap` template. -- The function name itself has to be unique in the module. - In other words, no two functions with - the same name but different signatures are allowed. C++ allows overloading - functions. This might be added in future versions of modules. - -### Documentation for exposed functions using Rcpp modules - -In addition to the name of the function and the function pointer, it is possible -to pass a short description of the function as the third parameter of `function`. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod) { - function("norm", &norm, - "Provides a simple vector norm"); -} -``` - -The description is used when displaying the function to the R prompt: - -```{r, eval=FALSE} -mod <- Module("mod", getDynLib(fx)) -show(mod$norm) -``` - -### Formal arguments specification - -`function` also gives the possibility to specify the formal arguments -of the R function that encapsulates the C++ function, by passing -a `Rcpp::List` after the function pointer. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals) { - function("norm", - &norm, - List::create(_["x"] = 0.0, - _["y"] = 0.0), - "Provides a simple vector norm"); -} -``` - -A simple usage example is provided below: - -```{r, eval=FALSE} -norm <- mod$norm -norm() -norm(y = 2) -norm(x = 2, y = 3) -args(norm) -``` - -To set formal arguments without default values, simply omit the rhs. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals2) { - function("norm", &norm, - List::create(_["x"], _["y"] = 0.0), - "Provides a simple vector norm"); -} -``` - -This can be used as follows: - -```{r, eval=FALSE} -norm <- mod$norm -args(norm) -``` - -The ellipsis (`...`) can be used to denote that additional arguments -are optional; it does not take a default value. - -```cpp -using namespace Rcpp; - -double norm(double x, double y) { - return sqrt(x*x + y*y); -} - -RCPP_MODULE(mod_formals3) { - function("norm", &norm, - List::create(_["x"], _["..."]), - "documentation for norm"); -} -``` - -and from the R side: - -```{r, eval=FALSE} -norm <- mod$norm -args(norm) -``` - - -## Exposing \proglang{C++} classes using Rcpp modules - -Rcpp modules also provide a mechanism for exposing \proglang{C++} classes, based -on the reference classes introduced in R 2.12.0. - -### Initial example - -A class is exposed using the `class_` keyword. The `Uniform` -class may be exposed to \proglang{R} as follows: - -```cpp -using namespace Rcpp; -class Uniform { -public: - Uniform(double min_, double max_) : - min(min_), max(max_) {} - - NumericVector draw(int n) const { - RNGScope scope; - return runif(n, min, max); - } - - double min, max; -}; - -double uniformRange(Uniform* w) { - return w->max - w->min; -} - -RCPP_MODULE(unif_module) { - - class_("Uniform") - - .constructor() - - .field("min", &Uniform::min) - .field("max", &Uniform::max) - - .method("draw", &Uniform::draw) - .method("range", &uniformRange) - ; - -} -``` - -```{r, eval=FALSE} -## assumes fx_unif <- cxxfunction(...) ran -unif_module <- Module("unif_module", - getDynLib(fx_unif)) -Uniform <- unif_module$Uniform -u <- new(Uniform, 0, 10) -u$draw(10L) -u$range() -u$max <- 1 -u$range() -u$draw(10) -``` - -`class_` is templated by the \proglang{C++} class or struct -that is to be exposed to \proglang{R}. -The parameter of the `class_` constructor is the name we will -use on the \proglang{R} side. It usually makes sense to use the same name as the class -name. While this is not enforced, it might be useful when exposing a class -generated from a template. - -Then constructors, fields and methods are exposed. - -### Exposing constructors using Rcpp modules - -Public constructors that take from 0 and 6 parameters can be exposed -to the R level using the `.constuctor` template method of `.class_`. - -Optionally, `.constructor` can take a description as the first argument. - -```cpp - .constructor("sets the min and " - "max value of the distribution") -``` - -Also, the second argument can be a function pointer (called validator) -matching the following type : - -```cpp -typedef bool (*ValidConstructor)(SEXP*,int); -``` - -The validator can be used to implement dispatch to the appropriate constructor, -when multiple constructors taking the same number of arguments are exposed. -The default validator always accepts the constructor as valid if it is passed -the appropriate number of arguments. For example, with the call above, the default -validator accepts any call from R with two `double` arguments (or -arguments that can be cast to `double`). - -TODO: include validator example here - -### Exposing fields and properties - -`class_` has three ways to expose fields and properties, as -illustrated in the example below : - -```cpp -using namespace Rcpp; -class Foo { -public: - Foo(double x_, double y_, double z_): - x(x_), y(y_), z(z_) {} - - double x; - double y; - - double get_z() { return z; } - void set_z(double z_) { z = z_; } - -private: - double z; -}; - -RCPP_MODULE(mod_foo) { - class_( "Foo" ) - - .constructor() - - .field("x", &Foo::x) - .field_readonly("y", &Foo::y) - - .property("z", &Foo::get_z, &Foo::set_z) - ; -} -``` - -The `.field` method exposes a public field with read/write access from R. -`field` accepts an extra parameter to give a short description of the -field: - -```cpp - .field("x", &Foo::x, "documentation for x") -``` - -The `.field_readonly` exposes a public field with read-only access from R. -It also accepts the description of the field. - -```cpp - .field_readonly("y", &Foo::y, - "documentation for y") -``` - -The `.property` method allows indirect access to fields through -a getter and a setter. The setter is optional, and the property is considered -read-only if the setter is not supplied. A description of the property is also -allowed: - -```cpp - // with getter and setter - .property("z", &Foo::get_z, - &Foo::set_z, "Documentation for z") - - // with only getter - .property("z", - &Foo::get_z, "Documentation for z") -``` - -The type of the field (\textbf{T}) is deduced from the return type of the getter, and if a -setter is given its unique parameter should be of the same type. - -Getters can be member functions taking no parameter and returning a \textbf{T} -(for example `get_z` above), or -a free function taking a pointer to the exposed -class and returning a \textbf{T}, for example: - -```cpp -double z_get(Foo* foo) { return foo->get_z(); } -``` - -Setters can be either a member function taking a `T` and returning void, such -as `set_z` above, or a free function taking a pointer to the target -class and a \textbf{T} : - -```cpp -void z_set(Foo* foo, double z) { foo->set_z(z); } -``` - -Using properties gives more flexibility in case field access has to be tracked -or has impact on other fields. For example, this class keeps track of how many times -the `x` field is read and written. - -```cpp -class Bar { -public: - - Bar(double x_) : x(x_), nread(0), nwrite(0) {} - - double get_x() { - nread++; - return x; - } - - void set_x(double x_) { - nwrite++; - x = x_; - } - - IntegerVector stats() const { - return - IntegerVector::create(_["read"] = nread, - _["write"] = nwrite); - } - -private: - double x; - int nread, nwrite; -}; - -RCPP_MODULE(mod_bar) { - class_( "Bar" ) - - .constructor() - - .property( "x", &Bar::get_x, &Bar::set_x ) - .method( "stats", &Bar::stats ) - ; -} -``` - -Here is a simple usage example: - -```{r, eval=FALSE} -Bar <- mod_bar$Bar -b <- new(Bar, 10) -b$x + b$x -b$stats() -b$x <- 10 -b$stats() -``` - -### Exposing methods using Rcpp modules - -`class_` has several overloaded and templated `.method` -functions allowing the programmer to expose a method associated with the class. - -A legitimate method to be exposed by `.method` can be: - -- A public member function of the class, either const or non const, that - returns void or any type that can be handled by `Rcpp::wrap`, and that - takes between 0 and 65 parameters whose types can be handled by `Rcpp::as`. -- A free function that takes a pointer to the target class as its first - parameter, followed by 0 or more (up to 65) parameters that can be handled by - `Rcpp::as` and returning a type that can be handled by `Rcpp::wrap` - or void. - -### Documenting methods - -`.method` can also include a short documentation of the method, after the method -(or free function) pointer. - -```cpp -.method("stats", &Bar::stats, - "vector indicating the number of " - "times x has been read and written") -``` - -TODO: mention overloading, need good example. - - -### Const and non-const member functions - -`method` is able to expose both `const` and `non const` -member functions of a class. There are however situations where -a class defines two versions of the same method, differing only in their -signature by the `const`-ness. It is for example the case of the -member functions `back` of the `std::vector` template from -the STL. - -```cpp -reference back ( ); -const_reference back ( ) const; -``` - -To resolve the ambiguity, it is possible to use `const_method` -or `nonconst_method` instead of `method` in order -to restrict the candidate methods. - -### Special methods - -\pkg{Rcpp} considers the methods `[[` and `[[<-` special, -and promotes them to indexing methods on the \proglang{R} side. - -### Object finalizers - -The `.finalizer` member function of `class_` can be used to -register a finalizer. A finalizer is a free function that takes a pointer -to the target class and return `void`. The finalizer is called -before the destructor and so operates on a valid object of the target class. - -It can be used to perform operations, releasing resources, etc ... - -The finalizer is called automatically when the \proglang{R} object that encapsulates -the \proglang{C++} object is garbage collected. - -### Object factories - -The `.factory` member function of `class_` can be used to register a -[factory](https://en.wikipedia.org/wiki/Factory_method_pattern) that -can be used as alternative to a constructor. A factory can be a -static member function or a free function that returns a pointer to -the target class. Typical use-cases include creating objects in a -hierarchy: - -```cpp -#include -using namespace Rcpp; - -// abstract class -class Base { - public: - virtual ~Base() {} - virtual std::string name() const = 0; -}; - -// first derived class -class Derived1: public Base { - public: - Derived1() : Base() {} - virtual std::string name() const { - return "Derived1"; - } -}; - -// second derived class -class Derived2: public Base { - public: - Derived2() : Base() {} - virtual std::string name() const { - return "Derived2"; - } -}; - -Base *newBase( const std::string &name ) { - if (name == "d1"){ - return new Derived1; - } else if (name == "d2"){ - return new Derived2; - } else { - return 0; - } -} - -RCPP_MODULE(mod) { - Rcpp::class_< Base >("Base") - .factory(newBase) - .method("name", &Base::name); -} -``` - -The `newBase` method returns a pointer to a `Base` object. Since that -class is an abstract class, the objects are actually instances of -`Derived1` or `Derived2`. The same behavior is now available in R: - -```{r, eval=FALSE} -dv1 <- new(Base, "d1") -dv1$name() # returns "Derived1" -dv2 <- new(Base, "d2") -dv2$name() # returns "Derived2" -``` - -### S4 dispatch - -When a \proglang{C++} class is exposed by the `class_` template, -a new S4 class is registered as well. The name of the S4 class is -obfuscated in order to avoid name clashes (i.e. two modules exposing the -same class). - -This allows implementation of \proglang{R}-level -(S4) dispatch. For example, one might implement the `show` -method for \proglang{C++} `World` objects: - -```{r, eval=FALSE} -setMethod("show", yada$World , function(object) { - msg <- paste("World object with message : ", - object$greet()) - writeLines(msg) -} ) -``` - -TODO: mention R inheritance (John ?) - -### Extending `Rcpp::as` and `Rcpp::wrap` - -Sometimes it is necessary to extend `Rcpp::as` or `Rcpp::wrap` for -classes that are also exposed using Rcpp modules. Instead of using the -general methods described in the _Rcpp Extending_ vignette, one can -use the `RCPP_EXPOSED_AS` or `RCPP_EXPOSED_WRAP` macros. -Alternatively the `RCPP_EXPOSED_CLASS` macro defines both `Rcpp::as` -and `Rcpp::wrap` specializations. Do not use these macros together -with the generic extension mechanisms. Note that opposesd to the -generic methods, these macros can be used _after_ `Rcpp.h` has been -loaded. Here an example of a pair of Rcpp modules exposed classes -where one of them has a method taking an instance of the other class -as argument. In this case it is suffcient to use `RCPP_EXPOSED_AS` to -enable the transparent conversion from \proglang{R} to \proglang{C++}: - -```cpp -#include - -class Foo { -public: - Foo() = default; -}; - -class Bar { -public: - Bar() = default; - void handleFoo(Foo foo) { - Rcpp::Rcout << "Got a Foo!" << std::endl; - }; -}; - -RCPP_EXPOSED_AS(Foo) - -RCPP_MODULE(Foo){ - Rcpp::class_("Foo") - .constructor(); -} - -RCPP_MODULE(Barl){ - Rcpp::class_("Bar") - .constructor() - .method("handleFoo", &Bar::handleFoo); -} -``` - -```{r, eval=FALSE} -foo <- new(Foo) -bar <- new(Bar) -bar$handleFoo(foo) -#> Got a Foo! -``` - -### Full example - - - -The following example illustrates how to use Rcpp modules to expose -the class `std::vector` from the STL. - -```cpp -typedef std::vector vec; -void vec_assign(vec* obj, - Rcpp::NumericVector data) { - obj->assign(data.begin(), data.end()); -} -void vec_insert(vec* obj, int position, - Rcpp::NumericVector data) { - vec::iterator it = obj->begin() + position; - obj->insert(it, data.begin(), data.end()); -} -Rcpp::NumericVector vec_asR( vec* obj ) { - return Rcpp::wrap( *obj ); -} -void vec_set(vec* obj, int i, double value) { - obj->at( i ) = value; -} - -RCPP_MODULE(mod_vec) { - using namespace Rcpp; - - // we expose class std::vector - // as "vec" on the R side - class_("vec") - - // exposing constructors - .constructor() - .constructor() - - // exposing member functions - .method("size", &vec::size) - .method("max_size", &vec::max_size) - .method("resize", &vec::resize) - .method("capacity", &vec::capacity) - .method("empty", &vec::empty) - .method("reserve", &vec::reserve) - .method("push_back", &vec::push_back) - .method("pop_back", &vec::pop_back) - .method("clear", &vec::clear) - - // exposing const member functions - .const_method("back", &vec::back) - .const_method("front", &vec::front) - .const_method("at", &vec::at ) - - // exposing free functions taking a - // std::vector* as their first - // argument - .method("assign", &vec_assign) - .method("insert", &vec_insert) - .method("as.vector", &vec_asR) - - // special methods for indexing - .const_method("[[", &vec::at) - .method("[[<-", &vec_set) - ; -} -``` - -```{r, eval=FALSE} -# for code compiled on the fly using -# cxxfunction() into 'fx_vec', we use -mod_vec <- Module("mod_vec", - getDynLib(fx_vec), - mustStart = TRUE) -vec <- mod_vec$vec -# and that is not needed in a package -# setup as e.g. one created -# via Rcpp.package.skeleton(..., module=TRUE) -v <- new(vec) -v$reserve(50L) -v$assign(1:10) -v$push_back(10) -v$size() -v$capacity() -v[[ 0L ]] -v$as.vector() -``` - -# Using modules in other packages {#sec:package} - -## Namespace import/export - -### Import all functions and classes - -When using \pkg{Rcpp} modules in a packages, the client package needs to -import \pkg{Rcpp}'s namespace. This is achieved by adding the -following line to the `NAMESPACE` file. - -```{r, echo=FALSE,eval=TRUE} -options( prompt = " ", continue = " " ) -``` - -```{r, eval=FALSE} -import(Rcpp) -``` - -In some case we have found that explicitly naming a symbol can be preferable: - -```{r, eval=FALSE} -import(Rcpp, evalCpp) -``` - -## Load the module - -### Deprecated older method using loadRcppModules - -Note: This approach is deprecated as of Rcpp 0.12.5, and now triggers a warning -message. Eventually this function will be withdrawn. - -The simplest way to load all functions and classes from a module directly -into a package namespace used to be to use the `loadRcppModules` function -within the `.onLoad` body. - -```{r, eval=FALSE} -.onLoad <- function(libname, pkgname) { - loadRcppModules() -} -``` - -This will look in the package's DESCRIPTION file for the `RcppModules` -field, load each declared module and populate their contents into the -package's namespace. For example, both the \pkg{testRcppModule} package -(which is part of large unit test suite for \pkg{Rcpp}) and the package -created via `Rcpp.package.skeleton("somename", module=TRUE)` have this -declaration: - -``` -RcppModules: yada, stdVector, NumEx -``` - -The `loadRcppModules` function has a single argument `direct` -with a default value of `TRUE`. With this default value, all content -from the module is exposed directly in the package namespace. If set to -`FALSE`, all content is exposed as components of the module. - -### Preferred current method using loadModule - -Starting with release 0.9.11, an alternative is provided by the -`loadModule()` function which takes the module name as an argument. -It can be placed in any `.R` file in the package. This is useful as it allows to load -the module from the same file as some auxiliary \proglang{R} functions using the -module. For the example module, the equivalent code to the `.onLoad()` -use shown above then becomes - -```{r, eval=FALSE} -loadModule("yada") -loadModule("stdVector") -loadModule("NumEx") -``` - -This feature is also used in the new Rcpp Classes introduced with Rcpp 0.9.11. - -### Just expose the module - -Alternatively, it is possible to just expose the module to the user of the package, -and let them extract the functions and classes as needed. This uses lazy loading -so that the module is only loaded the first time the user attempts to extract -a function or a class with the dollar extractor. - -```{r, eval=FALSE} -yada <- Module( "yada" ) - -.onLoad <- function(libname, pkgname) { - # placeholder -} -``` - -```{r, echo=FALSE,eval=TRUE} -options(prompt = "> ", continue = "+ ") -``` - - -## Support for modules in skeleton generator - -The `Rcpp.package.skeleton` function has been improved to help -\pkg{Rcpp} modules. When the `module` argument is set to `TRUE`, -the skeleton generator installs code that uses a simple module. - -```{r, eval=FALSE} -Rcpp.package.skeleton("testmod", module = TRUE) -``` - -Creating a new package using \textsl{Rcpp modules} is easiest via the call to -`Rcpp.package.skeleton()` with argument `module=TRUE` as a working -package with three example Modules results. - -## Module documentation - -\pkg{Rcpp} defines a `prompt` method for the -`Module` class, allowing generation of a skeleton of an Rd -file containing some information about the module. - -```{r, eval=FALSE} -yada <- Module("yada") -prompt(yada, "yada-module.Rd") -``` - -We strongly recommend using a package when working with Modules. But in case a -manually compiled shared library has to loaded, the return argument of the -`getDynLib()` function can be supplied as the `PACKAGE` argument to -the `Module()` function as well. - - -# Future extensions {#sec:future} - -`Boost.Python` has many more features that we would like to port -to Rcpp modules : class inheritance, default arguments, enum -types, ... - -# Known shortcomings {#sec:misfeatures} - -There are some things \textsl{Rcpp modules} is not good at: - -- serialization and deserialization of objects: modules are - implemented via an external pointer using a memory location, which is - non-constant and varies between session. Objects have to be re-created, - which is different from the (de-)serialization that R offers. So these - objects cannot be saved from session to session. -- mulitple inheritance: currently, only simple class structures are - representable via \textsl{Rcpp modules}. - -# Summary - -This note introduced \textsl{Rcpp modules} and illustrated how to expose -\proglang{C++} function and classes more easily to \proglang{R}. -We hope that \proglang{R} and \proglang{C++} programmers -find \textsl{Rcpp modules} useful. - - diff -Nru rcpp-1.0.2/vignettes/Rcpp-modules.Rnw rcpp-1.0.3/vignettes/Rcpp-modules.Rnw --- rcpp-1.0.2/vignettes/Rcpp-modules.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-modules.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-modules} +%\VignetteKeywords{Rcpp, modules, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-modules.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp-package.Rmd rcpp-1.0.3/vignettes/Rcpp-package.Rmd --- rcpp-1.0.2/vignettes/Rcpp-package.Rmd 2017-11-04 19:04:52.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-package.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,491 +0,0 @@ ---- -title: Writing a package that uses \pkg{Rcpp} - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document provides a short overview of how to use - \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} when writing - an \proglang{R} package. It shows how usage of the function - \rdoc{Rcpp}{Rcpp.package.skeleton} which creates a complete and - self-sufficient example package using \pkg{Rcpp}. All components of the - directory tree created by \rdoc{Rcpp}{Rcpp.package.skeleton} are discussed - in detail. This document thereby complements the \textsl{Writing R - Extensions} manual \citep{R:Extensions} which is the authoritative source - on how to extend \proglang{R} in general. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - package - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - -vignette: > - %\VignetteIndexEntry{Rcpp-package} - %\VignetteKeywords{Rcpp, package, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - - -# Introduction - -\pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp} is an extension -package for \proglang{R} which offers an easy-to-use yet featureful interface -between \proglang{C++} and \proglang{R}. However, it is somewhat different -from a traditional \proglang{R} package because its key component is a -\proglang{C++} library. A client package that wants to make use of the -\pkg{Rcpp} features must link against the library provided by \pkg{Rcpp}. - -It should be noted that \proglang{R} has only limited support for -\proglang{C(++)}-level dependencies between packages \citep{R:Extensions}. The -`LinkingTo` declaration in the package `DESCRIPTION` file -allows the client package to retrieve the headers of the target package (here -\pkg{Rcpp}), but support for linking against a library is not provided by -\proglang{R} and has to be added manually. - -This document follows the steps of the \rdoc{Rcpp}{Rcpp.package.skeleton} -function to illustrate a recommended way of using \pkg{Rcpp} from a client -package. We illustrate this using a simple \proglang{C++} function -which will be called by an \proglang{R} function. - -We strongly encourage the reader to become familiar with the material in the -\textsl{Writing R Extensions} manual \citep{R:Extensions}, as well as with other -documents on \proglang{R} package creation such as \cite{Leisch:2008:Tutorial}. Given -a basic understanding of how to create \proglang{R} package, the present -document aims to provide the additional information on how to use \pkg{Rcpp} -in such add-on packages. - -# Using `Rcpp.package.skeleton` - -## Overview - -\pkg{Rcpp} provides a function \rdoc{Rcpp}{Rcpp.package.skeleton}, modeled -after the base \proglang{R} function \rdoc{utils}{package.skeleton}, which -facilitates creation of a skeleton package using \pkg{Rcpp}. - -\rdoc{Rcpp}{Rcpp.package.skeleton} has a number of arguments documented on -its help page (and similar to those of \rdoc{utils}{package.skeleton}). The -main argument is the first one which provides the name of the package one -aims to create by invoking the function. An illustration of a call using an -argument `mypackage` is provided below. - -```r -Rcpp.package.skeleton("mypackage") -``` - -\begin{ShadedResult} -\begin{verbatim} -$ ls -1R mypackage/ -DESCRIPTION -NAMESPACE -R -Read-and-delete-me -man -src - -mypackage/R: -RcppExports.R - -mypackage/man: -mypackage-package.Rd -rcpp_hello_world.Rd - -mypackage/src: -Makevars # until Rcpp 0.10.6, see below -Makevars.win # until Rcpp 0.10.6, see below -RcppExports.cpp -rcpp_hello_world.cpp -$ -\end{verbatim} -\end{ShadedResult} - -Using \rdoc{Rcpp}{Rcpp.package.skeleton} is by far the simplest approach -as it fulfills two roles. It creates the complete set of files needed for a -package, and it also includes the different components needed for using -\pkg{Rcpp} that we discuss in the following sections. - -## \proglang{C++} code - -If the `attributes` argument is set to `TRUE`[^1], the -following \proglang{C++} file is included in the `src/` directory: - -```cpp -#include -using namespace Rcpp; - -// [[Rcpp::export]] -List rcpp_hello_world() { - - CharacterVector x = - CharacterVector::create("foo", "bar"); - NumericVector y = - NumericVector::create( 0.0, 1.0 ) ; - List z = List::create( x, y ) ; - - return z ; -} -``` - -The file defines the simple `rcpp_hello_world` function that -uses a few \pkg{Rcpp} classes and returns a `List`. - -This function is preceded by the `Rcpp::export` attribute to automatically -handle argument conversion because \proglang{R} has to be taught how to -e.g. handle the `List` class. - -\rdoc{Rcpp}{Rcpp.package.skeleton} then invokes \rdoc{Rcpp}{compileAttributes} -on the package, which generates the `RcppExports.cpp` file (where we indented -the first two lines for the more compact display here): - -```rcpp -// Generated by using Rcpp::compileAttributes() \ -// -> do not edit by hand -// Generator token: \ -// 10BE3573-1514-4C36-9D1C-5A225CD40393 - -#include - -using namespace Rcpp; - -// rcpp_hello_world -List rcpp_hello_world(); -RcppExport SEXP mypackage_rcpp_hello_world() { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - rcpp_result_gen = - Rcpp::wrap(rcpp_hello_world()); - return rcpp_result_gen; -END_RCPP -} -``` - -This file defines a function with the appropriate calling convention, suitable for -\rdoc{base}{.Call}. It needs to be regenerated each time functions -exposed by attributes are modified. This is the task of the -\rdoc{Rcpp}{compileAttributes} function. A discussion on attributes is -beyond the scope of this document and more information is available -in the attributes vignette \citep{CRAN:Rcpp:Attributes}. - -## \proglang{R} code - -The \rdoc{Rcpp}{compileAttributes} also generates \proglang{R} code -that uses the \proglang{C++} function. - -```r -# Generated by using Rcpp::compileAttributes() \ -# -> do not edit by hand -# Generator token: \ -# 10BE3573-1514-4C36-9D1C-5A225CD40393 - -rcpp_hello_world <- function() { - .Call('mypackage_rcpp_hello_world', - PACKAGE = 'mypackage') -} -``` - -This is also a generated file so it should not be modified manually, rather -regenerated as needed by \rdoc{Rcpp}{compileAttributes}. - -## `DESCRIPTION` - -The skeleton generates an appropriate `DESCRIPTION` file, using -both `Imports:` and `LinkingTo` for \pkg{Rcpp}: - -\begin{ShadedResult} -\begin{verbatim} -Package: mypackage -Type: Package -Title: What the package does (short line) -Version: 1.0 -Date: 2013-09-17 -Author: Who wrote it -Maintainer: Who -Description: More about what it does (maybe - more than one line) -License: What Licence is it under ? -Imports: Rcpp (>= 0.11.0) -LinkingTo: Rcpp -\end{verbatim} -\end{ShadedResult} - - -\rdoc{Rcpp}{Rcpp.package.skeleton} adds the three last lines to the -`DESCRIPTION` file generated by \rdoc{utils}{package.skeleton}. - -The `Imports` declaration indicates \proglang{R}-level dependency -between the client package and \pkg{Rcpp}; code from the latter is being -imported into the package described here. The `LinkingTo` declaration -indicates that the client package needs to use header files exposed by -\pkg{Rcpp}. - -## Now optional: `Makevars` and `Makevars.win` - -This behaviour changed with \pkg{Rcpp} release 0.11.0. These files used to be -mandatory, now they are merely optional. - -We will describe the old setting first as it was in use for a few years. The -new standard, however, is much easier and is described below. - -## Releases up until 0.10.6 - -Unfortunately, the `LinkingTo` declaration in itself was not -enough to link to the user \proglang{C++} library of \pkg{Rcpp}. Until more -explicit support for libraries is added to \proglang{R}, ones needes to manually -add the \pkg{Rcpp} library to the `PKG_LIBS` variable in the -`Makevars` and `Makevars.win` files. (This has now changed with -release 0.11.0; see below). -\pkg{Rcpp} provides the unexported function `Rcpp:::LdFlags()` to ease the process: - -```sh -## Use the R_HOME indirection to support -## installations of multiple R version -## -## NB: No longer needed, see below -PKG_LIBS = `$(R_HOME)/bin/Rscript -e \ - "Rcpp:::LdFlags()"` - -``` - -The `Makevars.win` is the equivalent, targeting windows. - -```sh -## Use the R_HOME indirection to support -## installations of multiple R version -## -## NB: No longer needed, see below -PKG_LIBS = $(shell \ - "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" \ - -e "Rcpp:::LdFlags()") -``` - -## Releases since 0.11.0 - -As of release 0.11.0, this is no longer needed as client packages obtain the -required code from \pkg{Rcpp} via explicit function registration. The user -does not have to do anything. - -This means that `PKG_LIBS` can now be empty---unless some client -libraries are needed. For example, \pkg{RcppCNPy} needs compression support -and hence uses `PKG_LIBS= -lz`. Similarly, when a third-party library is -required, it can and should be set here. - -## `NAMESPACE` - -The \rdoc{Rcpp}{Rcpp.package.skeleton} function also creates a file -`NAMESPACE`. - -```sh -useDynLib(mypackage) -exportPattern("^[[:alpha:]]+") -importFrom(Rcpp, evalCpp) -``` - -This file serves three purposes. First, it ensure that the dynamic library -contained in the package we are creating via -\rdoc{Rcpp}{Rcpp.package.skeleton} will be loaded and thereby made -available to the newly created \proglang{R} package. - -Second, it declares which functions should be globally visible from the -namespace of this package. As a reasonable default, we export all functions. - -Third, it instructs R to import a symbol from \pkg{Rcpp}. This sets up the -import of all registered function and, together with the `Imports:` -statement in `DESCRIPTION`, provides what is needed for client packages -to access \pkg{Rcpp} functionality. - -## Help files - -Also created is a directory `man` containing two help files. One is -for the package itself, the other for the (single) \proglang{R} function -being provided and exported. - -The \textsl{Writing R Extensions} manual \citep{R:Extensions} provides the complete -documentation on how to create suitable content for help files. - -## `mypackage-package.Rd` - -The help file `mypackage-package.Rd` can be used to describe -the new package (and we once again indented some lines): - -```sh -\name{mypackage-package} -\alias{mypackage-package} -\alias{mypackage} -\docType{package} -\title{ -What the package does (short line) -} -\description{ -More about what it does (maybe more than one line) -~~ A concise (1-5 lines) description of the -package ~~ -} -\details{ -\tabular{ll}{ -Package: \tab mypackage\cr -Type: \tab Package\cr -Version: \tab 1.0\cr -Date: \tab 2013-09-17\cr -License: \tab What license is it under?\cr -} -~~ An overview of how to use the package, -including the most important functions ~~ -} -\author{ -Who wrote it - -Maintainer: Who -} -\references{ -~~ Literature or other references for -background information ~~ -} -~~ Optionally other standard keywords, one per -line, from file KEYWORDS in the R -documentation directory ~~ -\keyword{ package } -\seealso{ -~~ Optional links to other man pages, e.g. ~~ -~~ \code{\link[:-package]{}} ~~ -} -\examples{ -%% ~~ simple examples of the most important -%% functions ~~ -} -``` - -## `rcpp_hello_world.Rd` - -The help file `rcpp_hello_world.Rd` serves as documentation for the -example \proglang{R} function. - -```sh -\name{rcpp_hello_world} -\alias{rcpp_hello_world} -\docType{package} -\title{ -Simple function using Rcpp -} -\description{ -Simple function using Rcpp -} -\usage{ -rcpp_hello_world() -} -\examples{ -\dontrun{ -rcpp_hello_world() -} -} -``` - -# Using modules - -This document does not cover the use of the `module` argument -of \rdoc{Rcpp}{Rcpp.package.skeleton}. It is covered -in the modules vignette \citep{CRAN:Rcpp:Modules}. - -# Further examples - -The canonical example of a package that uses \pkg{Rcpp} is the -\pkg{RcppExamples} \citep{CRAN:RcppExamples} package. \pkg{RcppExamples} -contains various examples of using \pkg{Rcpp}. Hence, the \pkg{RcppExamples} -package is provided as a template for employing \pkg{Rcpp} in packages. - -Other CRAN packages using the \pkg{Rcpp} package are \pkg{RcppArmadillo} -\citep{CRAN:RcppArmadillo}, -and \pkg{minqa} \citep{CRAN:minqa}. Several other packages follow older (but still supported -and appropriate) instructions. They can serve examples on how to get data to -and from \proglang{C++} routines, but should not be considered templates for -how to connect to \pkg{Rcpp}. The full list of packages using \pkg{Rcpp} can -be found at the [CRAN page](http://CRAN.R-project.org/package=Rcpp) of -\pkg{Rcpp}. - -# Other compilers - -Less experienced \proglang{R} users on the Windows platform frequently ask -about using \pkg{Rcpp} with the Visual Studio toolchain. That is simply not -possible as \proglang{R} is built with the \pkg{gcc} compiler. Different -compilers have different linking conventions. These conventions are -particularly hairy when it comes to using \proglang{C++}. In short, it is -not possible to simply drop sources (or header files) from \pkg{Rcpp} into a -\proglang{C++} project built with Visual Studio, and this note makes no -attempt at claiming otherwise. - -\pkg{Rcpp} is fully usable on Windows provided the standard Windows -toolchain for \proglang{R} is used. See the \textsl{Writing R Extensions} -manual \citep{R:Extensions} for details. - -# Summary - -This document described how to use the \pkg{Rcpp} package for \proglang{R} -and \proglang{C++} integration when writing an \proglang{R} extension -package. The use of the \rdoc{Rcpp}{Rcpp.package.skeleton} was shown in -detail, and references to further examples were provided. - -[^1]: Setting `attributes` to `TRUE` is the default. This document - does not cover the behavior of `Rcpp.package.skeleton` when `attributes` is set - to `FALSE` as we try to encourage package developpers to use - attributes. diff -Nru rcpp-1.0.2/vignettes/Rcpp-package.Rnw rcpp-1.0.3/vignettes/Rcpp-package.Rnw --- rcpp-1.0.2/vignettes/Rcpp-package.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-package.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-package} +%\VignetteKeywords{Rcpp, package, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-package.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp-quickref.Rmd rcpp-1.0.3/vignettes/Rcpp-quickref.Rmd --- rcpp-1.0.2/vignettes/Rcpp-quickref.Rmd 2018-12-26 11:59:01.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-quickref.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,554 +0,0 @@ ---- -title: \pkg{Rcpp} Quick Reference Guide - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This document provides short code snippets that are helpful for using the - \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp,Eddelbuettel:2013:Rcpp}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - quickref - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - -vignette: > - %\VignetteIndexEntry{Rcpp-quickref} - %\VignetteKeywords{Rcpp, quickref, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Important Notes - -```cpp -// If you experience compiler errors, please check -// that you have an appropriate version of g++. -// See `Rcpp-FAQ' for more information. - -// Many of the examples here imply the following: -#include -using namespace Rcpp; -// The cppFunction will automatically add this. - -// Or, prefix Rcpp objects with the Rcpp namespace -// as e.g. in: -Rcpp::NumericVector xx(10); -``` - -# Create simple vectors - -```cpp -SEXP x; std::vector y(10); - -// from SEXP -NumericVector xx(x); - -// of a given size (filled with 0) -NumericVector xx(10); -// ... with a default for all values -NumericVector xx(10, 2.0); - -// range constructor -NumericVector xx(y.begin(), y.end()); - -// using create -NumericVector xx = - NumericVector::create(1.0, 2.0, 3.0, 4.0); -NumericVector yy = - NumericVector::create(Named("foo") = 1.0, - _["bar"] = 2.0); - // _ short for Named -``` - -# Extract and set single elements - -```cpp -// extract single values -double x0 = xx[0]; -double x1 = xx(1); - -double y0 = yy["foo"]; -double y1 = yy["bar"]; - -// set single values -xx[0] = 2.1; -xx(1) = 4.2; - -yy["foo"] = 3.0; - -// grow the vector -yy["foobar"] = 10.0; -``` - -# Using matrices - -```cpp -// Initializing from SEXP, -// dimensions handled automatically -SEXP x; -NumericMatrix xx(x); - -// Matrix of 4 rows & 5 columns (filled with 0) -NumericMatrix xx(4, 5); - -// Fill with value -int xsize = xx.nrow() * xx.ncol(); -for (int i = 0; i < xsize; i++) { - xx[i] = 7; -} -// Same as above, using STL fill -std::fill(xx.begin(), xx.end(), 8); - -// Assign this value to single element -// (1st row, 2nd col) -xx(0,1) = 4; - -// Reference the second column -// Changes propagate to xx (same applies for Row) -NumericMatrix::Column zzcol = xx( _, 1); -zzcol = zzcol * 2; - -// Copy the second column into new object -NumericVector zz1 = xx( _, 1); -// Copy submatrix (top left 3x3) into new object -NumericMatrix zz2 = xx( Range(0,2), Range(0,2)); -``` - -# Inline C++ Compile in R - -```{r, eval = FALSE} -## Note - this is R code. -## cppFunction in Rcpp allows rapid testing. -require(Rcpp) - -cppFunction(" -NumericVector exfun(NumericVector x, int i){ - x = x*i; - return x; -}") - -exfun(1:5, 3) - -## Use evalCpp to evaluate C++ expressions -evalCpp("std::numeric_limits::max()") -``` - -# Interface with R - -## First step in R - -```{r, eval = FALSE} -# In R, create a package shell. For details, -# see the "Writing R Extensions" manual and -# the "Rcpp-package" vignette. - -Rcpp.package.skeleton("myPackage") - -# Add R code to pkg R/ directory. Call C++ -# function. Do type-checking in R. - -myfunR <- function(Rx, Ry) { - ret = .Call("myCfun", Rx, Ry, - package="myPackage") - return(ret) -} -``` - -## Additional C++ - -```cpp -// Add C++ code to pkg src/ directory. -using namespace Rcpp; -// Define function as extern with RcppExport -RcppExport SEXP myCfun( SEXP x, SEXP y) { - // If R/C++ types match, use pointer to x. - // Pointer is faster, but changes to xx - // propagate to R ( xx -> x == Rx). - NumericVector xx(x); - - // clone is slower and uses extra memory. - // Safe. No side effects. - NumericVector yy(clone(y)); - - xx[0] = yy[0] = -1.5; - int zz = xx[0]; - - // use wrap() to return non-SEXP objects, e.g: - // return(wrap(zz)); - // Build and return a list - List ret; - ret["x"] = xx; - ret["y"] = yy; - return(ret); -} -``` - -## On the command-line - -```sh -# From shell, above package directory -R CMD build myPackage -R CMD check myPackage_1.0.tar.gz ## Optional -R CMD INSTALL myPackage_1.0.tar.gz -``` - -## Back in R - -```{r, eval=FALSE} -require(myPackage) - -aa <- 1.5 -bb <- 1.5 -cc <- myfunR(aa, bb) -aa == bb -# FALSE, C++ modifies aa - -aa <- 1:2 -bb <- 1:2 -cc <- myfunR(aa, bb) -identical(aa, bb) -# TRUE, R/C++ types don't match -# so a copy was made -``` - -# STL interface - -```cpp -// sum a vector from beginning to end -double s = std::accumulate(x.begin(), - x.end(), 0.0); -// prod of elements from beginning to end -int p = std::accumulate(vec.begin(), - vec.end(), 1, - std::multiplies()); -// inner_product to compute sum of squares -double s2 = std::inner_product(res.begin(), - res.end(), - res.begin(), 0.0); -``` - -# Rcpp Attributes - -## In C++ - -```cpp -// Add code below into C++ file Rcpp_example.cpp - -#include -using namespace Rcpp; - -// Place the 'Rcpp::export' tag -// right above function declaration. - -// [[Rcpp::export]] -double muRcpp(NumericVector x){ - int n = x.size(); // Size of vector - double sum = 0; // Sum value - - // For loop, note cpp index shift to 0 - for(int i = 0; i < n; i++){ - // Shorthand for sum = sum + x[i] - sum += x[i]; - } - - return sum/n; // Obtain and return the Mean -} - -// Place dependent functions above call or -// declare the function definition with: -double muRcpp(NumericVector x); - -// [[Rcpp::export]] -double varRcpp(NumericVector x, bool bias = true){ - // Calculate the mean using C++ function - double mean = muRcpp(x); - double sum = 0; - int n = x.size(); - - for(int i = 0; i < n; i++){ - sum += pow(x[i] - mean, 2.0); // Square - } - - return sum/(n-bias); // Return variance -} -``` - -## In R: - -```{r, eval=FALSE} -Rcpp::sourceCpp("path/to/file/Rcpp_example.cpp") -x <- 1:5 -all.equal(muRcpp(x), mean(x)) -all.equal(var(x),varRcpp(x)) -``` - -# Rcpp Extensions - -```cpp -// Enable C++11 -// [[Rcpp::plugins(cpp11)]] - -// Enable OpenMP (excludes macOS) -// [[Rcpp::plugins(openmp)]] - -// Use the RcppArmadillo package -// Requires different header file from Rcpp.h -#include -// [[Rcpp::depends(RcppArmadillo)]] -``` - -# Rcpp sugar - -```cpp -NumericVector x = - NumericVector::create(-2.0,-1.0,0.0,1.0,2.0); -IntegerVector y = - IntegerVector::create(-2, -1, 0, 1, 2); - -NumericVector xx = abs( x ); -IntegerVector yy = abs( y ); - -bool b = all( x < 3.0 ).is_true() ; -bool b = any( y > 2 ).is_true(); - -NumericVector xx = ceil( x ); -NumericVector xx = ceiling( x ); -NumericVector yy = floor( y ); -NumericVector yy = floor( y ); - -NumericVector xx = exp( x ); -NumericVector yy = exp( y ); - -NumericVector xx = head( x, 2 ); -IntegerVector yy = head( y, 2 ); - -IntegerVector xx = seq_len( 10 ); -IntegerVector yy = seq_along( y ); - -NumericVector xx = rep( x, 3 ); -NumericVector xx = rep_len( x, 10 ); -NumericVector xx = rep_each( x, 3 ); - -IntegerVector yy = rev( y ); -``` - -# Random Number Generation functions} - -```cpp -// Set seed -RNGScope scope; - -// For details see Section 6.7.1--Distribution -// functions of the `Writing R Extensions' manual. -// In some cases (e.g. rnorm), dist-specific -// arguments can be omitted; when in doubt, -// specify all dist-specific arguments. The use -// of doublesrather than integers for dist- -// specific arguments is recommended. Unless -// explicitly specified, log=FALSE. - -// Equivalent to R calls -NumericVector xx = runif(20); -NumericVector xx1 = rnorm(20); -NumericVector xx1 = rnorm(20, 0); -NumericVector xx1 = rnorm(20, 0, 1); - -// Example vector of quantiles -NumericVector quants(5); -for (int i = 0; i < 5; i++) { - quants[i] = (i-2); -} - -// in R, dnorm(-2:2) -NumericVector yy = dnorm(quants) ; -NumericVector yy = dnorm(quants, 0.0, 1.0) ; - -// in R, dnorm(-2:2, mean=2, log=TRUE) -NumericVector yy = dnorm(quants, 2.0, true) ; - -// Note - cannot specify sd without mean -// in R, dnorm(-2:2, mean=0, sd=2, log=TRUE) -NumericVector yy = dnorm(quants, 0.0, 2.0, true) ; - -// To get original R api, use Rf_* -double zz = Rf_rnorm(0, 2); -``` - - -# Environment - -```cpp -// Special environments -Environment::Rcpp_namespace(); -Environment::base_env(); -Environment::base_namespace(); -Environment::global_env(); -Environment::empty_env(); - -// Obtain an R environment -Environment stats("package:stats"); -Environment env( 2 ); // by position -Environment glob = Environment::global_env(); - -// Extract function from specific environment -Function rnorm = stats["rnorm"]; - -// Assign into the environment -glob["x"] = "foo"; -glob["y"] = 3; - -// Retrieve information from environment -std::string x = glob["x"]; -glob.assign( "foo" , 3 ); -int foo = glob.get( "foo" ); -int foo = glob.find( "foo" ); -CharacterVector names = glob.ls(TRUE) -bool b = glob.exists( "foo" ); -glob.remove( "foo" ); - -// Administration -glob.lockBinding("foo"); -glob.unlockBinding("foo"); -bool b = glob.bindingIsLocked("foo"); -bool b = glob.bindingIsActive("foo"); - -// Retrieve related environments -Environment e = stats.parent(); -Environment e = glob.new_child(); -``` - -# Calling Functions in R - -```cpp -// Do NOT expect to have a performance gain -// when calling R functions from R! - -// Retrieve functions from default loaded env. -Function rnorm("rnorm"); -rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 ); - -// Passing in an R function and obtaining results -// Make sure function conforms with return type! -NumericVector callFunction(NumericVector x, - Function f) { - NumericVector res = f(x); - return res; -} - -/*** R -# The following is R code executed -# by sourceCpp() as a convenience. -x = 1:5 -callFunction(x, sum) -*/ -``` - -# Modules - -```cpp -// Warning -- Module-based objects do not persist -// across quit(save="yes")/reload cycles. To be -// safe, save results to R objects and remove -// module objects before exiting R. - -// To create a module-containing package from R: -// Rcpp.package.skeleton("mypackage", module=TRUE) - -class Bar { - public: - Bar(double x_) : x(x_), nread(0), nwrite(0) {} - - double get_x( ) { - nread++; - return x; - } - - void set_x( double x_) { - nwrite++; - x = x_; - } - - IntegerVector stats() const { - return - IntegerVector::create(_["read"] = nread, - _["write"] = nwrite); - } - private: - double x; int nread, nwrite; -}; - -RCPP_MODULE(mod_bar) { - class_( "Bar" ) - .constructor() - .property( "x", &Bar::get_x, &Bar::set_x, - "Docstring for x" ) - .method( "stats", &Bar::stats, - "Docstring for stats") -;} - -/*** R -## The following is R code. -require(mypackage) s -how(Bar) -b <- new(Bar, 10) -b$x <- 10 -b_persist <- list(stats=b$stats(), x=b$x) -rm(b) -*/ -``` diff -Nru rcpp-1.0.2/vignettes/Rcpp-quickref.Rnw rcpp-1.0.3/vignettes/Rcpp-quickref.Rnw --- rcpp-1.0.2/vignettes/Rcpp-quickref.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-quickref.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-quickref} +%\VignetteKeywords{Rcpp, quickref, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-quickref.pdf} +\end{document} diff -Nru rcpp-1.0.2/vignettes/Rcpp-sugar.Rmd rcpp-1.0.3/vignettes/Rcpp-sugar.Rmd --- rcpp-1.0.2/vignettes/Rcpp-sugar.Rmd 2018-09-02 19:06:26.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-sugar.Rmd 1970-01-01 00:00:00.000000000 +0000 @@ -1,835 +0,0 @@ ---- -title: \pkg{Rcpp} syntactic sugar - -# Use letters for affiliations -author: - - name: Dirk Eddelbuettel - affiliation: a - - name: Romain François - affiliation: b - -address: - - code: a - address: \url{http://dirk.eddelbuettel.com} - - code: b - address: \url{https://romain.rbind.io/} - -# For footer text -lead_author_surname: Eddelbuettel and François - -# Place DOI URL or CRAN Package URL here -doi: "https://cran.r-project.org/package=Rcpp" - -# Abstract -abstract: | - This note describes \sugar which has been introduced in version - 0.8.3 of \pkg{Rcpp} \citep{CRAN:Rcpp,JSS:Rcpp}. \sugar brings a - higher-level of abstraction to \proglang{C++} code written using the - \pkg{Rcpp} API. \sugar is based on expression templates - \citep{Abrahams+Gurtovoy:2004:TemplateMetaprogramming,Vandevoorde+Josuttis:2003:Templates} - and provides some 'syntactic sugar' facilities directly in - \pkg{Rcpp}. This is similar to how \pkg{RcppArmadillo} - \citep{CRAN:RcppArmadillo} offers linear algebra \proglang{C++} - classes based on \pkg{Armadillo} \citep{Sanderson:2010:Armadillo}. - -# Optional: Acknowledgements -# acknowledgements: | - -# Optional: One or more keywords -keywords: - - Rcpp - - sugar - - R - - C++ - -# Font size of the document, values of 9pt (default), 10pt, 11pt and 12pt -fontsize: 9pt - -# Optional: Force one-column layout, default is two-column -#one_column: true - -# Optional: Enables lineo mode, but only if one_column mode is also true -#lineno: true - -# Optional: Enable one-sided layout, default is two-sided -#one_sided: true - -# Optional: Enable section numbering, default is unnumbered -numbersections: true - -# Optional: Specify the depth of section number, default is 5 -#secnumdepth: 5 - -# Optional: Bibliography -bibliography: Rcpp - -# Optional: Enable a 'Draft' watermark on the document -#watermark: false - -# Customize footer, eg by referencing the vignette -footer_contents: "Rcpp Vignette" - -# Omit \pnasbreak at end -skip_final_break: true - -# Produce a pinp document -output: pinp::pinp - -header-includes: > - \newcommand{\proglang}[1]{\textsf{#1}} - \newcommand{\pkg}[1]{\textbf{#1}} - \newcommand{\faq}[1]{FAQ~\ref{#1}} - \newcommand{\rdoc}[2]{\href{http://www.rdocumentation.org/packages/#1/functions/#2}{\code{#2}}} - \newcommand{\sugar}{\textsl{Rcpp sugar}~} - \newcommand{\ith}{\textsl{i}-\textsuperscript{th}} - -vignette: > - %\VignetteIndexEntry{Rcpp-sugar} - %\VignetteKeywords{Rcpp, sugar, R, Cpp} - %\VignettePackage{Rcpp} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -# Motivation - -\pkg{Rcpp} facilitates development of internal compiled code in an \proglang{R} -package by abstracting low-level details of the \proglang{R} API \citep{R:Extensions} -into a consistent set of \proglang{C++} classes. - -Code written using \pkg{Rcpp} classes is easier to read, write and maintain, -without loosing performance. Consider the following code example which -provides a function `foo` as a \proglang{C++} extension to -\proglang{R} by using the \pkg{Rcpp} API: - -```cpp -RcppExport SEXP foo(SEXP x, SEXP y) { - Rcpp::NumericVector xx(x), yy(y); - int n = xx.size(); - Rcpp::NumericVector res(n); - double x_ = 0.0, y_ = 0.0; - for (int i=0; i y; -LogicalVector res = x <= y; -LogicalVector res = x >= y; -LogicalVector res = x == y; -LogicalVector res = x != y; - -// one vector, one single value -LogicalVector res = x < 2; -LogicalVector res = 2 > x; -LogicalVector res = y <= 2; -LogicalVector res = 2 != y; - -// two expressions -LogicalVector res = (x + y) < (x*x); -LogicalVector res = (x + y) >= (x*x); -LogicalVector res = (x + y) == (x*x); -``` - -## Unary operators - -The unary `operator-` can be used to negate a (numeric) sugar expression. -whereas the unary `operator!` negates a logical sugar expression: - -```cpp -// a numeric vector -NumericVector x; - -// negate x -NumericVector res = -x; - -// use it as part of a numerical expression -NumericVector res = -x * (x + 2.0); - -// two integer vectors of the same size -NumericVector y; -NumericVector z; - -// negate the logical expression "y < z" -LogicalVector res = !(y < z); -``` - -# Functions - -\sugar defines functions that closely match the behavior of \proglang{R} -functions of the same name. - -## Functions producing a single logical result - -Given a logical sugar expression, the `all` function identifies if all -the elements are `TRUE`. Similarly, the `any` function -identifies if any the element is `TRUE` when -given a logical sugar expression. - - -```cpp -IntegerVector x = seq_len(1000); -all(x*x < 3); -any(x*x < 3); -``` - -Either call to `all` and `any` creates an object of a class -that has member functions `is_true`, `is_false`, -`is_na` and a conversion to `SEXP` operator. - -One important thing to highlight is that `all` is lazy. Unlike -\proglang{R}, there is no need to fully evaluate the expression. In the -example above, the result of `all` is fully resolved after evaluating -only the two first indices of the expression \verb|x * x < 3|. `any` -is lazy too, so it will only need to resolve the first element of the example -above. - -### Conversion to bool - -One important thing to note concerns the conversion to the `bool` -type. In order to respect the concept of missing values (`NA`) in -\proglang{R}, expressions generated by `any` or `all` can not -be converted to `bool`. Instead one must use `is_true`, -`is_false` or `is_na`: - -```cpp -// wrong: will generate a compile error -bool res = any(x < y); - -// ok -bool res = is_true(any( x < y )); -bool res = is_false(any( x < y )); -bool res = is_na(any( x < y )); -``` - - - - -## Functions producing sugar expressions - -### is_na - -Given a sugar expression of any type, \verb|is_na| (just like the other -functions in this section) produces a logical sugar expression of the same -length. Each element of the result expression evaluates to `TRUE` if -the corresponding input is a missing value, or `FALSE` otherwise. - -```cpp -IntegerVector x = - IntegerVector::create(0, 1, NA_INTEGER, 3); - -is_na(x) -all(is_na( x )) -any(!is_na( x )) -``` - -### seq_along - -Given a sugar expression of any type, `seq_along` creates an -integer sugar expression whose values go from 1 to the size of the input. - -```cpp -IntegerVector x = - IntegerVector::create( 0, 1, NA_INTEGER, 3 ); - -IntegerVector y = seq_along(x); -IntegerVector z = seq_along(x * x * x * x * x * x); -``` - -This is the most lazy function, as it only needs to call the `size` -member function of the input expression. The input expression need not to be -resolved. The two examples above gives the same result with the same efficiency -at runtime. The compile time will be affected by the complexity of the -second expression, since the abstract syntax tree is built at compile time. - -### seq_len - -`seq_len` creates an integer sugar expression whose -\ith\ element expands to `i`. `seq_len` is particularly useful in -conjunction with `sapply` and `lapply`. - -```cpp -// 1, 2, ..., 10 -IntegerVector x = seq_len(10); - -List y = lapply(seq_len(10), seq_len); -``` - -### pmin and pmax - -Given two sugar expressions of the same type and size, or one expression and -one primitive value of the appropriate type, `pmin` (`pmax`) -generates a sugar expression of the same type whose \ith\ element expands to -the lowest (highest) value between the \ith\ element of the first expression -and the \ith element of the second expression. - -```cpp -IntegerVector x = seq_len(10); - -pmin(x, x*x); -pmin(x*x, 2); - -pmin(x, x*x); -pmin(x*x, 2); -``` - -### ifelse - -Given a logical sugar expression and either : -\begin{itemize} -\item two compatible sugar expression (same type, same size) -\item one sugar expression and one compatible primitive -\end{itemize} -`ifelse` expands to a sugar expression whose \ith\ -element is the \ith\ element of the first expression -if the \ith\ element of the condition expands to `TRUE` -or the \ith\ of the second expression if -the \ith\ element of the condition expands to `FALSE`, -or the appropriate missing value otherwise. - -```cpp -IntegerVector x; -IntegerVector y; - -ifelse(x < y, x, (x+y)*y) -ifelse(x > y, x, 2) -``` - -### sapply - -`sapply` applies a \proglang{C++} function to each element -of the given expression to create a new expression. The type of the -resulting expression is deduced by the compiler from the result type of -the function. - -The function can be a free \proglang{C++} function such as the overload -generated by the template function below: - -```cpp -template -T square(const T& x){ - return x * x; -} -sapply(seq_len(10), square); -``` - -Alternatively, the function can be a functor whose type has a nested type -called `result_type` - -```cpp -template -struct square : std::unary_function { - T operator()(const T& x){ - return x * x; - } -} -sapply(seq_len(10), square()); -``` - -### lapply - -`lapply` is similar to `sapply` except that the result is -allways an list expression (an expression of type `VECSXP`). - -### sign - -Given a numeric or integer expression, `sign` expands to an expression -whose values are one of 1, 0, -1 or `NA`, depending on the sign -of the input expression. - -```cpp -IntegerVector xx; - -sign(xx) -sign(xx * xx) -``` - -### diff - -The \ith\ element of the result of `diff` is -the difference between the $(i+1)^{\text{th}}$ and the -\ith\ element of the input expression. Supported types are -integer and numeric. - -```cpp -IntegerVector xx; - -diff(xx) -``` - -## Mathematical functions - -For the following set of functions, generally speaking, the \ith\ element of -the result of the given function (say, `abs`) is the result of -applying that function to this \ith\ element of the input expression. -Supported types are integer and numeric. - -```cpp -IntegerVector x; - -abs(x) -exp(x) -floor(x) -ceil(x) -pow(x, z) // x to the power of z -``` - - - -## The d/q/p/r statistical functions - -The framework provided by \sugar also permits easy and efficient access the -density, distribution function, quantile and random number generation -functions function by \proglang{R} in the \code{Rmath} library. - -Currently, most of these functions are vectorised for the first element which -denote size. Consequently, these calls works in \proglang{C++} just as they -would in \proglang{R}: - -```cpp -x1 = dnorm(y1, 0, 1); // density of y1 at m=0, sd=1 -x2 = qnorm(y2, 0, 1); // quantiles of y2 -x3 = pnorm(y3, 0, 1); // distribution of y3 -x4 = rnorm(n, 0, 1); // 'n' RNG draws of N(0, 1) -``` - -Similar d/q/p/r functions are provided for the most common distributions: -beta, binom, cauchy, chisq, exp, f, gamma, geom, hyper, lnorm, logis, nbeta, -nbinom, nbinom_mu, nchisq, nf, norm, nt, pois, t, unif, and weibull. - -Note that the parameterization used in these sugar functions may differ between -the top-level functions exposed in an \proglang{R} session. For example, -the internal \code{rexp} is parameterized by \code{scale}, -whereas the R-level \code{stats::rexp} is parameterized by \code{rate}. -Consult \href{http://cran.r-project.org/doc/manuals/r-release/R-exts.html#Distribution-functions}{Distribution Functions} -for more details on the parameterization used for these sugar functions. - -One point to note is that the programmer using these functions needs to -initialize the state of the random number generator as detailed in Section -6.3 of the `Writing R Extensions' manual \citep{R:Extensions}. A nice -\proglang{C++} solution for this is to use a \textsl{scoped} class that sets -the random number generatator on entry to a block and resets it on exit. We -offer the \code{RNGScope} class which allows code such as - -```cpp -RcppExport SEXP getRGamma() { - RNGScope scope; - NumericVector x = rgamma(10, 1, 1); - return x; -} -``` - -As there is some computational overhead involved in using \code{RNGScope}, we -are not wrapping it around each inner function. Rather, the user of these -functions (\textsl{i.e.} you) should place an \code{RNGScope} at the -appropriate level of your code. - - -# Performance -\label{sec:performance} - -TBD - -# Implementation - -This section details some of the techniques used in the implementation of -\sugar. Note that the user need not to be familiar with the implementation -details in order to use \sugar, so this section can be skipped upon a first -read of the paper. - -Writing \sugar functions is fairly repetitive and follows a well-structured -pattern. So once the basic concepts are mastered (which may take time given -the inherent complexities in template programming), it should be possible to -extend the set of function further following the established pattern. - -## The curiously recurring template pattern - -Expression templates such as those used by \sugar use a technique -called the _Curiously Recurring Template Pattern_ (CRTP). The general -form of CRTP is: - -```cpp -// The Curiously Recurring Template Pattern (CRTP) -template -struct base { - // ... -}; -struct derived : base { - // ... -}; -``` - -The `base` class is templated by the class that derives from it : -`derived`. This shifts the relationship between a base class and a -derived class as it allows the base class to access methods of the derived -class. - -## The VectorBase class - -The CRTP is used as the basis for \sugar with the `VectorBase` -class template. All sugar expression derive from one class generated by the -`VectorBase` template. The current definition of `VectorBase` -is given here: - -```cpp -template -class VectorBase { -public: - struct r_type : - traits::integral_constant{}; - struct can_have_na : - traits::integral_constant{}; - - typedef typename - traits::storage_type::type - stored_type; - - VECTOR& get_ref(){ - return static_cast(*this); - } - - inline stored_type operator[](int i) const { - return static_cast( - this)->operator[](i); - } - - inline int size() const { - return static_cast( - this)->size(); - } - - /* definition ommited here */ - class iterator; - - inline iterator begin() const { - return iterator(*this, 0); - } - inline iterator end() const { - return iterator(*this, size()); - } -} -``` - -The `VectorBase` template has three parameters: - - -- `RTYPE`: This controls the type of expression (INTSXP, REALSXP, ...) -- `na`: This embeds in the derived type information about whether - instances may contain missing values. \pkg{Rcpp} vector types - (`IntegerVector`, ...) derive from `VectorBase` with this - parameter set to `true` because there is no way to know at - compile-time if the vector will contain missing values at run-time. - However, this parameter is set to `false` for types that are - generated by sugar expressions as these are guaranteed to produce - expressions that are without missing values. An example is the - `is_na` function. This parameter is used in several places as part - of the compile time dispatch to limit the occurence of redundant - operations. -- `VECTOR`: This parameter is the key of \sugar. This is the - manifestation of CRTP. The indexing operator and the `size` method - of `VectorBase` use a static cast of `this` to the - `VECTOR` type to forward calls to the actual method of the derived - class. - -## Example: sapply - -As an example, the current implementation of `sapply`, supported by -the template class `Rcpp::sugar::Sapply` is given below: - -```cpp -template -class Sapply : public VectorBase< - Rcpp::traits::r_sexptype_traits< typename - ::Rcpp::traits::result_of::type - >::rtype, - true, - Sapply -> { -public: - typedef typename - ::Rcpp::traits::result_of::type; - - const static int RESULT_R_TYPE = - Rcpp::traits::r_sexptype_traits< - result_type>::rtype; - - typedef Rcpp::VectorBase VEC; - - typedef typename - Rcpp::traits::r_vector_element_converter< - RESULT_R_TYPE>::type - converter_type; - - typedef typename Rcpp::traits::storage_type< - RESULT_R_TYPE>::type STORAGE; - - Sapply(const VEC& vec_, Function fun_) : - vec(vec_), fun(fun_){} - - inline STORAGE operator[]( int i ) const { - return converter_type::get(fun(vec[i])); - } - - inline int size() const { - return vec.size(); - } - -private: - const VEC& vec; - Function fun; -}; - -// sugar - -template -inline sugar::Sapply -sapply(const Rcpp::VectorBase& t, - Function fun) { - - return - sugar::Sapply(t, fun); -} -``` - -### The sapply function - -`sapply` is a template function that takes two arguments. - -- The first argument is a sugar expression, which we recognize because of - the relationship with the `VectorBase` class template. -- The second argument is the function to apply. - -The `sapply` function itself does not do anything, it is just used -to trigger compiler detection of the template parameters that will be used -in the `sugar::Sapply` template. - -### Detection of return type of the function - -In order to decide which kind of expression is built, the `Sapply` -template class queries the template argument via the `Rcpp::traits::result_of` -template. - -```cpp -typedef typename - ::Rcpp::traits::result_of::type - result_type; -``` - -The `result_of` type trait is implemented as such: - -```{Rcpp, eval = FALSE} -template -struct result_of{ - typedef typename T::result_type type; -}; - -template -struct result_of { - typedef RESULT_TYPE type; -}; -``` - -The generic definition of `result_of` targets functors -with a nested `result_type` type. - -The second definition is a partial specialization targetting -function pointers. - -### Indentification of expression type - -Based on the result type of the function, the `r_sexptype_traits` -trait is used to identify the expression type. - -```cpp -const static int RESULT_R_TYPE = - Rcpp::traits::r_sexptype_traits< - result_type>::rtype; -``` - -### Converter - -The `r_vector_element_converter` class is used to convert an -object of the function's result type to the actual storage type suitable -for the sugar expression. - -```cpp -typedef typename - Rcpp::traits::r_vector_element_converter< - RESULT_R_TYPE>::type - converter_type; -``` - -### Storage type - -The `storage_type` trait is used to get access to the storage type -associated with a sugar expression type. For example, the storage type -of a `REALSXP` expression is `double`. - -```cpp -typedef typename - Rcpp::traits::storage_type::type - STORAGE; -``` - -### Input expression base type - -The input expression --- the expression over which `sapply` runs --- is -also typedef'ed for convenience: - -```cpp -typedef Rcpp::VectorBase VEC; -``` - -### Output expression base type - -In order to be part of the \sugar system, the type generated by the -`Sapply` class template must inherit from `VectorBase`. - -```cpp -template -class Sapply : public VectorBase< - Rcpp::traits::r_sexptype_traits< - typename - ::Rcpp::traits::result_of::type - >::rtype, - true, - Sapply -> -``` - -The expression built by `Sapply` depends on the result type -of the function, may contain missing values, and the third argument -is the manifestation of the _CRTP_. - -### Constructor - -The constructor of the `Sapply` class template is straightforward, it -simply consists of holding the reference to the input expression and the -function. - -```cpp -Sapply(const VEC& vec_, Function fun_): - vec(vec_), fun(fun_){} - -private: - const VEC& vec; - Function fun; -``` - -### Implementation - -The indexing operator and the `size` member function is what -the `VectorBase` expects. The size of the result expression is -the same as the size of the input expression and the $i^{\text{th}}$ -element of the result is simply retrieved by applying the function -and the converter. Both these methods are inline to maximize performance: - -```cpp -inline STORAGE operator[](int i) const { - return converter_type::get(fun(vec[i])); -} -inline int size() const { - return vec.size(); -} -``` - -# Summary - -TBD diff -Nru rcpp-1.0.2/vignettes/Rcpp-sugar.Rnw rcpp-1.0.3/vignettes/Rcpp-sugar.Rnw --- rcpp-1.0.2/vignettes/Rcpp-sugar.Rnw 1970-01-01 00:00:00.000000000 +0000 +++ rcpp-1.0.3/vignettes/Rcpp-sugar.Rnw 2019-10-27 19:15:02.000000000 +0000 @@ -0,0 +1,10 @@ +\documentclass{article} +\usepackage{pdfpages} +%\VignetteIndexEntry{Rcpp-sugar} +%\VignetteKeywords{Rcpp, sugar, R, Cpp} +%\VignettePackage{Rcpp} +%\VignetteEncoding{UTF-8} + +\begin{document} +\includepdf[pages=-, fitpaper=true]{pdf/Rcpp-sugar.pdf} +\end{document} Binary files /tmp/tmpwkvJP7/UrZOVt7cl9/rcpp-1.0.2/vignettes/Rcpp-unitTests.pdf and /tmp/tmpwkvJP7/L_KU8MNa6F/rcpp-1.0.3/vignettes/Rcpp-unitTests.pdf differ