https://github.com/uscbiostats/classy
Simple example of C++ Classes and External Pointers with Rcpp
https://github.com/uscbiostats/classy
cpp cpp11 hpc r-package r-programming rcpp rstats
Last synced: 10 months ago
JSON representation
Simple example of C++ Classes and External Pointers with Rcpp
- Host: GitHub
- URL: https://github.com/uscbiostats/classy
- Owner: USCbiostats
- License: other
- Created: 2018-10-16T19:09:35.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2021-04-28T17:28:32.000Z (almost 5 years ago)
- Last Synced: 2025-04-05T09:11:23.623Z (10 months ago)
- Topics: cpp, cpp11, hpc, r-package, r-programming, rcpp, rstats
- Language: C++
- Size: 18.6 KB
- Stars: 9
- Watchers: 5
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
README
---
output: github_document
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# classy
[](https://travis-ci.org/USCbiostats/classy) [](https://ci.appveyor.com/project/USCbiostats/classy) [](https://www.tidyverse.org/lifecycle/#experimental) [](https://cran.r-project.org/package=classy)
This R package illustrates how to work with classes and `Rcpp::XPtr` objects in R and Rcpp.
The R package includes documentation using [roxygen2](https://cran.r-project.org/package=roxygen2), so the `Rd` files in the `man` folder were generated automatically by it.
## Two types of examples
By default, all the `Rcpp::` objects that are mapped to R objects provide pointers instead of *deep copies*, which translates in efficient memory management and speed. The problem is that whenever you start using objects other than `NumericMatrix`, `NumericVector`, `IntegerMatrix`, etc. Rcpp generates copies of these objects.
The `classy` R package provides two different approaches when working with C++ classes. The first approach, `classy1`, more simple but inefficient, uses `std::vector< double >` member objects, which makes `Rcpp` duplicate the object that you are passing when creating the class. This should be OK whenever you don't care about memory usage, otherwise, if you are dealing with large memory objects (i.e. something that occupies a couple of gigs in your computer).
You can take a look at the source of the files:
- Header [classy1.h](src/classy1.h)
- Implementation [classy1.cpp](src/classy1.cpp)
- R wrappers (with Rcpp::XPtr) [R-wrappers1.cpp](src/R-wrappers1.cpp)
The second method provided, `classy3` (there will be an intermediate), uses `NumericVector` wrapped around smart pointers, in particular, [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr) instead, but it is also implemented using [class templates](https://en.wikipedia.org/wiki/Template_(C%2B%2B)#Class_templates). This is a more appropiate approach when dealing with large objects since data is never duplicated.
You can take a look at the source of the files:
- Header [classy3.h](src/classy3.h)
- Implementation [classy3.cpp](src/classy3.cpp)
- R wrappers (with Rcpp::XPtr) [R-wrappers3.cpp](src/R-wrappers3.cpp)
## Installation
``` r
devtools::install_github("USCbiostats/classy")
```
## Example 1: Using `classy1` (i.e. duplicating memory)
```{r example1}
# loading the package
library(classy)
set.seed(1)
x <- runif(10)
obj <- new_classy1(x)
# Getting the sum
classy_sum1(obj)
# Counting
classy_count1(obj)
# Conditional count
classy_count_if_less1(obj, 0.5)
# The object
classy_get1(obj)
```
## Example 2: Using `classy3` (i.e. using smart pointers)
```{r example3}
# loading the package
library(classy)
obj3 <- new_classy3(x)
# Getting the sum
classy_sum3(obj3)
# Counting
classy_count3(obj3)
# Conditional count
classy_count_if_less3(obj3, 0.5)
# The object
classy_get3(obj3)
```
## Checking out the addresses
The final challenge, make sure that `obj3` (`classy3`) is actually pointing to
the same object than `x`.
```{r}
get_address(x)
classy_get_address1(obj)
classy_get_address3(obj3)
```