From fb3583fac5d523f362d70b78cb67939a6edec2ee Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 3 Jan 2025 13:23:11 +0000 Subject: [PATCH 01/10] roxygen comments on cpp side (works ok with 1 roxygenised function per script for now) --- R/register.R | 34 ++++++--- cpp11test/DESCRIPTION | 2 +- cpp11test/R/cpp11.R | 160 ++++++++++++++++++++++++---------------- cpp11test/src/cpp11.cpp | 32 ++++++++ 4 files changed, 155 insertions(+), 73 deletions(-) diff --git a/R/register.R b/R/register.R index 3ea10d52..fe49f749 100644 --- a/R/register.R +++ b/R/register.R @@ -77,7 +77,6 @@ cpp_register <- function(path = ".", quiet = !is_interactive(), extension = c(". cli::cli_alert_success("generated file {.file {basename(r_path)}}") } - call_entries <- get_call_entries(path, funs$name, package) cpp_function_registration <- glue::glue_data(funs, ' {{ @@ -85,9 +84,9 @@ cpp_register <- function(path = ".", quiet = !is_interactive(), extension = c(". n_args = viapply(funs$args, nrow) ) - cpp_function_registration <- glue::glue_collapse(cpp_function_registration, sep = "\n") + cpp_function_registration <- glue::glue_collapse(cpp_function_registration, sep = "\n") - extra_includes <- character() + extra_includes <- character() if (pkg_links_to_rcpp(path)) { extra_includes <- c(extra_includes, "#include ", "#include ", "using namespace Rcpp;") } @@ -215,13 +214,13 @@ generate_init_functions <- function(funs) { } generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { - funs <- funs[c("name", "return_type", "args")] + funs <- funs[c("name", "return_type", "args", "file", "line", "decoration")] if (use_package) { package_call <- glue::glue(', PACKAGE = "{package}"') package_names <- glue::glue_data(funs, '"_{package}_{name}"') } else { - package_names <- glue::glue_data(funs, '`_{package}_{name}`') + package_names <- glue::glue_data(funs, "`_{package}_{name}`") package_call <- "" } @@ -235,15 +234,30 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { glue::glue_data(funs, '.Call({package_names}{params}{package_call})') ) - out <- glue::glue_data(funs, ' - {name} <- function({list_params}) {{ - {calls} - }} - ') + roxygen_comments <- lapply(funs$file, extract_roxygen_comments) + + out <- mapply(function(name, list_params, calls, roxygen_comment) { + glue::glue("{if (nzchar(roxygen_comment)) paste0(roxygen_comment, '\n') else ''}{name} <- function({list_params}) {{\n\t{calls}\n}}") + }, funs$name, funs$list_params, funs$calls, roxygen_comments, SIMPLIFY = TRUE) + out <- glue::trim(out) out <- glue::glue_collapse(out, sep = "\n\n") unclass(out) } +extract_roxygen_comments <- function(file) { + lines <- readLines(file) + roxygen_start <- grep("^/\\* roxygen start", lines) + roxygen_end <- grep("roxygen end \\*/$", lines) + + if (length(roxygen_start) == 0 || length(roxygen_end) == 0) { + return("") + } + + roxygen_lines <- lines[(roxygen_start + 1):(roxygen_end - 1)] + roxygen_lines <- sub("^@", "#' @", roxygen_lines) + paste(roxygen_lines, collapse = "\n") +} + wrap_call <- function(name, return_type, args) { call <- glue::glue('{name}({list_params})', list_params = glue_collapse_data(args, "cpp11::as_cpp>({name})")) if (return_type == "void") { diff --git a/cpp11test/DESCRIPTION b/cpp11test/DESCRIPTION index d1d05665..70c5649f 100644 --- a/cpp11test/DESCRIPTION +++ b/cpp11test/DESCRIPTION @@ -20,4 +20,4 @@ Suggests: xml2 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.1.1 +RoxygenNote: 7.3.2 diff --git a/cpp11test/R/cpp11.R b/cpp11test/R/cpp11.R index 038e7b76..3a4b1a2b 100644 --- a/cpp11test/R/cpp11.R +++ b/cpp11test/R/cpp11.R @@ -1,249 +1,285 @@ # Generated by cpp11: do not edit by hand cpp11_add_vec_for_ <- function(x, num) { - .Call(`_cpp11test_cpp11_add_vec_for_`, x, num) + .Call(`_cpp11test_cpp11_add_vec_for_`, x, num) } data_frame_ <- function() { - .Call(`_cpp11test_data_frame_`) + .Call(`_cpp11test_data_frame_`) } my_stop_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_stop_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_stop_n1fmt`, mystring)) } my_stop_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_stop_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_stop_n2fmt`, mystring, myarg)) } my_warning_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_warning_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_warning_n1fmt`, mystring)) } my_warning_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_warning_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_warning_n2fmt`, mystring, myarg)) } my_message_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_message_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_message_n1fmt`, mystring)) } my_message_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_message_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_message_n2fmt`, mystring, myarg)) } my_stop <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_stop`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_stop`, mystring, myarg)) } my_stop_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_stop_n1`, mystring)) + invisible(.Call(`_cpp11test_my_stop_n1`, mystring)) } my_warning <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_warning`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_warning`, mystring, myarg)) } my_warning_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_warning_n1`, mystring)) + invisible(.Call(`_cpp11test_my_warning_n1`, mystring)) } my_message <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_message`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_message`, mystring, myarg)) } my_message_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_message_n1`, mystring)) + invisible(.Call(`_cpp11test_my_message_n1`, mystring)) } remove_altrep <- function(x) { - .Call(`_cpp11test_remove_altrep`, x) + .Call(`_cpp11test_remove_altrep`, x) } upper_bound <- function(x, breaks) { - .Call(`_cpp11test_upper_bound`, x, breaks) + .Call(`_cpp11test_upper_bound`, x, breaks) } findInterval2 <- function(x, breaks) { - .Call(`_cpp11test_findInterval2`, x, breaks) + .Call(`_cpp11test_findInterval2`, x, breaks) } findInterval2_5 <- function(x, breaks) { - .Call(`_cpp11test_findInterval2_5`, x, breaks) + .Call(`_cpp11test_findInterval2_5`, x, breaks) } findInterval3 <- function(x, breaks) { - .Call(`_cpp11test_findInterval3`, x, breaks) + .Call(`_cpp11test_findInterval3`, x, breaks) } findInterval4 <- function(x, breaks) { - .Call(`_cpp11test_findInterval4`, x, breaks) + .Call(`_cpp11test_findInterval4`, x, breaks) } grow_ <- function(n) { - .Call(`_cpp11test_grow_`, n) + .Call(`_cpp11test_grow_`, n) } cpp11_insert_ <- function(num_sxp) { - .Call(`_cpp11test_cpp11_insert_`, num_sxp) + .Call(`_cpp11test_cpp11_insert_`, num_sxp) } gibbs_cpp <- function(N, thin) { - .Call(`_cpp11test_gibbs_cpp`, N, thin) + .Call(`_cpp11test_gibbs_cpp`, N, thin) } gibbs_cpp2 <- function(N, thin) { - .Call(`_cpp11test_gibbs_cpp2`, N, thin) + .Call(`_cpp11test_gibbs_cpp2`, N, thin) } gibbs_rcpp <- function(N, thin) { - .Call(`_cpp11test_gibbs_rcpp`, N, thin) + .Call(`_cpp11test_gibbs_rcpp`, N, thin) } gibbs_rcpp2 <- function(N, thin) { - .Call(`_cpp11test_gibbs_rcpp2`, N, thin) + .Call(`_cpp11test_gibbs_rcpp2`, N, thin) } row_sums <- function(x) { - .Call(`_cpp11test_row_sums`, x) + .Call(`_cpp11test_row_sums`, x) } col_sums <- function(x) { - .Call(`_cpp11test_col_sums`, x) + .Call(`_cpp11test_col_sums`, x) } protect_one_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_`, x, n)) } protect_one_sexp_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_sexp_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_sexp_`, x, n)) } protect_one_cpp11_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_cpp11_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_cpp11_`, x, n)) } protect_one_preserve_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_preserve_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_preserve_`, x, n)) } protect_many_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_`, n)) + invisible(.Call(`_cpp11test_protect_many_`, n)) } protect_many_cpp11_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_cpp11_`, n)) + invisible(.Call(`_cpp11test_protect_many_cpp11_`, n)) } protect_many_sexp_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_sexp_`, n)) + invisible(.Call(`_cpp11test_protect_many_sexp_`, n)) } protect_many_preserve_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_preserve_`, n)) + invisible(.Call(`_cpp11test_protect_many_preserve_`, n)) } protect_many_rcpp_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_rcpp_`, n)) + invisible(.Call(`_cpp11test_protect_many_rcpp_`, n)) } cpp11_release_ <- function(n) { - invisible(.Call(`_cpp11test_cpp11_release_`, n)) + invisible(.Call(`_cpp11test_cpp11_release_`, n)) } rcpp_release_ <- function(n) { - invisible(.Call(`_cpp11test_rcpp_release_`, n)) + invisible(.Call(`_cpp11test_rcpp_release_`, n)) +} + +#' @title Roxygenise C++ function +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @export +#' @examples roxcpp_(1.0) +roxcpp1_ <- function(x) { + .Call(`_cpp11test_roxcpp1_`, x) +} + +#' @title Roxygenise C++ function +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @export +#' @examples roxcpp_(1.0) +roxcpp2_ <- function(x) { + .Call(`_cpp11test_roxcpp2_`, x) +} + +#' @title Roxygenise C++ function +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @export +#' @examples roxcpp_(1.0) +roxcpp3_ <- function(x) { + .Call(`_cpp11test_roxcpp3_`, x) +} + +#' @title Roxygenise C++ function +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @export +#' @examples roxcpp_(1.0) +roxcpp4_ <- function(x) { + .Call(`_cpp11test_roxcpp4_`, x) } cpp11_safe_ <- function(x_sxp) { - .Call(`_cpp11test_cpp11_safe_`, x_sxp) + .Call(`_cpp11test_cpp11_safe_`, x_sxp) } string_proxy_assignment_ <- function() { - .Call(`_cpp11test_string_proxy_assignment_`) + .Call(`_cpp11test_string_proxy_assignment_`) } string_push_back_ <- function() { - .Call(`_cpp11test_string_push_back_`) + .Call(`_cpp11test_string_push_back_`) } sum_dbl_for_ <- function(x) { - .Call(`_cpp11test_sum_dbl_for_`, x) + .Call(`_cpp11test_sum_dbl_for_`, x) } sum_dbl_for2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_for2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_for2_`, x_sxp) } sum_dbl_for3_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_for3_`, x_sxp) + .Call(`_cpp11test_sum_dbl_for3_`, x_sxp) } sum_dbl_foreach_ <- function(x) { - .Call(`_cpp11test_sum_dbl_foreach_`, x) + .Call(`_cpp11test_sum_dbl_foreach_`, x) } sum_dbl_foreach2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_foreach2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_foreach2_`, x_sxp) } sum_dbl_accumulate_ <- function(x) { - .Call(`_cpp11test_sum_dbl_accumulate_`, x) + .Call(`_cpp11test_sum_dbl_accumulate_`, x) } sum_dbl_accumulate2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_accumulate2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_accumulate2_`, x_sxp) } sum_int_for_ <- function(x) { - .Call(`_cpp11test_sum_int_for_`, x) + .Call(`_cpp11test_sum_int_for_`, x) } sum_int_for2_ <- function(x_) { - .Call(`_cpp11test_sum_int_for2_`, x_) + .Call(`_cpp11test_sum_int_for2_`, x_) } sum_int_foreach_ <- function(x) { - .Call(`_cpp11test_sum_int_foreach_`, x) + .Call(`_cpp11test_sum_int_foreach_`, x) } sum_int_accumulate_ <- function(x) { - .Call(`_cpp11test_sum_int_accumulate_`, x) + .Call(`_cpp11test_sum_int_accumulate_`, x) } rcpp_sum_dbl_for_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_for_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_for_`, x_sxp) } rcpp_sum_int_for_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_int_for_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_int_for_`, x_sxp) } rcpp_sum_dbl_foreach_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_foreach_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_foreach_`, x_sxp) } rcpp_sum_dbl_accumulate_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_accumulate_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_accumulate_`, x_sxp) } rcpp_grow_ <- function(n_sxp) { - .Call(`_cpp11test_rcpp_grow_`, n_sxp) + .Call(`_cpp11test_rcpp_grow_`, n_sxp) } rcpp_push_and_truncate_ <- function(size_sxp) { - .Call(`_cpp11test_rcpp_push_and_truncate_`, size_sxp) + .Call(`_cpp11test_rcpp_push_and_truncate_`, size_sxp) } test_destruction_inner <- function() { - invisible(.Call(`_cpp11test_test_destruction_inner`)) + invisible(.Call(`_cpp11test_test_destruction_inner`)) } test_destruction_outer <- function() { - invisible(.Call(`_cpp11test_test_destruction_outer`)) + invisible(.Call(`_cpp11test_test_destruction_outer`)) } cpp11_push_and_truncate_ <- function(size_sexp) { - .Call(`_cpp11test_cpp11_push_and_truncate_`, size_sexp) + .Call(`_cpp11test_cpp11_push_and_truncate_`, size_sexp) } diff --git a/cpp11test/src/cpp11.cpp b/cpp11test/src/cpp11.cpp index 421de637..55e48fbc 100644 --- a/cpp11test/src/cpp11.cpp +++ b/cpp11test/src/cpp11.cpp @@ -303,6 +303,34 @@ extern "C" SEXP _cpp11test_rcpp_release_(SEXP n) { return R_NilValue; END_CPP11 } +// roxygen1.cpp +double roxcpp1_(double x); +extern "C" SEXP _cpp11test_roxcpp1_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp1_(cpp11::as_cpp>(x))); + END_CPP11 +} +// roxygen1.cpp +double roxcpp2_(double x); +extern "C" SEXP _cpp11test_roxcpp2_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp2_(cpp11::as_cpp>(x))); + END_CPP11 +} +// roxygen2.cpp +double roxcpp3_(double x); +extern "C" SEXP _cpp11test_roxcpp3_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp3_(cpp11::as_cpp>(x))); + END_CPP11 +} +// roxygen2.cpp +double roxcpp4_(double x); +extern "C" SEXP _cpp11test_roxcpp4_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp4_(cpp11::as_cpp>(x))); + END_CPP11 +} // safe.cpp SEXP cpp11_safe_(SEXP x_sxp); extern "C" SEXP _cpp11test_cpp11_safe_(SEXP x_sxp) { @@ -518,6 +546,10 @@ static const R_CallMethodDef CallEntries[] = { {"_cpp11test_rcpp_sum_int_for_", (DL_FUNC) &_cpp11test_rcpp_sum_int_for_, 1}, {"_cpp11test_remove_altrep", (DL_FUNC) &_cpp11test_remove_altrep, 1}, {"_cpp11test_row_sums", (DL_FUNC) &_cpp11test_row_sums, 1}, + {"_cpp11test_roxcpp1_", (DL_FUNC) &_cpp11test_roxcpp1_, 1}, + {"_cpp11test_roxcpp2_", (DL_FUNC) &_cpp11test_roxcpp2_, 1}, + {"_cpp11test_roxcpp3_", (DL_FUNC) &_cpp11test_roxcpp3_, 1}, + {"_cpp11test_roxcpp4_", (DL_FUNC) &_cpp11test_roxcpp4_, 1}, {"_cpp11test_string_proxy_assignment_", (DL_FUNC) &_cpp11test_string_proxy_assignment_, 0}, {"_cpp11test_string_push_back_", (DL_FUNC) &_cpp11test_string_push_back_, 0}, {"_cpp11test_sum_dbl_accumulate2_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate2_, 1}, From 14531dbcd16434838c475b2bf435dfc376494b0d Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 04:10:39 +0000 Subject: [PATCH 02/10] almost there with rx/no rx in the same file --- R/register.R | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/R/register.R b/R/register.R index fe49f749..10ff5cdb 100644 --- a/R/register.R +++ b/R/register.R @@ -224,21 +224,33 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { package_call <- "" } - funs$package <- package funs$package_call <- package_call funs$list_params <- vcapply(funs$args, glue_collapse_data, "{name}") funs$params <- vcapply(funs$list_params, function(x) if (nzchar(x)) paste0(", ", x) else x) is_void <- funs$return_type == "void" funs$calls <- ifelse(is_void, - glue::glue_data(funs, 'invisible(.Call({package_names}{params}{package_call}))'), - glue::glue_data(funs, '.Call({package_names}{params}{package_call})') + glue::glue_data(funs, "invisible(.Call({package_names}{params}{package_call}))"), + glue::glue_data(funs, ".Call({package_names}{params}{package_call})") ) roxygen_comments <- lapply(funs$file, extract_roxygen_comments) - out <- mapply(function(name, list_params, calls, roxygen_comment) { - glue::glue("{if (nzchar(roxygen_comment)) paste0(roxygen_comment, '\n') else ''}{name} <- function({list_params}) {{\n\t{calls}\n}}") - }, funs$name, funs$list_params, funs$calls, roxygen_comments, SIMPLIFY = TRUE) + out <- mapply(function(name, list_params, calls, file, line) { + comments <- extract_roxygen_comments(file) + roxygen_comment <- "" + for (comment in comments) { + if (comment$line < line) { + roxygen_comment <- comment$text + } + } + if (nzchar(roxygen_comment)) { + glue::glue("{roxygen_comment}\n{name} <- function({list_params}) {{\n\t{calls}\n}}") + } else { + glue::glue("{name} <- function({list_params}) {{\n\t{calls}\n}}") + } + }, funs$name, funs$list_params, funs$calls, funs$file, funs$line, SIMPLIFY = FALSE) + + out <- as.character(out) out <- glue::trim(out) out <- glue::glue_collapse(out, sep = "\n\n") unclass(out) @@ -250,12 +262,16 @@ extract_roxygen_comments <- function(file) { roxygen_end <- grep("roxygen end \\*/$", lines) if (length(roxygen_start) == 0 || length(roxygen_end) == 0) { - return("") + return(list()) } - roxygen_lines <- lines[(roxygen_start + 1):(roxygen_end - 1)] - roxygen_lines <- sub("^@", "#' @", roxygen_lines) - paste(roxygen_lines, collapse = "\n") + roxygen_comments <- mapply(function(start, end) { + roxygen_lines <- lines[(start + 1):(end - 1)] + roxygen_lines <- sub("^@", "#' @", roxygen_lines) + list(line = start, text = paste(roxygen_lines, collapse = "\n")) + }, roxygen_start, roxygen_end, SIMPLIFY = FALSE) + + roxygen_comments } wrap_call <- function(name, return_type, args) { From c750115870ec8a12de191414e53b70611c081703 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 04:56:13 +0000 Subject: [PATCH 03/10] correctly handles roxygen in cpp files --- R/register.R | 22 ++++++++++------- cpp11test/NAMESPACE | 5 ++++ cpp11test/R/cpp11.R | 49 +++++++++++++++++++++++++------------- cpp11test/man/roxcpp2_.Rd | 17 +++++++++++++ cpp11test/man/roxcpp3_.Rd | 17 +++++++++++++ cpp11test/man/roxcpp4_.Rd | 17 +++++++++++++ cpp11test/man/roxcpp5_.Rd | 17 +++++++++++++ cpp11test/man/roxcpp7_.Rd | 17 +++++++++++++ cpp11test/src/cpp11.cpp | 32 +++++++++++++++++++++---- cpp11test/src/roxygen1.cpp | 22 +++++++++++++++++ cpp11test/src/roxygen2.cpp | 28 ++++++++++++++++++++++ cpp11test/src/roxygen3.cpp | 34 ++++++++++++++++++++++++++ 12 files changed, 249 insertions(+), 28 deletions(-) create mode 100644 cpp11test/man/roxcpp2_.Rd create mode 100644 cpp11test/man/roxcpp3_.Rd create mode 100644 cpp11test/man/roxcpp4_.Rd create mode 100644 cpp11test/man/roxcpp5_.Rd create mode 100644 cpp11test/man/roxcpp7_.Rd create mode 100644 cpp11test/src/roxygen1.cpp create mode 100644 cpp11test/src/roxygen2.cpp create mode 100644 cpp11test/src/roxygen3.cpp diff --git a/R/register.R b/R/register.R index 10ff5cdb..cec5661c 100644 --- a/R/register.R +++ b/R/register.R @@ -233,22 +233,28 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { glue::glue_data(funs, ".Call({package_names}{params}{package_call})") ) - roxygen_comments <- lapply(funs$file, extract_roxygen_comments) - - out <- mapply(function(name, list_params, calls, file, line) { + # Parse and associate Roxygen comments + funs$roxygen_comment <- mapply(function(file, line) { comments <- extract_roxygen_comments(file) - roxygen_comment <- "" + matched_comment <- "" for (comment in comments) { - if (comment$line < line) { - roxygen_comment <- comment$text + # Check if the comment directly precedes the function without gaps + if (line == comment$line + 1) { + matched_comment <- comment$text + break } } + matched_comment + }, funs$file, funs$line, SIMPLIFY = TRUE) + + # Generate R functions with or without Roxygen comments + out <- mapply(function(name, list_params, calls, roxygen_comment) { if (nzchar(roxygen_comment)) { glue::glue("{roxygen_comment}\n{name} <- function({list_params}) {{\n\t{calls}\n}}") } else { glue::glue("{name} <- function({list_params}) {{\n\t{calls}\n}}") } - }, funs$name, funs$list_params, funs$calls, funs$file, funs$line, SIMPLIFY = FALSE) + }, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, SIMPLIFY = FALSE) out <- as.character(out) out <- glue::trim(out) @@ -268,7 +274,7 @@ extract_roxygen_comments <- function(file) { roxygen_comments <- mapply(function(start, end) { roxygen_lines <- lines[(start + 1):(end - 1)] roxygen_lines <- sub("^@", "#' @", roxygen_lines) - list(line = start, text = paste(roxygen_lines, collapse = "\n")) + list(line = end, text = paste(roxygen_lines, collapse = "\n")) }, roxygen_start, roxygen_end, SIMPLIFY = FALSE) roxygen_comments diff --git a/cpp11test/NAMESPACE b/cpp11test/NAMESPACE index 0cb4a22d..90d018a1 100644 --- a/cpp11test/NAMESPACE +++ b/cpp11test/NAMESPACE @@ -1,5 +1,10 @@ # Generated by roxygen2: do not edit by hand +export(roxcpp2_) +export(roxcpp3_) +export(roxcpp4_) +export(roxcpp5_) +export(roxcpp7_) export(run_tests) exportPattern("_$") importFrom(Rcpp,sourceCpp) diff --git a/cpp11test/R/cpp11.R b/cpp11test/R/cpp11.R index 3a4b1a2b..07a12506 100644 --- a/cpp11test/R/cpp11.R +++ b/cpp11test/R/cpp11.R @@ -156,42 +156,59 @@ rcpp_release_ <- function(n) { invisible(.Call(`_cpp11test_rcpp_release_`, n)) } -#' @title Roxygenise C++ function -#' @param x numeric value -#' @description Dummy function to test roxygen2. It adds 1.0 to a double. -#' @export -#' @examples roxcpp_(1.0) -roxcpp1_ <- function(x) { - .Call(`_cpp11test_roxcpp1_`, x) +notroxcpp1_ <- function(x) { + .Call(`_cpp11test_notroxcpp1_`, x) } -#' @title Roxygenise C++ function +#' @title Roxygenise C++ function II #' @param x numeric value -#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @description Dummy function to test roxygen2. It adds 2.0 to a double. #' @export -#' @examples roxcpp_(1.0) +#' @examples roxcpp2_(1.0) roxcpp2_ <- function(x) { .Call(`_cpp11test_roxcpp2_`, x) } -#' @title Roxygenise C++ function +#' @title Roxygenise C++ function III #' @param x numeric value -#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @description Dummy function to test roxygen2. It adds 3.0 to a double. #' @export -#' @examples roxcpp_(1.0) +#' @examples roxcpp3_(1.0) roxcpp3_ <- function(x) { .Call(`_cpp11test_roxcpp3_`, x) } -#' @title Roxygenise C++ function +#' @title Roxygenise C++ function IV #' @param x numeric value -#' @description Dummy function to test roxygen2. It adds 1.0 to a double. +#' @description Dummy function to test roxygen2. It adds 4.0 to a double. #' @export -#' @examples roxcpp_(1.0) +#' @examples roxcpp4_(1.0) roxcpp4_ <- function(x) { .Call(`_cpp11test_roxcpp4_`, x) } +#' @title Roxygenise C++ function V +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 5.0 to a double. +#' @export +#' @examples roxcpp5_(1.0) +roxcpp5_ <- function(x) { + .Call(`_cpp11test_roxcpp5_`, x) +} + +notroxcpp6_ <- function(x) { + .Call(`_cpp11test_notroxcpp6_`, x) +} + +#' @title Roxygenise C++ function VII +#' @param x numeric value +#' @description Dummy function to test roxygen2. It adds 7.0 to a double. +#' @export +#' @examples roxcpp7_(1.0) +roxcpp7_ <- function(x) { + .Call(`_cpp11test_roxcpp7_`, x) +} + cpp11_safe_ <- function(x_sxp) { .Call(`_cpp11test_cpp11_safe_`, x_sxp) } diff --git a/cpp11test/man/roxcpp2_.Rd b/cpp11test/man/roxcpp2_.Rd new file mode 100644 index 00000000..dd000a0f --- /dev/null +++ b/cpp11test/man/roxcpp2_.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cpp11.R +\name{roxcpp2_} +\alias{roxcpp2_} +\title{Roxygenise C++ function II} +\usage{ +roxcpp2_(x) +} +\arguments{ +\item{x}{numeric value} +} +\description{ +Dummy function to test roxygen2. It adds 2.0 to a double. +} +\examples{ +roxcpp2_(1.0) +} diff --git a/cpp11test/man/roxcpp3_.Rd b/cpp11test/man/roxcpp3_.Rd new file mode 100644 index 00000000..3d31d143 --- /dev/null +++ b/cpp11test/man/roxcpp3_.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cpp11.R +\name{roxcpp3_} +\alias{roxcpp3_} +\title{Roxygenise C++ function III} +\usage{ +roxcpp3_(x) +} +\arguments{ +\item{x}{numeric value} +} +\description{ +Dummy function to test roxygen2. It adds 3.0 to a double. +} +\examples{ +roxcpp3_(1.0) +} diff --git a/cpp11test/man/roxcpp4_.Rd b/cpp11test/man/roxcpp4_.Rd new file mode 100644 index 00000000..f9cbb022 --- /dev/null +++ b/cpp11test/man/roxcpp4_.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cpp11.R +\name{roxcpp4_} +\alias{roxcpp4_} +\title{Roxygenise C++ function IV} +\usage{ +roxcpp4_(x) +} +\arguments{ +\item{x}{numeric value} +} +\description{ +Dummy function to test roxygen2. It adds 4.0 to a double. +} +\examples{ +roxcpp4_(1.0) +} diff --git a/cpp11test/man/roxcpp5_.Rd b/cpp11test/man/roxcpp5_.Rd new file mode 100644 index 00000000..ada8f9ee --- /dev/null +++ b/cpp11test/man/roxcpp5_.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cpp11.R +\name{roxcpp5_} +\alias{roxcpp5_} +\title{Roxygenise C++ function V} +\usage{ +roxcpp5_(x) +} +\arguments{ +\item{x}{numeric value} +} +\description{ +Dummy function to test roxygen2. It adds 5.0 to a double. +} +\examples{ +roxcpp5_(1.0) +} diff --git a/cpp11test/man/roxcpp7_.Rd b/cpp11test/man/roxcpp7_.Rd new file mode 100644 index 00000000..bf972d1b --- /dev/null +++ b/cpp11test/man/roxcpp7_.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cpp11.R +\name{roxcpp7_} +\alias{roxcpp7_} +\title{Roxygenise C++ function VII} +\usage{ +roxcpp7_(x) +} +\arguments{ +\item{x}{numeric value} +} +\description{ +Dummy function to test roxygen2. It adds 7.0 to a double. +} +\examples{ +roxcpp7_(1.0) +} diff --git a/cpp11test/src/cpp11.cpp b/cpp11test/src/cpp11.cpp index 55e48fbc..4f4f84d0 100644 --- a/cpp11test/src/cpp11.cpp +++ b/cpp11test/src/cpp11.cpp @@ -304,10 +304,10 @@ extern "C" SEXP _cpp11test_rcpp_release_(SEXP n) { END_CPP11 } // roxygen1.cpp -double roxcpp1_(double x); -extern "C" SEXP _cpp11test_roxcpp1_(SEXP x) { +double notroxcpp1_(double x); +extern "C" SEXP _cpp11test_notroxcpp1_(SEXP x) { BEGIN_CPP11 - return cpp11::as_sexp(roxcpp1_(cpp11::as_cpp>(x))); + return cpp11::as_sexp(notroxcpp1_(cpp11::as_cpp>(x))); END_CPP11 } // roxygen1.cpp @@ -331,6 +331,27 @@ extern "C" SEXP _cpp11test_roxcpp4_(SEXP x) { return cpp11::as_sexp(roxcpp4_(cpp11::as_cpp>(x))); END_CPP11 } +// roxygen3.cpp +double roxcpp5_(double x); +extern "C" SEXP _cpp11test_roxcpp5_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp5_(cpp11::as_cpp>(x))); + END_CPP11 +} +// roxygen3.cpp +double notroxcpp6_(double x); +extern "C" SEXP _cpp11test_notroxcpp6_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(notroxcpp6_(cpp11::as_cpp>(x))); + END_CPP11 +} +// roxygen3.cpp +double roxcpp7_(double x); +extern "C" SEXP _cpp11test_roxcpp7_(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(roxcpp7_(cpp11::as_cpp>(x))); + END_CPP11 +} // safe.cpp SEXP cpp11_safe_(SEXP x_sxp); extern "C" SEXP _cpp11test_cpp11_safe_(SEXP x_sxp) { @@ -528,6 +549,8 @@ static const R_CallMethodDef CallEntries[] = { {"_cpp11test_my_warning_n1", (DL_FUNC) &_cpp11test_my_warning_n1, 1}, {"_cpp11test_my_warning_n1fmt", (DL_FUNC) &_cpp11test_my_warning_n1fmt, 1}, {"_cpp11test_my_warning_n2fmt", (DL_FUNC) &_cpp11test_my_warning_n2fmt, 2}, + {"_cpp11test_notroxcpp1_", (DL_FUNC) &_cpp11test_notroxcpp1_, 1}, + {"_cpp11test_notroxcpp6_", (DL_FUNC) &_cpp11test_notroxcpp6_, 1}, {"_cpp11test_protect_many_", (DL_FUNC) &_cpp11test_protect_many_, 1}, {"_cpp11test_protect_many_cpp11_", (DL_FUNC) &_cpp11test_protect_many_cpp11_, 1}, {"_cpp11test_protect_many_preserve_", (DL_FUNC) &_cpp11test_protect_many_preserve_, 1}, @@ -546,10 +569,11 @@ static const R_CallMethodDef CallEntries[] = { {"_cpp11test_rcpp_sum_int_for_", (DL_FUNC) &_cpp11test_rcpp_sum_int_for_, 1}, {"_cpp11test_remove_altrep", (DL_FUNC) &_cpp11test_remove_altrep, 1}, {"_cpp11test_row_sums", (DL_FUNC) &_cpp11test_row_sums, 1}, - {"_cpp11test_roxcpp1_", (DL_FUNC) &_cpp11test_roxcpp1_, 1}, {"_cpp11test_roxcpp2_", (DL_FUNC) &_cpp11test_roxcpp2_, 1}, {"_cpp11test_roxcpp3_", (DL_FUNC) &_cpp11test_roxcpp3_, 1}, {"_cpp11test_roxcpp4_", (DL_FUNC) &_cpp11test_roxcpp4_, 1}, + {"_cpp11test_roxcpp5_", (DL_FUNC) &_cpp11test_roxcpp5_, 1}, + {"_cpp11test_roxcpp7_", (DL_FUNC) &_cpp11test_roxcpp7_, 1}, {"_cpp11test_string_proxy_assignment_", (DL_FUNC) &_cpp11test_string_proxy_assignment_, 0}, {"_cpp11test_string_push_back_", (DL_FUNC) &_cpp11test_string_push_back_, 0}, {"_cpp11test_sum_dbl_accumulate2_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate2_, 1}, diff --git a/cpp11test/src/roxygen1.cpp b/cpp11test/src/roxygen1.cpp new file mode 100644 index 00000000..6ce5dea8 --- /dev/null +++ b/cpp11test/src/roxygen1.cpp @@ -0,0 +1,22 @@ +#include "cpp11/doubles.hpp" +using namespace cpp11; + +// Test: not documented + documented + +// Not Roxygenised C++ function I +[[cpp11::register]] double notroxcpp1_(double x) { + double y = x + 1.0; + return y; +} + +/* roxygen start +@title Roxygenise C++ function II +@param x numeric value +@description Dummy function to test roxygen2. It adds 2.0 to a double. +@export +@examples roxcpp2_(1.0) +roxygen end */ +[[cpp11::register]] double roxcpp2_(double x) { + double y = x + 2.0; + return y; +} diff --git a/cpp11test/src/roxygen2.cpp b/cpp11test/src/roxygen2.cpp new file mode 100644 index 00000000..ecd50221 --- /dev/null +++ b/cpp11test/src/roxygen2.cpp @@ -0,0 +1,28 @@ +#include "cpp11/doubles.hpp" +using namespace cpp11; + +// Test: documented + documented + +/* roxygen start +@title Roxygenise C++ function III +@param x numeric value +@description Dummy function to test roxygen2. It adds 3.0 to a double. +@export +@examples roxcpp3_(1.0) +roxygen end */ +[[cpp11::register]] double roxcpp3_(double x) { + double y = x + 3.0; + return y; +} + +/* roxygen start +@title Roxygenise C++ function IV +@param x numeric value +@description Dummy function to test roxygen2. It adds 4.0 to a double. +@export +@examples roxcpp4_(1.0) +roxygen end */ +[[cpp11::register]] double roxcpp4_(double x) { + double y = x + 4.0; + return y; +} diff --git a/cpp11test/src/roxygen3.cpp b/cpp11test/src/roxygen3.cpp new file mode 100644 index 00000000..44be0173 --- /dev/null +++ b/cpp11test/src/roxygen3.cpp @@ -0,0 +1,34 @@ +#include "cpp11/doubles.hpp" +using namespace cpp11; + +// Test: documented + not documented + documented + +/* roxygen start +@title Roxygenise C++ function V +@param x numeric value +@description Dummy function to test roxygen2. It adds 5.0 to a double. +@export +@examples roxcpp5_(1.0) +roxygen end */ +[[cpp11::register]] double roxcpp5_(double x) { + double y = x + 5.0; + return y; +} + +// Not Roxygenised C++ function VI +[[cpp11::register]] double notroxcpp6_(double x) { + double y = x + 6.0; + return y; +} + +/* roxygen start +@title Roxygenise C++ function VII +@param x numeric value +@description Dummy function to test roxygen2. It adds 7.0 to a double. +@export +@examples roxcpp7_(1.0) +roxygen end */ +[[cpp11::register]] double roxcpp7_(double x) { + double y = x + 7.0; + return y; +} From fb848c652de0f9d05eaf056a1cdbad14dbfa4ad3 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 05:01:19 +0000 Subject: [PATCH 04/10] revert some styler changes to make the changes more clear --- R/register.R | 8 +-- cpp11test/R/cpp11.R | 128 ++++++++++++++++++++++---------------------- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/R/register.R b/R/register.R index cec5661c..43610049 100644 --- a/R/register.R +++ b/R/register.R @@ -220,7 +220,7 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { package_call <- glue::glue(', PACKAGE = "{package}"') package_names <- glue::glue_data(funs, '"_{package}_{name}"') } else { - package_names <- glue::glue_data(funs, "`_{package}_{name}`") + package_names <- glue::glue_data(funs, '`_{package}_{name}`') package_call <- "" } @@ -229,8 +229,8 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { funs$params <- vcapply(funs$list_params, function(x) if (nzchar(x)) paste0(", ", x) else x) is_void <- funs$return_type == "void" funs$calls <- ifelse(is_void, - glue::glue_data(funs, "invisible(.Call({package_names}{params}{package_call}))"), - glue::glue_data(funs, ".Call({package_names}{params}{package_call})") + glue::glue_data(funs, 'invisible(.Call({package_names}{params}{package_call}))'), + glue::glue_data(funs, '.Call({package_names}{params}{package_call})') ) # Parse and associate Roxygen comments @@ -252,7 +252,7 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { if (nzchar(roxygen_comment)) { glue::glue("{roxygen_comment}\n{name} <- function({list_params}) {{\n\t{calls}\n}}") } else { - glue::glue("{name} <- function({list_params}) {{\n\t{calls}\n}}") + glue::glue("{name} <- function({list_params}) {{\n {calls}\n}}") } }, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, SIMPLIFY = FALSE) diff --git a/cpp11test/R/cpp11.R b/cpp11test/R/cpp11.R index 07a12506..32e52ed8 100644 --- a/cpp11test/R/cpp11.R +++ b/cpp11test/R/cpp11.R @@ -1,163 +1,163 @@ # Generated by cpp11: do not edit by hand cpp11_add_vec_for_ <- function(x, num) { - .Call(`_cpp11test_cpp11_add_vec_for_`, x, num) + .Call(`_cpp11test_cpp11_add_vec_for_`, x, num) } data_frame_ <- function() { - .Call(`_cpp11test_data_frame_`) + .Call(`_cpp11test_data_frame_`) } my_stop_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_stop_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_stop_n1fmt`, mystring)) } my_stop_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_stop_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_stop_n2fmt`, mystring, myarg)) } my_warning_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_warning_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_warning_n1fmt`, mystring)) } my_warning_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_warning_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_warning_n2fmt`, mystring, myarg)) } my_message_n1fmt <- function(mystring) { - invisible(.Call(`_cpp11test_my_message_n1fmt`, mystring)) + invisible(.Call(`_cpp11test_my_message_n1fmt`, mystring)) } my_message_n2fmt <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_message_n2fmt`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_message_n2fmt`, mystring, myarg)) } my_stop <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_stop`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_stop`, mystring, myarg)) } my_stop_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_stop_n1`, mystring)) + invisible(.Call(`_cpp11test_my_stop_n1`, mystring)) } my_warning <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_warning`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_warning`, mystring, myarg)) } my_warning_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_warning_n1`, mystring)) + invisible(.Call(`_cpp11test_my_warning_n1`, mystring)) } my_message <- function(mystring, myarg) { - invisible(.Call(`_cpp11test_my_message`, mystring, myarg)) + invisible(.Call(`_cpp11test_my_message`, mystring, myarg)) } my_message_n1 <- function(mystring) { - invisible(.Call(`_cpp11test_my_message_n1`, mystring)) + invisible(.Call(`_cpp11test_my_message_n1`, mystring)) } remove_altrep <- function(x) { - .Call(`_cpp11test_remove_altrep`, x) + .Call(`_cpp11test_remove_altrep`, x) } upper_bound <- function(x, breaks) { - .Call(`_cpp11test_upper_bound`, x, breaks) + .Call(`_cpp11test_upper_bound`, x, breaks) } findInterval2 <- function(x, breaks) { - .Call(`_cpp11test_findInterval2`, x, breaks) + .Call(`_cpp11test_findInterval2`, x, breaks) } findInterval2_5 <- function(x, breaks) { - .Call(`_cpp11test_findInterval2_5`, x, breaks) + .Call(`_cpp11test_findInterval2_5`, x, breaks) } findInterval3 <- function(x, breaks) { - .Call(`_cpp11test_findInterval3`, x, breaks) + .Call(`_cpp11test_findInterval3`, x, breaks) } findInterval4 <- function(x, breaks) { - .Call(`_cpp11test_findInterval4`, x, breaks) + .Call(`_cpp11test_findInterval4`, x, breaks) } grow_ <- function(n) { - .Call(`_cpp11test_grow_`, n) + .Call(`_cpp11test_grow_`, n) } cpp11_insert_ <- function(num_sxp) { - .Call(`_cpp11test_cpp11_insert_`, num_sxp) + .Call(`_cpp11test_cpp11_insert_`, num_sxp) } gibbs_cpp <- function(N, thin) { - .Call(`_cpp11test_gibbs_cpp`, N, thin) + .Call(`_cpp11test_gibbs_cpp`, N, thin) } gibbs_cpp2 <- function(N, thin) { - .Call(`_cpp11test_gibbs_cpp2`, N, thin) + .Call(`_cpp11test_gibbs_cpp2`, N, thin) } gibbs_rcpp <- function(N, thin) { - .Call(`_cpp11test_gibbs_rcpp`, N, thin) + .Call(`_cpp11test_gibbs_rcpp`, N, thin) } gibbs_rcpp2 <- function(N, thin) { - .Call(`_cpp11test_gibbs_rcpp2`, N, thin) + .Call(`_cpp11test_gibbs_rcpp2`, N, thin) } row_sums <- function(x) { - .Call(`_cpp11test_row_sums`, x) + .Call(`_cpp11test_row_sums`, x) } col_sums <- function(x) { - .Call(`_cpp11test_col_sums`, x) + .Call(`_cpp11test_col_sums`, x) } protect_one_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_`, x, n)) } protect_one_sexp_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_sexp_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_sexp_`, x, n)) } protect_one_cpp11_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_cpp11_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_cpp11_`, x, n)) } protect_one_preserve_ <- function(x, n) { - invisible(.Call(`_cpp11test_protect_one_preserve_`, x, n)) + invisible(.Call(`_cpp11test_protect_one_preserve_`, x, n)) } protect_many_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_`, n)) + invisible(.Call(`_cpp11test_protect_many_`, n)) } protect_many_cpp11_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_cpp11_`, n)) + invisible(.Call(`_cpp11test_protect_many_cpp11_`, n)) } protect_many_sexp_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_sexp_`, n)) + invisible(.Call(`_cpp11test_protect_many_sexp_`, n)) } protect_many_preserve_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_preserve_`, n)) + invisible(.Call(`_cpp11test_protect_many_preserve_`, n)) } protect_many_rcpp_ <- function(n) { - invisible(.Call(`_cpp11test_protect_many_rcpp_`, n)) + invisible(.Call(`_cpp11test_protect_many_rcpp_`, n)) } cpp11_release_ <- function(n) { - invisible(.Call(`_cpp11test_cpp11_release_`, n)) + invisible(.Call(`_cpp11test_cpp11_release_`, n)) } rcpp_release_ <- function(n) { - invisible(.Call(`_cpp11test_rcpp_release_`, n)) + invisible(.Call(`_cpp11test_rcpp_release_`, n)) } notroxcpp1_ <- function(x) { - .Call(`_cpp11test_notroxcpp1_`, x) + .Call(`_cpp11test_notroxcpp1_`, x) } #' @title Roxygenise C++ function II @@ -197,7 +197,7 @@ roxcpp5_ <- function(x) { } notroxcpp6_ <- function(x) { - .Call(`_cpp11test_notroxcpp6_`, x) + .Call(`_cpp11test_notroxcpp6_`, x) } #' @title Roxygenise C++ function VII @@ -210,93 +210,93 @@ roxcpp7_ <- function(x) { } cpp11_safe_ <- function(x_sxp) { - .Call(`_cpp11test_cpp11_safe_`, x_sxp) + .Call(`_cpp11test_cpp11_safe_`, x_sxp) } string_proxy_assignment_ <- function() { - .Call(`_cpp11test_string_proxy_assignment_`) + .Call(`_cpp11test_string_proxy_assignment_`) } string_push_back_ <- function() { - .Call(`_cpp11test_string_push_back_`) + .Call(`_cpp11test_string_push_back_`) } sum_dbl_for_ <- function(x) { - .Call(`_cpp11test_sum_dbl_for_`, x) + .Call(`_cpp11test_sum_dbl_for_`, x) } sum_dbl_for2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_for2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_for2_`, x_sxp) } sum_dbl_for3_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_for3_`, x_sxp) + .Call(`_cpp11test_sum_dbl_for3_`, x_sxp) } sum_dbl_foreach_ <- function(x) { - .Call(`_cpp11test_sum_dbl_foreach_`, x) + .Call(`_cpp11test_sum_dbl_foreach_`, x) } sum_dbl_foreach2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_foreach2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_foreach2_`, x_sxp) } sum_dbl_accumulate_ <- function(x) { - .Call(`_cpp11test_sum_dbl_accumulate_`, x) + .Call(`_cpp11test_sum_dbl_accumulate_`, x) } sum_dbl_accumulate2_ <- function(x_sxp) { - .Call(`_cpp11test_sum_dbl_accumulate2_`, x_sxp) + .Call(`_cpp11test_sum_dbl_accumulate2_`, x_sxp) } sum_int_for_ <- function(x) { - .Call(`_cpp11test_sum_int_for_`, x) + .Call(`_cpp11test_sum_int_for_`, x) } sum_int_for2_ <- function(x_) { - .Call(`_cpp11test_sum_int_for2_`, x_) + .Call(`_cpp11test_sum_int_for2_`, x_) } sum_int_foreach_ <- function(x) { - .Call(`_cpp11test_sum_int_foreach_`, x) + .Call(`_cpp11test_sum_int_foreach_`, x) } sum_int_accumulate_ <- function(x) { - .Call(`_cpp11test_sum_int_accumulate_`, x) + .Call(`_cpp11test_sum_int_accumulate_`, x) } rcpp_sum_dbl_for_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_for_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_for_`, x_sxp) } rcpp_sum_int_for_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_int_for_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_int_for_`, x_sxp) } rcpp_sum_dbl_foreach_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_foreach_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_foreach_`, x_sxp) } rcpp_sum_dbl_accumulate_ <- function(x_sxp) { - .Call(`_cpp11test_rcpp_sum_dbl_accumulate_`, x_sxp) + .Call(`_cpp11test_rcpp_sum_dbl_accumulate_`, x_sxp) } rcpp_grow_ <- function(n_sxp) { - .Call(`_cpp11test_rcpp_grow_`, n_sxp) + .Call(`_cpp11test_rcpp_grow_`, n_sxp) } rcpp_push_and_truncate_ <- function(size_sxp) { - .Call(`_cpp11test_rcpp_push_and_truncate_`, size_sxp) + .Call(`_cpp11test_rcpp_push_and_truncate_`, size_sxp) } test_destruction_inner <- function() { - invisible(.Call(`_cpp11test_test_destruction_inner`)) + invisible(.Call(`_cpp11test_test_destruction_inner`)) } test_destruction_outer <- function() { - invisible(.Call(`_cpp11test_test_destruction_outer`)) + invisible(.Call(`_cpp11test_test_destruction_outer`)) } cpp11_push_and_truncate_ <- function(size_sexp) { - .Call(`_cpp11test_cpp11_push_and_truncate_`, size_sexp) + .Call(`_cpp11test_cpp11_push_and_truncate_`, size_sexp) } From 17cac60d615da82ff9f095d5901f6f10f47ecf09 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 08:09:14 +0000 Subject: [PATCH 05/10] fix multi line roxygen examples --- R/register.R | 2 +- cpp11test/R/cpp11.R | 6 +++++- cpp11test/man/roxcpp7_.Rd | 7 ++++++- cpp11test/src/roxygen3.cpp | 6 +++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/R/register.R b/R/register.R index 43610049..feec5450 100644 --- a/R/register.R +++ b/R/register.R @@ -273,7 +273,7 @@ extract_roxygen_comments <- function(file) { roxygen_comments <- mapply(function(start, end) { roxygen_lines <- lines[(start + 1):(end - 1)] - roxygen_lines <- sub("^@", "#' @", roxygen_lines) + roxygen_lines <- sub("^", "#' ", roxygen_lines) list(line = end, text = paste(roxygen_lines, collapse = "\n")) }, roxygen_start, roxygen_end, SIMPLIFY = FALSE) diff --git a/cpp11test/R/cpp11.R b/cpp11test/R/cpp11.R index 32e52ed8..d5ae1ab2 100644 --- a/cpp11test/R/cpp11.R +++ b/cpp11test/R/cpp11.R @@ -204,7 +204,11 @@ notroxcpp6_ <- function(x) { #' @param x numeric value #' @description Dummy function to test roxygen2. It adds 7.0 to a double. #' @export -#' @examples roxcpp7_(1.0) +#' @examples +#' my_fun <- function(x) { +#' roxcpp7_(x) +#' } +#' @seealso \code{\link{roxcpp1_}} roxcpp7_ <- function(x) { .Call(`_cpp11test_roxcpp7_`, x) } diff --git a/cpp11test/man/roxcpp7_.Rd b/cpp11test/man/roxcpp7_.Rd index bf972d1b..17466bf6 100644 --- a/cpp11test/man/roxcpp7_.Rd +++ b/cpp11test/man/roxcpp7_.Rd @@ -13,5 +13,10 @@ roxcpp7_(x) Dummy function to test roxygen2. It adds 7.0 to a double. } \examples{ -roxcpp7_(1.0) +my_fun <- function(x) { + roxcpp7_(x) +} +} +\seealso{ +\code{\link{roxcpp1_}} } diff --git a/cpp11test/src/roxygen3.cpp b/cpp11test/src/roxygen3.cpp index 44be0173..7ede7a08 100644 --- a/cpp11test/src/roxygen3.cpp +++ b/cpp11test/src/roxygen3.cpp @@ -26,7 +26,11 @@ roxygen end */ @param x numeric value @description Dummy function to test roxygen2. It adds 7.0 to a double. @export -@examples roxcpp7_(1.0) +@examples +my_fun <- function(x) { + roxcpp7_(x) +} +@seealso \code{\link{roxcpp1_}} roxygen end */ [[cpp11::register]] double roxcpp7_(double x) { double y = x + 7.0; From 7a436d62b5d0714bede89af148217319e306b6a1 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 08:14:59 +0000 Subject: [PATCH 06/10] add roxygen example to documentation --- vignettes/converting.Rmd | 1 - vignettes/cpp11.Rmd | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/vignettes/converting.Rmd b/vignettes/converting.Rmd index 4a30dfd2..31507ca1 100644 --- a/vignettes/converting.Rmd +++ b/vignettes/converting.Rmd @@ -119,7 +119,6 @@ as_tibble(x, ".rows"_nm = num_rows, ".name_repair"_nm = name_repair); - Some parts of [Attributes](https://CRAN.R-project.org/package=Rcpp/vignettes/Rcpp-attributes.pdf) - No dependencies - No random number generator restoration - - No support for roxygen2 comments - No interfaces ### RNGs diff --git a/vignettes/cpp11.Rmd b/vignettes/cpp11.Rmd index 5f10fcc6..c23a2dbc 100644 --- a/vignettes/cpp11.Rmd +++ b/vignettes/cpp11.Rmd @@ -349,6 +349,34 @@ For the remainder of this vignette C++ code will be presented stand-alone rather If you want to try compiling and/or modifying the examples you should paste them into a C++ source file that includes the elements described above. This is easy to do in RMarkdown by using `{cpp11}` instead of `{r}` at the beginning of your code blocks. +## Roxygen support + +It is possible to use `roxygen2` to document your C++ functions. Here is an +example of how to do this: + +```{cpp11} +/* roxygen start +@title Mean of a numeric vector +@param x A numeric vector +@return The mean of the input vector +@examples mean_cpp(1:10) +@export +roxygen end */ +[[cpp11::register]] double mean_roxygenised_cpp(doubles x) { + int n = x.size(); + double total = 0; + for(double value : x) { + total += value; + } + return total / n; +} +``` + +Unlike R scripts, you need to use `/* roxygen start` and `roxygen end */` to +delimit the roxygen comments. The logic behind this is that C++ compilers +understand `/*` and `*/` as multi-linecomments, and therefore it is not required +to prepend `#' ` to each line of the roxygen comments as in R scripts. + ### Exercises 1. With the basics of C++ in hand, it's now a great time to practice by reading and writing some simple C++ functions. For each of the following functions, read the code and figure out what the corresponding base R function is. You might not understand every part of the code yet, but you should be able to figure out the basics of what the function does. From a781c99c5543e6f3220d8f7994cee47152946e56 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 12:09:54 +0000 Subject: [PATCH 07/10] consider the case where a file does not exist --- R/register.R | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/R/register.R b/R/register.R index feec5450..5022e801 100644 --- a/R/register.R +++ b/R/register.R @@ -220,7 +220,7 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { package_call <- glue::glue(', PACKAGE = "{package}"') package_names <- glue::glue_data(funs, '"_{package}_{name}"') } else { - package_names <- glue::glue_data(funs, '`_{package}_{name}`') + package_names <- glue::glue_data(funs, "`_{package}_{name}`") package_call <- "" } @@ -229,22 +229,26 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { funs$params <- vcapply(funs$list_params, function(x) if (nzchar(x)) paste0(", ", x) else x) is_void <- funs$return_type == "void" funs$calls <- ifelse(is_void, - glue::glue_data(funs, 'invisible(.Call({package_names}{params}{package_call}))'), - glue::glue_data(funs, '.Call({package_names}{params}{package_call})') + glue::glue_data(funs, "invisible(.Call({package_names}{params}{package_call}))"), + glue::glue_data(funs, ".Call({package_names}{params}{package_call})") ) # Parse and associate Roxygen comments funs$roxygen_comment <- mapply(function(file, line) { - comments <- extract_roxygen_comments(file) - matched_comment <- "" - for (comment in comments) { - # Check if the comment directly precedes the function without gaps - if (line == comment$line + 1) { - matched_comment <- comment$text - break + if (file.exists(file)) { + comments <- extract_roxygen_comments(file) + matched_comment <- "" + for (comment in comments) { + # Check if the comment directly precedes the function without gaps + if (line == comment$line + 1) { + matched_comment <- comment$text + break + } } + matched_comment + } else { + "" } - matched_comment }, funs$file, funs$line, SIMPLIFY = TRUE) # Generate R functions with or without Roxygen comments @@ -254,9 +258,8 @@ generate_r_functions <- function(funs, package = "cpp11", use_package = FALSE) { } else { glue::glue("{name} <- function({list_params}) {{\n {calls}\n}}") } - }, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, SIMPLIFY = FALSE) + }, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, SIMPLIFY = TRUE) - out <- as.character(out) out <- glue::trim(out) out <- glue::glue_collapse(out, sep = "\n\n") unclass(out) From f71771348085ec055d8fc2350e635c57819e9839 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 4 Jan 2025 12:18:39 +0000 Subject: [PATCH 08/10] do not roxygenize chunk in vignette --- vignettes/cpp11.Rmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vignettes/cpp11.Rmd b/vignettes/cpp11.Rmd index c23a2dbc..741a0ca1 100644 --- a/vignettes/cpp11.Rmd +++ b/vignettes/cpp11.Rmd @@ -354,7 +354,7 @@ This is easy to do in RMarkdown by using `{cpp11}` instead of `{r}` at the begin It is possible to use `roxygen2` to document your C++ functions. Here is an example of how to do this: -```{cpp11} +```{cpp11, eval = FALSE} /* roxygen start @title Mean of a numeric vector @param x A numeric vector @@ -362,7 +362,8 @@ example of how to do this: @examples mean_cpp(1:10) @export roxygen end */ -[[cpp11::register]] double mean_roxygenised_cpp(doubles x) { +[[cpp11::register]] +double mean_roxygenised_cpp(doubles x) { int n = x.size(); double total = 0; for(double value : x) { From fbb365f685d3a44c126740c83021fd16d8787997 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sun, 5 Jan 2025 09:40:42 +0000 Subject: [PATCH 09/10] workaround for roxygen comments in cpp chunks --- vignettes/cpp11.Rmd | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vignettes/cpp11.Rmd b/vignettes/cpp11.Rmd index 741a0ca1..0adcd2d3 100644 --- a/vignettes/cpp11.Rmd +++ b/vignettes/cpp11.Rmd @@ -16,6 +16,14 @@ knitr::opts_chunk$set( comment = "#>", eval = as.logical(Sys.getenv("CPP11_EVAL", "false")) ) +knitr::knit_hooks$set(strip_roxygen = function(before, options, envir) { + if (before) { + code <- options$code + code <- gsub("/\\* roxygen start.*?roxygen end \\*/", "", code, perl = TRUE) + options$code <- code + options + } +}) library(cpp11) ``` @@ -354,7 +362,7 @@ This is easy to do in RMarkdown by using `{cpp11}` instead of `{r}` at the begin It is possible to use `roxygen2` to document your C++ functions. Here is an example of how to do this: -```{cpp11, eval = FALSE} +```{cpp11, strip_roxygen = TRUE} /* roxygen start @title Mean of a numeric vector @param x A numeric vector From c91f4ef648096a7510df1ebe6d189e71c83339ff Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sun, 5 Jan 2025 09:51:04 +0000 Subject: [PATCH 10/10] revert to eval = F --- vignettes/cpp11.Rmd | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/vignettes/cpp11.Rmd b/vignettes/cpp11.Rmd index 0adcd2d3..741a0ca1 100644 --- a/vignettes/cpp11.Rmd +++ b/vignettes/cpp11.Rmd @@ -16,14 +16,6 @@ knitr::opts_chunk$set( comment = "#>", eval = as.logical(Sys.getenv("CPP11_EVAL", "false")) ) -knitr::knit_hooks$set(strip_roxygen = function(before, options, envir) { - if (before) { - code <- options$code - code <- gsub("/\\* roxygen start.*?roxygen end \\*/", "", code, perl = TRUE) - options$code <- code - options - } -}) library(cpp11) ``` @@ -362,7 +354,7 @@ This is easy to do in RMarkdown by using `{cpp11}` instead of `{r}` at the begin It is possible to use `roxygen2` to document your C++ functions. Here is an example of how to do this: -```{cpp11, strip_roxygen = TRUE} +```{cpp11, eval = FALSE} /* roxygen start @title Mean of a numeric vector @param x A numeric vector