Skip to content

Commit b11a05e

Browse files
committed
updated vignettes
1 parent 2943c72 commit b11a05e

File tree

140 files changed

+5215
-5867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+5215
-5867
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ script.R
3131
^\.cache$
3232
^docs$
3333
^pkgdown$
34+
^cpp4rexamples$
3435
^cpp4rdummyols$
3536
^cpp4rgaussjordan$
3637
^cpp4romp$

.github/workflows/R-CMD-check.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
- uses: pachadotdev/clang-format@main
5151
if: matrix.config.custom == 'clang-format'
5252
with:
53-
version: '14'
53+
version: '18'
5454
files: 'src/*.cpp src/*.h inst/include/*.h'
5555
auto-commit: true
5656
commit-message: 'style: format C++ code in R package'

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ site:
2020
install:
2121
@Rscript -e 'devtools::install()'
2222

23-
clang_format=`which clang-format-20`
23+
clang_format=`which clang-format-18`
2424

2525
format: $(shell find . -name '*.h') $(shell find . -name '*.hpp') $(shell find . -name '*.cpp')
2626
@${clang_format} -i $?

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
export(pkg_template)
34
export(register)
45
export(unvendor)
56
export(vendor)

R/register.R

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,16 @@ register <- function(path = ".", quiet = !is_interactive(), extension = c(".cpp"
7777
cli::cli_alert_success("generated file {.file {basename(r_path)}}")
7878
}
7979

80-
8180
call_entries <- get_call_entries(path, funs$name, package)
8281

8382
cpp_function_registration <- glue::glue_data(funs, ' {{
8483
"_cpp4r_{name}", (DL_FUNC) &_{package}_{name}, {n_args}}}, ',
8584
n_args = viapply(funs$args, nrow)
8685
)
8786

88-
cpp_function_registration <- glue::glue_collapse(cpp_function_registration, sep = "\n")
87+
cpp_function_registration <- glue::glue_collapse(cpp_function_registration, sep = "\n")
8988

90-
extra_includes <- character()
89+
extra_includes <- character()
9190
if (pkg_links_to_rcpp(path)) {
9291
extra_includes <- c(extra_includes, "#include <cpp4r/R.hpp>", "#include <Rcpp.h>", "using namespace Rcpp;")
9392
}
@@ -215,35 +214,92 @@ generate_init_functions <- function(funs) {
215214
}
216215

217216
generate_r_functions <- function(funs, package = "cpp4r", use_package = FALSE) {
218-
funs <- funs[c("name", "return_type", "args")]
217+
funs <- funs[c("name", "return_type", "args", "file", "line", "decoration")]
219218

220219
if (use_package) {
221220
package_call <- glue::glue(', PACKAGE = "{package}"')
222221
package_names <- glue::glue_data(funs, '"_{package}_{name}"')
223222
} else {
224-
package_names <- glue::glue_data(funs, '`_{package}_{name}`')
223+
package_names <- glue::glue_data(funs, "`_{package}_{name}`")
225224
package_call <- ""
226225
}
227226

228-
funs$package <- package
229227
funs$package_call <- package_call
230228
funs$list_params <- vcapply(funs$args, glue_collapse_data, "{name}")
231229
funs$params <- vcapply(funs$list_params, function(x) if (nzchar(x)) paste0(", ", x) else x)
232230
is_void <- funs$return_type == "void"
233231
funs$calls <- ifelse(is_void,
234-
glue::glue_data(funs, 'invisible(.Call({package_names}{params}{package_call}))'),
235-
glue::glue_data(funs, '.Call({package_names}{params}{package_call})')
232+
glue::glue_data(funs, "invisible(.Call({package_names}{params}{package_call}))"),
233+
glue::glue_data(funs, ".Call({package_names}{params}{package_call})")
236234
)
237235

238-
out <- glue::glue_data(funs, '
239-
{name} <- function({list_params}) {{
240-
{calls}
241-
}}
242-
')
236+
# Parse and associate Roxygen comments
237+
funs$roxygen_comment <- mapply(function(file, line) {
238+
if (file.exists(file)) {
239+
comments <- extract_roxygen_comments(file)
240+
matched_comment <- ""
241+
for (comment in comments) {
242+
# Check if the comment directly precedes the function without gaps
243+
if (line == comment$line + 1) {
244+
matched_comment <- comment$text
245+
break
246+
}
247+
}
248+
matched_comment
249+
} else {
250+
""
251+
}
252+
}, funs$file, funs$line, SIMPLIFY = TRUE)
253+
254+
# Generate R functions with or without Roxygen comments
255+
out <- mapply(function(name, list_params, calls, roxygen_comment) {
256+
if (nzchar(roxygen_comment)) {
257+
glue::glue("{roxygen_comment}\n{name} <- function({list_params}) {{\n\t{calls}\n}}")
258+
} else {
259+
glue::glue("{name} <- function({list_params}) {{\n {calls}\n}}")
260+
}
261+
}, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, SIMPLIFY = TRUE)
262+
263+
out <- glue::trim(out)
243264
out <- glue::glue_collapse(out, sep = "\n\n")
244265
unclass(out)
245266
}
246267

268+
extract_roxygen_comments <- function(file) {
269+
lines <- readLines(file)
270+
271+
# Look for roxygen comments that start with /* roxygen
272+
roxygen_start <- grep("^/\\* roxygen\\s*$", lines)
273+
274+
if (length(roxygen_start) == 0) {
275+
return(list())
276+
}
277+
278+
roxygen_comments <- lapply(roxygen_start, function(start) {
279+
# Find the end of the comment block (line ending with */)
280+
end_line <- start + 1
281+
while (end_line <= length(lines) && !grepl("\\*/$", lines[end_line])) {
282+
end_line <- end_line + 1
283+
}
284+
285+
# If we didn't find an end, skip this comment
286+
if (end_line > length(lines)) {
287+
return(NULL)
288+
}
289+
290+
# Extract the roxygen content (excluding the start and end lines)
291+
roxygen_lines <- lines[(start + 1):(end_line - 1)]
292+
293+
# Convert to R roxygen format by adding #' prefix
294+
roxygen_lines <- sub("^", "#' ", roxygen_lines)
295+
296+
list(line = end_line, text = paste(roxygen_lines, collapse = "\n"))
297+
})
298+
299+
# Remove NULL entries
300+
roxygen_comments[!sapply(roxygen_comments, is.null)]
301+
}
302+
247303
wrap_call <- function(name, return_type, args) {
248304
call <- glue::glue('{name}({list_params})', list_params = glue_collapse_data(args, "cpp4r::as_cpp<cpp4r::decay_t<{type}>>({name})"))
249305
if (return_type == "void") {

R/template.R

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# The function itself just echos its inputs and outputs to a file called INDEX,
2+
# which is then opened by RStudio when the new project is opened.
3+
#' Start a new project with the cpp4r package template
4+
#' @param path Path to the new project
5+
#' @param pkgname Name of the new package
6+
#' @return The file path to the copied template (invisibly).
7+
#' @examples
8+
#' # create a new directory
9+
#' dir <- tempdir()
10+
#' dir.create(dir)
11+
#'
12+
#' # copy the package template into the directory
13+
#' pkg_template(dir, "mynewpkg")
14+
#' @export
15+
pkg_template <- function(path = NULL, pkgname = NULL) {
16+
if (is.null(path)) {
17+
stop("You must provide a path to the new project", call. = FALSE)
18+
}
19+
if (is.null(pkgname)) {
20+
pkgname <- basename(path)
21+
}
22+
23+
# ensure path exists
24+
dir.create(path, recursive = TRUE, showWarnings = FALSE)
25+
26+
# copy files
27+
file.copy(
28+
list.files(
29+
system.file("extdata/pkgtemplate", "", package = "cpp4r"),
30+
full.names = TRUE
31+
),
32+
path,
33+
recursive = TRUE
34+
)
35+
36+
dir.create(paste0(path, "/R"), recursive = TRUE, showWarnings = FALSE)
37+
38+
lines <- c(
39+
"^.*\\.Rproj$",
40+
"^\\.Rproj\\.user$",
41+
"^\\.Renviron$",
42+
"^docs$",
43+
"^vignettes/images$",
44+
"^\\.github$",
45+
"^\\.vscode$",
46+
"^dev$",
47+
"^LICENSE\\.md$",
48+
"^README$",
49+
"^README\\.Rmd$"
50+
)
51+
52+
writeLines(lines, con = paste0(path, "/.Rbuildignore"))
53+
54+
lines <- c(
55+
paste0("#' @useDynLib ", pkgname, ", .registration = TRUE"),
56+
"#' @keywords internal",
57+
"\"_PACKAGE\""
58+
)
59+
60+
writeLines(lines, con = paste0(path, "/R/", pkgname, "-package.R"))
61+
62+
# get roxygen version
63+
roxyver <- as.character(utils::packageVersion("roxygen2"))
64+
65+
lines <- c(
66+
paste("Package:", pkgname),
67+
"Type: Package",
68+
"Title: ADD TITLE",
69+
"Version: 0.1",
70+
"Authors@R: c(",
71+
" person(",
72+
" given = \"YOUR\",",
73+
" family = \"NAME\",",
74+
" role = c(\"aut\", \"cre\"),",
75+
" email = \"[email protected]\",",
76+
" comment = c(ORCID = \"0000-0001-0002-0003\"))",
77+
" )",
78+
"Suggests: ",
79+
" knitr,",
80+
" rmarkdown",
81+
"Depends: R(>= 3.5.0)",
82+
"Description: ADD DESCRIPTION. TWO OR MORE LINES",
83+
"License: ADD LICENSE",
84+
"BugReports: https://github.com/USERNAME/PKGNAME/issues",
85+
"URL: https://WEBSITE.COM",
86+
# "RoxygenNote: 7.3.0",
87+
paste0("RoxygenNote: ", roxyver),
88+
"Encoding: UTF-8",
89+
"NeedsCompilation: yes",
90+
"VignetteBuilder: knitr",
91+
"LinkingTo: cpp4r"
92+
)
93+
94+
writeLines(lines, con = paste0(path, "/DESCRIPTION"))
95+
96+
invisible(path)
97+
}

README.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,37 @@ After discussing some [pull requests](https://github.com/r-lib/cpp11/pulls/pacha
2424
- [x] Provide flexibility with data types (e.g., cpp4r's `as_integers()` and `as_doubles()` accept logical inputs while cpp11's do not).
2525
- [x] Some internal optimizations for better speed (e.g., https://github.com/r-lib/cpp11/pull/463 and https://github.com/r-lib/cpp11/pull/430).
2626

27+
## Getting started
28+
29+
Check the [documentation](https://cpp4r.org/) to get started using cpp4r in your scripts, particularly if you are new to C++ programming.
30+
2731
## Using cpp4r in a package
2832

33+
Create a new package with `cpp4r::pkg_template("~/path/to/mypkg")` and then edit the generated files.
34+
2935
To add cpp4r to an existing package, put your C++ files in the `src/` directory and add the following to your DESCRIPTION file:
3036

3137
```
3238
LinkingTo: cpp4r
3339
```
3440

41+
Then add a roxygen header, for example, to `R/mypkg-package.R`:
42+
43+
```r
44+
#' @useDynLib mypkg, .registration = TRUE
45+
#' @keywords internal
46+
"_PACKAGE"
47+
```
48+
3549
Then decorate C++ functions you want to expose to R with `[[cpp4r::register]]`.
3650

37-
cpp4r is a header only library with no hard dependencies and does not use a shared library, so it is straightforward and reliable to use in packages without fear of compile-time and run-time mismatches.
51+
cpp4r is a header only library with no hard dependencies and does not use a shared library. It is straightforward and reliable to use in packages without fear of compile-time and run-time mismatches.
3852

39-
Alternatively, you can [vendor](https://cpp4r.org/articles/motivations.html#vendoring) the current installed version of cpp4r headers into your package with `cpp4r::vendor_cpp4r()`.
40-
This ensures the headers will remain unchanged until you explicitly update them.
53+
## Vendoring
4154

42-
## Getting started
55+
You can [vendor](https://cpp4r.org/articles/motivations.html#vendoring) the current installed version of cpp4r headers into your package with `cpp4r::vendor_cpp4r()`.
4356

44-
See [vignette("cpp4r")](https://cpp4r.org/articles/cpp4r.html) to get started using cpp4r in your scripts, particularly if you are new to C++ programming.
57+
This ensures the headers will remain unchanged until you explicitly update them.
4558

4659
## Getting help
4760

_pkgdown.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
template:
22
bootstrap: 5
33

4-
url: https://cpp4r.org
4+
url: "./"
55
destination: docs

cpp4rexamples/.Rbuildignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
^.*\.Rproj$
2+
^\.Rproj\.user$
3+
^\.Renviron$
4+
^docs$
5+
^vignettes/images$
6+
^\.github$
7+
^\.vscode$
8+
^dev$
9+
^LICENSE\.md$
10+
^README$
11+
^README\.Rmd$

cpp4rexamples/DESCRIPTION

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Package: cpp4rexamples
2+
Type: Package
3+
Title: ADD TITLE
4+
Version: 0.1
5+
Authors@R: c(
6+
person(
7+
given = "YOUR",
8+
family = "NAME",
9+
role = c("aut", "cre"),
10+
email = "[email protected]",
11+
comment = c(ORCID = "0000-0001-0002-0003"))
12+
)
13+
Suggests:
14+
knitr,
15+
rmarkdown
16+
Depends: R(>= 3.5.0)
17+
Description: ADD DESCRIPTION. TWO OR MORE LINES
18+
License: ADD LICENSE
19+
BugReports: https://github.com/USERNAME/PKGNAME/issues
20+
URL: https://WEBSITE.COM
21+
RoxygenNote: 7.3.2
22+
Encoding: UTF-8
23+
NeedsCompilation: yes
24+
VignetteBuilder: knitr
25+
LinkingTo: cpp4r

0 commit comments

Comments
 (0)