Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
71c2dcc
vendor path
pachadotdev Feb 16, 2024
10d3565
Update tests/testthat/test-vendor.R
pachadotdev Apr 6, 2024
da1c84e
fix vendor
pachadotdev Apr 7, 2024
e2df430
improve DESCRIPTION change with vendoring
pachadotdev Apr 9, 2024
8845015
replace DESC/Make funs with user msg
pachadotdev May 13, 2024
6778095
fix eventual CRAN warning
pachadotdev May 13, 2024
c90eea4
testthat 3e
pachadotdev Oct 23, 2024
2729233
add and test unvendor function
pachadotdev Dec 6, 2024
fd99010
implement 25% of #297
pachadotdev Dec 17, 2024
b1d8858
almost complete implementation of r_complex
pachadotdev Dec 20, 2024
628ae8f
UPDATE AS.HPP
pachadotdev Dec 25, 2024
ca9c11e
temporary as.hpp
pachadotdev Dec 25, 2024
17ba519
handle cpp complex <-> R sexp
pachadotdev Dec 25, 2024
ea98a87
almost ok, push_back for complexes is pending
pachadotdev Dec 26, 2024
8e044f6
trying to add push_back for cplx
pachadotdev Dec 26, 2024
49ee179
trying to get push_back for cplx to work :\
pachadotdev Dec 26, 2024
b003c28
complex tests work, BUT THERE IS A CATCH ERROR I DO NOT GET
pachadotdev Dec 26, 2024
e642aa6
passed all test for cplx :D
pachadotdev Dec 27, 2024
d42f512
complex_matrix<>
pachadotdev Dec 27, 2024
f7ead22
cpp11test: add rcpp to imports + .here to .Rbuildignore
pachadotdev Dec 27, 2024
66b4ade
revert complexes_matrix<> for now
pachadotdev Dec 27, 2024
f5d6054
clang format
pachadotdev Dec 27, 2024
713f147
bool -> int + using transform for bool -> double
pachadotdev Dec 27, 2024
127e700
Merge branch 'main' into testthat3e
pachadotdev Dec 27, 2024
f7383a0
fix #273
pachadotdev Dec 27, 2024
73231a5
use sexp instead of auto for C++ older than 14
pachadotdev Dec 27, 2024
812e6ce
replace auto with attribute_proxy<V>
pachadotdev Dec 27, 2024
5217ded
use SEXP
pachadotdev Dec 27, 2024
1b51d23
test again
pachadotdev Dec 27, 2024
b919f41
try to fix build error on gh actions
pachadotdev Dec 27, 2024
a91c3ed
Define SET_COMPLEX_ELT if not defined
pachadotdev Dec 27, 2024
814b408
implement @stephematician suggestion
pachadotdev Dec 28, 2024
511a7ed
re-add complex matrix with tests
pachadotdev Dec 29, 2024
bbee709
fix #406
pachadotdev Jan 1, 2025
496dd6b
borrow from @traversc's push_back_fast
pachadotdev Jan 1, 2025
008ab7c
add benchmarks
pachadotdev Jan 1, 2025
f717e3d
fix unvendor example
pachadotdev Jan 1, 2025
6f84867
implement #431
pachadotdev Jan 1, 2025
2d4bbb5
implement #432
pachadotdev Jan 1, 2025
9673bb2
implement #435
pachadotdev Jan 1, 2025
6dbf339
fix pkgdown error
pachadotdev Jan 1, 2025
a03a126
draft map -> list/sexp
pachadotdev Jan 1, 2025
aaed104
ordered and unordered C++ maps are converted to R lists
pachadotdev Jan 2, 2025
70c68df
template map to list conversion
pachadotdev Jan 2, 2025
9ebcf41
fix sum rcpp error on Unix systems (cpp11test)
pachadotdev Jan 3, 2025
fb3583f
roxygen comments on cpp side (works ok with 1 roxygenised function pe…
pachadotdev Jan 3, 2025
14531db
almost there with rx/no rx in the same file
pachadotdev Jan 4, 2025
c750115
correctly handles roxygen in cpp files
pachadotdev Jan 4, 2025
fb848c6
revert some styler changes to make the changes more clear
pachadotdev Jan 4, 2025
17cac60
fix multi line roxygen examples
pachadotdev Jan 4, 2025
7a436d6
add roxygen example to documentation
pachadotdev Jan 4, 2025
a781c99
consider the case where a file does not exist
pachadotdev Jan 4, 2025
f717713
do not roxygenize chunk in vignette
pachadotdev Jan 4, 2025
fbb365f
workaround for roxygen comments in cpp chunks
pachadotdev Jan 5, 2025
c91f4ef
revert to eval = F
pachadotdev Jan 5, 2025
b1d8ecd
implement #312
pachadotdev Feb 1, 2025
7a72ec9
implement fix for #445
pachadotdev May 9, 2025
fcb7756
only one cstdlib in data_frame.hpp
pachadotdev May 9, 2025
012e4e0
use inline constexpr for doubles/integers/list/logicals/strings
pachadotdev May 9, 2025
2be6542
use noexcept in protect/sexp
pachadotdev May 9, 2025
91c3bd4
noexcept in operator SEXP (attribute proxy)
pachadotdev May 9, 2025
472f40f
+ noexcept
pachadotdev May 9, 2025
4209cf0
clang format
pachadotdev May 9, 2025
b0b3f47
rollback noexcept
pachadotdev May 9, 2025
8fdaaef
clang format
pachadotdev May 9, 2025
a80ae91
fix typos
pachadotdev May 9, 2025
ff8e314
fix r_Vector
pachadotdev May 9, 2025
f7fd0e0
fix strings
pachadotdev May 9, 2025
e0229d5
rollback strings
pachadotdev May 9, 2025
ddf5300
rollback strings
pachadotdev May 9, 2025
9851423
use a lamba to unwind protect around the loop
pachadotdev Aug 26, 2025
c016918
Use values added to a vector with push_back immediately
pachadotdev Aug 26, 2025
8ee112a
fix clang format
pachadotdev Aug 26, 2025
8093e12
llvm formatt
pachadotdev Sep 7, 2025
6783944
Global symbol visibility
pachadotdev Sep 15, 2025
5114411
clang ofrmat
pachadotdev Sep 15, 2025
acdcf61
clang format
pachadotdev Sep 15, 2025
e340f78
clang format 12
pachadotdev Sep 15, 2025
3c6e5c6
clang fmt
pachadotdev Sep 15, 2025
224b9af
check unix tests
pachadotdev Sep 15, 2025
72d2f37
Merge pull request #1 from pachadotdev/issue460
pachadotdev Sep 16, 2025
36ef9b7
Merge pull request #2 from pachadotdev/issue453
pachadotdev Sep 16, 2025
2c56e1a
Merge pull request #3 from pachadotdev/issue452
pachadotdev Sep 16, 2025
7256c37
Merge pull request #4 from pachadotdev/issue406
pachadotdev Sep 16, 2025
8e7a80d
Merge pull request #5 from pachadotdev/issue297
pachadotdev Sep 16, 2025
66d37b1
Merge pull request #6 from pachadotdev/compilationspeed
pachadotdev Sep 16, 2025
1487985
Merge pull request #7 from pachadotdev/nullable_extptr
pachadotdev Sep 16, 2025
5eff766
Merge branch 'main' into roxygen
pachadotdev Sep 16, 2025
bd30629
Merge pull request #8 from pachadotdev/roxygen
pachadotdev Sep 16, 2025
b63d96c
Merge branch 'main' into 419
pachadotdev Sep 16, 2025
a33c8b5
Merge pull request #9 from pachadotdev/419
pachadotdev Sep 16, 2025
4441386
Merge branch 'main' into vignettes
pachadotdev Sep 16, 2025
49953b9
Merge pull request #10 from pachadotdev/vignettes
pachadotdev Sep 16, 2025
b041c48
Merge branch 'main' into named_arg_utf8
pachadotdev Sep 16, 2025
67f3fb1
Merge pull request #11 from pachadotdev/named_arg_utf8
pachadotdev Sep 16, 2025
55fd0f0
Merge branch 'main' into vmaxgetset
pachadotdev Sep 16, 2025
b44690d
Merge pull request #12 from pachadotdev/vmaxgetset
pachadotdev Sep 16, 2025
6b36c1a
Merge branch 'main' into 3Fto1T
pachadotdev Sep 16, 2025
926b078
Merge pull request #13 from pachadotdev/3Fto1T
pachadotdev Sep 16, 2025
fbded54
Merge branch 'main' into matrix_attr
pachadotdev Sep 16, 2025
5e945fc
Merge pull request #14 from pachadotdev/matrix_attr
pachadotdev Sep 16, 2025
b5e5e34
Merge branch 'main' into complex
pachadotdev Sep 16, 2025
a107194
Merge pull request #15 from pachadotdev/complex
pachadotdev Sep 16, 2025
fd74b51
Merge branch 'main' into 255
pachadotdev Sep 16, 2025
e62c914
Merge pull request #16 from pachadotdev/255
pachadotdev Sep 16, 2025
bd5d79b
Merge branch 'main' into testthat3e
pachadotdev Sep 16, 2025
e350bbf
Merge pull request #17 from pachadotdev/testthat3e
pachadotdev Sep 16, 2025
33d04f4
Merge branch 'main' into vendoring
pachadotdev Sep 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: cpp11
Title: A C++11 Interface for R's C Interface
Version: 0.5.2.9000
Version: 0.6.0.9000
Authors@R:
c(
person("Davis", "Vaughan", email = "davis@posit.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4777-038X")),
Expand Down Expand Up @@ -31,7 +31,6 @@ Suggests:
glue,
knitr,
lobstr,
mockery,
progress,
rmarkdown,
scales,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export(cpp_eval)
export(cpp_function)
export(cpp_register)
export(cpp_source)
export(cpp_unvendor)
export(cpp_vendor)
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

* Fixed an issue related to `-Wdeprecated-literal-operator` (#447, @andrjohns).

# cpp11 0.5.1.9000

* Uses testthat 3e style tests (#402).
* Removes the mockery dependence.
* The vendoring function accepts a custom path (i.e., to use the GitHub version of the package)

# cpp11 0.5.1

* cpp11 now requires R >=4.0.0, in line with the
Expand Down
65 changes: 52 additions & 13 deletions R/register.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,16 @@ 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, ' {{
"_cpp11_{name}", (DL_FUNC) &_{package}_{name}, {n_args}}}, ',
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 <cpp11/R.hpp>", "#include <Rcpp.h>", "using namespace Rcpp;")
}
Expand Down Expand Up @@ -215,35 +214,75 @@ 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 <- ""
}

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})")
)

out <- glue::glue_data(funs, '
{name} <- function({list_params}) {{
{calls}
}}
')
# Parse and associate Roxygen comments
funs$roxygen_comment <- mapply(function(file, line) {
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 {
""
}
}, 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 {calls}\n}}")
}
}, funs$name, funs$list_params, funs$calls, funs$roxygen_comment, 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(list())
}

roxygen_comments <- mapply(function(start, end) {
roxygen_lines <- lines[(start + 1):(end - 1)]
roxygen_lines <- sub("^", "#' ", roxygen_lines)
list(line = end, text = paste(roxygen_lines, collapse = "\n"))
}, roxygen_start, roxygen_end, SIMPLIFY = FALSE)

roxygen_comments
}

wrap_call <- function(name, return_type, args) {
call <- glue::glue('{name}({list_params})', list_params = glue_collapse_data(args, "cpp11::as_cpp<cpp11::decay_t<{type}>>({name})"))
if (return_type == "void") {
Expand Down
32 changes: 22 additions & 10 deletions R/source.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
#' uses 'CXX11' if unset.
#' @param dir The directory to store the generated source files. `tempfile()` is
#' used by default. The directory will be removed if `clean` is `TRUE`.
#' @param local Passed to [dyn.load()]. If `TRUE` (the default) the shared
#' library is loaded with local symbols; if `FALSE` symbols are made global
#' (equivalent to `dyn.load(..., local = FALSE)`), which can be required when
#' other shared objects need to see RTTI/vtable symbols from this library.
#' @note See the unit test that demonstrates this usage at
#' \code{tests/testthat/test-source-local.R} (shows how `local = FALSE` exports
#' the necessary symbols so separate shared objects can link against them).
#' @return For [cpp_source()] and `[cpp_function()]` the results of
#' [dyn.load()] (invisibly). For `[cpp_eval()]` the results of the evaluated
#' expression.
Expand Down Expand Up @@ -65,7 +72,7 @@
#' }
#'
#' @export
cpp_source <- function(file, code = NULL, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11"), dir = tempfile()) {
cpp_source <- function(file, code = NULL, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11"), dir = tempfile(), local = TRUE) {
stop_unless_installed(c("brio", "callr", "cli", "decor", "desc", "glue", "tibble", "vctrs"))
if (!missing(file) && !file.exists(file)) {
stop("Can't find `file` at this path:\n", file, "\n", call. = FALSE)
Expand Down Expand Up @@ -145,7 +152,7 @@ cpp_source <- function(file, code = NULL, env = parent.frame(), clean = TRUE, qu
brio::write_lines(r_functions, r_path)
source(r_path, local = env)

dyn.load(shared_lib, local = TRUE, now = TRUE)
dyn.load(shared_lib, local = local, now = TRUE)
}

the <- new.env(parent = emptyenv())
Expand All @@ -163,12 +170,15 @@ generate_cpp_name <- function(name, loaded_dlls = c("cpp11", names(getLoadedDLLs
sprintf("%s.%s", new_name, ext)
}



generate_include_paths <- function(packages) {
generate_include_paths <- function(packages, custom_path = NULL) {
out <- character(length(packages))
for (i in seq_along(packages)) {
path <- system.file(package = packages[[i]], "include")
if (!is.null(custom_path)) {
path <- custom_path
} else {
path <- system.file(package = packages[[i]], "include")
}

if (is_windows()) {
path <- utils::shortPathName(path)
}
Expand All @@ -183,7 +193,7 @@ generate_makevars <- function(includes, cxx_std) {

#' @rdname cpp_source
#' @export
cpp_function <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11")) {
cpp_function <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11"), local = TRUE) {
cpp_source(code = paste(c('#include "cpp11.hpp"',
"using namespace ::cpp11;",
"namespace writable = ::cpp11::writable;",
Expand All @@ -193,15 +203,16 @@ cpp_function <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE,
env = env,
clean = clean,
quiet = quiet,
cxx_std = cxx_std
cxx_std = cxx_std,
local = local
)
}

utils::globalVariables("f")

#' @rdname cpp_source
#' @export
cpp_eval <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11")) {
cpp_eval <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11"), local = TRUE) {
cpp_source(code = paste(c('#include "cpp11.hpp"',
"using namespace ::cpp11;",
"namespace writable = ::cpp11::writable;",
Expand All @@ -214,7 +225,8 @@ cpp_eval <- function(code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx
env = env,
clean = clean,
quiet = quiet,
cxx_std = cxx_std
cxx_std = cxx_std,
local = local
)
f()
}
Expand Down
39 changes: 39 additions & 0 deletions R/unvendor.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#' Unvendor the cpp11 dependency
#'
#' This function removes the vendored cpp11 headers from your package and
#' restores the `LinkingTo: cpp11` field in the DESCRIPTION file if it was removed.
#'
#' @inheritParams cpp_register
#' @return The file path to the unvendored code (invisibly).
#' @export
#' @examples
#' # create a new directory
#' dir <- tempfile()
#' dir.create(dir)
#'
#' # vendor the cpp11 headers into the directory
#' cpp_vendor(dir)
#'
#' # unvendor the cpp11 headers from the directory
#' cpp_unvendor(dir)
#'
#' list.files(file.path(dir, "inst", "include", "cpp11"))
#'
#' # cleanup
#' unlink(dir, recursive = TRUE)
cpp_unvendor <- function(path = ".") {
new <- file.path(path, "inst", "include", "cpp11")

if (!dir.exists(new)) {
stop("'", new, "' does not exist", call. = FALSE)
}

unlink(new, recursive = TRUE)

cpp11_hpp <- file.path(dirname(new), "cpp11.hpp")
if (file.exists(cpp11_hpp)) {
unlink(cpp11_hpp)
}

invisible(new)
}
88 changes: 71 additions & 17 deletions R/vendor.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
#' 'cpp11 version: XYZ' to the top of the files, where XYZ is the version of
#' cpp11 currently installed on your machine.
#'
#' If you choose to vendor the headers you should _remove_ `LinkingTo:
#' cpp11` from your DESCRIPTION.
#'
#' **Note**: vendoring places the responsibility of updating the code on
#' **you**. Bugfixes and new features in cpp11 will not be available for your
#' code until you run `cpp_vendor()` again.
#'
#' @inheritParams cpp_register
#' @param dir The directoyy to vendor the code into.
#' @param subdir The subdirectory to vendor the code into.
#' @param headers The path to the cpp11 headers to vendor. By default this is
#' the path where R installed the cpp11 package. You can change this to
#' use a different version of cpp11, such as as the development version
#' from GitHub.
#' @return The file path to the vendored code (invisibly).
#' @export
#' @examples
Expand All @@ -30,34 +33,85 @@
#'
#' # cleanup
#' unlink(dir, recursive = TRUE)
cpp_vendor <- function(path = ".") {
new <- file.path(path, "inst", "include", "cpp11")
cpp_vendor <- function(dir = NULL, subdir = "/inst/include") {
if (is.null(dir)) {
stop("You must provide a path to vendor the code into", call. = FALSE)
}

path <- paste0(dir, subdir)

if (dir.exists(new)) {
stop("'", new, "' already exists\n * run unlink('", new, "', recursive = TRUE)", call. = FALSE)
path2 <- file.path(path, "cpp11")
if (dir.exists(path2)) {
stop("'", path2, "' already exists\n * run unlink('", path2, "', recursive = TRUE)", call. = FALSE)
}

dir.create(new , recursive = TRUE, showWarnings = FALSE)
# Vendor cpp11 ----

dir.create(
path2,
recursive = TRUE,
showWarnings = FALSE
)

current_cpp11 <- system.file(
"include",
"cpp11",
package = "cpp11"
)

current <- system.file("include", "cpp11", package = "cpp11")
if (!nzchar(current)) {
if (!nzchar(current_cpp11)) {
stop("cpp11 is not installed", call. = FALSE)
}

cpp11_version <- utils::packageVersion("cpp11")

cpp11_header <- sprintf("// cpp11 version: %s\n// vendored on: %s", cpp11_version, Sys.Date())
cpp11_header <- sprintf(
"// cpp11 version: %s\n// vendored on: %s",
cpp11_version,
Sys.Date()
)

files <- list.files(current, full.names = TRUE)
write_header(
path, "cpp11.hpp", "cpp11",
cpp11_header
)

copy_files(
list.files(current_cpp11, full.names = TRUE),
path, "cpp11", cpp11_header
)

# Additional steps to make vendoring work ----

message(paste(
"Makevars and/or Makevars.win should have a line such as",
"'PKG_CPPFLAGS = -I../inst/include'"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this now need to show the new path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that line is added automatically, and uses the path the user wants

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i reallize i never pushed that change, done now

))

message("DESCRIPTION should not have lines such as 'LinkingTo: cpp11'")

files <- list.files(headers, full.names = TRUE)

invisible(path)
}

write_header <- function(path, header, pkg, cpp11armadillo_header) {
writeLines(
c(cpp11_header, readLines(system.file("include", "cpp11.hpp", package = "cpp11"))),
file.path(dirname(new), "cpp11.hpp")
c(
cpp11armadillo_header,
readLines(
system.file("include", header, package = pkg)
)
),
file.path(path, header)
)
}

copy_files <- function(files, path, out, cpp11armadillo_header) {
for (f in files) {
writeLines(c(cpp11_header, readLines(f)), file.path(new, basename(f)))
writeLines(
c(cpp11armadillo_header, readLines(f)),
file.path(path, out, basename(f))
)
}

invisible(new)
}
Loading
Loading