├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── pkgdown.yaml ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── R ├── RcppExports.R ├── student-exports.R └── student-pkg.R ├── README.md ├── RcppStudent.Rproj ├── _pkgdown.yml ├── man ├── RcppStudent-package.Rd ├── Student.Rd └── simulate_student.Rd └── src ├── .gitignore ├── Makevars ├── Makevars.win ├── RcppExports.cpp ├── student.cpp ├── student.h ├── student_export.cpp └── student_non_modules.cpp /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^\.travis\.yml$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^\.github$ 5 | ^_pkgdown\.yml$ 6 | ^docs$ 7 | ^pkgdown$ 8 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | R_KEEP_PKG_SOURCE: yes 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::rcmdcheck 27 | needs: check 28 | 29 | - uses: r-lib/actions/check-r-package@v2 30 | with: 31 | upload-snapshots: true 32 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 33 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | permissions: 23 | contents: write 24 | steps: 25 | - uses: actions/checkout@v4 26 | 27 | - uses: r-lib/actions/setup-pandoc@v2 28 | 29 | - uses: r-lib/actions/setup-r@v2 30 | with: 31 | use-public-rspm: true 32 | 33 | - uses: r-lib/actions/setup-r-dependencies@v2 34 | with: 35 | extra-packages: any::pkgdown, local::. 36 | needs: website 37 | 38 | - name: Build site 39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 40 | shell: Rscript {0} 41 | 42 | - name: Deploy to GitHub pages 🚀 43 | if: github.event_name != 'pull_request' 44 | uses: JamesIves/github-pages-deploy-action@v4.5.0 45 | with: 46 | clean: false 47 | branch: gh-pages 48 | folder: docs 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | docs 9 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: RcppStudent 2 | Type: Package 3 | Title: Expose the Student C++ Class using 'Rcpp Modules' 4 | Version: 0.0.1 5 | Authors@R: c( 6 | person("James", "Balamuta", email = "balamut2@illinois.edu", role = c("aut", "cre")), 7 | person("Ben", "Gorman", email = "bgorman@gormanalysis.com", role = c("aut")) 8 | ) 9 | Description: Provides an implementation of a Student 'C++' class being 10 | connected to 'R' using 'Rcpp Modules' to expose the underlying class methods. 11 | BugReports: https://github.com/coatless-rd-rcpp/rcpp-modules-student/issues 12 | URL: https://github.com/coatless-rd-rcpp/rcpp-modules-student, https://rd-rcpp.thecoatlessprofessor.com/rcpp-modules-student/ 13 | Depends: R (>= 4.3.0) 14 | Imports: Rcpp (>= 1.0.12), methods 15 | LinkingTo: Rcpp 16 | License: GPL (>= 2) 17 | Encoding: UTF-8 18 | RoxygenNote: 7.3.1 19 | Roxygen: list(markdown = TRUE) 20 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(Student) 4 | export(simulate_student) 5 | import(Rcpp) 6 | import(methods) 7 | useDynLib(RcppStudent, .registration = TRUE) 8 | -------------------------------------------------------------------------------- /R/RcppExports.R: -------------------------------------------------------------------------------- 1 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | #' Create a `Student` object. 5 | #' 6 | #' Constructes a `Student` object with non-default values and accesses 7 | #' their favorite numbers. 8 | #' 9 | #' @return 10 | #' An `integer` vector containing the student's favorite numbers. 11 | #' 12 | #' @export 13 | simulate_student <- function() { 14 | .Call(`_RcppStudent_simulate_student`) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /R/student-exports.R: -------------------------------------------------------------------------------- 1 | 2 | #' Create a Student Object from the Student C++ Class 3 | #' 4 | #' Allows for the creation of a Student Object in _C++_ from _R_ 5 | #' using the _C++_ Student class. 6 | #' 7 | #' @param name Name of Student 8 | #' @param age Age of Student 9 | #' @param male Is Student a Male? 10 | #' 11 | #' @return 12 | #' A `Student` object from the _C++_ Student Class. 13 | #' 14 | #' @examples 15 | #' ################## 16 | #' ## Constructor 17 | #' 18 | #' # Construct new Student object called "ben" 19 | #' ben = new(Student, name = "Ben", age = 26, male = TRUE) 20 | #' 21 | #' ################## 22 | #' ## Getters 23 | #' 24 | #' ben$LikesBlue() 25 | #' 26 | #' ben$GetAge() 27 | #' 28 | #' ben$IsMale() 29 | #' 30 | #' ben$GetName() 31 | #' 32 | #' ben$GetFavoriteNumbers() 33 | #' @name Student 34 | #' @export Student 35 | 36 | # ^^^^^^^^^^^^^^^^ 37 | # Export the "Student" C++ class by explicitly requesting Student be 38 | # exported via roxygen2's export tag. 39 | # Also, provide a name for the Rd file. 40 | 41 | 42 | # Load the Rcpp module exposed with RCPP_MODULE( ... ) macro. 43 | loadModule(module = "RcppStudentEx", TRUE) 44 | -------------------------------------------------------------------------------- /R/student-pkg.R: -------------------------------------------------------------------------------- 1 | #' @details 2 | #' RcppStudent is a package showing how to use Rcpp Modules to make available 3 | #' a C++ class under S4. 4 | #' 5 | #' @useDynLib RcppStudent, .registration = TRUE 6 | #' @import methods Rcpp 7 | "_PACKAGE" 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Exposing _C++_ Classes into _R_ Through Rcpp Modules 2 | 3 | 4 | [![R-CMD-check](https://github.com/coatless-rd-rcpp/rcpp-modules-student/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/coatless-rd-rcpp/rcpp-modules-student/actions/workflows/R-CMD-check.yaml) 5 | 6 | 7 | The `RcppStudent` _R_ package provides an example of using [Rcpp Modules](https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-modules.pdf) 8 | to expose _C++_ classes and their methods to _R_. 9 | 10 | Code for this example is based off a question that arose on StackOverflow titled 11 | "[Expose simple C++ Student class to R using Rcpp modules](https://stackoverflow.com/questions/53659500/expose-simple-c-student-class-to-r-using-rcpp-modules)" 12 | by [Ben Gorman](https://github.com/ben519). 13 | 14 | ### Usage 15 | 16 | To install the package, you must first have a compiler on your system that is 17 | compatible with R. For help on obtaining a compiler consult either 18 | [macOS](http://thecoatlessprofessor.com/programming/r-compiler-tools-for-rcpp-on-os-x/) 19 | or 20 | [Windows](http://thecoatlessprofessor.com/programming/rcpp/install-rtools-for-rcpp/) 21 | guides. 22 | 23 | With a compiler in hand, one can then install the package from GitHub by: 24 | 25 | ```r 26 | # install.packages("remotes") 27 | remotes::install_github("coatless-rd-rcpp/rcpp-modules-student") 28 | library("RcppStudent") 29 | ``` 30 | 31 | ### Implementation Details 32 | 33 | This guide focuses on providing an implementation along the path suggested 34 | in [Rcpp Modules Section 2.2: Exposing C++ classes using Rcpp modules](https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-modules.pdf#page=4). 35 | In particular, the focus is to expose a pure _C++_ class inside of _R_ without 36 | modifying the underlying _C++_ class. Largely, this means that the _C++_ class 37 | must be "marked up" for export using `RCPP_MODULE( ... )` macro in a separate 38 | file. 39 | 40 | ```bash 41 | RcppStudent 42 | ├── DESCRIPTION # Package metadata 43 | ├── NAMESPACE # Function and dependency registration 44 | ├── R 45 | │ ├── RcppExports.R 46 | │ ├── student-exports.R # Exporting Rcpp Module's Student into R 47 | │ └── student-pkg.R # NAMESPACE Import Code for Rcpp Modules 48 | ├── README.md # Implementation Overview 49 | ├── RcppStudent.Rproj 50 | ├── man 51 | │ ├── RcppStudent-package.Rd 52 | │ └── Student.Rd 53 | └── src 54 | ├── Makevars # Enable C++11 55 | ├── RcppExports.cpp 56 | ├── student.cpp # Class Implementation 57 | ├── student.h # Class Definition 58 | ├── student_export.cpp # Exporting the C++ Class with RCPP_MODULE 59 | └── student_non_modules.cpp # Example with Rcpp Attributes 60 | ``` 61 | 62 | 63 | ### C++ Class Definition 64 | 65 | Inside of [src/student.h](src/student.h), the **definition** of the _C++_ class 66 | is written with an inclusion guard. The definition is a "bare-bones" overview 67 | of what to expect. The meat or the implementation of the class is given in the 68 | [src/student.cpp](src/student.cpp) file. 69 | 70 | ```c++ 71 | // Student.h 72 | 73 | #ifndef Student_H 74 | #define Student_H 75 | 76 | #include 77 | #include 78 | 79 | class Student 80 | { 81 | public: 82 | 83 | // Constructor 84 | Student(std::string name, int age, bool male); 85 | 86 | // Getters 87 | std::string GetName(); 88 | int GetAge(); 89 | bool IsMale(); 90 | std::vector GetFavoriteNumbers(); 91 | 92 | // Methods 93 | bool LikesBlue(); 94 | 95 | private: 96 | 97 | // Member variables 98 | std::string name; 99 | int age; 100 | bool male; 101 | std::vector favoriteNumbers; 102 | }; 103 | 104 | #endif /* Student_H */ 105 | ``` 106 | 107 | #### C++ Class Implementation 108 | 109 | In [src/student.cpp](src/student.cpp), the **meat** behind the _C++_ 110 | class is implemented. The "meat" emphasizes how different methods within the 111 | class should behave. By 112 | 113 | ```cpp 114 | // Student.cpp 115 | 116 | #include "student.h" 117 | 118 | // Constructor 119 | Student::Student(std::string name, int age, bool male) { 120 | this->name = name; 121 | this->age = age; 122 | this->male = male; 123 | this->favoriteNumbers = {2, 3, 5, 7, 11}; // Requires C++11 124 | } 125 | 126 | // Getters 127 | bool Student::IsMale() { return male; } 128 | int Student::GetAge() { return age; } 129 | std::string Student::GetName() { return name; } 130 | std::vector Student::GetFavoriteNumbers() { return favoriteNumbers; } 131 | 132 | // Methods 133 | bool Student::LikesBlue() { 134 | return (male || age >= 10); 135 | } 136 | ``` 137 | 138 | ### Writing the Glue 139 | 140 | With the class definition and implementation in hand, the task switches to exposing 141 | the definition into _R_ by creating [src/student_export.cpp](src/student_export.cpp). 142 | Within this file, the Rcpp Module is defined using the `RCPP_MODULE( ... )` macro. 143 | Through the macro, the class' information must be specified using different 144 | member functions of `Rcpp::class_`. A subset of these member functions is 145 | given next: 146 | 147 | - Constructor: 148 | - `.constructor()` 149 | - Exposes a constructor with recognizable _C++_ data types. 150 | - e.g. `double`, `int`, `std::string`, and so on. 151 | - Methods: 152 | - `.method("FunctionName", &ClassName::FunctionName)` 153 | - Exposes a class method from `ClassName` given by `FunctionName`. 154 | - `.property("VariableName", &ClassName::GetFunction, &ClassName::SetFunction )` 155 | - Indirect access to a Class' fields through getter and setter functions. 156 | - Fields: 157 | - `.field("VariableName", &ClassName::VariableName, "documentation for VariableName")` 158 | - Exposes a public field with **read and write** access from R 159 | - `.field_readonly("VariableName", &Foo::VariableName, "documentation for VariableName read only")` 160 | - Exposes a public field with read access from R 161 | 162 | 163 | ```c++ 164 | // student_export.cpp 165 | 166 | // Include Rcpp system header file (e.g. <>) 167 | #include 168 | 169 | // Include our definition of the student file (e.g. "") 170 | #include "student.h" 171 | 172 | // Expose (some of) the Student class 173 | RCPP_MODULE(RcppStudentEx) { // Name used to "loadModule" in R script 174 | Rcpp::class_("Student") // This must be the C++ class name. 175 | .constructor() 176 | .method("GetName", &Student::GetName) 177 | .method("GetAge", &Student::GetAge) 178 | .method("IsMale", &Student::IsMale) 179 | .method("GetFavoriteNumbers", &Student::GetFavoriteNumbers) 180 | .method("LikesBlue", &Student::LikesBlue); 181 | } 182 | ``` 183 | 184 | ### Exporting and documenting an Rcpp Module 185 | 186 | In the [R/student-exports.R](R/student-exports.R) file, write the load 187 | statement for the module exposed via the `RCPP_MODULE( ... )` macro. In addition, 188 | make sure to export the class name so that when the package is loaded anyone 189 | can access it via `new()`. 190 | 191 | ```r 192 | # Export the "Student" C++ class by explicitly requesting Student be 193 | # exported via roxygen2's export tag. 194 | #' @export Student 195 | 196 | loadModule(module = "RcppStudentEx", TRUE) 197 | ``` 198 | 199 | ### Package Structure 200 | 201 | To register the required components for Rcpp Modules, the [`NAMESPACE`](NAMESPACE) file 202 | must be populated with imports for `Rcpp` and the `methods` _R_ packages. 203 | In addition, the package's dynamic library must be specified as well. 204 | 205 | There are two ways to go about this: 206 | 207 | 1. Let `roxygen2` automatically generate the `NAMESPACE` file; or 208 | 2. Manually specify in the `NAMESPACE` file. 209 | 210 | The `roxygen2` markup required can be found in [R/student-pkg.R](R/student-pkg.R). 211 | 212 | ```r 213 | #' @useDynLib RcppStudent, .registration = TRUE 214 | #' @import methods Rcpp 215 | "_PACKAGE" 216 | ``` 217 | 218 | Once the above is run during the documentation generation phase, the 219 | [`NAMESPACE`](NAMESPACE) file will be created with: 220 | 221 | ```r 222 | # Generated by roxygen2: do not edit by hand 223 | 224 | export(Student) 225 | import(Rcpp) 226 | import(methods) 227 | useDynLib(RcppStudent, .registration = TRUE) 228 | ``` 229 | 230 | Make sure to build and reload the package prior to accessing methods. 231 | 232 | ### Calling an Rcpp Module in R 233 | 234 | At this point, everything boils down to constructing an object from the class 235 | using `new()` from the `methods` package. The `new()` function initializes a 236 | _C++_ object from the specified _C++_ class and treats it like a 237 | traditional **S4** object. 238 | 239 | ```r 240 | ################## 241 | ## Constructor 242 | 243 | # Construct new Student object called "ben" 244 | ben = new(Student, name = "Ben", age = 26, male = TRUE) 245 | 246 | ################## 247 | ## Getters 248 | 249 | ben$LikesBlue() 250 | # [1] TRUE 251 | 252 | ben$GetAge() 253 | # [1] 26 254 | 255 | ben$IsMale() 256 | # [1] TRUE 257 | 258 | ben$GetName() 259 | # [1] "Ben" 260 | 261 | ben$GetFavoriteNumbers() 262 | # [1] 2 3 5 7 11 263 | ``` 264 | 265 | ## License 266 | 267 | GPL (\>= 2) 268 | -------------------------------------------------------------------------------- /RcppStudent.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://rd-rcpp.thecoatlessprofessor.com/rcpp-modules-student/ 2 | template: 3 | bootstrap: 5 4 | includes: 5 | in_header: | 6 | 8 | 9 | 10 | 17 | -------------------------------------------------------------------------------- /man/RcppStudent-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/student-pkg.R 3 | \docType{package} 4 | \name{RcppStudent-package} 5 | \alias{RcppStudent} 6 | \alias{RcppStudent-package} 7 | \title{RcppStudent: Expose the Student C++ Class using 'Rcpp Modules'} 8 | \description{ 9 | Provides an implementation of a Student 'C++' class being connected to 'R' using 'Rcpp Modules' to expose the underlying class methods. 10 | } 11 | \details{ 12 | RcppStudent is a package showing how to use Rcpp Modules to make available 13 | a C++ class under S4. 14 | } 15 | \seealso{ 16 | Useful links: 17 | \itemize{ 18 | \item \url{https://github.com/coatless-rd-rcpp/rcpp-modules-student} 19 | \item \url{https://rd-rcpp.thecoatlessprofessor.com/rcpp-modules-student/} 20 | \item Report bugs at \url{https://github.com/coatless-rd-rcpp/rcpp-modules-student/issues} 21 | } 22 | 23 | } 24 | \author{ 25 | \strong{Maintainer}: James Balamuta \email{balamut2@illinois.edu} 26 | 27 | Authors: 28 | \itemize{ 29 | \item Ben Gorman \email{bgorman@gormanalysis.com} 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /man/Student.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/student-exports.R 3 | \name{Student} 4 | \alias{Student} 5 | \title{Create a Student Object from the Student C++ Class} 6 | \arguments{ 7 | \item{name}{Name of Student} 8 | 9 | \item{age}{Age of Student} 10 | 11 | \item{male}{Is Student a Male?} 12 | } 13 | \value{ 14 | A \code{Student} object from the \emph{C++} Student Class. 15 | } 16 | \description{ 17 | Allows for the creation of a Student Object in \emph{C++} from \emph{R} 18 | using the \emph{C++} Student class. 19 | } 20 | \examples{ 21 | ################## 22 | ## Constructor 23 | 24 | # Construct new Student object called "ben" 25 | ben = new(Student, name = "Ben", age = 26, male = TRUE) 26 | 27 | ################## 28 | ## Getters 29 | 30 | ben$LikesBlue() 31 | 32 | ben$GetAge() 33 | 34 | ben$IsMale() 35 | 36 | ben$GetName() 37 | 38 | ben$GetFavoriteNumbers() 39 | } 40 | -------------------------------------------------------------------------------- /man/simulate_student.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{simulate_student} 4 | \alias{simulate_student} 5 | \title{Create a \code{Student} object.} 6 | \usage{ 7 | simulate_student() 8 | } 9 | \value{ 10 | An \code{integer} vector containing the student's favorite numbers. 11 | } 12 | \description{ 13 | Constructes a \code{Student} object with non-default values and accesses 14 | their favorite numbers. 15 | } 16 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | CXX_STD = CXX11 # Required for C++11 2 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | CXX_STD = CXX11 # Required for C++11 2 | -------------------------------------------------------------------------------- /src/RcppExports.cpp: -------------------------------------------------------------------------------- 1 | // Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | #include 5 | 6 | using namespace Rcpp; 7 | 8 | #ifdef RCPP_USE_GLOBAL_ROSTREAM 9 | Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); 10 | Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); 11 | #endif 12 | 13 | // simulate_student 14 | std::vector simulate_student(); 15 | RcppExport SEXP _RcppStudent_simulate_student() { 16 | BEGIN_RCPP 17 | Rcpp::RObject rcpp_result_gen; 18 | Rcpp::RNGScope rcpp_rngScope_gen; 19 | rcpp_result_gen = Rcpp::wrap(simulate_student()); 20 | return rcpp_result_gen; 21 | END_RCPP 22 | } 23 | 24 | RcppExport SEXP _rcpp_module_boot_RcppStudentEx(); 25 | 26 | static const R_CallMethodDef CallEntries[] = { 27 | {"_RcppStudent_simulate_student", (DL_FUNC) &_RcppStudent_simulate_student, 0}, 28 | {"_rcpp_module_boot_RcppStudentEx", (DL_FUNC) &_rcpp_module_boot_RcppStudentEx, 0}, 29 | {NULL, NULL, 0} 30 | }; 31 | 32 | RcppExport void R_init_RcppStudent(DllInfo *dll) { 33 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); 34 | R_useDynamicSymbols(dll, FALSE); 35 | } 36 | -------------------------------------------------------------------------------- /src/student.cpp: -------------------------------------------------------------------------------- 1 | // Student.cpp 2 | 3 | #include "student.h" 4 | 5 | // Constructor 6 | Student::Student(std::string name, int age, bool male) { 7 | this->name = name; 8 | this->age = age; 9 | this->male = male; 10 | this->favoriteNumbers = {2, 3, 5, 7, 11}; 11 | } 12 | 13 | // Getters 14 | bool Student::IsMale() { return male; } 15 | int Student::GetAge() { return age; } 16 | std::string Student::GetName() { return name; } 17 | std::vector Student::GetFavoriteNumbers() { return favoriteNumbers; } 18 | 19 | // Methods 20 | bool Student::LikesBlue() { 21 | return (male || age >= 10); 22 | } 23 | -------------------------------------------------------------------------------- /src/student.h: -------------------------------------------------------------------------------- 1 | // Student.h 2 | 3 | #ifndef Student_H 4 | #define Student_H 5 | 6 | #include 7 | #include 8 | 9 | class Student 10 | { 11 | public: 12 | 13 | // Constructor 14 | Student(std::string name, int age, bool male); 15 | 16 | // Getters 17 | std::string GetName(); 18 | int GetAge(); 19 | bool IsMale(); 20 | std::vector GetFavoriteNumbers(); 21 | 22 | // Methods 23 | bool LikesBlue(); 24 | 25 | private: 26 | 27 | // Member variables 28 | std::string name; 29 | int age; 30 | bool male; 31 | std::vector favoriteNumbers; 32 | }; 33 | 34 | #endif /* Student_H */ 35 | -------------------------------------------------------------------------------- /src/student_export.cpp: -------------------------------------------------------------------------------- 1 | // Include Rcpp system header file (e.g. <>) 2 | #include 3 | 4 | // Include our definition of the student file (e.g. "") 5 | #include "student.h" 6 | 7 | // Expose (some of) the Student class 8 | RCPP_MODULE(RcppStudentEx){ 9 | Rcpp::class_("Student") 10 | .constructor() 11 | .method("GetName", &Student::GetName) 12 | .method("GetAge", &Student::GetAge) 13 | .method("IsMale", &Student::IsMale) 14 | .method("GetFavoriteNumbers", &Student::GetFavoriteNumbers) 15 | .method("LikesBlue", &Student::LikesBlue); 16 | } 17 | -------------------------------------------------------------------------------- /src/student_non_modules.cpp: -------------------------------------------------------------------------------- 1 | // Include Rcpp system header file (e.g. <>) 2 | #include 3 | 4 | // Include our definition of the student file (e.g. "") 5 | #include "student.h" 6 | 7 | //' Create a `Student` object. 8 | //' 9 | //' Constructes a `Student` object with non-default values and accesses 10 | //' their favorite numbers. 11 | //' 12 | //' @return 13 | //' An `integer` vector containing the student's favorite numbers. 14 | //' 15 | //' @export 16 | // [[Rcpp::export]] 17 | std::vector simulate_student() { 18 | Student s = Student("bob", 10, true); 19 | return s.GetFavoriteNumbers(); 20 | } 21 | --------------------------------------------------------------------------------