cpp4r is now on CRAN! | R bloggers

cpp4r is now on CRAN! | R bloggers

2 minutes, 59 seconds Read

[This article was first published on pacha.dev/blog, and kindly contributed to R-bloggers]. (You can report a problem with the content on this page here)


Want to share your content on R bloggers? click here if you have a blog, or here if you don’t.

If this post is useful to you, I kindly ask for a minimum donation Buy me a coffee. It will be used to continue my Open Source efforts. You can find the full explanation here: A personal message from an open source contributor.

You can send me questions for the blog at this form and subscribe to receive an email when there is a new post.

cpp4r helps you interact with R objects using C++ code. It’s a fork of the cpp11 package with identical syntax and similar goals.

All documentation is here, including basic configurations, custom configurations, and advanced use cases: https://cpp4r.org/.

cpp4r can be used as a replacement for cpp11 in existing or new packages. Think of cpp11 and cpp4r as MySQL and MariaDB: they are almost identical, but cpp4r has some extra features.

Using cpp4r in a package

To add cpp4r to an existing package, first install it:

install.packages("cpp4r", repos = "https://cran.r-project.org")

# or the development version:
remotes::install_github("pachadotdev/cpp4r")

Then place your C++ files into the src/ directory and add the following to your DESCRIPTION file:

LinkingTo: cpp4r

Then decorate C++ functions that you want to expose to R [[cpp4r::register]].

cpp4r is a headers-only library, with no hard dependencies and does not use a shared library, so it is simple and reliable to use in packages without fear of discrepancies during compile and run.

Alternatively, you can do that too supplier the currently installed version of cpp4r headers in your package cpp4r::vendor(). This ensures that the headers remain unchanged until you explicitly update them.

Get started

See the documentation to get started using cpp4r in your scripts, especially if you’re new to C++ programming.

Get help

Open an issue or send me an email. I will do my best to respond within 48 hours.

Examples

Add dim names to an array on the C++ side:

cpp4r::writable::doubles_matrix<> out(2, 2);

out(0, 0) = 1;
out(0, 1) = 2;
out(1, 0) = 3;
out(1, 1) = 4;

cpp4r::writable::list dimnames(2);
dimnames[0] = R_NilValue; // No row names
dimnames[1] = cpp4r::strings({"x1", "x2"});

out.attr("dimnames") = dimnames;

Using complex numbers (not possible in cpp11):

cpp4r::r_complex zero{0, 0};
cpp4r::r_complex one{1, 1};
cpp4r::r_complex two{2, 2};
cpp4r::r_complex three{3, 3};

cpp4r::writable::complexes x({one, two, three});
cpp4r::writable::complexes y({zero});

auto x_data = x.data();
y = std::move(x);

bool y.size() == 3; // true
bool y.data() == x_data; // true
bool y.is_altrep() == false; // true

Some implicit conversions for lists (cpp11 needs as_sexp() around scalars for this):

writable::list result;

double one = 1.0, two = 2.0, three = 3.0;

result.push_back({"one"_nm = one});
result.push_back(named_arg("two", two));
result.push_back({"three"_nm = 3});

writable::list result2(4);

int four = 4;
bool five = false;
const char* six = "six";
std::vector seven = {7.0, 7.1, 7.2};

result2[0] = four;
result2[1] = five;
result2[2] = six;
result2[3] = seven;

result2.names() = {"four", "five", "six", "seven"};

Contributions

Contributions are welcome! See the internal vignette for more information about design choices and coding style.

Code of conduct

Please note that the cpp4r project is released with a Code of Conduct for Contributors. By contributing to this project, you agree to abide by its terms.


#cpp4r #CRAN #bloggers

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *