Functions decorated with [[cpp11::register]]
in files ending in .cc
,
.cpp
, .h
or .hpp
will be wrapped in generated code and registered to
be called from R.
cpp_register(
path = ".",
quiet = !is_interactive(),
extension = c(".cpp", ".cc")
)
path |
The path to the package root directory |
quiet |
If |
extension |
The file extension to use for the generated src/cpp11 file.
|
Note registered functions will not be exported from your package unless
you also add a @export
roxygen2 directive for them.
In order to use cpp_register()
the cli
, decor
, desc
, glue
,
tibble
and vctrs
packages must also be installed.
The paths to the generated R and C++ source files (in that order).
# create a minimal package
dir <- tempfile()
dir.create(dir)
writeLines("Package: testPkg", file.path(dir, "DESCRIPTION"))
writeLines("useDynLib(testPkg, .registration = TRUE)", file.path(dir, "NAMESPACE"))
# create a C++ file with a decorated function
dir.create(file.path(dir, "src"))
writeLines("[[cpp11::register]] int one() { return 1; }", file.path(dir, "src", "one.cpp"))
# register the functions in the package
cpp_register(dir)
# Files generated by registration
file.exists(file.path(dir, "R", "cpp11.R"))
file.exists(file.path(dir, "src", "cpp11.cpp"))
# cleanup
unlink(dir, recursive = TRUE)
cpp_source()
compiles and loads a single C++ file for use in R.
cpp_function()
compiles and loads a single function for use in R.
cpp_eval()
evaluates a single C++ expression and returns the result.
cpp_source(
file,
code = NULL,
env = parent.frame(),
clean = TRUE,
quiet = TRUE,
cxx_std = Sys.getenv("CXX_STD", "CXX11"),
dir = tempfile()
)
cpp_function(
code,
env = parent.frame(),
clean = TRUE,
quiet = TRUE,
cxx_std = Sys.getenv("CXX_STD", "CXX11")
)
cpp_eval(
code,
env = parent.frame(),
clean = TRUE,
quiet = TRUE,
cxx_std = Sys.getenv("CXX_STD", "CXX11")
)
file |
A file containing C++ code to compile |
code |
If non-null, the C++ code to compile |
env |
The R environment where the R wrapping functions should be defined. |
clean |
If |
quiet |
If 'TRUE', do not show compiler output |
cxx_std |
The C++ standard to use, the |
dir |
The directory to store the generated source files. |
Within C++ code you can use [[cpp11::linking_to("pkgxyz")]]
to link to
external packages. This is equivalent to putting those packages in the
LinkingTo
field in a package DESCRIPTION.
For cpp_source()
and [cpp_function()]
the results of
dyn.load()
(invisibly). For [cpp_eval()]
the results of the evaluated
expression.
cpp_source(
code = '#include "cpp11/integers.hpp"
[[cpp11::register]]
int num_odd(cpp11::integers x) {
int total = 0;
for (int val : x) {
if ((val % 2) == 1) {
++total;
}
}
return total;
}
')
num_odd(as.integer(c(1:10, 15, 23)))
if (interactive() && require("progress")) {
cpp_source(
code = '
#include <cpp11/R.hpp>
#include <RProgress.h>
[[cpp11::linking_to("progress")]]
[[cpp11::register]] void
show_progress() {
RProgress::RProgress pb("Processing [:bar] ETA: :eta");
pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep(2.0 / 100 * 1000000);
pb.tick();
}
}
')
show_progress()
}
Vendoring is the act of making your own copy of the 3rd party packages your project is using. It is often used in the go language community.
cpp_vendor(path = ".")
path |
The path to the package root directory |
This function vendors cpp11 into your package by copying the cpp11
headers into the inst/include
folder of your package and adding
'cpp11 version: XYZ' to the top of the files, where XYZ is the version of
cpp11 currently installed on your machine.
If you choose to vendor the headers you should remove LinkingTo: cpp11
from your DESCRIPTION.
Note: vendoring places the responsibility of updating the code on
you. Bugfixes and new features in cpp11 will not be available for your
code until you run cpp_vendor()
again.
The file path to the vendored code (invisibly).
# create a new directory
dir <- tempfile()
dir.create(dir)
# vendor the cpp11 headers into the directory
cpp_vendor(dir)
list.files(file.path(dir, "inst", "include", "cpp11"))
# cleanup
unlink(dir, recursive = TRUE)