---
title: "03 - Package Skeleton"
output:
  litedown::html_format:
    options:
      toc: true
      number_sections: true
vignette: >
  %\VignetteIndexEntry{03 - Package Skeleton}
  %\VignetteEngine{litedown::vignette}
  %\VignetteEncoding{UTF-8}
editor:
  markdown:
    wrap: sentence
bibliography: ["references.bib"]
---

The reference for this vignette is @usethis24.

## Loading the Required R Packages

This vignette and the next use the following R packages:

```r
library(cpp4r)
library(tinydev)
```

## Creating a Dummy Package

You can create a new package in RStudio (or VSCode) by running:

```r
pkg_template("~/mypkg")
```

This command will create a new folder containing the `mypkg` package.

## Print a Number

The `pkg_template()` function automatically creates `./mypkg/R/mypkg-package.R` with the following content:

```r
#' @title Package Title
#' @description Some description. CRAN asks for at least one paragraph with two full sentences. Like this.
#' @useDynLib mypkg, .registration = TRUE
"_PACKAGE"
```

It also creates `./mypkg/src/main.cpp`. The rest of `src/` aims to provide an organization to keep the code
organized into different files according to their purpose.

Give a look at `./mypkg/src/01_plus_one.h`, which contains the following C++ code:

```cpp
/* roxygen
@title Plus 1 (C++)
@param x integer
@description It adds 1 to an integer value.
@export
@examples plus_one(1)
*/
[[cpp4r::register]]
int plus_one(int x) {
  return x + 1;
}
```

This code is called by `main.cpp` and it makes sense to keep this organization when the codebase grows,
otherwise you can end up with a single large cpp file containing thousands of lines of code that will be harder to
maintain. With R packages, there is no need to create a `main()` function in C++, which is the entry point of a
standalone C++ program.

Unlike cpp11, cpp4r can document the C++ functions using Roxygen comments. The comments must be placed before the
`[[cpp4r::register]]` attribute.

## Exporting a Registered Function

Decorating a function with `[[cpp4r::register]]` only makes it callable via `.Call()` from R; it does not export or
document it. For example, this alone leaves `sum` undocumented and unexported:

```cpp
[[cpp4r::register]] int sum(int a, int b) { return a + b; }
```

There are two ways to export a registered function:

- Add a `/* roxygen ... */` comment block, including an `@export` tag, directly before the decorated function in the
  `C++` file, as shown above for `plus_one()`. `register()` copies it verbatim onto the generated R wrapper, so
  running `tinydev::pkg_document()` afterwards will export the wrapper and document it as usual.
- Give the `C++` function a name you don't want exposed directly (e.g. `sum_`), then write your own R wrapper that
  calls it and add a normal `#'` Roxygen comment block with `@export` above that wrapper instead.

Either way, `register()` and `[[cpp4r::register]]` alone never modify `NAMESPACE`; running `tinydev::pkg_document(".")`
(or hand-editing `NAMESPACE`) is what actually exports the function.

With cpp11, you would need to write a separate wrapper, like this:

```cpp
[[cpp11::register]] int plus_one_(int x) {
  return x + 1;
}
```

```r
#' @title Plus 1 (C++)
#' @param x integer
#' @description It adds 1 to an integer value.
#' @export
#' @examples plus_one(1)
plus_one <- function(x) {
  plus_one_(x)
}
```

With cpp4r you can type:

```cpp
/* roxygen
@title Plus 1 (C++)
@param x integer
@description It adds 1 to an integer value.
@export
@examples plus_one(1)
*/
[[cpp4r::register]] int plus_one(int x) {
  return x + 1;
}
```

The R version of the previous function is as follows:

```r
#' Plus one (R)
#' @param x integer
#' @description It adds 1 to an integer value.
#' @export
#' @examples plus_one_r(1)
plus_one_r <- function(x) {
  x + 1
}
```

To use the C++ function, you can register and document it by running:

```r
cpp4r::register()
tinydev::pkg_document(".")
tinydev::pkg_load(".")
```

Which should print:

```r
> plus_one(1)
[1] 2
```

Try `plus_two(1)` and `plus_two(1.0)`. Why does 1 and 1.0 matter in C++?

## Number's Sign

A more complex function is one that returns the sign of a number:

```cpp
[[cpp4r::register]] int sign_cpp(double x) {
  if (x > 0) {
    return 1;
  } else if (x == 0) {
    return 0;
  } else {
    return -1;
  }
}
```

Add this function to a new file `src/03_sign.h`.

Here is the R version of the function:

```r
sign_r <- function(x) {
  if (x > 0) {
    1
  } else if (x == 0) {
    0
  } else {
    -1
  }
}
```

Do not forget to include the new header file in `main.cpp`.

Document both functions and compare their outputs.

## Installing the Package

To document and install the package as an R library, you can run the following functions:

```r
cpp4r::register()
tinydev::pkg_document(".")
tinydev::pkg_install(".")
```

Afterward, you can access the functions by loading the package with `library(mypkg)`.

Each time you need to make changes to the C++ code, you can run `load_all()` again to test and then reinstall the package.

## Good Practice

It is good practice to include a license for your code. For example, you can use the Apache license by running:

```r
tinydev::license_apache(".")
```

You also need to ignore files that are unnecessary for package installation. For example, to ignore the `docs` folder, add
`^docs$` to `.Rbuildignore`. Your `.Rbuildignore` file can include the following lines, which you can edit manually to exclude
specific files and directories:

```
^\.vscode$
^LICENSE\.txt$
`^docs$`
```

## References
