diff --git a/dev/articles/FAQ.html b/dev/articles/FAQ.html index d8cbca8a..86977a1c 100644 --- a/dev/articles/FAQ.html +++ b/dev/articles/FAQ.html @@ -357,10 +357,10 @@

14. How do I modify a vector in place
 x <- c(1L, 2L, 3L, 4L)
 .Internal(inspect(x))
-#> @55a68b793528 13 INTSXP g0c2 [REF(2)] (len=4, tl=0) 1,2,3,4
+#> @56199c572e88 13 INTSXP g0c2 [REF(2)] (len=4, tl=0) 1,2,3,4
 add_one(x)
 .Internal(inspect(x))
-#> @55a68b793528 13 INTSXP g0c2 [REF(5)] (len=4, tl=0) 2,3,4,5
+#> @56199c572e88 13 INTSXP g0c2 [REF(5)] (len=4, tl=0) 2,3,4,5
 x
 #> [1] 2 3 4 5
@@ -605,7 +605,7 @@

16. Ok but I #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> -#> 1 test_extract_cpp11(x) 41.86ms 44.48ms 21.9 0B 37.8 +#> 1 test_extract_cpp11(x) 40.66ms 44.1ms 22.3 0B 39.0 #> 2 test_extract_r_api(x) 2.16ms 2.17ms 459. 0B 0

We plan to improve on this in the future, but for now this is one of the only places where we feel it is reasonable to call diff --git a/dev/articles/cpp11.html b/dev/articles/cpp11.html index 0da386e0..3a6760cd 100644 --- a/dev/articles/cpp11.html +++ b/dev/articles/cpp11.html @@ -169,7 +169,7 @@

Getting started with C++add #> function (x, y, z) #> { -#> .Call("_code_1a78291414c7_add", x, y, z, PACKAGE = "code_1a78291414c7") +#> .Call("_code_19f31774bf9f_add", x, y, z, PACKAGE = "code_19f31774bf9f") #> } add(1, 2, 3) #> [1] 6 @@ -328,9 +328,9 @@

Vector input, scalar output#> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> -#> 1 sum(x) 2.06µs 2.16µs 434978. 0B 0 -#> 2 sum_cpp(x) 2.03µs 2.15µs 410478. 0B 0 -#> 3 sum_r(x) 20.14µs 20.56µs 47885. 35.7KB 0 +#> 1 sum(x) 2.06µs 2.13µs 442749. 0B 0 +#> 2 sum_cpp(x) 2.05µs 2.21µs 394362. 0B 0 +#> 3 sum_r(x) 20.16µs 20.61µs 47922. 35.7KB 0 +#> 1 pdist_r(0.5, y) 5.01ms 5.18ms 189. 7.63MB 94.5 +#> 2 pdist_cpp(0.5, y) 3.93ms 3.98ms 250. 7.63MB 127.

On my computer, it takes around 5 ms with a 1 million element y vector. The C++ function is about 2.5 times faster, ~2 ms, but assuming it took you 10 minutes to write the C++ function, you’d @@ -1153,8 +1153,8 @@

Gibbs sampler#> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> <bch:expr> <dbl> <dbl> <dbl> <dbl> <dbl> -#> 1 r 23.3 24.0 1 33.0 12.0 -#> 2 cpp 1 1 24.3 1 1 +#> 1 r 23.8 25.1 1 33.0 11.9 +#> 2 cpp 1 1 25.1 1 1

R vectorisation versus C++ vectorisation @@ -1253,9 +1253,9 @@

R vectorisation versus C++ vecto #> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> -#> 1 vacc1 1.48ms 1.52ms 637. 7.86KB 34.6 -#> 2 vacc2 44.44µs 50.02µs 19223. 148.56KB 36.4 -#> 3 vacc3 11.86µs 12.24µs 80648. 14.02KB 8.07

+#> 1 vacc1 1.49ms 1.52ms 650. 7.86KB 34.2 +#> 2 vacc2 42.61µs 45.53µs 20843. 148.56KB 39.6 +#> 3 vacc3 11.9µs 12.17µs 79465. 14.02KB 7.95

Not surprisingly, our original approach with loops is very slow. Vectorising in R gives a huge speedup, and we can eke out even more performance (about ten times) with the C++ loop. I was a little diff --git a/dev/news/index.html b/dev/news/index.html index ce7464b0..d6beb89d 100644 --- a/dev/news/index.html +++ b/dev/news/index.html @@ -43,7 +43,8 @@

Changelog

cpp11 (development version)

-
  • cpp11::writable::r_vector<T>::proxy now implements copy assignment. Practically this means that x[i] = y[i] now works when both x and y are writable vectors (#300, #339).

  • +
    • cpp11::function now protects its underlying function, for maximum safety (#294).

    • +
    • cpp11::writable::r_vector<T>::proxy now implements copy assignment. Practically this means that x[i] = y[i] now works when both x and y are writable vectors (#300, #339).

    • Implicit conversion from sexp to bool, size_t, and double has been marked as deprecated and will be removed in the next version of cpp11. The 3 packages that were using this have been notified and sent PRs. The recommended approach is to instead use cpp11::as_cpp<T>, which performs type and length checking, making it much safer to use.

    • New writable::data_frame constructor that also takes the number of rows as input. This accounts for the edge case where the input list has 0 columns but you’d still like to specify a known number of rows (#272).

    • cpp11::writable::r_vector<T>::iterator no longer implicitly deletes its copy assignment operator (#360).

    • diff --git a/dev/pkgdown.yml b/dev/pkgdown.yml index 589ef71a..2ac3cd22 100644 --- a/dev/pkgdown.yml +++ b/dev/pkgdown.yml @@ -7,7 +7,7 @@ articles: FAQ: FAQ.html internals: internals.html motivations: motivations.html -last_built: 2024-08-26T14:20Z +last_built: 2024-08-26T18:31Z urls: reference: https://cpp11.r-lib.org/reference article: https://cpp11.r-lib.org/articles diff --git a/dev/search.json b/dev/search.json index 5871cbaf..bcfb91e4 100644 --- a/dev/search.json +++ b/dev/search.json @@ -1 +1 @@ -[{"path":[]},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement [INSERT CONTACT METHOD]. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/ code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https:// www.contributor-covenant.org/translations.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"Contributing to cpp11","title":"Contributing to cpp11","text":"outlines propose change cpp11. detailed info contributing , tidyverse packages, please see development contributing guide.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"fixing-typos","dir":"","previous_headings":"","what":"Fixing typos","title":"Contributing to cpp11","text":"can fix typos, spelling mistakes, grammatical errors documentation directly using GitHub web interface, long changes made source file. generally means ’ll need edit roxygen2 comments .R, .Rd file. can find .R file generates .Rd reading comment first line.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"bigger-changes","dir":"","previous_headings":"","what":"Bigger changes","title":"Contributing to cpp11","text":"want make bigger change, ’s good idea first file issue make sure someone team agrees ’s needed. ’ve found bug, please file issue illustrates bug minimal reprex (also help write unit test, needed).","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"pull-request-process","dir":"","previous_headings":"Bigger changes","what":"Pull request process","title":"Contributing to cpp11","text":"Fork package clone onto computer. haven’t done , recommend using usethis::create_from_github(\"r-lib/cpp11\", fork = TRUE). Install development dependences devtools::install_dev_deps(), make sure package passes R CMD check running devtools::check(). R CMD check doesn’t pass cleanly, ’s good idea ask help continuing. Create Git branch pull request (PR). recommend using usethis::pr_init(\"brief-description--change\"). Make changes, commit git, create PR running usethis::pr_push(), following prompts browser. title PR briefly describe change. body PR contain Fixes #issue-number. user-facing changes, add bullet top NEWS.md (.e. just first header). Follow style described https://style.tidyverse.org/news.html.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"Bigger changes","what":"Code style","title":"Contributing to cpp11","text":"New code follow tidyverse style guide. can use styler package apply styles, please don’t restyle code nothing PR. use roxygen2, Markdown syntax, documentation. use testthat unit tests. Contributions test cases included easier accept.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Contributing to cpp11","text":"Please note cpp11 project released Contributor Code Conduct. contributing project agree abide terms.","code":""},{"path":"https://cpp11.r-lib.org/dev/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2020 RStudio Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"current-state","dir":"","previous_headings":"","what":"Current state","title":"NA","text":"state cpp11 pretty stable, seems features need projects using C++.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"running-the-cpp11test-tests","dir":"","previous_headings":"Known outstanding issues","what":"Running the cpp11test tests","title":"NA","text":"test suite sub-package, cpp11test. Probably best way run tests install development version cpp11 run devtools::test() run cpp11test test suite. tests failures occur output Catch isn’t always easy interpret. branch testthat https://github.com/jimhester/testthat/tree/catch-detailed-output make things easier understand. contributed changes main testthat, something changed merging detailed output lost, unfortunately never time track cause fix . addition getting debugger catch errors happen can fiddly running cpp11test tests, something way Catch redirects stderr / stdout interacts debugger. GitHub Actions workflow additional logic handle running cpp11 tests https://github.com/r-lib/cpp11/blob/fd8ef97d006db847f7f17166cf52e1e0383b2d35/.github/workflows/R-CMD-check.yaml#L95-L102, https://github.com/r-lib/cpp11/blob/fd8ef97d006db847f7f17166cf52e1e0383b2d35/.github/workflows/R-CMD-check.yaml#L117-L124.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"false-positive-url-checks-for-git-repositories-in-the-vignettes","dir":"","previous_headings":"Known outstanding issues","what":"False positive URL checks for git repositories in the vignettes","title":"NA","text":"run urlchecker::url_check() repo see following false positives. happen urlchecker package, can safely ignored real CRAN checks show .","code":"! Warning: vignettes/motivations.Rmd:363:11 Moved git clone https://github.com/r-lib/cpp11.git ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://github.com/r-lib/cpp11 ! Warning: vignettes/motivations.Rmd:354:11 Moved git clone https://github.com/RcppCore/Rcpp.git ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://github.com/RcppCore/Rcpp >"},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"ensure-you-use-syssetenvcpp11_eval--true-devtoolssubmit_cran-when-submitting","dir":"","previous_headings":"","what":"Ensure you use Sys.setenv(\"CPP11_EVAL\" = \"true\"); devtools::submit_cran() when submitting.","title":"NA","text":"forget set CPP_EVAL = \"true\" vignette chunks run properly vignettes rendered properly.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"regenerating-benchmark-objects-used-in-motivationsrmd","dir":"","previous_headings":"","what":"Regenerating benchmark objects used in motivations.Rmd","title":"NA","text":"need regenerate benchmark objects (RDS objects) utilized motivations.Rmd, set Sys.setenv(\"CPP11TEST_SHOULD_RUN_BENCHMARKS\" = \"TRUE\") running Rmd. ’ll also need make sure cpp11test actually installed. See cpp11test:::should_run_benchmarks() .","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"usage-with-clangd","dir":"","previous_headings":"","what":"Usage with clangd","title":"NA","text":"Since cpp11 header , use clangd ’ll bit issue tools like bear pkgload won’t know generate compile_commands.json file. Instead, can create manually something like , seems work well. Note paths specific computer. Key notes: R.hpp seems enough. imagine header files, reasonable pick “root” one pretty much others include. Using -std=gnu++11 keep us honest C++11 features. Using -\\\"/Library/Frameworks/R.framework/Resources/include\\\" access R headers. Using -\\\"/Users/davis/files/r/packages/cpp11/inst/include\\\" “self include”, seems key whole thing. modifying tests benchmarks, also need: -\\\"/Users/davis/Library/R/arm64/4.4/library/Rcpp/include\\\" Rcpp headers. -\\\"/Users/davis/Library/R/arm64/4.4/library/testthat/include\\\" testthat headers related Catch tests. Note specific path machine R version currently working .","code":"[ { \"command\": \"g++ -std=gnu++11 -I\\\"/Users/davis/files/r/packages/cpp11/inst/include\\\" -I\\\"/Library/Frameworks/R.framework/Resources/include\\\" -I\\\"/Users/davis/Library/R/arm64/4.4/library/Rcpp/include\\\" -I\\\"/Users/davis/Library/R/arm64/4.4/library/testthat/include\\\" -I\\\"/opt/homebrew/include\\\" -Wall -pedantic\", \"file\": \"R.hpp\", \"directory\": \"/Users/davis/files/r/packages/cpp11/inst/include/cpp11\" } ]"},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"future-directions","dir":"","previous_headings":"","what":"Future directions","title":"NA","text":"work spent smoothing cpp_source() / knitr chunk experience. main focus use cases R packages, usage tested. don’t typically use cpp11 non package contexts use cases may nice. similar reasons matrix support might somewhat lacking, majority use cases deal numeric matrices.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":null,"dir":"","previous_headings":"","what":"Getting help with cpp11","title":"Getting help with cpp11","text":"Thanks using cpp11! filing issue, places explore pieces put together make process smooth possible.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"make-a-reprex","dir":"","previous_headings":"","what":"Make a reprex","title":"Getting help with cpp11","text":"Start making minimal reproducible example using reprex package. haven’t heard used reprex , ’re treat! Seriously, reprex make R-question-asking endeavors easier (pretty insane ROI five ten minutes ’ll take learn ’s ). additional reprex pointers, check Get help! section tidyverse site.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"where-to-ask","dir":"","previous_headings":"","what":"Where to ask?","title":"Getting help with cpp11","text":"Armed reprex, next step figure ask. ’s question: start community.rstudio.com, /StackOverflow. people answer questions. ’s bug: ’re right place, file issue. ’re sure: let community help figure ! problem bug feature request, can easily return report . opening new issue, sure search issues pull requests make sure bug hasn’t reported /already fixed development version. default, search pre-populated :issue :open. can edit qualifiers (e.g. :pr, :closed) needed. example, ’d simply remove :open search issues repo, open closed.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"what-happens-next","dir":"","previous_headings":"","what":"What happens next?","title":"Getting help with cpp11","text":"efficient possible, development tidyverse packages tends bursty, shouldn’t worry don’t get immediate response. Typically don’t look repo sufficient quantity issues accumulates, ’s burst intense activity focus efforts. makes development efficient avoids expensive context switching problems, cost taking longer get back . process makes good reprex particularly important might multiple months initial report start working . can’t reproduce bug, can’t fix !","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-add-elements-to-a-named-list","dir":"Articles","previous_headings":"","what":"2. How do I add elements to a named list?","title":"FAQ","text":"Use push_back() method named literal syntax. named literal syntax defined cpp11::literals namespace.","code":"#include [[cpp11::register]] cpp11::list foo_push() { using namespace cpp11::literals; cpp11::writable::list x; x.push_back({\"foo\"_nm = 1}); return x; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"does-cpp11-support-default-arguments","dir":"Articles","previous_headings":"","what":"3. Does cpp11 support default arguments?","title":"FAQ","text":"cpp11 support default arguments, convenient require complexity support currently worthwhile. need default argument support can use wrapper function around cpp11 registered function. common convention name internal function trailing _.","code":"#include [[cpp11::register]] double add_some_(double x, double amount) { return x + amount; } add_some <- function(x, amount = 1) { add_some_(x, amount) } add_some(1) #> [1] 2 add_some(1, amount = 5) #> [1] 6"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-create-a-new-empty-list","dir":"Articles","previous_headings":"","what":"4. How do I create a new empty list?","title":"FAQ","text":"Define new writable list object. cpp11::writable::list x;","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-retrieve-named-elements-from-a-named-vectorlist","dir":"Articles","previous_headings":"","what":"5. How do I retrieve (named) elements from a named vector/list?","title":"FAQ","text":"Use [] accessor function. x[\"foo\"]","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-tell-whether-a-vector-is-named","dir":"Articles","previous_headings":"","what":"6. How can I tell whether a vector is named?","title":"FAQ","text":"Use named() method vector classes.","code":"#include [[cpp11::register]] bool is_named(cpp11::strings x) { return x.named(); } is_named(\"foo\") #> [1] FALSE is_named(c(x = \"foo\")) #> [1] TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-return-a-cpp11writablelogicals-object-with-only-a-false-value","dir":"Articles","previous_headings":"","what":"7. How do I return a cpp11::writable::logicals object with only a FALSE value?","title":"FAQ","text":"need use list initialization {} create object.","code":"#include [[cpp11::register]] cpp11::writable::logicals my_false() { return {FALSE}; } [[cpp11::register]] cpp11::writable::logicals my_true() { return {TRUE}; } [[cpp11::register]] cpp11::writable::logicals my_both() { return {TRUE, FALSE, TRUE}; } my_false() #> [1] FALSE my_true() #> [1] TRUE my_both() #> [1] TRUE FALSE TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-create-a-new-empty-environment","dir":"Articles","previous_headings":"","what":"8. How do I create a new empty environment?","title":"FAQ","text":"need call base::new.env() function C++. can done creating cpp11::function object calling generate new environment.","code":"#include [[cpp11::register]] cpp11::environment create_environment() { cpp11::function new_env(cpp11::package(\"base\")[\"new.env\"]); return new_env(); }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-assign-and-retrieve-values-in-an-environment-what-happens-if-i-try-to-get-a-value-that-doesnt-exist","dir":"Articles","previous_headings":"","what":"9. How do I assign and retrieve values in an environment? What happens if I try to get a value that doesn’t exist?","title":"FAQ","text":"Use [] retrieve assign values environment name. value exist, error. check existence ahead time, use exists() method.","code":"#include [[cpp11::register]] bool foo_exists(cpp11::environment x) { return x.exists(\"foo\"); } [[cpp11::register]] void set_foo(cpp11::environment x, double value) { x[\"foo\"] = value; } x <- new.env() foo_exists(x) #> [1] FALSE set_foo(x, 1) foo_exists(x) #> [1] TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-create-a-cpp11raws-from-a-stdstring","dir":"Articles","previous_headings":"","what":"10. How can I create a cpp11:raws from a std::string?","title":"FAQ","text":"built way . One method push_back() element string individually.","code":"#include [[cpp11::register]] cpp11::raws push_raws() { std::string x(\"hi\"); cpp11::writable::raws out; for (auto c : x) { out.push_back(c); } return out; } push_raws() #> [1] 68 69"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-create-a-stdstring-from-a-cpp11writablestring","dir":"Articles","previous_headings":"","what":"11. How can I create a std::string from a cpp11::writable::string?","title":"FAQ","text":"C++ allow two implicit cast, explicitly cast cpp11::r_string first.","code":"#include #include [[cpp11::register]] std::string my_string() { cpp11::writable::strings x({\"foo\", \"bar\"}); std::string elt = cpp11::r_string(x[0]); return elt; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"what-are-the-types-for-c-iterators","dir":"Articles","previous_headings":"","what":"12. What are the types for C++ iterators?","title":"FAQ","text":"iterators ::iterator classes contained inside vector classes. example iterator cpp11::doubles cpp11::doubles::iterator iterator cpp11::writable::doubles cpp11::writable::doubles::iterator.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"my-code-has-using-namespace-std-why-do-i-still-have-to-include-std-in-the-signatures-of-cpp11register-functions","dir":"Articles","previous_headings":"","what":"13. My code has using namespace std, why do I still have to include std:: in the signatures of [[cpp11::register]] functions?","title":"FAQ","text":"using namespace std directive included generated code function signatures, still need fully qualified. However need qualify type names within functions. following won’t compile compile work intended","code":"#include #include using namespace std; [[cpp11::register]] string foobar() { return string(\"foo\") + \"-bar\"; } #include #include using namespace std; [[cpp11::register]] std::string foobar() { return string(\"foo\") + \"-bar\"; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-modify-a-vector-in-place","dir":"Articles","previous_headings":"","what":"14. How do I modify a vector in place?","title":"FAQ","text":"place modification breaks normal semantics R code. general avoided, cpp11::writable classes always copy data constructed. However positive -place modification necessary use case can use move constructor .","code":"#include [[cpp11::register]] void add_one(cpp11::sexp x_sexp) { cpp11::writable::integers x(std::move(x_sexp.data())); for (auto&& value : x) { ++value; } } x <- c(1L, 2L, 3L, 4L) .Internal(inspect(x)) #> @55a68b793528 13 INTSXP g0c2 [REF(2)] (len=4, tl=0) 1,2,3,4 add_one(x) .Internal(inspect(x)) #> @55a68b793528 13 INTSXP g0c2 [REF(5)] (len=4, tl=0) 2,3,4,5 x #> [1] 2 3 4 5"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"should-i-call-cpp11unwind_protect-manually","dir":"Articles","previous_headings":"","what":"15. Should I call cpp11::unwind_protect() manually?","title":"FAQ","text":"cpp11::unwind_protect() cpp11’s way safely calling R’s C API. short, allows run function might throw R error, catch longjmp() error, promote exception thrown caught try/catch cpp11 sets .Call() time (allows destructors run), finally tells R continue unwinding stack now C++ objects chance destruct needed. Since cpp11::unwind_protect() takes arbitrary function, may wondering use custom needs. general, advise extremely advanced feature prone subtle hard debug issues.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"destructors","dir":"Articles","previous_headings":"15. Should I call cpp11::unwind_protect() manually?","what":"Destructors","title":"FAQ","text":"following setup test_destructor_ok() manual call unwind_protect() work: happen move unwind_protect(), won’t destructed, ’ll end memory leak best, much sinister issue destructor important: general, code can called within unwind_protect() “pure” C code C++ code uses POD (plain-old-data) types exceptions. mix complex C++ objects R’s C API within unwind_protect(), R errors result jump prevents destructors running.","code":"#include class A { public: ~A(); }; A::~A() { Rprintf(\"hi from the destructor!\"); } [[cpp11::register]] void test_destructor_ok() { A a{}; cpp11::unwind_protect([&] { Rf_error(\"oh no!\"); }); } [[cpp11::register]] void test_destructor_bad() { cpp11::unwind_protect([&] { A a{}; Rf_error(\"oh no!\"); }); } test_destructor_ok() #> Error: oh no! #> hi from the destructor! test_destructor_bad() #> Error: oh no!"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"nested-unwind_protect","dir":"Articles","previous_headings":"15. Should I call cpp11::unwind_protect() manually?","what":"Nested unwind_protect()","title":"FAQ","text":"Another issue can arise nested calls unwind_protect(). hard (impossible) end invalidly nested unwind_protect() calls using typical cpp11 API, can manually create scenario like following: run test_nested() R, likely crash hang R session due following chain events: test_nested() sets try/catch catch unwind exceptions outer unwind_protect() called. uses C function R_UnwindProtect() call lambda function. inner unwind_protect() called. uses R_UnwindProtect(), time call Rf_error(). Rf_error() performs longjmp() caught inner unwind_protect() promoted exception. exception thrown, outer call R_UnwindProtect() (C function), end throwing exception across C stack frames. undefined behavior, known caused R crash certain platforms. might think ’d never , scenario can also occur combination 1 call unwind_protect() combined usage cpp11 API: cpp11::stop() (cpp11 API) uses unwind_protect() internally, ’ve indirectly ended nested unwind_protect() scenario . general, must use unwind_protect() must careful use cpp11 API inside unwind_protect() call. worth pointing calling R function cpp11 calls back cpp11 still safe, .e. registered version imaginary test_outer() function called R, work: might seem unsafe cpp11::package() uses unwind_protect() call R function test_inner(), goes back C++ call cpp11::stop(), uses unwind_protect(), seems like nested scenario, scenario actually work. makes sense analyze one step time: Call R function test_outer() try/catch set catch unwind exceptions C++ function test_outer() called cpp11::package() uses unwind_protect() call R function test_inner() Call R function test_inner() try/catch set catch unwind exceptions (key!) C++ function test_inner() called cpp11::stop(\"oh !\") called, uses unwind_protect() call Rf_error(), causing longjmp(), caught unwind_protect() promoted exception. exception thrown, time caught try/catch set test_inner() entered R side. prevents exception crossing C++ -> C boundary. try/catch calls R_ContinueUnwind(), longjmp()s , now unwind_protect() set cpp11::package() catches , promotes exception. exception thrown caught try/catch set test_outer(). try/catch calls R_ContinueUnwind(), longjmp()s , point can safely let longjmp() proceed force R error.","code":"#include [[cpp11::register]] void test_nested() { cpp11::unwind_protect([&] { cpp11::unwind_protect([&] { Rf_error(\"oh no!\"); }); }); } #include [[cpp11::register]] void test_hidden_nested() { cpp11::unwind_protect([&] { cpp11::stop(\"oh no!\"); }); } #include [[cpp11::register]] void test_inner() { cpp11::stop(\"oh no!\") } [[cpp11::register]] void test_outer() { auto fn = cpp11::package(\"mypackage\")[\"test_inner\"] fn(); }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"ok-but-i-really-want-to-call-cpp11unwind_protect-manually","dir":"Articles","previous_headings":"","what":"16. Ok but I really want to call cpp11::unwind_protect() manually","title":"FAQ","text":"’ve read bullet still feel like need call unwind_protect(), keep mind following writing function unwind-protect: shouldn’t create C++ objects destructors. shouldn’t use parts cpp11 API may call unwind_protect(). must careful call unwind_protect() nested manner. words, use plain-old-data types, careful never throw exceptions, use R’s C API, can use unwind_protect(). One place may want working long character vectors. Unfortunately, due way cpp11 must protect individual CHARSXP objects make character vector, can currently quite slow use cpp11 API . Consider example extracting individual elements x[] vs using native R API: plan improve future, now one places feel reasonable call unwind_protect() manually.","code":"#include [[cpp11::register]] cpp11::sexp test_extract_cpp11(cpp11::strings x) { const R_xlen_t size = x.size(); for (R_xlen_t i = 0; i < size; ++i) { (void) x[i]; } return R_NilValue; } [[cpp11::register]] cpp11::sexp test_extract_r_api(cpp11::strings x) { const R_xlen_t size = x.size(); const SEXP data{x}; cpp11::unwind_protect([&] { for (R_xlen_t i = 0; i < size; ++i) { (void) STRING_ELT(data, i); } }); return R_NilValue; } set.seed(123) x <- sample(letters, 1e6, replace = TRUE) bench::mark( test_extract_cpp11(x), test_extract_r_api(x) ) #> Warning: Some expressions had a GC in every iteration; so filtering is #> disabled. #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 test_extract_cpp11(x) 41.86ms 44.48ms 21.9 0B 37.8 #> 2 test_extract_r_api(x) 2.16ms 2.17ms 459. 0B 0"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"getting-started","dir":"Articles","previous_headings":"","what":"Getting started","title":"Converting from Rcpp","text":"Add cpp11 calling usethis::use_cpp11(). Start converting function function. Converting code bit time (regularly running tests) best way conversion correctly make progress. separate commit converting file (possibly function) can make finding regressions git bisect much easier future. Convert #include #include . Convert instances // [[Rcpp::export]] [[cpp11::register]]. Grep Rcpp:: replace equivalent cpp11 function using cheatsheets . Remove Rcpp Remove Rcpp LinkingTo Imports fields. Remove @importFrom Rcpp sourceCpp. Delete src/RccpExports.cpp R/RcppExports.R. Delete src/Makevars contains PKG_CPPFLAGS=-DSTRICT_R_HEADERS. Clean old compiled code pkgbuild::clean_dll(). Re-document package update NAMESPACE.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"vectors","dir":"Articles","previous_headings":"Cheatsheet","what":"Vectors","title":"Converting from Rcpp","text":"Note cpp11 vector class read-writeable version. default classes, e.g. cpp11::doubles read-classes permit modification. want modify data create new vector, use writeable variant. Another major difference Rcpp cpp11 vectors grown. Rcpp vectors push_back() method, unlike std::vector() additional space reserved pushing. makes calling push_back() repeatably expensive, entire vector copied call. contrast cpp11 vectors grow efficiently, reserving extra space. See https://cpp11.r-lib.org/articles/motivations.html#growing-vectors details. Rcpp also allows flexible implicit conversions, e.g. pass REALSXP function takes Rcpp::IntegerVector() implicitly converted INTSXP. conversions nice usability, require (implicit) duplication data, associated runtime costs. cpp11 throws error cases. want implicit coercions can add call .integer() .double() appropriate R call function.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"functions","dir":"Articles","previous_headings":"Cheatsheet","what":"Functions","title":"Converting from Rcpp","text":"Note cpp11::stop() cpp11::warning() thin wrappers around Rf_stop() Rf_warning(). simple C functions printf() API, understand C++ objects like std::string. Therefore need call obj.c_str() passing string data .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"r-functions","dir":"Articles","previous_headings":"Cheatsheet","what":"R functions","title":"Converting from Rcpp","text":"Calling R functions C++ similar using Rcpp.","code":"// Rcpp ----------------------------------------------- Rcpp::Function as_tibble(\"as_tibble\", Rcpp::Environment::namespace_env(\"tibble\")); as_tibble(x, Rcpp::Named(\".rows\", num_rows), Rcpp::Named(\".name_repair\", name_repair)); // cpp11 ----------------------------------------------- using namespace cpp11::literals; // so we can use \"\"_nm syntax auto as_tibble = cpp11::package(\"tibble\")[\"as_tibble\"]; as_tibble(x, \".rows\"_nm = num_rows, \".name_repair\"_nm = name_repair);"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"unsupported-rcpp-features","dir":"Articles","previous_headings":"Cheatsheet","what":"Unsupported Rcpp features","title":"Converting from Rcpp","text":"None Modules None Sugar dependencies random number generator restoration support roxygen2 comments interfaces","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"rngs","dir":"Articles","previous_headings":"Cheatsheet","what":"RNGs","title":"Converting from Rcpp","text":"Rcpp includes calls GetRNGstate() PutRNGstate() around wrapped function. ensures C++ code calls R API functions unif_rand(), norm_rand(), exp_rand(), R_unif_index() random seed state set accordingly. cpp11 , must include calls GetRNGstate() PutRNGstate() use functions C++ code. See R-exts 6.3 - Random number generation details functions. One convenient way safely use simple class:","code":"class local_rng { public: local_rng() { GetRNGstate(); } ~local_rng(){ PutRNGstate(); } }; void foo() { local_rng rng_state; /* my code using the RNG */ }"},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"stl-includes","dir":"Articles","previous_headings":"Common issues when converting","what":"STL includes","title":"Converting from Rcpp","text":"Rcpp.h includes number STL headers automatically, notably , however cpp11 headers generally . errors like need include appropriate STL header, case .","code":"error: no type named 'string' in namespace 'std'"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"strict-headers","dir":"Articles","previous_headings":"Common issues when converting","what":"Strict headers","title":"Converting from Rcpp","text":"see something like : Make sure remove PKG_CPPFLAGS=-DSTRICT_R_HEADERS src/Makevars.","code":"In file included from file.cpp:1: In file included from path/cpp11/include/cpp11.hpp:3: path/cpp11/include/cpp11/R.hpp:12:9: warning: 'STRICT_R_HEADERS' macro redefined [-Wmacro-redefined] #define STRICT_R_HEADERS"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"r-api-includes","dir":"Articles","previous_headings":"Common issues when converting","what":"R API includes","title":"Converting from Rcpp","text":"cpp11 conflicts macros declared R headers unless macros R_NO_REMAP STRICT_R_HEADERS defined. include cpp11.hpp (, minimum, cpp11/R.hpp) R headers macros defined appropriately, otherwise may see errors like R headers included cpp11 headers least one R_NO_REMAP STRICT_R_HEADERS defined. indicate must either change include order add preprocessor definitions R_NO_REMAP STRICT_R_HEADERS. Note transitive includes R headers (example, included Rcpp.h) can also introduce conflicting macros.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"type-aliases","dir":"Articles","previous_headings":"Common issues when converting","what":"Type aliases","title":"Converting from Rcpp","text":"use typedefs cpp11 types define custom types need define pkgname_types.hpp file cpp_register() can include generated code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"logical-vector-construction","dir":"Articles","previous_headings":"Common issues when converting","what":"Logical vector construction","title":"Converting from Rcpp","text":"constructing length 1 logical vector may need explicitly use r_bool() object initializer list rather TRUE, FALSE NA_INTEGER. issue occurs clang compiler, gcc. constructing vectors one element issue","code":"// bad cpp11::writable::logicals({FALSE}); // good cpp11::writable::logicals({r_bool(FALSE)}); // good cpp11::writable::logicals({FALSE, NA_LOGICAL});"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Get started with cpp11","text":"Sometimes R code just isn’t fast enough. ’ve used profiling figure bottlenecks , ’ve done everything can R, code still isn’t fast enough. vignette ’ll learn improve performance rewriting key functions C++. magic comes way cpp11 package. cpp11 makes simple connect C++ R. possible write C Fortran code use R, painful comparison. cpp11 provides clean, approachable API lets write high-performance code, insulated R’s complex C API. Typical bottlenecks C++ can address include: Loops can’t easily vectorised subsequent iterations depend previous ones. Recursive functions, problems involve calling functions millions times. overhead calling function C++ much lower R. Problems require advanced data structures algorithms R doesn’t provide. standard template library (STL), C++ efficient implementations many important data structures, ordered maps double-ended queues. aim vignette discuss aspects C++ cpp11 absolutely necessary help eliminate bottlenecks code. won’t spend much time advanced features like object-oriented programming templates focus writing small, self-contained functions, big programs. working knowledge C++ helpful, essential. Many good tutorials references freely available, including https://www.learncpp.com/ https://en.cppreference.com/w/cpp. advanced topics, Effective C++ series Scott Meyers popular choice.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"outline","dir":"Articles","previous_headings":"Introduction","what":"Outline","title":"Get started with cpp11","text":"Section intro teaches write C++ converting simple R functions C++ equivalents. ’ll learn C++ differs R, key scalar, vector, matrix classes called. Section cpp_source shows use cpp11::cpp_source() load C++ file disk way use source() load file R code. Section classes discusses modify attributes cpp11, mentions important classes. Section na teaches work R’s missing values C++. Section stl shows use important data structures algorithms standard template library, STL, built-C++. Section case-studies shows two real case studies cpp11 used get considerable performance improvements. Section package teaches add C++ code R package. Section concludes vignette pointers resources help learn cpp11 C++.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"prerequisites","dir":"Articles","previous_headings":"Introduction","what":"Prerequisites","title":"Get started with cpp11","text":"’ll use cpp11 call C++ R: ’ll also need working C++ compiler. get : Windows, install Rtools. Mac, install Xcode app store. Linux, sudo apt-get install r-base-dev similar.","code":"library(cpp11)"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"intro","dir":"Articles","previous_headings":"","what":"Getting started with C++","title":"Get started with cpp11","text":"cpp_function() allows write C++ functions R: run code, cpp11 compile C++ code construct R function connects compiled C++ function. ’s lot going underneath hood cpp11 takes care details don’t need worry . following sections teach basics translating simple R functions C++ equivalents. ’ll start simple function inputs scalar output, make progressively complicated: Scalar input scalar output Vector input scalar output Vector input vector output Matrix input vector output","code":"cpp_function('int add(int x, int y, int z) { int sum = x + y + z; return sum; }') # add works like a regular R function add #> function (x, y, z) #> { #> .Call(\"_code_1a78291414c7_add\", x, y, z, PACKAGE = \"code_1a78291414c7\") #> } add(1, 2, 3) #> [1] 6"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"no-inputs-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"No inputs, scalar output","title":"Get started with cpp11","text":"Let’s start simple function. arguments always returns integer 1: equivalent C++ function : can compile use R cpp_function() small function illustrates number important differences R C++: syntax create function looks like syntax call function; don’t use assignment create functions R. must declare type output function returns. function returns int (scalar integer). classes common types R vectors : doubles, integers, strings, logicals. Scalars vectors different. scalar equivalents numeric, integer, character, logical vectors : double, int, String, bool. must use explicit return statement return value function. Every statement terminated ;.","code":"one <- function() 1L int one() { return 1; } cpp_function('int one() { return 1; }')"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"scalar-input-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Scalar input, scalar output","title":"Get started with cpp11","text":"next example function implements scalar version sign() function returns 1 input positive, -1 ’s negative: C++ version: declare type input way declare type output. makes code little verbose, also makes clear type input function needs. syntax identical — big differences R C++, also lots similarities! C++ also statement works way R’s. R can use break exit loop, skip one iteration need use continue instead next.","code":"sign_r <- function(x) { if (x > 0) { 1 } else if (x == 0) { 0 } else { -1 } } cpp_function('int sign_cpp(int x) { if (x > 0) { return 1; } else if (x == 0) { return 0; } else { return -1; } }')"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vector-input-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Vector input, scalar output","title":"Get started with cpp11","text":"One big difference R C++ cost loops much lower C++. example, implement sum function R using loop. ’ve programming R , ’ll probably visceral reaction function! C++, loops little overhead, ’s fine use . Section stl, ’ll see alternatives loops clearly express intent; ’re faster, can make code easier understand. C++ version similar, : find length vector, use .size() method, returns integer. C++ methods called . (.e., full stop). statement different syntax: (init; check; increment). loop initialised creating new variable called value 0. iteration check < n, terminate loop ’s . iteration, increment value one, using special prefix operator ++ increases value 1. C++, vector indices start 0, means last element position n - 1. ’ll say ’s important: C++, VECTOR INDICES START 0! common source bugs converting R functions C++. Use = assignment, <-. C++ provides operators modify -place: total += x[] equivalent total = total + x[]. Similar -place operators -=, *=, /=. good example C++ much efficient R. shown following microbenchmark, sum_cpp() competitive built-(highly optimised) sum(), sum_r() several orders magnitude slower.","code":"sum_r <- function(x) { total <- 0 for (i in seq_along(x)) { total <- total + x[i] } total } cpp_function('double sum_cpp(doubles x) { int n = x.size(); double total = 0; for(int i = 0; i < n; ++i) { total += x[i]; } return total; }') x <- runif(1e3) bench::mark( sum(x), sum_cpp(x), sum_r(x) )[1:6] #> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 sum(x) 2.06µs 2.16µs 434978. 0B 0 #> 2 sum_cpp(x) 2.03µs 2.15µs 410478. 0B 0 #> 3 sum_r(x) 20.14µs 20.56µs 47885. 35.7KB 0"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vector-input-vector-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Vector input, vector output","title":"Get started with cpp11","text":"Next ’ll create function computes Euclidean distance value vector values: R, ’s obvious want x scalar function definition, ’d need make clear documentation. ’s problem C++ version explicit types: function introduces new concepts: creating new vector need use writable::doubles rather read-doubles. create new numeric vector length n constructor: cpp11::writable::doubles (n). Another useful way making vector copy existing one: cpp11::doubles zs(ys). C++ uses pow(), ^, exponentiation. Note R version fully vectorised, ’s already going fast. computer, takes around 5 ms 1 million element y vector. C++ function 2.5 times faster, ~2 ms, assuming took 10 minutes write C++ function, ’d need run ~200,000 times make rewriting worthwhile. reason C++ function faster subtle, relates memory management. R version needs create intermediate vector length y (x - ys), allocating memory expensive operation. C++ function avoids overhead uses intermediate scalar.","code":"pdist_r <- function(x, ys) { sqrt((x - ys) ^ 2) } cpp_function('doubles pdist_cpp(double x, doubles ys) { int n = ys.size(); writable::doubles out(n); for(int i = 0; i < n; ++i) { out[i] = sqrt(pow(ys[i] - x, 2.0)); } return out; }') y <- runif(1e6) bench::mark( pdist_r(0.5, y), pdist_cpp(0.5, y) )[1:6] #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 pdist_r(0.5, y) 4.91ms 5.46ms 183. 7.63MB 89.9 #> 2 pdist_cpp(0.5, y) 3.88ms 4.21ms 238. 7.63MB 119."},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"cpp-source","dir":"Articles","previous_headings":"Getting started with C++","what":"Using cpp_source","title":"Get started with cpp11","text":"far, ’ve used inline C++ cpp_function(). makes presentation simpler, real problems, ’s usually easier use stand-alone C++ files source R using cpp_source(). lets take advantage text editor support C++ files (e.g., syntax highlighting) well making easier identify line numbers compilation errors. stand-alone C++ file extension .cpp, needs start : function want available within R, need prefix : ’re familiar roxygen2, might wonder relates @export. cpp11::register registers C++ function called R. @export controls whether function exported package made available user. compile C++ code, use cpp_source(\"path//file.cpp\"). create matching R functions add current session. Note functions can saved .Rdata file reloaded later session; must recreated time restart R. example also illustrates different kind loop, -loop. NB: run code, ’ll notice mean_cpp() faster built-mean(). trades numerical accuracy speed. remainder vignette C++ code presented stand-alone rather wrapped call cpp_function. want try compiling /modifying examples paste C++ source file includes elements described . easy RMarkdown using cpp11 instead {r} beginning code blocks.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] #include \"cpp11/doubles.hpp\" using namespace cpp11; [[cpp11::register]] double mean_cpp(doubles x) { int n = x.size(); double total = 0; for(double value : x) { total += value; } return total / n; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises","dir":"Articles","previous_headings":"Getting started with C++","what":"Exercises","title":"Get started with cpp11","text":"basics C++ hand, ’s now great time practice reading writing simple C++ functions. following functions, read code figure corresponding base R function . might understand every part code yet, able figure basics function . practice function writing skills, convert following functions C++. now, assume inputs missing values. (). cumprod(), cummin(), cummax(). diff(). Start assuming lag 1, generalise lag n. range(). var(). Read approaches can take Wikipedia. Whenever implementing numerical algorithm, ’s always good check already known problem.","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] double f1(doubles x) { int n = x.size(); double y = 0; for(int i = 0; i < n; ++i) { y += x[i] / n; } return y; } [[cpp11::register]] doubles f2(doubles x) { int n = x.size(); writable::doubles out(n); out[0] = x[0]; for(int i = 1; i < n; ++i) { out[i] = out[i - 1] + x[i]; } return out; } [[cpp11::register]] bool f3(logicals x) { int n = x.size(); for(int i = 0; i < n; ++i) { if (x[i]) { return true; } } return false; } [[cpp11::register]] int f4(cpp11::function pred, list x) { int n = x.size(); for(int i = 0; i < n; ++i) { logicals res(pred(x[i])); if (res[0]) { return i + 1; } } return 0; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"classes","dir":"Articles","previous_headings":"","what":"Other classes","title":"Get started with cpp11","text":"’ve already seen basic vector classes (integers, doubles, logicals, strings) scalar (int, double, bool, string) equivalents. cpp11 also provides wrappers base data types. important lists data frames, functions, attributes, described .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"lists-and-data-frames","dir":"Articles","previous_headings":"Other classes","what":"Lists and data frames","title":"Get started with cpp11","text":"cpp11 also provides list data_frame classes, useful output input. lists data frames can contain arbitrary classes C++ needs know classes advance. list known structure (e.g., ’s S3 object), can extract components manually convert C++ equivalents as_cpp(). example, object created lm(), function fits linear model, list whose components always type. following code illustrates might extract mean percentage error (mpe()) linear model. isn’t good example use C++, ’s easily implemented R, shows work important S3 class. Note use Rf_inherits() stop() check object really linear model.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double mpe(list mod) { if (!Rf_inherits(mod, \"lm\")) { stop(\"Input must be a linear model\"); } doubles resid(mod[\"residuals\"]); doubles fitted(mod[\"fitted.values\"]); int n = resid.size(); double err = 0; for(int i = 0; i < n; ++i) { err += resid[i] / (fitted[i] + resid[i]); } return err / n; } mod <- lm(mpg ~ wt, data = mtcars) mpe(mod) #> [1] -0.01541615"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"functions-cpp11","dir":"Articles","previous_headings":"Other classes","what":"Functions","title":"Get started with cpp11","text":"can put R functions object type function. makes calling R function C++ straightforward. challenge don’t know type output function return, use catchall type sexp. stands S-Expression used type R Objects internal C code. Calling R functions positional arguments obvious: need special syntax named arguments:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] sexp call_with_one(function f) { return f(1); } call_with_one(function(x) x + 1) #> [1] 2 call_with_one(paste) #> [1] \"1\" f(\"y\", 1); using namespace cpp11::literals; f(\"x\"_nm = \"y\", \"value\"_nm = 1);"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"attributes","dir":"Articles","previous_headings":"Other classes","what":"Attributes","title":"Get started with cpp11","text":"R objects attributes, can queried modified .attr(). cpp11 also provides .names() alias names attribute. following code snippet illustrates methods. Note use {} initializer list syntax. allows create R vector C++ scalar values:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] doubles attribs() { writable::doubles out = {1., 2., 3.}; out.names() = {\"a\", \"b\", \"c\"}; out.attr(\"my-attr\") = \"my-value\"; out.attr(\"class\") = \"my-class\"; return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"na","dir":"Articles","previous_headings":"","what":"Missing values","title":"Get started with cpp11","text":"’re working missing values, need know two things: R’s missing values behave C++’s scalars (e.g., double). get set missing values vectors (e.g., doubles).","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"scalars","dir":"Articles","previous_headings":"Missing values","what":"Scalars","title":"Get started with cpp11","text":"following code explores happens take one R’s missing values, coerce scalar, coerce back R vector. Note kind experimentation useful way figure operation . exception bool, things look pretty good : missing values preserved. However, ’ll see following sections, things quite straightforward seem.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] list scalar_missings() { int int_s = NA_INTEGER; r_string chr_s = NA_STRING; bool lgl_s = NA_LOGICAL; double num_s = NA_REAL; return writable::list({as_sexp(int_s), as_sexp(chr_s), as_sexp(lgl_s), as_sexp(num_s)}); } str(scalar_missings()) #> List of 4 #> $ : int NA #> $ : chr NA #> $ : logi TRUE #> $ : num NA"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"integers","dir":"Articles","previous_headings":"Missing values > Scalars","what":"Integers","title":"Get started with cpp11","text":"integers, missing values stored smallest integer. don’t anything , ’ll preserved. , since C++ doesn’t know smallest integer special behaviour, anything ’re likely get incorrect value: example, cpp_eval('NA_INTEGER + 1') gives -2147483647. want work missing values integers, either use length 1 integers careful code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"doubles","dir":"Articles","previous_headings":"Missing values > Scalars","what":"Doubles","title":"Get started with cpp11","text":"doubles, may able get away ignoring missing values working NaNs (number). R’s NA special type IEEE 754 floating point number NaN. logical expression involves NaN (C++, NAN) always evaluates FALSE: (’m using cpp_eval() allows see result running single C++ expression, making excellent sort interactive experimentation.) careful combining Boolean values: However, numeric contexts NaNs propagate NAs:","code":"cpp_eval(\"NAN == 1\") #> [1] FALSE cpp_eval(\"NAN < 1\") #> [1] FALSE cpp_eval(\"NAN > 1\") #> [1] FALSE cpp_eval(\"NAN == NAN\") #> [1] FALSE cpp_eval(\"NAN && TRUE\") #> [1] TRUE cpp_eval(\"NAN || FALSE\") #> [1] TRUE cpp_eval(\"NAN + 1\") #> [1] NaN cpp_eval(\"NAN - 1\") #> [1] NaN cpp_eval(\"NAN / 1\") #> [1] NaN cpp_eval(\"NAN * 1\") #> [1] NaN"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"strings","dir":"Articles","previous_headings":"Missing values","what":"Strings","title":"Get started with cpp11","text":"String scalar string class introduced cpp11, knows deal missing values.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"boolean","dir":"Articles","previous_headings":"Missing values","what":"Boolean","title":"Get started with cpp11","text":"C++’s bool two possible values (true false), logical vector R three (TRUE, FALSE, NA). coerce length 1 logical vector, make sure doesn’t contain missing values; otherwise converted TRUE. One way fix use int instead, can represent TRUE, FALSE, NA.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vectors-cpp11","dir":"Articles","previous_headings":"Missing values","what":"Vectors","title":"Get started with cpp11","text":"vectors, need use missing value specific type vector, NA_REAL, NA_INTEGER, NA_LOGICAL, NA_STRING:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] list missing_sampler() { return writable::list({ writable::doubles({NA_REAL}), writable::integers({NA_INTEGER}), writable::logicals({r_bool(NA_LOGICAL)}), writable::strings({NA_STRING}) }); } str(missing_sampler()) #> List of 4 #> $ : num NA #> $ : int NA #> $ : logi NA #> $ : chr NA"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises-1","dir":"Articles","previous_headings":"Missing values","what":"Exercises","title":"Get started with cpp11","text":"Rewrite functions first exercise deal missing values. na_rm true, ignore missing values. na_rm false, return missing value input contains missing values. good functions practice min(), max(), range(), mean(), var(). Rewrite cumsum() diff() can handle missing values. Note functions slightly complicated behaviour.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"stl","dir":"Articles","previous_headings":"","what":"Standard Template Library","title":"Get started with cpp11","text":"real strength C++ revealed need implement complex algorithms. standard template library (STL) provides set extremely useful data structures algorithms. section explain important algorithms data structures point right direction learn . can’t teach everything need know STL, hopefully examples show power STL, persuade ’s useful learn . need algorithm data structure isn’t implemented STL, one place look boost. Installing boost computer beyond scope vignette, installed, can use boost data structures algorithms including appropriate header file (e.g.) #include .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"using-iterators","dir":"Articles","previous_headings":"Standard Template Library","what":"Using iterators","title":"Get started with cpp11","text":"Iterators used extensively STL: many functions either accept return iterators. next step basic loops, abstracting away details underlying data structure. Iterators three main operators: Advance ++. Get value refer , dereference, *. Compare ==. example re-write sum function using iterators: main changes loop: start x.begin() loop get x.end(). small optimization store value end iterator don’t need look time. saves 2 ns per iteration, ’s important calculations loop simple. Instead indexing x, use dereference operator get current value: *. Notice use auto rather giving type iterator. code can simplified still use C++11 feature: range-based loops. Iterators also allow us use C++ equivalents apply family functions. example, rewrite sum() use accumulate() function, takes starting ending iterator, adds values vector. third argument accumulate gives initial value: ’s particularly important also determines data type accumulate uses (use 0.0 0 accumulate uses double, int.). use accumulate() need include header.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum2(doubles x) { double total = 0; for(auto it = x.begin(); it != x.end(); ++it) { total += *it; } return total; } #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum3(doubles xs) { double total = 0; for(auto x : xs) { total += x; } return total; } #include #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum4(doubles x) { return std::accumulate(x.begin(), x.end(), 0.0); }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"algorithms","dir":"Articles","previous_headings":"Standard Template Library","what":"Algorithms","title":"Get started with cpp11","text":" header provides large number algorithms work iterators. good reference available https://en.cppreference.com/w/cpp/algorithm. example, write basic cpp11 version findInterval() takes two arguments, vector values vector breaks, locates bin x falls . shows advanced iterator features. Read code see can figure works. key points : step two iterators (input output) simultaneously. can assign dereferenced iterator (out_it) change values . upper_bound() returns iterator. wanted value upper_bound() dereference ; figure location, use distance() function. doubt, generally better use algorithms STL hand rolled loops. Effective STL, Scott Meyers gives three reasons: efficiency, correctness, maintainability. Algorithms STL written C++ experts extremely efficient, around long time well tested. Using standard algorithms also makes intent code clear, helping make readable maintainable.","code":"#include #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] integers findInterval2(doubles x, doubles breaks) { writable::integers out(x.size()); auto out_it = out.begin(); for (auto&& val : x) { auto pos = std::upper_bound(breaks.begin(), breaks.end(), val); *out_it = std::distance(breaks.begin(), pos); ++out_it; } return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"data-structures-cpp11","dir":"Articles","previous_headings":"Standard Template Library","what":"Data structures","title":"Get started with cpp11","text":"STL provides large set data structures: array, bitset, list, forward_list, map, multimap, multiset, priority_queue, queue, deque, set, stack, unordered_map, unordered_set, unordered_multimap, unordered_multiset, vector. important data structures vector, unordered_set, unordered_map. ’ll focus three section, using others similar: just different performance trade-offs. example, deque (pronounced “deck”) similar interface vectors different underlying implementation different performance trade-offs. may want try problem. good reference STL data structures https://en.cppreference.com/w/cpp/container — recommend keep open working STL. cpp11 knows convert many STL data structures R equivalents, can return functions without explicitly converting R data structures.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vectors-stl","dir":"Articles","previous_headings":"Standard Template Library","what":"Vectors","title":"Get started with cpp11","text":"STL vector similar R vector, except grows efficiently. makes STL vectors appropriate use don’t know advance big output . Vectors templated, means need specify type object vector contain create : vector, vector, vector, vector. can access individual elements vector using standard [] notation, can add new element end vector using .push_back(). idea advance big vector , can use .reserve() allocate sufficient storage. following code implements run length encoding (rle()). produces two vectors output: vector values, vector lengths giving many times element repeated. works looping input vector x comparing value previous: ’s , increments last value lengths; ’s different, adds value end values, sets corresponding length 1. (alternative implementation replace iterator lengths.rbegin() always points last element vector. might want try implementing .) methods vector described https://en.cppreference.com/w/cpp/container/vector.","code":"#include \"cpp11.hpp\" #include using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] list rle_cpp(doubles x) { std::vector lengths; std::vector values; // Initialise first value int i = 0; double prev = x[0]; values.push_back(prev); lengths.push_back(1); for(auto it = x.begin() + 1; it != x.end(); ++it) { if (prev == *it) { lengths[i]++; } else { values.push_back(*it); lengths.push_back(1); i++; prev = *it; } } return writable::list({ \"lengths\"_nm = lengths, \"values\"_nm = values }); }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"sets","dir":"Articles","previous_headings":"Standard Template Library","what":"Sets","title":"Get started with cpp11","text":"Sets maintain unique set values, can efficiently tell ’ve seen value . useful problems involve duplicates unique values (like unique, duplicated, ). C++ provides ordered (std::set) unordered sets (std::unordered_set), depending whether order matters . Unordered sets can somtimes much faster (use hash table internally rather tree). Often even need ordered set, consider using unordered set sorting output. Benchmarking expected dataset best way determine fastest data. Like vectors, sets templated, need request appropriate type set purpose: unordered_set, unordered_set, etc. details available https://en.cppreference.com/w/cpp/container/set https://en.cppreference.com/w/cpp/container/unordered_set. following function uses unordered set implement equivalent duplicated() integer vectors. Note use seen.insert(x[]).second. insert() returns pair, .first value iterator points element .second value Boolean ’s true value new addition set.","code":"#include #include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] logicals duplicated_cpp(integers x) { std::unordered_set seen; int n = x.size(); writable::logicals out(n); for (int i = 0; i < n; ++i) { out[i] = !seen.insert(x[i]).second; } return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises-2","dir":"Articles","previous_headings":"Standard Template Library","what":"Exercises","title":"Get started with cpp11","text":"practice using STL algorithms data structures, implement following using R functions C++, using hints provided: median.default() using partial_sort. %% using unordered_set find() count() methods. unique() using unordered_set (challenge: one line!). min() using std::min(), max() using std::max(). .min() using min_element, .max() using max_element. setdiff(), union(), intersect() integers using sorted ranges set_union, set_intersection set_difference.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"case-studies","dir":"Articles","previous_headings":"","what":"Case studies","title":"Get started with cpp11","text":"following case studies illustrate real life uses C++ replace slow R code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"gibbs-sampler","dir":"Articles","previous_headings":"Case studies","what":"Gibbs sampler","title":"Get started with cpp11","text":"following case study updates example blogged Dirk Eddelbuettel, illustrating conversion Gibbs sampler R C++. R C++ code shown similar (took minutes convert R version C++ version), runs 30 times faster computer. Dirk’s blog post also shows another way make even faster: using faster random number generator functions GSL (easily accessible R RcppGSL package) can make another two three times faster. R code follows: relatively straightforward convert C++. : Add type declarations variables. Use ( instead [ index matrix. Include “Rmath.h” call functions Rf_. Benchmarking two implementations yields significant speedup running loops C++:","code":"gibbs_r <- function(N, thin) { mat <- matrix(nrow = N, ncol = 2) x <- y <- 0 for (i in 1:N) { for (j in 1:thin) { x <- rgamma(1, 3, y * y + 4) y <- rnorm(1, 1 / (x + 1), 1 / sqrt(2 * (x + 1))) } mat[i, ] <- c(x, y) } mat } #include \"cpp11/matrix.hpp\" #include \"cpp11/doubles.hpp\" #include \"Rmath.h\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] cpp11::doubles_matrix<> gibbs_cpp(int N, int thin) { writable::doubles_matrix<> mat(N, 2); double x = 0, y = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < thin; j++) { x = Rf_rgamma(3., 1. / double(y * y + 4)); y = Rf_rnorm(1. / (x + 1.), 1. / sqrt(2. * (x + 1.))); } mat(i, 0) = x; mat(i, 1) = y; } return mat; } bench::mark( r = { set.seed(42) gibbs_r(100, 10) }, cpp = { set.seed(42) gibbs_cpp(100, 10) }, check = TRUE, relative = TRUE ) #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 r 23.3 24.0 1 33.0 12.0 #> 2 cpp 1 1 24.3 1 1"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"r-vectorisation-versus-c-vectorisation","dir":"Articles","previous_headings":"Case studies","what":"R vectorisation versus C++ vectorisation","title":"Get started with cpp11","text":"example adapted “Rcpp smoking fast agent-based models data frames”. challenge predict model response three inputs. basic R version predictor looks like: want able apply function many inputs, might write vector-input version using loop. ’re familiar R, ’ll gut feeling slow, indeed . two ways attack problem. good R vocabulary, might immediately see vectorise function (using ifelse(), pmin(), pmax()). Alternatively, rewrite vacc1a() vacc1() C++, using knowledge loops function calls much lower overhead C++. Either approach fairly straightforward. R: (’ve worked R lot might recognise potential bottlenecks code: ifelse, pmin, pmax known slow, replaced p * 0.75 + p * 0.5 * female, p[p < 0] <- 0, p[p > 1] <- 1. might want try timing variations.) C++: next generate sample data, check three versions return values: original blog post forgot , introduced bug C++ version: used 0.004 instead 0.04. Finally, can benchmark three approaches: surprisingly, original approach loops slow. Vectorising R gives huge speedup, can eke even performance (ten times) C++ loop. little surprised C++ much faster, R version create 11 vectors store intermediate results, C++ code needs create 1.","code":"vacc1a <- function(age, female, ily) { p <- 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily p <- p * if (female) 1.25 else 0.75 p <- max(0, p) p <- min(1, p) p } vacc1 <- function(age, female, ily) { n <- length(age) out <- numeric(n) for (i in seq_len(n)) { out[i] <- vacc1a(age[i], female[i], ily[i]) } out } vacc2 <- function(age, female, ily) { p <- 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily p <- p * ifelse(female, 1.25, 0.75) p <- pmax(0, p) p <- pmin(1, p) p } #include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] double vacc3a(double age, bool female, bool ily){ double p = 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily; p = p * (female ? 1.25 : 0.75); p = std::max(p, 0.0); p = std::min(p, 1.0); return p; } [[cpp11::register]] doubles vacc3(doubles age, logicals female, logicals ily) { int n = age.size(); writable::doubles out(n); for(int i = 0; i < n; ++i) { out[i] = vacc3a(age[i], female[i], ily[i]); } return out; } n <- 1000 age <- rnorm(n, mean = 50, sd = 10) female <- sample(c(T, F), n, rep = TRUE) ily <- sample(c(T, F), n, prob = c(0.8, 0.2), rep = TRUE) stopifnot( all.equal(vacc1(age, female, ily), vacc2(age, female, ily)), all.equal(vacc1(age, female, ily), vacc3(age, female, ily)) ) bench::mark( vacc1 = vacc1(age, female, ily), vacc2 = vacc2(age, female, ily), vacc3 = vacc3(age, female, ily) ) #> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 vacc1 1.48ms 1.52ms 637. 7.86KB 34.6 #> 2 vacc2 44.44µs 50.02µs 19223. 148.56KB 36.4 #> 3 vacc3 11.86µs 12.24µs 80648. 14.02KB 8.07"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"package","dir":"Articles","previous_headings":"","what":"Using cpp11 in a package","title":"Get started with cpp11","text":"C++ code used cpp_source() can also bundled package. several benefits moving code stand-alone C++ source file package: code can made available users without C++ development tools. Multiple source files dependencies handled automatically R package build system. Packages provide additional infrastructure testing, documentation, consistency. add cpp11 existing package first put C++ files src/ directory package. easiest way configure everything call usethis::use_cpp11(). Alternatively: Add DESCRIPTION file: add following roxygen directive somewhere package’s R files. (common location R/pkgname-package.R) ’ll need run devtools::document() update NAMESPACE file include useDynLib statement. don’t use devtools::load_all(), ’ll also need run cpp11::cpp_register() building package. function scans C++ files [[cpp11::register]] attributes generates binding code required make functions available R. Re-run cpp11::cpp_register() whenever functions added, removed, signatures changed.","code":"LinkingTo: cpp11 #' @useDynLib pkgname, .registration = TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"more","dir":"Articles","previous_headings":"","what":"Learning more","title":"Get started with cpp11","text":"C++ large, complex language takes years master. like dive deeper write complex functions resources ’ve found helpful learning C++ : Effective C++ Effective STL C++ Annotations, aimed knowledgeable users C (language using C-like grammar, like Perl Java) like know , make transition , C++. Algorithm Libraries, provides technical, still concise, description important STL concepts. (Follow links notes.) Writing performant code may also require rethink basic approach: solid understanding basic data structures algorithms helpful . ’s beyond scope vignette, ’d suggest Algorithm Design Manual MIT’s Introduction Algorithms, Algorithms Robert Sedgewick Kevin Wayne free online textbook matching Coursera course.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"initial-setup-and-dev-workflow","dir":"Articles","previous_headings":"","what":"Initial setup and dev workflow","title":"cpp11 internals","text":"First install dependencies needed development. can load package interactive R session run cpp11 tests extensive tests cpp11test directory. Generally developing C++ headers run R working directory cpp11test directory use devtools::test() run cpp11tests. change cpp11 headers need install new version cpp11 clean recompile cpp11test package: calculate code coverage cpp11 package run following cpp11 root directory.","code":"install.packages(\"remotes\") remotes::install_deps(dependencies = TRUE) devtools::load_all() devtools::test() # Assuming your working directory is `cpp11test/` devtools::clean_dll() devtools::load_all() covr::report(cpp11_coverage())"},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"code-formatting","dir":"Articles","previous_headings":"","what":"Code formatting","title":"cpp11 internals","text":"project uses clang-format (version 10) automatically format c++ code. can run make format re-format code project. system clang-format version 10, can installed using homebrew tap command line brew install r-lib/taps/clang-format@10. may need link newly installed version 10. , run brew unlink clang-format followed brew link clang-format@10. Alternatively many IDEs support automatically running clang-format every time files written.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"code-organization","dir":"Articles","previous_headings":"","what":"Code organization","title":"cpp11 internals","text":"cpp11 header library, source code exposed users lives inst/include. R code used register functions cpp11::cpp_source() R/. Tests code R/ tests/testthat/. rest code separate cpp11test/ package included source tree. Inside cpp11test/src files start test- C++ tests using Catch support testthat. addition regular R tests cpp11test/tests/testthat/.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"naming-conventions","dir":"Articles","previous_headings":"","what":"Naming conventions","title":"cpp11 internals","text":"header files named .hpp extension. source files named .cpp extension. Public header files put inst/include/cpp11 Read r_vector classes free functions put cpp11 namespace. Writable r_vector class put cpp11::writable namespace. Private classes functions put cpp11::internal namespace.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"vector-classes","dir":"Articles","previous_headings":"","what":"Vector classes","title":"cpp11 internals","text":"basic r_vector classes class templates, base template defined cpp11/r_vector.hpp. template parameter type value particular R vector stores, e.g. double cpp11::doubles. differs Rcpp, whose first template parameter R vector type, e.g. REALSXP. file first class declarations, function definitions file. Specializations various types separate files, e.g. cpp11/doubles.hpp, cpp11/integers.hpp","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"coercion-functions","dir":"Articles","previous_headings":"","what":"Coercion functions","title":"cpp11 internals","text":"two different coercion functions as_sexp() takes C++ object coerces SEXP object, can used R. as_cpp<>() template function takes SEXP creates C++ object various methods functions defined cpp11/.hpp definitely complex part cpp11 code, extensive use template metaprogramming. particular substitution failure error (SFINAE) technique used control overloading functions. use C++20 lot code made simpler Concepts, alas. common C++ types included test suite work without issues, exotic types used real projects additional issues may arise. useful links SFINAE https://www.fluentcpp.com/2018/05/15/make-sfinae-pretty-1--value-sfinae-brings--code/, https://www.fluentcpp.com/2018/05/18/make-sfinae-pretty-2-hidden-beauty-sfinae/","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"protect-list","dir":"Articles","previous_headings":"Protection","what":"Protect list","title":"cpp11 internals","text":"cpp11 uses idea proposed Luke Tierney use double linked list head preserved protect objects cpp11 protecting. node list uses head (CAR) part point previous node, CDR part point next node. TAG used point object protected. head tail list R_NilValue CAR CDR pointers respectively. Calling cpp11::detail::store::insert() regular R object add new node list return protect token corresponding node added. Calling cpp11::detail::store::release() returned token release protection unlinking node linked list. two functions considered internal cpp11, use packages. scheme scales O(1) time release insert object vs O(N) worse time R_PreserveObject() / R_ReleaseObject(). package unique protection list, avoids need manage “global” protection list shared across packages. previous version cpp11 used global protection list stored R global option, caused multiple issues. functions defined protect.hpp.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"unwind-protect","dir":"Articles","previous_headings":"Protection","what":"Unwind Protect","title":"cpp11 internals","text":"cpp11 uses R_UnwindProtect() protect () calls R API fail. usually allocate memory, though truth R API functions error along paths. error happens R_UnwindProtect(), cpp11 throw C++ exception. exception caught try/catch block defined BEGIN_CPP11 macro cpp11/declarations.hpp. exception cause C++ destructors run, freeing resources held C++ objects. try/catch block exits, R error unwinding continued R_ContinueUnwind() normal R error results. require R >=3.5 use cpp11, created wanted support back R 3.3, R_ContinueUnwind() wasn’t available R 3.5. options considered support older R versions: Using R_TopLevelExec() works avoid C long jump, code always run top level context errors messages thrown caught tryCatch() similar techniques. Using R_TryCatch() available prior R 3.4, also serious bug R 3.4 (fixed R 3.5). Calling R level tryCatch() function contains expression runs C function runs C++ code option, implementing convoluted impact performance, perhaps severely. cpp11::unwind_protect() -op versions. means resources held C++ objects leak, including cpp11::r_vector / cpp11::sexp objects. None options perfect, pros cons . Causes behavior changes test failures, ruled . also ruled since wanted support back R 3.3. ruled partially implementation somewhat tricky performance suffer greatly. ended requiring R 3.5. leaked protected objects R API errors.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"motivations","dir":"Articles","previous_headings":"","what":"Motivations","title":"Motivations for cpp11","text":"R S long history interacting compiled languages. fact original version S written late 1970s mainly wrapper around FORTRAN routines (History--S). Released 2000, cxx package early prototype C++ bindings R. Rcpp first published CRAN 2008, Rcpp11 2014. Rcpp far widest adoption, 2000 reverse dependencies 2020. Rcpp widely successful project, however years number issues additional C++ features arisen. Adding features Rcpp require great deal work, cases impossible without severely breaking backwards compatibility. cpp11 ground rewrite C++ bindings R different design trade-offs features. Changes motivated cpp11 include: Enforcing copy--write semantics. Improving safety using R API C++ code. Supporting ALTREP objects. Using UTF-8 strings everywhere. Applying newer C++11 features. straightforward, simpler implementation. Faster compilation time lower memory requirements. completely header avoid ABI issues. Capable vendoring desired. robust protection using much efficient linked list data structure. Growing vectors efficiently.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"copy-on-write-semantics","dir":"Articles","previous_headings":"Motivations","what":"Copy-on-write semantics","title":"Motivations for cpp11","text":"R uses copy--write (also called copy--modify) semantics. Lets say two variables x y point underlying data. modify y, R first copy values x new position, point y new location copy modify y. allows x retain original values. C++ copy--write built language, however related concepts, copy--value copy--reference. Copy--value works similarly R, except R copies something changed, C++ always copies. Copy--reference opposite, x y always point underlying value. C++ specify reference &. Copy--reference valuable technique, avoids overhead copying data. However can also lead errors internal functions change inputs unexpectedly. Rcpp uses copy--reference default (even pass Rcpp vector class value). gives Rcpp functions completely different semantics normal R functions. can illustrate creating Rcpp function multiples input vector 2. regular R functions, see value y x * 2, value x unchanged. However now call times_two_rcpp() function get right output value, now x also changed. cpp11 strives make functions behave similarly normal R functions, preserving speed Rcpp read access needed. r_vector classes cpp11 normal read version uses copy--reference, writable version uses copy--value. Using cpp11::writable::doubles first copies input vector, multiplication modify original data.","code":"x <- c(1, 2, 3) y <- x y[[3]] <- 4 y #> [1] 1 2 4 x #> [1] 1 2 3 int x = 42; int y = x; y = 0; // x is still == 42 int x = 42; int &y = x; y = 0; // both x and y are now 0 #include \"Rcpp.h\" using namespace Rcpp; // [[Rcpp::export]] NumericVector times_two_rcpp(NumericVector x) { for (int i = 0; i < x.size(); ++i) { x[i] = x[i] * 2; } return x; } x <- c(1, 2, 3) y <- x * 2 y #> [1] 2 4 6 x #> [1] 1 2 3 z <- times_two_rcpp(x) z #> [1] 2 4 6 x #> [1] 2 4 6 #include \"cpp11/doubles.hpp\" [[cpp11::register]] cpp11::doubles times_two_cpp11(cpp11::writable::doubles x) { for (int i = 0; i < x.size(); ++i) { x[i] = x[i] * 2; } return x; } x <- c(1, 2, 3) z <- times_two_cpp11(x) z #> [1] 2 4 6 x #> [1] 1 2 3"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"improve-safety","dir":"Articles","previous_headings":"Motivations","what":"Improve safety","title":"Motivations for cpp11","text":"Internally R written C, C++. general C C++ work well together, large part C++’s success due high interoperability C code. However one area C C++ generally interoperable error handling. C++ common way handle errors exceptions. Exceptions provide clean, safe way objects obtain cleanup resources automatically even errors occur.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c-safety","dir":"Articles","previous_headings":"Motivations > Improve safety","what":"C safety","title":"Motivations for cpp11","text":"C language support exceptions, error handling done variety ways. include error codes like errno, conditional statements, R codebase longjmp function. longjmp, stands ‘long jump’ function allows transfer control flow program another location elsewhere program. R uses long jumps extensively error handling routines. R function executing error occurs, long jump called ‘jumps’ control flow error handling code. Crucially long jumps incompatible C++ destructors. long jump occurs destructors active C++ objects run, therefore resources (memory, file handles, etc.) managed objects cause resource leak. example, following unsafe code leak memory allocated C++ std::vector x R API function Rf_allocVector() fails (since can’t create vector -1 size). cpp11 provides two mechanisms make interfacing Rs C API C++ code safer. cpp11::unwind_protect() takes functional object (C++11 lamdba function std::function) converts C long jumps encountered C++ exceptions. Now instead C long jump happening Rf_allocVector() call fails, C++ exception occurs, trigger std::vector destructor, memory automatically released. cpp11::safe() concise way wrap particular R API function unwind_protect(). using cpp11::safe() converts C long jump C++ exception, memory automatically released. cpp11 uses mechanisms extensively internally calling R C API, make cpp11 much safer resource leaks using Rcpp calling Rs C API hand.","code":"std::vector x({1., 2., 3.}); SEXP y = PROTECT(Rf_allocVector(REALSXP, -1)); std::vector x({1., 2., 3.}); SEXP y; unwind_protect([]() { y = Rf_allocVector(REALSXP, -1); }) std::vector x({1., 2., 3.}); SEXP y = PROTECT(safe[Rf_allocVector](REALSXP, -1));"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c-safety-1","dir":"Articles","previous_headings":"Motivations > Improve safety","what":"C++ safety","title":"Motivations for cpp11","text":"inverse C safety also need ensure C++ exceptions reach C call stack, terminate R occurs. Like Rcpp, cpp11 automatically generates try / catch guards around registered functions prevent also converts C++ exceptions normal R errors. done without developer facing code changes. C C++ sides coin covered can safely use R’s C API C++ code together C++ objects without leaking resources.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"altrep-support","dir":"Articles","previous_headings":"Motivations","what":"Altrep support","title":"Motivations for cpp11","text":"ALTREP stands ALTernative REPresntations feature introduced R 3.5. ALTREP allows R internals package authors define alternative ways representing data R. One example use altrep : operator. Prior R 3.5 : generated full vector entire sequence. e.g. 1:1000 require 1000 individual values. R 3.5 sequence instead represented ALTREP vector, none values actually exist memory. Instead time R access particular value sequence value computed --fly. saves memory excution time, allows users use sequences otherwise big fit memory. Rcpp predates introduction ALTREP, support interfaces needed access ALTREP objects. means objects must converted normal R objects soon used Rcpp. Whereas cpp11 objects preserve ALTREP object.","code":"1:1e9 #> [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #> [ reached getOption(\"max.print\") -- omitted 999999980 entries ] #include \"Rcpp.h\" // [[Rcpp::export]] Rcpp::IntegerVector identity_rcpp(Rcpp::IntegerVector x) { return x; } x <- identity_rcpp(1:100000) lobstr::obj_size(x) #> 400.73 kB #include \"cpp11/integers.hpp\" [[cpp11::register]] cpp11::integers identity_cpp11(cpp11::integers x) { return x; } y <- identity_cpp11(1:100000) lobstr::obj_size(y) #> 680 B"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"altrep-benchmarks","dir":"Articles","previous_headings":"Motivations > Altrep support","what":"Altrep benchmarks","title":"Motivations for cpp11","text":"benchmarks note Rcpp allocates memory ALTREP vectors. Rcpp implicitly converts normal R vectors. cpp11 retains ALTREP vectors, additional memory needed. foreach accumulate use iterators take advantage REAL_GET_REGION buffer queries. makes faster naive C-style loops ALTREP vectors. for2 case shows optimization can use know compile-time won’t dealing ALTREP vectors. specifying false second argument (is_altrep), can disable ALTREP support. causes ALTREP conditional code compiled resulting loop unrolling (speeds) identical generated Rcpp. cpp11test/src/sum.cpp contains code ran benchmarks.","code":"library(cpp11test) cases <- expand.grid( len = 3e6, vector = c(\"normal\", \"altrep\"), method = c(\"for\", \"foreach\", \"accumulate\"), pkg = c(\"cpp11\", \"rcpp\"), stringsAsFactors = FALSE ) # Add special case cases <- rbind(list(len = 3e6, vector = \"normal\", method = \"for2\", pkg = \"cpp11\"), cases) b_sum <- bench::press( .grid = cases, { seq_real <- function(x) as.numeric(seq_len(x)) funs <- c(\"normal\" = rnorm, \"altrep\" = seq_real) x <- funs[[vector]](len) fun <- match.fun(sprintf(\"%ssum_dbl_%s_\", ifelse(pkg == \"cpp11\", \"\", paste0(pkg, \"_\")), method)) bench::mark( fun(x) ) } )[c(\"pkg\", \"method\", \"vector\", \"min\", \"median\", \"mem_alloc\", \"itr/sec\", \"n_gc\")] saveRDS(b_sum, \"sum.Rds\", version = 2) knitr::kable(readRDS(\"sum.Rds\"))"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"utf-8-everywhere","dir":"Articles","previous_headings":"Motivations","what":"UTF-8 everywhere","title":"Motivations for cpp11","text":"R complicated support Unicode strings non-ASCII code pages, whose behavior often differs substantially different operating systems, particularly Windows. Correctly dealing challenging often feels like whack mole. combat complexity cpp11 uses UTF-8 everywhere philosophy. means whenever text data converted R data structures C++ data structures cpp11 data translated UTF-8. Conversely text data coming C++ code assumed UTF-8 marked R. universally avoids many locale specific issues dealing Unicode text. Concretely cpp11 always uses Rf_translateCharUTF8() obtaining const char* CHRSXP objects uses Rf_mkCharCE(, CE_UTF8) creating new CHRSXP objects const char* inputs.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c11-features","dir":"Articles","previous_headings":"Motivations","what":"C++11 features","title":"Motivations for cpp11","text":"C++11 provides host new features C++ language. cpp11 uses number including move semantics type traits initializer_list variadic templates / parameter packs user defined literals user defined attributes","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"simpler-implementation","dir":"Articles","previous_headings":"Motivations","what":"Simpler implementation","title":"Motivations for cpp11","text":"Rcpp ambitious, number advanced features, including modules, sugar extensive support attributes. useful features, many R packages use one advanced features. addition code needed support features complex can challenging maintain. cpp11 takes limited scope, providing set r_vector wrappers R vector types, coercion methods C++ limited attributes necessary support use R packages. limited scope allows implementation much simpler, headers Rcpp 1.0.4 74,658 lines code (excluding blank commented lines) 379 files. headers Rcpp automatically generated, removing still gives 25,249 lines code 357 files. contrast headers cpp11 contain 1,734 lines code 19 files. reduction complexity make cpp11 easier project maintain ensure correctness, particularly around interactions R garbage collector.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"compilation-speed","dir":"Articles","previous_headings":"Motivations","what":"Compilation speed","title":"Motivations for cpp11","text":"Rcpp always bundles headers together, causes slow compilation times high peak memory usage compiling. headers cpp11 easily decoupled, can include particular headers actually use source file. can significantly improve compilation speed memory usage compile package. real examples reduction compile time peak memory usage converting packages cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"header-only","dir":"Articles","previous_headings":"Motivations","what":"Header only","title":"Motivations for cpp11","text":"Rcpp long mostly header library, however completely header library. cases package first installed version X Rcpp, newer version Rcpp later installed. original package X loaded R crash, Application Binary Interface Rcpp changed two versions. cpp11 consists exclusively headers issue occur.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"vendoring","dir":"Articles","previous_headings":"Motivations","what":"Vendoring","title":"Motivations for cpp11","text":"go community concept vendoring widespread. Vendoring means copy code dependencies project’s source tree. ensures dependency code fixed stable updated. cpp11 fully header can vendor code way. cpp11::vendor_cpp11() provided choose. Vendoring advantages drawbacks however. advantage changes cpp11 project never break existing code. drawbacks minor, package size now slightly larger, major, longer get bugfixes new features explicitly update cpp11. think majority packages use LinkingTo: cpp11 vendor cpp11 dependency. However, vendoring can appropriate certain situations.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"protection","dir":"Articles","previous_headings":"Motivations","what":"Protection","title":"Motivations for cpp11","text":"cpp11 uses custom double linked list data structure track objects managing. structure much efficient large numbers objects using R_PreserveObject() / R_ReleaseObjects() done Rcpp. plot shows average time protect release given object essentially constant cpp11. Whereas linear worse number objects tracked Rcpp.","code":"library(cpp11test) grid <- expand.grid(len = c(10 ^ (2:5), 2e5), pkg = c(\"cpp11\", \"rcpp\"), stringsAsFactors = FALSE) b_release <- bench::press(.grid = grid, { fun = match.fun(sprintf(\"%s_release_\", pkg)) bench::mark( fun(len), iterations = 1 ) } )[c(\"len\", \"pkg\", \"min\")] saveRDS(b_release, \"release.Rds\", version = 2)"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"growing-vectors","dir":"Articles","previous_headings":"Motivations","what":"Growing vectors","title":"Motivations for cpp11","text":"One major difference Rcpp cpp11 vectors grown. Rcpp vectors push_back() method, unlike std::vector() additional space reserved pushing. makes calling push_back() repeatably expensive, entire vector copied call. contrast cpp11 vectors grow efficiently, reserving extra space. can ~10,000,000 vector appends cpp11 approximately amount time Rcpp 10,000, benchmark demonstrates.","code":"grid <- expand.grid(len = 10 ^ (0:7), pkg = \"cpp11\", stringsAsFactors = FALSE) grid <- rbind( grid, expand.grid(len = 10 ^ (0:4), pkg = \"rcpp\", stringsAsFactors = FALSE) ) b_grow <- bench::press(.grid = grid, { fun = match.fun(sprintf(\"%sgrow_\", ifelse(pkg == \"cpp11\", \"\", paste0(pkg, \"_\")))) bench::mark( fun(len), min_iterations = 100 ) } )[c(\"len\", \"pkg\", \"min\", \"mem_alloc\", \"n_itr\", \"n_gc\")] saveRDS(b_grow, \"growth.Rds\", version = 2)"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"conclusion","dir":"Articles","previous_headings":"Motivations","what":"Conclusion","title":"Motivations for cpp11","text":"Rcpp continue widely successful. cpp11 alternative implementation C++ bindings R chooses different design trade-offs features. packages can co-exist (even used package!) continue enrich R community.","code":""},{"path":"https://cpp11.r-lib.org/dev/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Davis Vaughan. Author, maintainer. Jim Hester. Author. Romain François. Author. Benjamin Kietzman. Contributor. . Copyright holder, funder.","code":""},{"path":"https://cpp11.r-lib.org/dev/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Vaughan D, Hester J, François R (2024). cpp11: C++11 Interface R's C Interface. R package version 0.4.7.9000, https://github.com/r-lib/cpp11, https://cpp11.r-lib.org.","code":"@Manual{, title = {cpp11: A C++11 Interface for R's C Interface}, author = {Davis Vaughan and Jim Hester and Romain François}, year = {2024}, note = {R package version 0.4.7.9000, https://github.com/r-lib/cpp11}, url = {https://cpp11.r-lib.org}, }"},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"cpp11","dir":"","previous_headings":"","what":"A C++11 Interface for R's C Interface","title":"A C++11 Interface for R's C Interface","text":"cpp11 helps interact R objects using C++ code. goals syntax similar excellent Rcpp package.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"using-cpp11-in-a-package","dir":"","previous_headings":"","what":"Using cpp11 in a package","title":"A C++11 Interface for R's C Interface","text":"add cpp11 existing package, put C++ files src/ directory add following DESCRIPTION file: decorate C++ functions want expose R [[cpp11::register]]. Note C++11 attribute, comment like used Rcpp. cpp11 header library hard dependencies use shared library, straightforward reliable use packages without fear compile-time run-time mismatches. Alternatively, can vendor current installed version cpp11 headers package cpp11::vendor_cpp11(). ensures headers remain unchanged explicitly update .","code":"LinkingTo: cpp11"},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"getting-started","dir":"","previous_headings":"","what":"Getting started","title":"A C++11 Interface for R's C Interface","text":"See vignette(“cpp11”) get started using cpp11 scripts, particularly new C++ programming.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"getting-help","dir":"","previous_headings":"","what":"Getting help","title":"A C++11 Interface for R's C Interface","text":"Posit Community best place ask help using cpp11 interfacing C++ R.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"motivations","dir":"","previous_headings":"","what":"Motivations","title":"A C++11 Interface for R's C Interface","text":"Rcpp widely successful project, however years number issues additional C++ features arisen. Adding features Rcpp require great deal work, cases impossible without severely breaking backwards compatibility. cpp11 ground rewrite C++ bindings R different design trade-offs features. Changes motivated cpp11 include: Enforcing copy--write semantics. Improving safety using R API C++ code. Supporting ALTREP objects. Using UTF-8 strings everywhere. Applying newer C++11 features. straightforward, simpler implementation. Faster compilation time lower memory requirements. completely header avoid ABI issues. Capable vendoring desired. robust protection using much efficient linked list data structure. Growing vectors efficiently. See vignette(“motivations”) full details motivations writing cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"conversion-from-rcpp","dir":"","previous_headings":"","what":"Conversion from Rcpp","title":"A C++11 Interface for R's C Interface","text":"See vignette(“converting”) already familiar Rcpp existing package uses Rcpp want convert use cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"learning-more","dir":"","previous_headings":"","what":"Learning More","title":"A C++11 Interface for R's C Interface","text":"Welding R C++ - Presentation SatRday Columbus (slides)","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"internals","dir":"","previous_headings":"","what":"Internals","title":"A C++11 Interface for R's C Interface","text":"See vignette(“internals”) details cpp11 implementation like contribute cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"A C++11 Interface for R's C Interface","text":"Please note cpp11 project released Contributor Code Conduct. contributing project, agree abide terms.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"thanks","dir":"","previous_headings":"","what":"Thanks","title":"A C++11 Interface for R's C Interface","text":"cpp11 exist without Rcpp. Thanks Rcpp authors, Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Douglas Bates John Chambers work writing maintaining Rcpp.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp11-package.html","id":null,"dir":"Reference","previous_headings":"","what":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","title":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","text":"Provides header , C++11 interface R's C interface. Compared approaches 'cpp11' strives safe long jumps C API well C++ exceptions, conform normal R function semantics supports interaction 'ALTREP' vectors.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/reference/cpp11-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","text":"Maintainer: Davis Vaughan davis@posit.co (ORCID) Authors: Jim Hester (ORCID) Romain François (ORCID) contributors: Benjamin Kietzman [contributor] Posit Software, PBC [copyright holder, funder]","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":null,"dir":"Reference","previous_headings":"","what":"Generates wrappers for registered C++ functions — cpp_register","title":"Generates wrappers for registered C++ functions — cpp_register","text":"Functions decorated [[cpp11::register]] files ending .cc, .cpp, .h .hpp wrapped generated code registered called R.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generates wrappers for registered C++ functions — cpp_register","text":"","code":"cpp_register( path = \".\", quiet = !is_interactive(), extension = c(\".cpp\", \".cc\") )"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generates wrappers for registered C++ functions — cpp_register","text":"path path package root directory quiet TRUE suppresses output function extension file extension use generated src/cpp11 file. .cpp default, .cc also supported.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generates wrappers for registered C++ functions — cpp_register","text":"paths generated R C++ source files (order).","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Generates wrappers for registered C++ functions — cpp_register","text":"Note registered functions exported package unless also add @export roxygen2 directive . order use cpp_register() cli, decor, desc, glue, tibble vctrs packages must also installed.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Generates wrappers for registered C++ functions — cpp_register","text":"","code":"# create a minimal package dir <- tempfile() dir.create(dir) writeLines(\"Package: testPkg\", file.path(dir, \"DESCRIPTION\")) writeLines(\"useDynLib(testPkg, .registration = TRUE)\", file.path(dir, \"NAMESPACE\")) # create a C++ file with a decorated function dir.create(file.path(dir, \"src\")) writeLines(\"[[cpp11::register]] int one() { return 1; }\", file.path(dir, \"src\", \"one.cpp\")) # register the functions in the package cpp_register(dir) # Files generated by registration file.exists(file.path(dir, \"R\", \"cpp11.R\")) #> [1] TRUE file.exists(file.path(dir, \"src\", \"cpp11.cpp\")) #> [1] TRUE # cleanup unlink(dir, recursive = TRUE)"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile C++ code — cpp_source","title":"Compile C++ code — cpp_source","text":"cpp_source() compiles loads single C++ file use R. cpp_function() compiles loads single function use R. cpp_eval() evaluates single C++ expression returns result.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile C++ code — cpp_source","text":"","code":"cpp_source( file, code = NULL, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\"), dir = tempfile() ) cpp_function( code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\") ) cpp_eval( code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\") )"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile C++ code — cpp_source","text":"file file containing C++ code compile code non-null, C++ code compile env R environment R wrapping functions defined. clean TRUE, cleanup files sourcing quiet 'TRUE`, show compiler output cxx_std C++ standard use, CXX_STD make macro set value. default value queries CXX_STD environment variable, uses 'CXX11' unset. dir directory store generated source files. tempfile() used default. directory removed clean TRUE.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile C++ code — cpp_source","text":"cpp_source() [cpp_function()] results dyn.load() (invisibly). [cpp_eval()] results evaluated expression.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compile C++ code — cpp_source","text":"Within C++ code can use [[cpp11::linking_to(\"pkgxyz\")]] link external packages. equivalent putting packages LinkingTo field package DESCRIPTION.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compile C++ code — cpp_source","text":"","code":"cpp_source( code = '#include \"cpp11/integers.hpp\" [[cpp11::register]] int num_odd(cpp11::integers x) { int total = 0; for (int val : x) { if ((val % 2) == 1) { ++total; } } return total; } ') num_odd(as.integer(c(1:10, 15, 23))) #> [1] 7 if (interactive() && require(\"progress\")) { cpp_source( code = ' #include #include [[cpp11::linking_to(\"progress\")]] [[cpp11::register]] void show_progress() { RProgress::RProgress pb(\"Processing [:bar] ETA: :eta\"); pb.tick(0); for (int i = 0; i < 100; i++) { usleep(2.0 / 100 * 1000000); pb.tick(); } } ') show_progress() }"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":null,"dir":"Reference","previous_headings":"","what":"Vendor the cpp11 dependency — cpp_vendor","title":"Vendor the cpp11 dependency — cpp_vendor","text":"Vendoring act making copy 3rd party packages project using. often used go language community.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Vendor the cpp11 dependency — cpp_vendor","text":"","code":"cpp_vendor(path = \".\")"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Vendor the cpp11 dependency — cpp_vendor","text":"path path package root directory","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Vendor the cpp11 dependency — cpp_vendor","text":"file path vendored code (invisibly).","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Vendor the cpp11 dependency — cpp_vendor","text":"function vendors cpp11 package copying cpp11 headers inst/include folder package adding 'cpp11 version: XYZ' top files, XYZ version cpp11 currently installed machine. choose vendor headers remove LinkingTo: cpp11 DESCRIPTION. Note: vendoring places responsibility updating code . Bugfixes new features cpp11 available code run cpp_vendor() .","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Vendor the cpp11 dependency — cpp_vendor","text":"","code":"# create a new directory dir <- tempfile() dir.create(dir) # vendor the cpp11 headers into the directory cpp_vendor(dir) list.files(file.path(dir, \"inst\", \"include\", \"cpp11\")) #> [1] \"R.hpp\" \"altrep.hpp\" \"as.hpp\" #> [4] \"attribute_proxy.hpp\" \"data_frame.hpp\" \"declarations.hpp\" #> [7] \"doubles.hpp\" \"environment.hpp\" \"external_pointer.hpp\" #> [10] \"function.hpp\" \"integers.hpp\" \"list.hpp\" #> [13] \"list_of.hpp\" \"logicals.hpp\" \"matrix.hpp\" #> [16] \"named_arg.hpp\" \"protect.hpp\" \"r_bool.hpp\" #> [19] \"r_string.hpp\" \"r_vector.hpp\" \"raws.hpp\" #> [22] \"sexp.hpp\" \"strings.hpp\" # cleanup unlink(dir, recursive = TRUE)"},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-development-version","dir":"Changelog","previous_headings":"","what":"cpp11 (development version)","title":"cpp11 (development version)","text":"cpp11::writable::r_vector::proxy now implements copy assignment. Practically means x[] = y[] now works x y writable vectors (#300, #339). Implicit conversion sexp bool, size_t, double marked deprecated removed next version cpp11. 3 packages using notified sent PRs. recommended approach instead use cpp11::as_cpp, performs type length checking, making much safer use. New writable::data_frame constructor also takes number rows input. accounts edge case input list 0 columns ’d still like specify known number rows (#272). cpp11::writable::r_vector::iterator longer implicitly deletes copy assignment operator (#360). std::max_element() can now used writable vectors (#334). environment class longer uses non-API function Rf_findVarInFrame3() (#367). exists() method now uses new R_existsVarInFrame() function. SEXP conversion operator now uses new R_getVar() function. Note stricter Rf_findVarInFrame3() 3 ways. object must exist environment (.e. R_UnboundValue longer returned), object R_MissingArg, object promise, promise now evaluated. backported new strictness older versions R well. Fixed issue writable::matrix copy constructor underlying SEXP copied . now consistent behavior equivalent writable::r_vector copy constructor. Added missing implementation x.(\"name\") read vectors (#370). Constructors writable vectors initializer_list now check named_arg contains length 1 object correct type, throws either cpp11::type_error std::length_error case (#382). Repeated assignment cpp11::writable::strings vector either x[] = elt x.push_back(elt) now performant, tradeoff slightly less safety (long elt actually CHARSXP within bounds, chance failure, kind invariants placed vector types) (#378). Read r_vectors now move constructor move assignment operator (#365). Fixed issue writable vectors protected twice (#365). Removed usage following non-API functions: SETLENGTH() SET_TRUELENGTH() SET_GROWABLE_BIT() functions used part efficient growable vectors cpp11 offered, .e. happens hood use push_back(). removal non-API functions means cpp11 writable vectors pushed push_back() likely force 1 extra allocation conversion cpp11::writable::r_vector SEXP occurs (typically return result back R). affect performance push_back() , general growable vectors still quite efficient (#362). Fixed memory leak cpp11::writable::r_vector move assignment operator (#338). approach protection list managed cpp11 tweaked slightly. 0.4.6, changed approach creates one protection list per compilation unit, now believe ’ve found approach guaranteed C++ standard create one protection list per package, makes slightly sense still benefits reduced maintanence burden mentioned 0.4.6 news bullet (#364). side effect new approach preserved object exposed protect.hpp longer exists. don’t believe anyone using . also means longer see “unused variable” warnings preserved (#249). Dropped support gcc 4.8, mainly issue extremely old CentOS 7 systems used default compiler. June 2024, CentOS 7 past Vendor end support date therefore also scope Posit time (#359).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-047","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.7","title":"cpp11 0.4.7","text":"CRAN release: 2023-12-02 Internal changes requested CRAN fix invalid format string tokens (@paleolimbot, #345).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-046","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.6","title":"cpp11 0.4.6","text":"CRAN release: 2023-08-10 R >=3.5.0 now required use cpp11. line (even goes beyond) tidyverse standard supporting previous 5 minor releases R. also ensures R_UnwindProtect() available avoid C++ memory leaks (#332). cpp11::preserved.release_all() removed. intended support expert developers R <3.5.0 cpp11 used global protection list. Since cpp11 longer uses global protection list requires R >=3.5.0, longer needed. far can tell, package actively using (#332). cpp11 now creates one protection list per compilation unit, rather one global protection list shared across compilation units across packages. greatly reduces complexity managing protection list state make easier make changes protection list structure future without breaking packages compiled older versions cpp11 (#330). Nested calls cpp11::unwind_protect() longer supported encouraged. Previously, something done performance improvements, ultimately feature proven cause problems worth hard use safely. information, see new vignette(\"FAQ\") section titled “call cpp11::unwind_protect() manually?” (#327). features bug fixes cpp11 0.4.4 added back .","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-045","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.5","title":"cpp11 0.4.5","text":"CRAN release: 2023-07-20 2023-07-20, cpp11 temporarily rolled back 0.4.3 manually CRAN due bug 0.4.4 immediately fix due cpp11 maintainer vacation.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-044","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.4","title":"cpp11 0.4.4","text":"CRAN release: 2023-06-30 Davis Vaughan now maintainer. as_doubles() as_integers() now propagate missing values correctly (#265, #319). Fixed performance issue related nested unwind_protect() calls (#298). Minor performance improvements cpp11 protect code. (@kevinushey) cpp_register() gains argument extension= governing file extension src/cpp11 file. default ’s .cpp, .cc now supported well (#292, @MichaelChirico)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-043","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.3","title":"cpp11 0.4.3","text":"CRAN release: 2022-10-12 Modernized GitHub Actions workflows updated internal tests better align changes workflows latest version R (#279). cpp_source() errors non-existent file (#261). cpp_register() quiet default R non interactive (#289). updated test adapt changes R 4.2.1 (#290).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-042","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.2","title":"cpp11 0.4.2","text":"CRAN release: 2021-11-30 Romain François now maintainer.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-041","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.1","title":"cpp11 0.4.1","text":"CRAN release: 2021-11-03 Fix crash related unwind protect optimization (#244)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-040","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.0","title":"cpp11 0.4.0","text":"CRAN release: 2021-09-22","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-features-0-4-0","dir":"Changelog","previous_headings":"","what":"New Features","title":"cpp11 0.4.0","text":"New opt-message formatting {fmt} C++ library cpp11::messages() cpp11::stop() cpp11::warning(). Set CPP11_USE_FMT macro use feature package. (@sbearrows, #169, #208) New as_double() as_integer() methods coerce integers doubles doubles integers doubles (@sbearrows, #46) cpp11::matrix iterators can now used either row-wise column-wise (default) depending user’s choice (@alyst, #229)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"improvements-and-fixes-0-4-0","dir":"Changelog","previous_headings":"","what":"Improvements and fixes","title":"cpp11 0.4.0","text":"Read-matrix accessors now marked const (#234) writable::r_vector default constructors now return 0 length vector converted SEXP (#166) Read-r_vector constructors now disallow implicit construction named arguments (#237) Read-r_vector.attr() methods now return const objects, compile time error try assign (#237) Fixed + += operators r_vector::[const_]iterator conform iterators concept: += updates iterator, + returns updated copy, keeping original unchanged (@alyst, #231) Remove undefined behavior constructing global cpp11::sexps (#224) Removed redundant .Call calls cpp11.cpp file (@sbearrows, #170) Error messages now output original file name rather temporary file name (@sbearrows, #194) cpp_register() now includes attribute_visible init function, packages compiled C_VISIBILITY find init function. Fixed bug running cpp_source() file (@sbearrows, #202) Allow cpp11 decorators form cpp11::linking_to (@sbearrows, #193) Removed internal instances cpp11::stop() replaced C++ exceptions (@sbearrows, #203) Names named lists now resized along list elements (@sbearrows, #206)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-031","dir":"Changelog","previous_headings":"","what":"cpp11 0.3.1","title":"cpp11 0.3.1","text":"CRAN release: 2021-06-25 Fix stringop-truncation warning generated wrapping code.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-functions-and-features-0-3-0","dir":"Changelog","previous_headings":"","what":"New functions and features","title":"cpp11 0.3.0","text":"New x.empty() method check vector empty (@sbearrows, #182) New x.named() method check vector named (@sbearrows, #186) New na() free function return NA sentinels R objects (@sbearrows, #179)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"major-fixes-0-3-0","dir":"Changelog","previous_headings":"","what":"Major fixes","title":"cpp11 0.3.0","text":"Memory longer inadvertently leaks move constructing vectors (#173)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"minor-improvements-and-fixes-0-3-0","dir":"Changelog","previous_headings":"","what":"Minor improvements and fixes","title":"cpp11 0.3.0","text":"Incorrectly formatted cpp11 decorators now output informative error message (@sbearrows, #127) Generated registration code now uses C collation avoid spurious changes tools::package_native_routine_registration_skeleton() (@sbearrows, #171) Makevars files include filenames now handle spaces paths properly (@klmr, #160)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-027","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.7","title":"cpp11 0.2.7","text":"CRAN release: 2021-03-29 Fix transient memory leak functions return values cpp11::unwind_protect() cpp11::safe (#154) cpp_source() now gets argument dir allow customized temporary directory store generated source files. makes easier debug C++ source files non-package project via source mapping. (@renkun-ken, #156)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-026","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.6","title":"cpp11 0.2.6","text":"CRAN release: 2021-01-29 cpp_register() now uses symbols exclusively .Call() interface. allows robust interactive use pkgload package.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-025","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.5","title":"cpp11 0.2.5","text":"CRAN release: 2021-01-12 cpp_source() gains cxx_std argument control C++ standard used. allows use code C++14 later standards cpp_source(). (#100) cpp11 knitr engine now allows set cxx_std chunk option control C++ standard used. cpp_source() now much informative error messages compilation fails (#125, #139) cpp_source() now uses unique name DLL, works run multiple times source file Windows (#143) writable::list_of now supports modification vectors intended (#131). Errors running tools::package_native_routine_registration_skeleton() longer swallowed (#134) cpp_source() can now accept source file called cpp11.cpp (#133) named_arg now explicitly protect values, avoiding protection issues using large inputs. tidyverse/readr#1145 r_string(std::string) now uses Rf_mkCharLenCE() instead Rf_mkChar(), avoids performance cost checking string length. Writable vector classes now properly set lengths intended copied read class (#128).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-024","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.4","title":"cpp11 0.2.4","text":"CRAN release: 2020-11-05 preserve list now robust invalid values, XPtr address non-xptr’s stored option. fixes errors reloading packages using cpp11 RStudio’s session restores. preserve list now robust invalid values, null pointers XPtr serialized. situation occurs ‘Install Restart’ RStudio (#121)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-023","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.3","title":"cpp11 0.2.3","text":"CRAN release: 2020-10-14 r_vector::const_iterator::operator* now const method (#113, @bkietz, @xhochy) preserve list now stored XPtr, rather environment, avoid issues serializing preserve environment, happens implicitly RStudio RStudio Cloud saves options resuming session (#116)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-022","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.2","title":"cpp11 0.2.2","text":"CRAN release: 2020-10-01 r_bool added adapter bool Rboolean values (#57, @bkietz) data_frame() objects now number rows correctly set real length, reserved length (#91) Fixed potential memory leak cpp11::writable classes.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-021","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.1","title":"cpp11 0.2.1","text":"CRAN release: 2020-08-11 Ensures backwards compatibility code generation cpp11 0.1.0 (#88) push_back() now works consistently named arguments (#86)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-020","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.0","title":"cpp11 0.2.0","text":"CRAN release: 2020-08-10","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-features-0-2-0","dir":"Changelog","previous_headings":"","what":"New features","title":"cpp11 0.2.0","text":"cpp11 now able compile gcc 4.8.5 (#69, @bkietz) cpp_source(), cpp_function() cpp_eval() now support [[cpp11::linking_to()]] syntax link third party packages C++ headers. (#48)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"minor-improvements-and-fixes-0-2-0","dir":"Changelog","previous_headings":"","what":"Minor improvements and fixes","title":"cpp11 0.2.0","text":"as_cpp() now works enumeration types (#52, @bkietz) as_cpp() as_cpp() now implicitly coerce 3 types single NA values (#53). list::const_iterator::operator*() added iterators used list objects (#60, @romainfrancois) safe[] can now work functions return type (#70, @bkietz) END_CPP macro now includes catch(...) block catch C++ exceptions inherit std::exception (#47). Improve consistency inserting NA values r_string objects (#45) Added NEWS.md file track changes package.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-010","dir":"Changelog","previous_headings":"","what":"cpp11 0.1.0","title":"cpp11 0.1.0","text":"CRAN release: 2020-07-10 Initial release","code":""}] +[{"path":[]},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement [INSERT CONTACT METHOD]. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"https://cpp11.r-lib.org/dev/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/ code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https:// www.contributor-covenant.org/translations.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"Contributing to cpp11","title":"Contributing to cpp11","text":"outlines propose change cpp11. detailed info contributing , tidyverse packages, please see development contributing guide.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"fixing-typos","dir":"","previous_headings":"","what":"Fixing typos","title":"Contributing to cpp11","text":"can fix typos, spelling mistakes, grammatical errors documentation directly using GitHub web interface, long changes made source file. generally means ’ll need edit roxygen2 comments .R, .Rd file. can find .R file generates .Rd reading comment first line.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"bigger-changes","dir":"","previous_headings":"","what":"Bigger changes","title":"Contributing to cpp11","text":"want make bigger change, ’s good idea first file issue make sure someone team agrees ’s needed. ’ve found bug, please file issue illustrates bug minimal reprex (also help write unit test, needed).","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"pull-request-process","dir":"","previous_headings":"Bigger changes","what":"Pull request process","title":"Contributing to cpp11","text":"Fork package clone onto computer. haven’t done , recommend using usethis::create_from_github(\"r-lib/cpp11\", fork = TRUE). Install development dependences devtools::install_dev_deps(), make sure package passes R CMD check running devtools::check(). R CMD check doesn’t pass cleanly, ’s good idea ask help continuing. Create Git branch pull request (PR). recommend using usethis::pr_init(\"brief-description--change\"). Make changes, commit git, create PR running usethis::pr_push(), following prompts browser. title PR briefly describe change. body PR contain Fixes #issue-number. user-facing changes, add bullet top NEWS.md (.e. just first header). Follow style described https://style.tidyverse.org/news.html.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"Bigger changes","what":"Code style","title":"Contributing to cpp11","text":"New code follow tidyverse style guide. can use styler package apply styles, please don’t restyle code nothing PR. use roxygen2, Markdown syntax, documentation. use testthat unit tests. Contributions test cases included easier accept.","code":""},{"path":"https://cpp11.r-lib.org/dev/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Contributing to cpp11","text":"Please note cpp11 project released Contributor Code Conduct. contributing project agree abide terms.","code":""},{"path":"https://cpp11.r-lib.org/dev/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2020 RStudio Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"current-state","dir":"","previous_headings":"","what":"Current state","title":"NA","text":"state cpp11 pretty stable, seems features need projects using C++.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"running-the-cpp11test-tests","dir":"","previous_headings":"Known outstanding issues","what":"Running the cpp11test tests","title":"NA","text":"test suite sub-package, cpp11test. Probably best way run tests install development version cpp11 run devtools::test() run cpp11test test suite. tests failures occur output Catch isn’t always easy interpret. branch testthat https://github.com/jimhester/testthat/tree/catch-detailed-output make things easier understand. contributed changes main testthat, something changed merging detailed output lost, unfortunately never time track cause fix . addition getting debugger catch errors happen can fiddly running cpp11test tests, something way Catch redirects stderr / stdout interacts debugger. GitHub Actions workflow additional logic handle running cpp11 tests https://github.com/r-lib/cpp11/blob/fd8ef97d006db847f7f17166cf52e1e0383b2d35/.github/workflows/R-CMD-check.yaml#L95-L102, https://github.com/r-lib/cpp11/blob/fd8ef97d006db847f7f17166cf52e1e0383b2d35/.github/workflows/R-CMD-check.yaml#L117-L124.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"false-positive-url-checks-for-git-repositories-in-the-vignettes","dir":"","previous_headings":"Known outstanding issues","what":"False positive URL checks for git repositories in the vignettes","title":"NA","text":"run urlchecker::url_check() repo see following false positives. happen urlchecker package, can safely ignored real CRAN checks show .","code":"! Warning: vignettes/motivations.Rmd:363:11 Moved git clone https://github.com/r-lib/cpp11.git ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://github.com/r-lib/cpp11 ! Warning: vignettes/motivations.Rmd:354:11 Moved git clone https://github.com/RcppCore/Rcpp.git ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://github.com/RcppCore/Rcpp >"},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"ensure-you-use-syssetenvcpp11_eval--true-devtoolssubmit_cran-when-submitting","dir":"","previous_headings":"","what":"Ensure you use Sys.setenv(\"CPP11_EVAL\" = \"true\"); devtools::submit_cran() when submitting.","title":"NA","text":"forget set CPP_EVAL = \"true\" vignette chunks run properly vignettes rendered properly.","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"regenerating-benchmark-objects-used-in-motivationsrmd","dir":"","previous_headings":"","what":"Regenerating benchmark objects used in motivations.Rmd","title":"NA","text":"need regenerate benchmark objects (RDS objects) utilized motivations.Rmd, set Sys.setenv(\"CPP11TEST_SHOULD_RUN_BENCHMARKS\" = \"TRUE\") running Rmd. ’ll also need make sure cpp11test actually installed. See cpp11test:::should_run_benchmarks() .","code":""},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"usage-with-clangd","dir":"","previous_headings":"","what":"Usage with clangd","title":"NA","text":"Since cpp11 header , use clangd ’ll bit issue tools like bear pkgload won’t know generate compile_commands.json file. Instead, can create manually something like , seems work well. Note paths specific computer. Key notes: R.hpp seems enough. imagine header files, reasonable pick “root” one pretty much others include. Using -std=gnu++11 keep us honest C++11 features. Using -\\\"/Library/Frameworks/R.framework/Resources/include\\\" access R headers. Using -\\\"/Users/davis/files/r/packages/cpp11/inst/include\\\" “self include”, seems key whole thing. modifying tests benchmarks, also need: -\\\"/Users/davis/Library/R/arm64/4.4/library/Rcpp/include\\\" Rcpp headers. -\\\"/Users/davis/Library/R/arm64/4.4/library/testthat/include\\\" testthat headers related Catch tests. Note specific path machine R version currently working .","code":"[ { \"command\": \"g++ -std=gnu++11 -I\\\"/Users/davis/files/r/packages/cpp11/inst/include\\\" -I\\\"/Library/Frameworks/R.framework/Resources/include\\\" -I\\\"/Users/davis/Library/R/arm64/4.4/library/Rcpp/include\\\" -I\\\"/Users/davis/Library/R/arm64/4.4/library/testthat/include\\\" -I\\\"/opt/homebrew/include\\\" -Wall -pedantic\", \"file\": \"R.hpp\", \"directory\": \"/Users/davis/files/r/packages/cpp11/inst/include/cpp11\" } ]"},{"path":"https://cpp11.r-lib.org/dev/MAINTENANCE.html","id":"future-directions","dir":"","previous_headings":"","what":"Future directions","title":"NA","text":"work spent smoothing cpp_source() / knitr chunk experience. main focus use cases R packages, usage tested. don’t typically use cpp11 non package contexts use cases may nice. similar reasons matrix support might somewhat lacking, majority use cases deal numeric matrices.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":null,"dir":"","previous_headings":"","what":"Getting help with cpp11","title":"Getting help with cpp11","text":"Thanks using cpp11! filing issue, places explore pieces put together make process smooth possible.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"make-a-reprex","dir":"","previous_headings":"","what":"Make a reprex","title":"Getting help with cpp11","text":"Start making minimal reproducible example using reprex package. haven’t heard used reprex , ’re treat! Seriously, reprex make R-question-asking endeavors easier (pretty insane ROI five ten minutes ’ll take learn ’s ). additional reprex pointers, check Get help! section tidyverse site.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"where-to-ask","dir":"","previous_headings":"","what":"Where to ask?","title":"Getting help with cpp11","text":"Armed reprex, next step figure ask. ’s question: start community.rstudio.com, /StackOverflow. people answer questions. ’s bug: ’re right place, file issue. ’re sure: let community help figure ! problem bug feature request, can easily return report . opening new issue, sure search issues pull requests make sure bug hasn’t reported /already fixed development version. default, search pre-populated :issue :open. can edit qualifiers (e.g. :pr, :closed) needed. example, ’d simply remove :open search issues repo, open closed.","code":""},{"path":"https://cpp11.r-lib.org/dev/SUPPORT.html","id":"what-happens-next","dir":"","previous_headings":"","what":"What happens next?","title":"Getting help with cpp11","text":"efficient possible, development tidyverse packages tends bursty, shouldn’t worry don’t get immediate response. Typically don’t look repo sufficient quantity issues accumulates, ’s burst intense activity focus efforts. makes development efficient avoids expensive context switching problems, cost taking longer get back . process makes good reprex particularly important might multiple months initial report start working . can’t reproduce bug, can’t fix !","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-add-elements-to-a-named-list","dir":"Articles","previous_headings":"","what":"2. How do I add elements to a named list?","title":"FAQ","text":"Use push_back() method named literal syntax. named literal syntax defined cpp11::literals namespace.","code":"#include [[cpp11::register]] cpp11::list foo_push() { using namespace cpp11::literals; cpp11::writable::list x; x.push_back({\"foo\"_nm = 1}); return x; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"does-cpp11-support-default-arguments","dir":"Articles","previous_headings":"","what":"3. Does cpp11 support default arguments?","title":"FAQ","text":"cpp11 support default arguments, convenient require complexity support currently worthwhile. need default argument support can use wrapper function around cpp11 registered function. common convention name internal function trailing _.","code":"#include [[cpp11::register]] double add_some_(double x, double amount) { return x + amount; } add_some <- function(x, amount = 1) { add_some_(x, amount) } add_some(1) #> [1] 2 add_some(1, amount = 5) #> [1] 6"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-create-a-new-empty-list","dir":"Articles","previous_headings":"","what":"4. How do I create a new empty list?","title":"FAQ","text":"Define new writable list object. cpp11::writable::list x;","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-retrieve-named-elements-from-a-named-vectorlist","dir":"Articles","previous_headings":"","what":"5. How do I retrieve (named) elements from a named vector/list?","title":"FAQ","text":"Use [] accessor function. x[\"foo\"]","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-tell-whether-a-vector-is-named","dir":"Articles","previous_headings":"","what":"6. How can I tell whether a vector is named?","title":"FAQ","text":"Use named() method vector classes.","code":"#include [[cpp11::register]] bool is_named(cpp11::strings x) { return x.named(); } is_named(\"foo\") #> [1] FALSE is_named(c(x = \"foo\")) #> [1] TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-return-a-cpp11writablelogicals-object-with-only-a-false-value","dir":"Articles","previous_headings":"","what":"7. How do I return a cpp11::writable::logicals object with only a FALSE value?","title":"FAQ","text":"need use list initialization {} create object.","code":"#include [[cpp11::register]] cpp11::writable::logicals my_false() { return {FALSE}; } [[cpp11::register]] cpp11::writable::logicals my_true() { return {TRUE}; } [[cpp11::register]] cpp11::writable::logicals my_both() { return {TRUE, FALSE, TRUE}; } my_false() #> [1] FALSE my_true() #> [1] TRUE my_both() #> [1] TRUE FALSE TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-create-a-new-empty-environment","dir":"Articles","previous_headings":"","what":"8. How do I create a new empty environment?","title":"FAQ","text":"need call base::new.env() function C++. can done creating cpp11::function object calling generate new environment.","code":"#include [[cpp11::register]] cpp11::environment create_environment() { cpp11::function new_env(cpp11::package(\"base\")[\"new.env\"]); return new_env(); }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-assign-and-retrieve-values-in-an-environment-what-happens-if-i-try-to-get-a-value-that-doesnt-exist","dir":"Articles","previous_headings":"","what":"9. How do I assign and retrieve values in an environment? What happens if I try to get a value that doesn’t exist?","title":"FAQ","text":"Use [] retrieve assign values environment name. value exist, error. check existence ahead time, use exists() method.","code":"#include [[cpp11::register]] bool foo_exists(cpp11::environment x) { return x.exists(\"foo\"); } [[cpp11::register]] void set_foo(cpp11::environment x, double value) { x[\"foo\"] = value; } x <- new.env() foo_exists(x) #> [1] FALSE set_foo(x, 1) foo_exists(x) #> [1] TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-create-a-cpp11raws-from-a-stdstring","dir":"Articles","previous_headings":"","what":"10. How can I create a cpp11:raws from a std::string?","title":"FAQ","text":"built way . One method push_back() element string individually.","code":"#include [[cpp11::register]] cpp11::raws push_raws() { std::string x(\"hi\"); cpp11::writable::raws out; for (auto c : x) { out.push_back(c); } return out; } push_raws() #> [1] 68 69"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-can-i-create-a-stdstring-from-a-cpp11writablestring","dir":"Articles","previous_headings":"","what":"11. How can I create a std::string from a cpp11::writable::string?","title":"FAQ","text":"C++ allow two implicit cast, explicitly cast cpp11::r_string first.","code":"#include #include [[cpp11::register]] std::string my_string() { cpp11::writable::strings x({\"foo\", \"bar\"}); std::string elt = cpp11::r_string(x[0]); return elt; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"what-are-the-types-for-c-iterators","dir":"Articles","previous_headings":"","what":"12. What are the types for C++ iterators?","title":"FAQ","text":"iterators ::iterator classes contained inside vector classes. example iterator cpp11::doubles cpp11::doubles::iterator iterator cpp11::writable::doubles cpp11::writable::doubles::iterator.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"my-code-has-using-namespace-std-why-do-i-still-have-to-include-std-in-the-signatures-of-cpp11register-functions","dir":"Articles","previous_headings":"","what":"13. My code has using namespace std, why do I still have to include std:: in the signatures of [[cpp11::register]] functions?","title":"FAQ","text":"using namespace std directive included generated code function signatures, still need fully qualified. However need qualify type names within functions. following won’t compile compile work intended","code":"#include #include using namespace std; [[cpp11::register]] string foobar() { return string(\"foo\") + \"-bar\"; } #include #include using namespace std; [[cpp11::register]] std::string foobar() { return string(\"foo\") + \"-bar\"; }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"how-do-i-modify-a-vector-in-place","dir":"Articles","previous_headings":"","what":"14. How do I modify a vector in place?","title":"FAQ","text":"place modification breaks normal semantics R code. general avoided, cpp11::writable classes always copy data constructed. However positive -place modification necessary use case can use move constructor .","code":"#include [[cpp11::register]] void add_one(cpp11::sexp x_sexp) { cpp11::writable::integers x(std::move(x_sexp.data())); for (auto&& value : x) { ++value; } } x <- c(1L, 2L, 3L, 4L) .Internal(inspect(x)) #> @56199c572e88 13 INTSXP g0c2 [REF(2)] (len=4, tl=0) 1,2,3,4 add_one(x) .Internal(inspect(x)) #> @56199c572e88 13 INTSXP g0c2 [REF(5)] (len=4, tl=0) 2,3,4,5 x #> [1] 2 3 4 5"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"should-i-call-cpp11unwind_protect-manually","dir":"Articles","previous_headings":"","what":"15. Should I call cpp11::unwind_protect() manually?","title":"FAQ","text":"cpp11::unwind_protect() cpp11’s way safely calling R’s C API. short, allows run function might throw R error, catch longjmp() error, promote exception thrown caught try/catch cpp11 sets .Call() time (allows destructors run), finally tells R continue unwinding stack now C++ objects chance destruct needed. Since cpp11::unwind_protect() takes arbitrary function, may wondering use custom needs. general, advise extremely advanced feature prone subtle hard debug issues.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"destructors","dir":"Articles","previous_headings":"15. Should I call cpp11::unwind_protect() manually?","what":"Destructors","title":"FAQ","text":"following setup test_destructor_ok() manual call unwind_protect() work: happen move unwind_protect(), won’t destructed, ’ll end memory leak best, much sinister issue destructor important: general, code can called within unwind_protect() “pure” C code C++ code uses POD (plain-old-data) types exceptions. mix complex C++ objects R’s C API within unwind_protect(), R errors result jump prevents destructors running.","code":"#include class A { public: ~A(); }; A::~A() { Rprintf(\"hi from the destructor!\"); } [[cpp11::register]] void test_destructor_ok() { A a{}; cpp11::unwind_protect([&] { Rf_error(\"oh no!\"); }); } [[cpp11::register]] void test_destructor_bad() { cpp11::unwind_protect([&] { A a{}; Rf_error(\"oh no!\"); }); } test_destructor_ok() #> Error: oh no! #> hi from the destructor! test_destructor_bad() #> Error: oh no!"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"nested-unwind_protect","dir":"Articles","previous_headings":"15. Should I call cpp11::unwind_protect() manually?","what":"Nested unwind_protect()","title":"FAQ","text":"Another issue can arise nested calls unwind_protect(). hard (impossible) end invalidly nested unwind_protect() calls using typical cpp11 API, can manually create scenario like following: run test_nested() R, likely crash hang R session due following chain events: test_nested() sets try/catch catch unwind exceptions outer unwind_protect() called. uses C function R_UnwindProtect() call lambda function. inner unwind_protect() called. uses R_UnwindProtect(), time call Rf_error(). Rf_error() performs longjmp() caught inner unwind_protect() promoted exception. exception thrown, outer call R_UnwindProtect() (C function), end throwing exception across C stack frames. undefined behavior, known caused R crash certain platforms. might think ’d never , scenario can also occur combination 1 call unwind_protect() combined usage cpp11 API: cpp11::stop() (cpp11 API) uses unwind_protect() internally, ’ve indirectly ended nested unwind_protect() scenario . general, must use unwind_protect() must careful use cpp11 API inside unwind_protect() call. worth pointing calling R function cpp11 calls back cpp11 still safe, .e. registered version imaginary test_outer() function called R, work: might seem unsafe cpp11::package() uses unwind_protect() call R function test_inner(), goes back C++ call cpp11::stop(), uses unwind_protect(), seems like nested scenario, scenario actually work. makes sense analyze one step time: Call R function test_outer() try/catch set catch unwind exceptions C++ function test_outer() called cpp11::package() uses unwind_protect() call R function test_inner() Call R function test_inner() try/catch set catch unwind exceptions (key!) C++ function test_inner() called cpp11::stop(\"oh !\") called, uses unwind_protect() call Rf_error(), causing longjmp(), caught unwind_protect() promoted exception. exception thrown, time caught try/catch set test_inner() entered R side. prevents exception crossing C++ -> C boundary. try/catch calls R_ContinueUnwind(), longjmp()s , now unwind_protect() set cpp11::package() catches , promotes exception. exception thrown caught try/catch set test_outer(). try/catch calls R_ContinueUnwind(), longjmp()s , point can safely let longjmp() proceed force R error.","code":"#include [[cpp11::register]] void test_nested() { cpp11::unwind_protect([&] { cpp11::unwind_protect([&] { Rf_error(\"oh no!\"); }); }); } #include [[cpp11::register]] void test_hidden_nested() { cpp11::unwind_protect([&] { cpp11::stop(\"oh no!\"); }); } #include [[cpp11::register]] void test_inner() { cpp11::stop(\"oh no!\") } [[cpp11::register]] void test_outer() { auto fn = cpp11::package(\"mypackage\")[\"test_inner\"] fn(); }"},{"path":"https://cpp11.r-lib.org/dev/articles/FAQ.html","id":"ok-but-i-really-want-to-call-cpp11unwind_protect-manually","dir":"Articles","previous_headings":"","what":"16. Ok but I really want to call cpp11::unwind_protect() manually","title":"FAQ","text":"’ve read bullet still feel like need call unwind_protect(), keep mind following writing function unwind-protect: shouldn’t create C++ objects destructors. shouldn’t use parts cpp11 API may call unwind_protect(). must careful call unwind_protect() nested manner. words, use plain-old-data types, careful never throw exceptions, use R’s C API, can use unwind_protect(). One place may want working long character vectors. Unfortunately, due way cpp11 must protect individual CHARSXP objects make character vector, can currently quite slow use cpp11 API . Consider example extracting individual elements x[] vs using native R API: plan improve future, now one places feel reasonable call unwind_protect() manually.","code":"#include [[cpp11::register]] cpp11::sexp test_extract_cpp11(cpp11::strings x) { const R_xlen_t size = x.size(); for (R_xlen_t i = 0; i < size; ++i) { (void) x[i]; } return R_NilValue; } [[cpp11::register]] cpp11::sexp test_extract_r_api(cpp11::strings x) { const R_xlen_t size = x.size(); const SEXP data{x}; cpp11::unwind_protect([&] { for (R_xlen_t i = 0; i < size; ++i) { (void) STRING_ELT(data, i); } }); return R_NilValue; } set.seed(123) x <- sample(letters, 1e6, replace = TRUE) bench::mark( test_extract_cpp11(x), test_extract_r_api(x) ) #> Warning: Some expressions had a GC in every iteration; so filtering is #> disabled. #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 test_extract_cpp11(x) 40.66ms 44.1ms 22.3 0B 39.0 #> 2 test_extract_r_api(x) 2.16ms 2.17ms 459. 0B 0"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"getting-started","dir":"Articles","previous_headings":"","what":"Getting started","title":"Converting from Rcpp","text":"Add cpp11 calling usethis::use_cpp11(). Start converting function function. Converting code bit time (regularly running tests) best way conversion correctly make progress. separate commit converting file (possibly function) can make finding regressions git bisect much easier future. Convert #include #include . Convert instances // [[Rcpp::export]] [[cpp11::register]]. Grep Rcpp:: replace equivalent cpp11 function using cheatsheets . Remove Rcpp Remove Rcpp LinkingTo Imports fields. Remove @importFrom Rcpp sourceCpp. Delete src/RccpExports.cpp R/RcppExports.R. Delete src/Makevars contains PKG_CPPFLAGS=-DSTRICT_R_HEADERS. Clean old compiled code pkgbuild::clean_dll(). Re-document package update NAMESPACE.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"vectors","dir":"Articles","previous_headings":"Cheatsheet","what":"Vectors","title":"Converting from Rcpp","text":"Note cpp11 vector class read-writeable version. default classes, e.g. cpp11::doubles read-classes permit modification. want modify data create new vector, use writeable variant. Another major difference Rcpp cpp11 vectors grown. Rcpp vectors push_back() method, unlike std::vector() additional space reserved pushing. makes calling push_back() repeatably expensive, entire vector copied call. contrast cpp11 vectors grow efficiently, reserving extra space. See https://cpp11.r-lib.org/articles/motivations.html#growing-vectors details. Rcpp also allows flexible implicit conversions, e.g. pass REALSXP function takes Rcpp::IntegerVector() implicitly converted INTSXP. conversions nice usability, require (implicit) duplication data, associated runtime costs. cpp11 throws error cases. want implicit coercions can add call .integer() .double() appropriate R call function.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"functions","dir":"Articles","previous_headings":"Cheatsheet","what":"Functions","title":"Converting from Rcpp","text":"Note cpp11::stop() cpp11::warning() thin wrappers around Rf_stop() Rf_warning(). simple C functions printf() API, understand C++ objects like std::string. Therefore need call obj.c_str() passing string data .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"r-functions","dir":"Articles","previous_headings":"Cheatsheet","what":"R functions","title":"Converting from Rcpp","text":"Calling R functions C++ similar using Rcpp.","code":"// Rcpp ----------------------------------------------- Rcpp::Function as_tibble(\"as_tibble\", Rcpp::Environment::namespace_env(\"tibble\")); as_tibble(x, Rcpp::Named(\".rows\", num_rows), Rcpp::Named(\".name_repair\", name_repair)); // cpp11 ----------------------------------------------- using namespace cpp11::literals; // so we can use \"\"_nm syntax auto as_tibble = cpp11::package(\"tibble\")[\"as_tibble\"]; as_tibble(x, \".rows\"_nm = num_rows, \".name_repair\"_nm = name_repair);"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"unsupported-rcpp-features","dir":"Articles","previous_headings":"Cheatsheet","what":"Unsupported Rcpp features","title":"Converting from Rcpp","text":"None Modules None Sugar dependencies random number generator restoration support roxygen2 comments interfaces","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"rngs","dir":"Articles","previous_headings":"Cheatsheet","what":"RNGs","title":"Converting from Rcpp","text":"Rcpp includes calls GetRNGstate() PutRNGstate() around wrapped function. ensures C++ code calls R API functions unif_rand(), norm_rand(), exp_rand(), R_unif_index() random seed state set accordingly. cpp11 , must include calls GetRNGstate() PutRNGstate() use functions C++ code. See R-exts 6.3 - Random number generation details functions. One convenient way safely use simple class:","code":"class local_rng { public: local_rng() { GetRNGstate(); } ~local_rng(){ PutRNGstate(); } }; void foo() { local_rng rng_state; /* my code using the RNG */ }"},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"stl-includes","dir":"Articles","previous_headings":"Common issues when converting","what":"STL includes","title":"Converting from Rcpp","text":"Rcpp.h includes number STL headers automatically, notably , however cpp11 headers generally . errors like need include appropriate STL header, case .","code":"error: no type named 'string' in namespace 'std'"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"strict-headers","dir":"Articles","previous_headings":"Common issues when converting","what":"Strict headers","title":"Converting from Rcpp","text":"see something like : Make sure remove PKG_CPPFLAGS=-DSTRICT_R_HEADERS src/Makevars.","code":"In file included from file.cpp:1: In file included from path/cpp11/include/cpp11.hpp:3: path/cpp11/include/cpp11/R.hpp:12:9: warning: 'STRICT_R_HEADERS' macro redefined [-Wmacro-redefined] #define STRICT_R_HEADERS"},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"r-api-includes","dir":"Articles","previous_headings":"Common issues when converting","what":"R API includes","title":"Converting from Rcpp","text":"cpp11 conflicts macros declared R headers unless macros R_NO_REMAP STRICT_R_HEADERS defined. include cpp11.hpp (, minimum, cpp11/R.hpp) R headers macros defined appropriately, otherwise may see errors like R headers included cpp11 headers least one R_NO_REMAP STRICT_R_HEADERS defined. indicate must either change include order add preprocessor definitions R_NO_REMAP STRICT_R_HEADERS. Note transitive includes R headers (example, included Rcpp.h) can also introduce conflicting macros.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"type-aliases","dir":"Articles","previous_headings":"Common issues when converting","what":"Type aliases","title":"Converting from Rcpp","text":"use typedefs cpp11 types define custom types need define pkgname_types.hpp file cpp_register() can include generated code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/converting.html","id":"logical-vector-construction","dir":"Articles","previous_headings":"Common issues when converting","what":"Logical vector construction","title":"Converting from Rcpp","text":"constructing length 1 logical vector may need explicitly use r_bool() object initializer list rather TRUE, FALSE NA_INTEGER. issue occurs clang compiler, gcc. constructing vectors one element issue","code":"// bad cpp11::writable::logicals({FALSE}); // good cpp11::writable::logicals({r_bool(FALSE)}); // good cpp11::writable::logicals({FALSE, NA_LOGICAL});"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Get started with cpp11","text":"Sometimes R code just isn’t fast enough. ’ve used profiling figure bottlenecks , ’ve done everything can R, code still isn’t fast enough. vignette ’ll learn improve performance rewriting key functions C++. magic comes way cpp11 package. cpp11 makes simple connect C++ R. possible write C Fortran code use R, painful comparison. cpp11 provides clean, approachable API lets write high-performance code, insulated R’s complex C API. Typical bottlenecks C++ can address include: Loops can’t easily vectorised subsequent iterations depend previous ones. Recursive functions, problems involve calling functions millions times. overhead calling function C++ much lower R. Problems require advanced data structures algorithms R doesn’t provide. standard template library (STL), C++ efficient implementations many important data structures, ordered maps double-ended queues. aim vignette discuss aspects C++ cpp11 absolutely necessary help eliminate bottlenecks code. won’t spend much time advanced features like object-oriented programming templates focus writing small, self-contained functions, big programs. working knowledge C++ helpful, essential. Many good tutorials references freely available, including https://www.learncpp.com/ https://en.cppreference.com/w/cpp. advanced topics, Effective C++ series Scott Meyers popular choice.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"outline","dir":"Articles","previous_headings":"Introduction","what":"Outline","title":"Get started with cpp11","text":"Section intro teaches write C++ converting simple R functions C++ equivalents. ’ll learn C++ differs R, key scalar, vector, matrix classes called. Section cpp_source shows use cpp11::cpp_source() load C++ file disk way use source() load file R code. Section classes discusses modify attributes cpp11, mentions important classes. Section na teaches work R’s missing values C++. Section stl shows use important data structures algorithms standard template library, STL, built-C++. Section case-studies shows two real case studies cpp11 used get considerable performance improvements. Section package teaches add C++ code R package. Section concludes vignette pointers resources help learn cpp11 C++.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"prerequisites","dir":"Articles","previous_headings":"Introduction","what":"Prerequisites","title":"Get started with cpp11","text":"’ll use cpp11 call C++ R: ’ll also need working C++ compiler. get : Windows, install Rtools. Mac, install Xcode app store. Linux, sudo apt-get install r-base-dev similar.","code":"library(cpp11)"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"intro","dir":"Articles","previous_headings":"","what":"Getting started with C++","title":"Get started with cpp11","text":"cpp_function() allows write C++ functions R: run code, cpp11 compile C++ code construct R function connects compiled C++ function. ’s lot going underneath hood cpp11 takes care details don’t need worry . following sections teach basics translating simple R functions C++ equivalents. ’ll start simple function inputs scalar output, make progressively complicated: Scalar input scalar output Vector input scalar output Vector input vector output Matrix input vector output","code":"cpp_function('int add(int x, int y, int z) { int sum = x + y + z; return sum; }') # add works like a regular R function add #> function (x, y, z) #> { #> .Call(\"_code_19f31774bf9f_add\", x, y, z, PACKAGE = \"code_19f31774bf9f\") #> } add(1, 2, 3) #> [1] 6"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"no-inputs-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"No inputs, scalar output","title":"Get started with cpp11","text":"Let’s start simple function. arguments always returns integer 1: equivalent C++ function : can compile use R cpp_function() small function illustrates number important differences R C++: syntax create function looks like syntax call function; don’t use assignment create functions R. must declare type output function returns. function returns int (scalar integer). classes common types R vectors : doubles, integers, strings, logicals. Scalars vectors different. scalar equivalents numeric, integer, character, logical vectors : double, int, String, bool. must use explicit return statement return value function. Every statement terminated ;.","code":"one <- function() 1L int one() { return 1; } cpp_function('int one() { return 1; }')"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"scalar-input-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Scalar input, scalar output","title":"Get started with cpp11","text":"next example function implements scalar version sign() function returns 1 input positive, -1 ’s negative: C++ version: declare type input way declare type output. makes code little verbose, also makes clear type input function needs. syntax identical — big differences R C++, also lots similarities! C++ also statement works way R’s. R can use break exit loop, skip one iteration need use continue instead next.","code":"sign_r <- function(x) { if (x > 0) { 1 } else if (x == 0) { 0 } else { -1 } } cpp_function('int sign_cpp(int x) { if (x > 0) { return 1; } else if (x == 0) { return 0; } else { return -1; } }')"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vector-input-scalar-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Vector input, scalar output","title":"Get started with cpp11","text":"One big difference R C++ cost loops much lower C++. example, implement sum function R using loop. ’ve programming R , ’ll probably visceral reaction function! C++, loops little overhead, ’s fine use . Section stl, ’ll see alternatives loops clearly express intent; ’re faster, can make code easier understand. C++ version similar, : find length vector, use .size() method, returns integer. C++ methods called . (.e., full stop). statement different syntax: (init; check; increment). loop initialised creating new variable called value 0. iteration check < n, terminate loop ’s . iteration, increment value one, using special prefix operator ++ increases value 1. C++, vector indices start 0, means last element position n - 1. ’ll say ’s important: C++, VECTOR INDICES START 0! common source bugs converting R functions C++. Use = assignment, <-. C++ provides operators modify -place: total += x[] equivalent total = total + x[]. Similar -place operators -=, *=, /=. good example C++ much efficient R. shown following microbenchmark, sum_cpp() competitive built-(highly optimised) sum(), sum_r() several orders magnitude slower.","code":"sum_r <- function(x) { total <- 0 for (i in seq_along(x)) { total <- total + x[i] } total } cpp_function('double sum_cpp(doubles x) { int n = x.size(); double total = 0; for(int i = 0; i < n; ++i) { total += x[i]; } return total; }') x <- runif(1e3) bench::mark( sum(x), sum_cpp(x), sum_r(x) )[1:6] #> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 sum(x) 2.06µs 2.13µs 442749. 0B 0 #> 2 sum_cpp(x) 2.05µs 2.21µs 394362. 0B 0 #> 3 sum_r(x) 20.16µs 20.61µs 47922. 35.7KB 0"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vector-input-vector-output","dir":"Articles","previous_headings":"Getting started with C++","what":"Vector input, vector output","title":"Get started with cpp11","text":"Next ’ll create function computes Euclidean distance value vector values: R, ’s obvious want x scalar function definition, ’d need make clear documentation. ’s problem C++ version explicit types: function introduces new concepts: creating new vector need use writable::doubles rather read-doubles. create new numeric vector length n constructor: cpp11::writable::doubles (n). Another useful way making vector copy existing one: cpp11::doubles zs(ys). C++ uses pow(), ^, exponentiation. Note R version fully vectorised, ’s already going fast. computer, takes around 5 ms 1 million element y vector. C++ function 2.5 times faster, ~2 ms, assuming took 10 minutes write C++ function, ’d need run ~200,000 times make rewriting worthwhile. reason C++ function faster subtle, relates memory management. R version needs create intermediate vector length y (x - ys), allocating memory expensive operation. C++ function avoids overhead uses intermediate scalar.","code":"pdist_r <- function(x, ys) { sqrt((x - ys) ^ 2) } cpp_function('doubles pdist_cpp(double x, doubles ys) { int n = ys.size(); writable::doubles out(n); for(int i = 0; i < n; ++i) { out[i] = sqrt(pow(ys[i] - x, 2.0)); } return out; }') y <- runif(1e6) bench::mark( pdist_r(0.5, y), pdist_cpp(0.5, y) )[1:6] #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 pdist_r(0.5, y) 5.01ms 5.18ms 189. 7.63MB 94.5 #> 2 pdist_cpp(0.5, y) 3.93ms 3.98ms 250. 7.63MB 127."},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"cpp-source","dir":"Articles","previous_headings":"Getting started with C++","what":"Using cpp_source","title":"Get started with cpp11","text":"far, ’ve used inline C++ cpp_function(). makes presentation simpler, real problems, ’s usually easier use stand-alone C++ files source R using cpp_source(). lets take advantage text editor support C++ files (e.g., syntax highlighting) well making easier identify line numbers compilation errors. stand-alone C++ file extension .cpp, needs start : function want available within R, need prefix : ’re familiar roxygen2, might wonder relates @export. cpp11::register registers C++ function called R. @export controls whether function exported package made available user. compile C++ code, use cpp_source(\"path//file.cpp\"). create matching R functions add current session. Note functions can saved .Rdata file reloaded later session; must recreated time restart R. example also illustrates different kind loop, -loop. NB: run code, ’ll notice mean_cpp() faster built-mean(). trades numerical accuracy speed. remainder vignette C++ code presented stand-alone rather wrapped call cpp_function. want try compiling /modifying examples paste C++ source file includes elements described . easy RMarkdown using cpp11 instead {r} beginning code blocks.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] #include \"cpp11/doubles.hpp\" using namespace cpp11; [[cpp11::register]] double mean_cpp(doubles x) { int n = x.size(); double total = 0; for(double value : x) { total += value; } return total / n; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises","dir":"Articles","previous_headings":"Getting started with C++","what":"Exercises","title":"Get started with cpp11","text":"basics C++ hand, ’s now great time practice reading writing simple C++ functions. following functions, read code figure corresponding base R function . might understand every part code yet, able figure basics function . practice function writing skills, convert following functions C++. now, assume inputs missing values. (). cumprod(), cummin(), cummax(). diff(). Start assuming lag 1, generalise lag n. range(). var(). Read approaches can take Wikipedia. Whenever implementing numerical algorithm, ’s always good check already known problem.","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] double f1(doubles x) { int n = x.size(); double y = 0; for(int i = 0; i < n; ++i) { y += x[i] / n; } return y; } [[cpp11::register]] doubles f2(doubles x) { int n = x.size(); writable::doubles out(n); out[0] = x[0]; for(int i = 1; i < n; ++i) { out[i] = out[i - 1] + x[i]; } return out; } [[cpp11::register]] bool f3(logicals x) { int n = x.size(); for(int i = 0; i < n; ++i) { if (x[i]) { return true; } } return false; } [[cpp11::register]] int f4(cpp11::function pred, list x) { int n = x.size(); for(int i = 0; i < n; ++i) { logicals res(pred(x[i])); if (res[0]) { return i + 1; } } return 0; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"classes","dir":"Articles","previous_headings":"","what":"Other classes","title":"Get started with cpp11","text":"’ve already seen basic vector classes (integers, doubles, logicals, strings) scalar (int, double, bool, string) equivalents. cpp11 also provides wrappers base data types. important lists data frames, functions, attributes, described .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"lists-and-data-frames","dir":"Articles","previous_headings":"Other classes","what":"Lists and data frames","title":"Get started with cpp11","text":"cpp11 also provides list data_frame classes, useful output input. lists data frames can contain arbitrary classes C++ needs know classes advance. list known structure (e.g., ’s S3 object), can extract components manually convert C++ equivalents as_cpp(). example, object created lm(), function fits linear model, list whose components always type. following code illustrates might extract mean percentage error (mpe()) linear model. isn’t good example use C++, ’s easily implemented R, shows work important S3 class. Note use Rf_inherits() stop() check object really linear model.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double mpe(list mod) { if (!Rf_inherits(mod, \"lm\")) { stop(\"Input must be a linear model\"); } doubles resid(mod[\"residuals\"]); doubles fitted(mod[\"fitted.values\"]); int n = resid.size(); double err = 0; for(int i = 0; i < n; ++i) { err += resid[i] / (fitted[i] + resid[i]); } return err / n; } mod <- lm(mpg ~ wt, data = mtcars) mpe(mod) #> [1] -0.01541615"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"functions-cpp11","dir":"Articles","previous_headings":"Other classes","what":"Functions","title":"Get started with cpp11","text":"can put R functions object type function. makes calling R function C++ straightforward. challenge don’t know type output function return, use catchall type sexp. stands S-Expression used type R Objects internal C code. Calling R functions positional arguments obvious: need special syntax named arguments:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] sexp call_with_one(function f) { return f(1); } call_with_one(function(x) x + 1) #> [1] 2 call_with_one(paste) #> [1] \"1\" f(\"y\", 1); using namespace cpp11::literals; f(\"x\"_nm = \"y\", \"value\"_nm = 1);"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"attributes","dir":"Articles","previous_headings":"Other classes","what":"Attributes","title":"Get started with cpp11","text":"R objects attributes, can queried modified .attr(). cpp11 also provides .names() alias names attribute. following code snippet illustrates methods. Note use {} initializer list syntax. allows create R vector C++ scalar values:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] doubles attribs() { writable::doubles out = {1., 2., 3.}; out.names() = {\"a\", \"b\", \"c\"}; out.attr(\"my-attr\") = \"my-value\"; out.attr(\"class\") = \"my-class\"; return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"na","dir":"Articles","previous_headings":"","what":"Missing values","title":"Get started with cpp11","text":"’re working missing values, need know two things: R’s missing values behave C++’s scalars (e.g., double). get set missing values vectors (e.g., doubles).","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"scalars","dir":"Articles","previous_headings":"Missing values","what":"Scalars","title":"Get started with cpp11","text":"following code explores happens take one R’s missing values, coerce scalar, coerce back R vector. Note kind experimentation useful way figure operation . exception bool, things look pretty good : missing values preserved. However, ’ll see following sections, things quite straightforward seem.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] list scalar_missings() { int int_s = NA_INTEGER; r_string chr_s = NA_STRING; bool lgl_s = NA_LOGICAL; double num_s = NA_REAL; return writable::list({as_sexp(int_s), as_sexp(chr_s), as_sexp(lgl_s), as_sexp(num_s)}); } str(scalar_missings()) #> List of 4 #> $ : int NA #> $ : chr NA #> $ : logi TRUE #> $ : num NA"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"integers","dir":"Articles","previous_headings":"Missing values > Scalars","what":"Integers","title":"Get started with cpp11","text":"integers, missing values stored smallest integer. don’t anything , ’ll preserved. , since C++ doesn’t know smallest integer special behaviour, anything ’re likely get incorrect value: example, cpp_eval('NA_INTEGER + 1') gives -2147483647. want work missing values integers, either use length 1 integers careful code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"doubles","dir":"Articles","previous_headings":"Missing values > Scalars","what":"Doubles","title":"Get started with cpp11","text":"doubles, may able get away ignoring missing values working NaNs (number). R’s NA special type IEEE 754 floating point number NaN. logical expression involves NaN (C++, NAN) always evaluates FALSE: (’m using cpp_eval() allows see result running single C++ expression, making excellent sort interactive experimentation.) careful combining Boolean values: However, numeric contexts NaNs propagate NAs:","code":"cpp_eval(\"NAN == 1\") #> [1] FALSE cpp_eval(\"NAN < 1\") #> [1] FALSE cpp_eval(\"NAN > 1\") #> [1] FALSE cpp_eval(\"NAN == NAN\") #> [1] FALSE cpp_eval(\"NAN && TRUE\") #> [1] TRUE cpp_eval(\"NAN || FALSE\") #> [1] TRUE cpp_eval(\"NAN + 1\") #> [1] NaN cpp_eval(\"NAN - 1\") #> [1] NaN cpp_eval(\"NAN / 1\") #> [1] NaN cpp_eval(\"NAN * 1\") #> [1] NaN"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"strings","dir":"Articles","previous_headings":"Missing values","what":"Strings","title":"Get started with cpp11","text":"String scalar string class introduced cpp11, knows deal missing values.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"boolean","dir":"Articles","previous_headings":"Missing values","what":"Boolean","title":"Get started with cpp11","text":"C++’s bool two possible values (true false), logical vector R three (TRUE, FALSE, NA). coerce length 1 logical vector, make sure doesn’t contain missing values; otherwise converted TRUE. One way fix use int instead, can represent TRUE, FALSE, NA.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vectors-cpp11","dir":"Articles","previous_headings":"Missing values","what":"Vectors","title":"Get started with cpp11","text":"vectors, need use missing value specific type vector, NA_REAL, NA_INTEGER, NA_LOGICAL, NA_STRING:","code":"#include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] list missing_sampler() { return writable::list({ writable::doubles({NA_REAL}), writable::integers({NA_INTEGER}), writable::logicals({r_bool(NA_LOGICAL)}), writable::strings({NA_STRING}) }); } str(missing_sampler()) #> List of 4 #> $ : num NA #> $ : int NA #> $ : logi NA #> $ : chr NA"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises-1","dir":"Articles","previous_headings":"Missing values","what":"Exercises","title":"Get started with cpp11","text":"Rewrite functions first exercise deal missing values. na_rm true, ignore missing values. na_rm false, return missing value input contains missing values. good functions practice min(), max(), range(), mean(), var(). Rewrite cumsum() diff() can handle missing values. Note functions slightly complicated behaviour.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"stl","dir":"Articles","previous_headings":"","what":"Standard Template Library","title":"Get started with cpp11","text":"real strength C++ revealed need implement complex algorithms. standard template library (STL) provides set extremely useful data structures algorithms. section explain important algorithms data structures point right direction learn . can’t teach everything need know STL, hopefully examples show power STL, persuade ’s useful learn . need algorithm data structure isn’t implemented STL, one place look boost. Installing boost computer beyond scope vignette, installed, can use boost data structures algorithms including appropriate header file (e.g.) #include .","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"using-iterators","dir":"Articles","previous_headings":"Standard Template Library","what":"Using iterators","title":"Get started with cpp11","text":"Iterators used extensively STL: many functions either accept return iterators. next step basic loops, abstracting away details underlying data structure. Iterators three main operators: Advance ++. Get value refer , dereference, *. Compare ==. example re-write sum function using iterators: main changes loop: start x.begin() loop get x.end(). small optimization store value end iterator don’t need look time. saves 2 ns per iteration, ’s important calculations loop simple. Instead indexing x, use dereference operator get current value: *. Notice use auto rather giving type iterator. code can simplified still use C++11 feature: range-based loops. Iterators also allow us use C++ equivalents apply family functions. example, rewrite sum() use accumulate() function, takes starting ending iterator, adds values vector. third argument accumulate gives initial value: ’s particularly important also determines data type accumulate uses (use 0.0 0 accumulate uses double, int.). use accumulate() need include header.","code":"#include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum2(doubles x) { double total = 0; for(auto it = x.begin(); it != x.end(); ++it) { total += *it; } return total; } #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum3(doubles xs) { double total = 0; for(auto x : xs) { total += x; } return total; } #include #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] double sum4(doubles x) { return std::accumulate(x.begin(), x.end(), 0.0); }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"algorithms","dir":"Articles","previous_headings":"Standard Template Library","what":"Algorithms","title":"Get started with cpp11","text":" header provides large number algorithms work iterators. good reference available https://en.cppreference.com/w/cpp/algorithm. example, write basic cpp11 version findInterval() takes two arguments, vector values vector breaks, locates bin x falls . shows advanced iterator features. Read code see can figure works. key points : step two iterators (input output) simultaneously. can assign dereferenced iterator (out_it) change values . upper_bound() returns iterator. wanted value upper_bound() dereference ; figure location, use distance() function. doubt, generally better use algorithms STL hand rolled loops. Effective STL, Scott Meyers gives three reasons: efficiency, correctness, maintainability. Algorithms STL written C++ experts extremely efficient, around long time well tested. Using standard algorithms also makes intent code clear, helping make readable maintainable.","code":"#include #include \"cpp11.hpp\" using namespace cpp11; [[cpp11::register]] integers findInterval2(doubles x, doubles breaks) { writable::integers out(x.size()); auto out_it = out.begin(); for (auto&& val : x) { auto pos = std::upper_bound(breaks.begin(), breaks.end(), val); *out_it = std::distance(breaks.begin(), pos); ++out_it; } return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"data-structures-cpp11","dir":"Articles","previous_headings":"Standard Template Library","what":"Data structures","title":"Get started with cpp11","text":"STL provides large set data structures: array, bitset, list, forward_list, map, multimap, multiset, priority_queue, queue, deque, set, stack, unordered_map, unordered_set, unordered_multimap, unordered_multiset, vector. important data structures vector, unordered_set, unordered_map. ’ll focus three section, using others similar: just different performance trade-offs. example, deque (pronounced “deck”) similar interface vectors different underlying implementation different performance trade-offs. may want try problem. good reference STL data structures https://en.cppreference.com/w/cpp/container — recommend keep open working STL. cpp11 knows convert many STL data structures R equivalents, can return functions without explicitly converting R data structures.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"vectors-stl","dir":"Articles","previous_headings":"Standard Template Library","what":"Vectors","title":"Get started with cpp11","text":"STL vector similar R vector, except grows efficiently. makes STL vectors appropriate use don’t know advance big output . Vectors templated, means need specify type object vector contain create : vector, vector, vector, vector. can access individual elements vector using standard [] notation, can add new element end vector using .push_back(). idea advance big vector , can use .reserve() allocate sufficient storage. following code implements run length encoding (rle()). produces two vectors output: vector values, vector lengths giving many times element repeated. works looping input vector x comparing value previous: ’s , increments last value lengths; ’s different, adds value end values, sets corresponding length 1. (alternative implementation replace iterator lengths.rbegin() always points last element vector. might want try implementing .) methods vector described https://en.cppreference.com/w/cpp/container/vector.","code":"#include \"cpp11.hpp\" #include using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] list rle_cpp(doubles x) { std::vector lengths; std::vector values; // Initialise first value int i = 0; double prev = x[0]; values.push_back(prev); lengths.push_back(1); for(auto it = x.begin() + 1; it != x.end(); ++it) { if (prev == *it) { lengths[i]++; } else { values.push_back(*it); lengths.push_back(1); i++; prev = *it; } } return writable::list({ \"lengths\"_nm = lengths, \"values\"_nm = values }); }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"sets","dir":"Articles","previous_headings":"Standard Template Library","what":"Sets","title":"Get started with cpp11","text":"Sets maintain unique set values, can efficiently tell ’ve seen value . useful problems involve duplicates unique values (like unique, duplicated, ). C++ provides ordered (std::set) unordered sets (std::unordered_set), depending whether order matters . Unordered sets can somtimes much faster (use hash table internally rather tree). Often even need ordered set, consider using unordered set sorting output. Benchmarking expected dataset best way determine fastest data. Like vectors, sets templated, need request appropriate type set purpose: unordered_set, unordered_set, etc. details available https://en.cppreference.com/w/cpp/container/set https://en.cppreference.com/w/cpp/container/unordered_set. following function uses unordered set implement equivalent duplicated() integer vectors. Note use seen.insert(x[]).second. insert() returns pair, .first value iterator points element .second value Boolean ’s true value new addition set.","code":"#include #include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] logicals duplicated_cpp(integers x) { std::unordered_set seen; int n = x.size(); writable::logicals out(n); for (int i = 0; i < n; ++i) { out[i] = !seen.insert(x[i]).second; } return out; }"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"exercises-2","dir":"Articles","previous_headings":"Standard Template Library","what":"Exercises","title":"Get started with cpp11","text":"practice using STL algorithms data structures, implement following using R functions C++, using hints provided: median.default() using partial_sort. %% using unordered_set find() count() methods. unique() using unordered_set (challenge: one line!). min() using std::min(), max() using std::max(). .min() using min_element, .max() using max_element. setdiff(), union(), intersect() integers using sorted ranges set_union, set_intersection set_difference.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"case-studies","dir":"Articles","previous_headings":"","what":"Case studies","title":"Get started with cpp11","text":"following case studies illustrate real life uses C++ replace slow R code.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"gibbs-sampler","dir":"Articles","previous_headings":"Case studies","what":"Gibbs sampler","title":"Get started with cpp11","text":"following case study updates example blogged Dirk Eddelbuettel, illustrating conversion Gibbs sampler R C++. R C++ code shown similar (took minutes convert R version C++ version), runs 30 times faster computer. Dirk’s blog post also shows another way make even faster: using faster random number generator functions GSL (easily accessible R RcppGSL package) can make another two three times faster. R code follows: relatively straightforward convert C++. : Add type declarations variables. Use ( instead [ index matrix. Include “Rmath.h” call functions Rf_. Benchmarking two implementations yields significant speedup running loops C++:","code":"gibbs_r <- function(N, thin) { mat <- matrix(nrow = N, ncol = 2) x <- y <- 0 for (i in 1:N) { for (j in 1:thin) { x <- rgamma(1, 3, y * y + 4) y <- rnorm(1, 1 / (x + 1), 1 / sqrt(2 * (x + 1))) } mat[i, ] <- c(x, y) } mat } #include \"cpp11/matrix.hpp\" #include \"cpp11/doubles.hpp\" #include \"Rmath.h\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] cpp11::doubles_matrix<> gibbs_cpp(int N, int thin) { writable::doubles_matrix<> mat(N, 2); double x = 0, y = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < thin; j++) { x = Rf_rgamma(3., 1. / double(y * y + 4)); y = Rf_rnorm(1. / (x + 1.), 1. / sqrt(2. * (x + 1.))); } mat(i, 0) = x; mat(i, 1) = y; } return mat; } bench::mark( r = { set.seed(42) gibbs_r(100, 10) }, cpp = { set.seed(42) gibbs_cpp(100, 10) }, check = TRUE, relative = TRUE ) #> # A tibble: 2 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 r 23.8 25.1 1 33.0 11.9 #> 2 cpp 1 1 25.1 1 1"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"r-vectorisation-versus-c-vectorisation","dir":"Articles","previous_headings":"Case studies","what":"R vectorisation versus C++ vectorisation","title":"Get started with cpp11","text":"example adapted “Rcpp smoking fast agent-based models data frames”. challenge predict model response three inputs. basic R version predictor looks like: want able apply function many inputs, might write vector-input version using loop. ’re familiar R, ’ll gut feeling slow, indeed . two ways attack problem. good R vocabulary, might immediately see vectorise function (using ifelse(), pmin(), pmax()). Alternatively, rewrite vacc1a() vacc1() C++, using knowledge loops function calls much lower overhead C++. Either approach fairly straightforward. R: (’ve worked R lot might recognise potential bottlenecks code: ifelse, pmin, pmax known slow, replaced p * 0.75 + p * 0.5 * female, p[p < 0] <- 0, p[p > 1] <- 1. might want try timing variations.) C++: next generate sample data, check three versions return values: original blog post forgot , introduced bug C++ version: used 0.004 instead 0.04. Finally, can benchmark three approaches: surprisingly, original approach loops slow. Vectorising R gives huge speedup, can eke even performance (ten times) C++ loop. little surprised C++ much faster, R version create 11 vectors store intermediate results, C++ code needs create 1.","code":"vacc1a <- function(age, female, ily) { p <- 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily p <- p * if (female) 1.25 else 0.75 p <- max(0, p) p <- min(1, p) p } vacc1 <- function(age, female, ily) { n <- length(age) out <- numeric(n) for (i in seq_len(n)) { out[i] <- vacc1a(age[i], female[i], ily[i]) } out } vacc2 <- function(age, female, ily) { p <- 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily p <- p * ifelse(female, 1.25, 0.75) p <- pmax(0, p) p <- pmin(1, p) p } #include \"cpp11.hpp\" using namespace cpp11; namespace writable = cpp11::writable; [[cpp11::register]] double vacc3a(double age, bool female, bool ily){ double p = 0.25 + 0.3 * 1 / (1 - exp(0.04 * age)) + 0.1 * ily; p = p * (female ? 1.25 : 0.75); p = std::max(p, 0.0); p = std::min(p, 1.0); return p; } [[cpp11::register]] doubles vacc3(doubles age, logicals female, logicals ily) { int n = age.size(); writable::doubles out(n); for(int i = 0; i < n; ++i) { out[i] = vacc3a(age[i], female[i], ily[i]); } return out; } n <- 1000 age <- rnorm(n, mean = 50, sd = 10) female <- sample(c(T, F), n, rep = TRUE) ily <- sample(c(T, F), n, prob = c(0.8, 0.2), rep = TRUE) stopifnot( all.equal(vacc1(age, female, ily), vacc2(age, female, ily)), all.equal(vacc1(age, female, ily), vacc3(age, female, ily)) ) bench::mark( vacc1 = vacc1(age, female, ily), vacc2 = vacc2(age, female, ily), vacc3 = vacc3(age, female, ily) ) #> # A tibble: 3 × 6 #> expression min median `itr/sec` mem_alloc `gc/sec` #> #> 1 vacc1 1.49ms 1.52ms 650. 7.86KB 34.2 #> 2 vacc2 42.61µs 45.53µs 20843. 148.56KB 39.6 #> 3 vacc3 11.9µs 12.17µs 79465. 14.02KB 7.95"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"package","dir":"Articles","previous_headings":"","what":"Using cpp11 in a package","title":"Get started with cpp11","text":"C++ code used cpp_source() can also bundled package. several benefits moving code stand-alone C++ source file package: code can made available users without C++ development tools. Multiple source files dependencies handled automatically R package build system. Packages provide additional infrastructure testing, documentation, consistency. add cpp11 existing package first put C++ files src/ directory package. easiest way configure everything call usethis::use_cpp11(). Alternatively: Add DESCRIPTION file: add following roxygen directive somewhere package’s R files. (common location R/pkgname-package.R) ’ll need run devtools::document() update NAMESPACE file include useDynLib statement. don’t use devtools::load_all(), ’ll also need run cpp11::cpp_register() building package. function scans C++ files [[cpp11::register]] attributes generates binding code required make functions available R. Re-run cpp11::cpp_register() whenever functions added, removed, signatures changed.","code":"LinkingTo: cpp11 #' @useDynLib pkgname, .registration = TRUE"},{"path":"https://cpp11.r-lib.org/dev/articles/cpp11.html","id":"more","dir":"Articles","previous_headings":"","what":"Learning more","title":"Get started with cpp11","text":"C++ large, complex language takes years master. like dive deeper write complex functions resources ’ve found helpful learning C++ : Effective C++ Effective STL C++ Annotations, aimed knowledgeable users C (language using C-like grammar, like Perl Java) like know , make transition , C++. Algorithm Libraries, provides technical, still concise, description important STL concepts. (Follow links notes.) Writing performant code may also require rethink basic approach: solid understanding basic data structures algorithms helpful . ’s beyond scope vignette, ’d suggest Algorithm Design Manual MIT’s Introduction Algorithms, Algorithms Robert Sedgewick Kevin Wayne free online textbook matching Coursera course.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"initial-setup-and-dev-workflow","dir":"Articles","previous_headings":"","what":"Initial setup and dev workflow","title":"cpp11 internals","text":"First install dependencies needed development. can load package interactive R session run cpp11 tests extensive tests cpp11test directory. Generally developing C++ headers run R working directory cpp11test directory use devtools::test() run cpp11tests. change cpp11 headers need install new version cpp11 clean recompile cpp11test package: calculate code coverage cpp11 package run following cpp11 root directory.","code":"install.packages(\"remotes\") remotes::install_deps(dependencies = TRUE) devtools::load_all() devtools::test() # Assuming your working directory is `cpp11test/` devtools::clean_dll() devtools::load_all() covr::report(cpp11_coverage())"},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"code-formatting","dir":"Articles","previous_headings":"","what":"Code formatting","title":"cpp11 internals","text":"project uses clang-format (version 10) automatically format c++ code. can run make format re-format code project. system clang-format version 10, can installed using homebrew tap command line brew install r-lib/taps/clang-format@10. may need link newly installed version 10. , run brew unlink clang-format followed brew link clang-format@10. Alternatively many IDEs support automatically running clang-format every time files written.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"code-organization","dir":"Articles","previous_headings":"","what":"Code organization","title":"cpp11 internals","text":"cpp11 header library, source code exposed users lives inst/include. R code used register functions cpp11::cpp_source() R/. Tests code R/ tests/testthat/. rest code separate cpp11test/ package included source tree. Inside cpp11test/src files start test- C++ tests using Catch support testthat. addition regular R tests cpp11test/tests/testthat/.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"naming-conventions","dir":"Articles","previous_headings":"","what":"Naming conventions","title":"cpp11 internals","text":"header files named .hpp extension. source files named .cpp extension. Public header files put inst/include/cpp11 Read r_vector classes free functions put cpp11 namespace. Writable r_vector class put cpp11::writable namespace. Private classes functions put cpp11::internal namespace.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"vector-classes","dir":"Articles","previous_headings":"","what":"Vector classes","title":"cpp11 internals","text":"basic r_vector classes class templates, base template defined cpp11/r_vector.hpp. template parameter type value particular R vector stores, e.g. double cpp11::doubles. differs Rcpp, whose first template parameter R vector type, e.g. REALSXP. file first class declarations, function definitions file. Specializations various types separate files, e.g. cpp11/doubles.hpp, cpp11/integers.hpp","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"coercion-functions","dir":"Articles","previous_headings":"","what":"Coercion functions","title":"cpp11 internals","text":"two different coercion functions as_sexp() takes C++ object coerces SEXP object, can used R. as_cpp<>() template function takes SEXP creates C++ object various methods functions defined cpp11/.hpp definitely complex part cpp11 code, extensive use template metaprogramming. particular substitution failure error (SFINAE) technique used control overloading functions. use C++20 lot code made simpler Concepts, alas. common C++ types included test suite work without issues, exotic types used real projects additional issues may arise. useful links SFINAE https://www.fluentcpp.com/2018/05/15/make-sfinae-pretty-1--value-sfinae-brings--code/, https://www.fluentcpp.com/2018/05/18/make-sfinae-pretty-2-hidden-beauty-sfinae/","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"protect-list","dir":"Articles","previous_headings":"Protection","what":"Protect list","title":"cpp11 internals","text":"cpp11 uses idea proposed Luke Tierney use double linked list head preserved protect objects cpp11 protecting. node list uses head (CAR) part point previous node, CDR part point next node. TAG used point object protected. head tail list R_NilValue CAR CDR pointers respectively. Calling cpp11::detail::store::insert() regular R object add new node list return protect token corresponding node added. Calling cpp11::detail::store::release() returned token release protection unlinking node linked list. two functions considered internal cpp11, use packages. scheme scales O(1) time release insert object vs O(N) worse time R_PreserveObject() / R_ReleaseObject(). package unique protection list, avoids need manage “global” protection list shared across packages. previous version cpp11 used global protection list stored R global option, caused multiple issues. functions defined protect.hpp.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/internals.html","id":"unwind-protect","dir":"Articles","previous_headings":"Protection","what":"Unwind Protect","title":"cpp11 internals","text":"cpp11 uses R_UnwindProtect() protect () calls R API fail. usually allocate memory, though truth R API functions error along paths. error happens R_UnwindProtect(), cpp11 throw C++ exception. exception caught try/catch block defined BEGIN_CPP11 macro cpp11/declarations.hpp. exception cause C++ destructors run, freeing resources held C++ objects. try/catch block exits, R error unwinding continued R_ContinueUnwind() normal R error results. require R >=3.5 use cpp11, created wanted support back R 3.3, R_ContinueUnwind() wasn’t available R 3.5. options considered support older R versions: Using R_TopLevelExec() works avoid C long jump, code always run top level context errors messages thrown caught tryCatch() similar techniques. Using R_TryCatch() available prior R 3.4, also serious bug R 3.4 (fixed R 3.5). Calling R level tryCatch() function contains expression runs C function runs C++ code option, implementing convoluted impact performance, perhaps severely. cpp11::unwind_protect() -op versions. means resources held C++ objects leak, including cpp11::r_vector / cpp11::sexp objects. None options perfect, pros cons . Causes behavior changes test failures, ruled . also ruled since wanted support back R 3.3. ruled partially implementation somewhat tricky performance suffer greatly. ended requiring R 3.5. leaked protected objects R API errors.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"motivations","dir":"Articles","previous_headings":"","what":"Motivations","title":"Motivations for cpp11","text":"R S long history interacting compiled languages. fact original version S written late 1970s mainly wrapper around FORTRAN routines (History--S). Released 2000, cxx package early prototype C++ bindings R. Rcpp first published CRAN 2008, Rcpp11 2014. Rcpp far widest adoption, 2000 reverse dependencies 2020. Rcpp widely successful project, however years number issues additional C++ features arisen. Adding features Rcpp require great deal work, cases impossible without severely breaking backwards compatibility. cpp11 ground rewrite C++ bindings R different design trade-offs features. Changes motivated cpp11 include: Enforcing copy--write semantics. Improving safety using R API C++ code. Supporting ALTREP objects. Using UTF-8 strings everywhere. Applying newer C++11 features. straightforward, simpler implementation. Faster compilation time lower memory requirements. completely header avoid ABI issues. Capable vendoring desired. robust protection using much efficient linked list data structure. Growing vectors efficiently.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"copy-on-write-semantics","dir":"Articles","previous_headings":"Motivations","what":"Copy-on-write semantics","title":"Motivations for cpp11","text":"R uses copy--write (also called copy--modify) semantics. Lets say two variables x y point underlying data. modify y, R first copy values x new position, point y new location copy modify y. allows x retain original values. C++ copy--write built language, however related concepts, copy--value copy--reference. Copy--value works similarly R, except R copies something changed, C++ always copies. Copy--reference opposite, x y always point underlying value. C++ specify reference &. Copy--reference valuable technique, avoids overhead copying data. However can also lead errors internal functions change inputs unexpectedly. Rcpp uses copy--reference default (even pass Rcpp vector class value). gives Rcpp functions completely different semantics normal R functions. can illustrate creating Rcpp function multiples input vector 2. regular R functions, see value y x * 2, value x unchanged. However now call times_two_rcpp() function get right output value, now x also changed. cpp11 strives make functions behave similarly normal R functions, preserving speed Rcpp read access needed. r_vector classes cpp11 normal read version uses copy--reference, writable version uses copy--value. Using cpp11::writable::doubles first copies input vector, multiplication modify original data.","code":"x <- c(1, 2, 3) y <- x y[[3]] <- 4 y #> [1] 1 2 4 x #> [1] 1 2 3 int x = 42; int y = x; y = 0; // x is still == 42 int x = 42; int &y = x; y = 0; // both x and y are now 0 #include \"Rcpp.h\" using namespace Rcpp; // [[Rcpp::export]] NumericVector times_two_rcpp(NumericVector x) { for (int i = 0; i < x.size(); ++i) { x[i] = x[i] * 2; } return x; } x <- c(1, 2, 3) y <- x * 2 y #> [1] 2 4 6 x #> [1] 1 2 3 z <- times_two_rcpp(x) z #> [1] 2 4 6 x #> [1] 2 4 6 #include \"cpp11/doubles.hpp\" [[cpp11::register]] cpp11::doubles times_two_cpp11(cpp11::writable::doubles x) { for (int i = 0; i < x.size(); ++i) { x[i] = x[i] * 2; } return x; } x <- c(1, 2, 3) z <- times_two_cpp11(x) z #> [1] 2 4 6 x #> [1] 1 2 3"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"improve-safety","dir":"Articles","previous_headings":"Motivations","what":"Improve safety","title":"Motivations for cpp11","text":"Internally R written C, C++. general C C++ work well together, large part C++’s success due high interoperability C code. However one area C C++ generally interoperable error handling. C++ common way handle errors exceptions. Exceptions provide clean, safe way objects obtain cleanup resources automatically even errors occur.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c-safety","dir":"Articles","previous_headings":"Motivations > Improve safety","what":"C safety","title":"Motivations for cpp11","text":"C language support exceptions, error handling done variety ways. include error codes like errno, conditional statements, R codebase longjmp function. longjmp, stands ‘long jump’ function allows transfer control flow program another location elsewhere program. R uses long jumps extensively error handling routines. R function executing error occurs, long jump called ‘jumps’ control flow error handling code. Crucially long jumps incompatible C++ destructors. long jump occurs destructors active C++ objects run, therefore resources (memory, file handles, etc.) managed objects cause resource leak. example, following unsafe code leak memory allocated C++ std::vector x R API function Rf_allocVector() fails (since can’t create vector -1 size). cpp11 provides two mechanisms make interfacing Rs C API C++ code safer. cpp11::unwind_protect() takes functional object (C++11 lamdba function std::function) converts C long jumps encountered C++ exceptions. Now instead C long jump happening Rf_allocVector() call fails, C++ exception occurs, trigger std::vector destructor, memory automatically released. cpp11::safe() concise way wrap particular R API function unwind_protect(). using cpp11::safe() converts C long jump C++ exception, memory automatically released. cpp11 uses mechanisms extensively internally calling R C API, make cpp11 much safer resource leaks using Rcpp calling Rs C API hand.","code":"std::vector x({1., 2., 3.}); SEXP y = PROTECT(Rf_allocVector(REALSXP, -1)); std::vector x({1., 2., 3.}); SEXP y; unwind_protect([]() { y = Rf_allocVector(REALSXP, -1); }) std::vector x({1., 2., 3.}); SEXP y = PROTECT(safe[Rf_allocVector](REALSXP, -1));"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c-safety-1","dir":"Articles","previous_headings":"Motivations > Improve safety","what":"C++ safety","title":"Motivations for cpp11","text":"inverse C safety also need ensure C++ exceptions reach C call stack, terminate R occurs. Like Rcpp, cpp11 automatically generates try / catch guards around registered functions prevent also converts C++ exceptions normal R errors. done without developer facing code changes. C C++ sides coin covered can safely use R’s C API C++ code together C++ objects without leaking resources.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"altrep-support","dir":"Articles","previous_headings":"Motivations","what":"Altrep support","title":"Motivations for cpp11","text":"ALTREP stands ALTernative REPresntations feature introduced R 3.5. ALTREP allows R internals package authors define alternative ways representing data R. One example use altrep : operator. Prior R 3.5 : generated full vector entire sequence. e.g. 1:1000 require 1000 individual values. R 3.5 sequence instead represented ALTREP vector, none values actually exist memory. Instead time R access particular value sequence value computed --fly. saves memory excution time, allows users use sequences otherwise big fit memory. Rcpp predates introduction ALTREP, support interfaces needed access ALTREP objects. means objects must converted normal R objects soon used Rcpp. Whereas cpp11 objects preserve ALTREP object.","code":"1:1e9 #> [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #> [ reached getOption(\"max.print\") -- omitted 999999980 entries ] #include \"Rcpp.h\" // [[Rcpp::export]] Rcpp::IntegerVector identity_rcpp(Rcpp::IntegerVector x) { return x; } x <- identity_rcpp(1:100000) lobstr::obj_size(x) #> 400.73 kB #include \"cpp11/integers.hpp\" [[cpp11::register]] cpp11::integers identity_cpp11(cpp11::integers x) { return x; } y <- identity_cpp11(1:100000) lobstr::obj_size(y) #> 680 B"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"altrep-benchmarks","dir":"Articles","previous_headings":"Motivations > Altrep support","what":"Altrep benchmarks","title":"Motivations for cpp11","text":"benchmarks note Rcpp allocates memory ALTREP vectors. Rcpp implicitly converts normal R vectors. cpp11 retains ALTREP vectors, additional memory needed. foreach accumulate use iterators take advantage REAL_GET_REGION buffer queries. makes faster naive C-style loops ALTREP vectors. for2 case shows optimization can use know compile-time won’t dealing ALTREP vectors. specifying false second argument (is_altrep), can disable ALTREP support. causes ALTREP conditional code compiled resulting loop unrolling (speeds) identical generated Rcpp. cpp11test/src/sum.cpp contains code ran benchmarks.","code":"library(cpp11test) cases <- expand.grid( len = 3e6, vector = c(\"normal\", \"altrep\"), method = c(\"for\", \"foreach\", \"accumulate\"), pkg = c(\"cpp11\", \"rcpp\"), stringsAsFactors = FALSE ) # Add special case cases <- rbind(list(len = 3e6, vector = \"normal\", method = \"for2\", pkg = \"cpp11\"), cases) b_sum <- bench::press( .grid = cases, { seq_real <- function(x) as.numeric(seq_len(x)) funs <- c(\"normal\" = rnorm, \"altrep\" = seq_real) x <- funs[[vector]](len) fun <- match.fun(sprintf(\"%ssum_dbl_%s_\", ifelse(pkg == \"cpp11\", \"\", paste0(pkg, \"_\")), method)) bench::mark( fun(x) ) } )[c(\"pkg\", \"method\", \"vector\", \"min\", \"median\", \"mem_alloc\", \"itr/sec\", \"n_gc\")] saveRDS(b_sum, \"sum.Rds\", version = 2) knitr::kable(readRDS(\"sum.Rds\"))"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"utf-8-everywhere","dir":"Articles","previous_headings":"Motivations","what":"UTF-8 everywhere","title":"Motivations for cpp11","text":"R complicated support Unicode strings non-ASCII code pages, whose behavior often differs substantially different operating systems, particularly Windows. Correctly dealing challenging often feels like whack mole. combat complexity cpp11 uses UTF-8 everywhere philosophy. means whenever text data converted R data structures C++ data structures cpp11 data translated UTF-8. Conversely text data coming C++ code assumed UTF-8 marked R. universally avoids many locale specific issues dealing Unicode text. Concretely cpp11 always uses Rf_translateCharUTF8() obtaining const char* CHRSXP objects uses Rf_mkCharCE(, CE_UTF8) creating new CHRSXP objects const char* inputs.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"c11-features","dir":"Articles","previous_headings":"Motivations","what":"C++11 features","title":"Motivations for cpp11","text":"C++11 provides host new features C++ language. cpp11 uses number including move semantics type traits initializer_list variadic templates / parameter packs user defined literals user defined attributes","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"simpler-implementation","dir":"Articles","previous_headings":"Motivations","what":"Simpler implementation","title":"Motivations for cpp11","text":"Rcpp ambitious, number advanced features, including modules, sugar extensive support attributes. useful features, many R packages use one advanced features. addition code needed support features complex can challenging maintain. cpp11 takes limited scope, providing set r_vector wrappers R vector types, coercion methods C++ limited attributes necessary support use R packages. limited scope allows implementation much simpler, headers Rcpp 1.0.4 74,658 lines code (excluding blank commented lines) 379 files. headers Rcpp automatically generated, removing still gives 25,249 lines code 357 files. contrast headers cpp11 contain 1,734 lines code 19 files. reduction complexity make cpp11 easier project maintain ensure correctness, particularly around interactions R garbage collector.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"compilation-speed","dir":"Articles","previous_headings":"Motivations","what":"Compilation speed","title":"Motivations for cpp11","text":"Rcpp always bundles headers together, causes slow compilation times high peak memory usage compiling. headers cpp11 easily decoupled, can include particular headers actually use source file. can significantly improve compilation speed memory usage compile package. real examples reduction compile time peak memory usage converting packages cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"header-only","dir":"Articles","previous_headings":"Motivations","what":"Header only","title":"Motivations for cpp11","text":"Rcpp long mostly header library, however completely header library. cases package first installed version X Rcpp, newer version Rcpp later installed. original package X loaded R crash, Application Binary Interface Rcpp changed two versions. cpp11 consists exclusively headers issue occur.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"vendoring","dir":"Articles","previous_headings":"Motivations","what":"Vendoring","title":"Motivations for cpp11","text":"go community concept vendoring widespread. Vendoring means copy code dependencies project’s source tree. ensures dependency code fixed stable updated. cpp11 fully header can vendor code way. cpp11::vendor_cpp11() provided choose. Vendoring advantages drawbacks however. advantage changes cpp11 project never break existing code. drawbacks minor, package size now slightly larger, major, longer get bugfixes new features explicitly update cpp11. think majority packages use LinkingTo: cpp11 vendor cpp11 dependency. However, vendoring can appropriate certain situations.","code":""},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"protection","dir":"Articles","previous_headings":"Motivations","what":"Protection","title":"Motivations for cpp11","text":"cpp11 uses custom double linked list data structure track objects managing. structure much efficient large numbers objects using R_PreserveObject() / R_ReleaseObjects() done Rcpp. plot shows average time protect release given object essentially constant cpp11. Whereas linear worse number objects tracked Rcpp.","code":"library(cpp11test) grid <- expand.grid(len = c(10 ^ (2:5), 2e5), pkg = c(\"cpp11\", \"rcpp\"), stringsAsFactors = FALSE) b_release <- bench::press(.grid = grid, { fun = match.fun(sprintf(\"%s_release_\", pkg)) bench::mark( fun(len), iterations = 1 ) } )[c(\"len\", \"pkg\", \"min\")] saveRDS(b_release, \"release.Rds\", version = 2)"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"growing-vectors","dir":"Articles","previous_headings":"Motivations","what":"Growing vectors","title":"Motivations for cpp11","text":"One major difference Rcpp cpp11 vectors grown. Rcpp vectors push_back() method, unlike std::vector() additional space reserved pushing. makes calling push_back() repeatably expensive, entire vector copied call. contrast cpp11 vectors grow efficiently, reserving extra space. can ~10,000,000 vector appends cpp11 approximately amount time Rcpp 10,000, benchmark demonstrates.","code":"grid <- expand.grid(len = 10 ^ (0:7), pkg = \"cpp11\", stringsAsFactors = FALSE) grid <- rbind( grid, expand.grid(len = 10 ^ (0:4), pkg = \"rcpp\", stringsAsFactors = FALSE) ) b_grow <- bench::press(.grid = grid, { fun = match.fun(sprintf(\"%sgrow_\", ifelse(pkg == \"cpp11\", \"\", paste0(pkg, \"_\")))) bench::mark( fun(len), min_iterations = 100 ) } )[c(\"len\", \"pkg\", \"min\", \"mem_alloc\", \"n_itr\", \"n_gc\")] saveRDS(b_grow, \"growth.Rds\", version = 2)"},{"path":"https://cpp11.r-lib.org/dev/articles/motivations.html","id":"conclusion","dir":"Articles","previous_headings":"Motivations","what":"Conclusion","title":"Motivations for cpp11","text":"Rcpp continue widely successful. cpp11 alternative implementation C++ bindings R chooses different design trade-offs features. packages can co-exist (even used package!) continue enrich R community.","code":""},{"path":"https://cpp11.r-lib.org/dev/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Davis Vaughan. Author, maintainer. Jim Hester. Author. Romain François. Author. Benjamin Kietzman. Contributor. . Copyright holder, funder.","code":""},{"path":"https://cpp11.r-lib.org/dev/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Vaughan D, Hester J, François R (2024). cpp11: C++11 Interface R's C Interface. R package version 0.4.7.9000, https://github.com/r-lib/cpp11, https://cpp11.r-lib.org.","code":"@Manual{, title = {cpp11: A C++11 Interface for R's C Interface}, author = {Davis Vaughan and Jim Hester and Romain François}, year = {2024}, note = {R package version 0.4.7.9000, https://github.com/r-lib/cpp11}, url = {https://cpp11.r-lib.org}, }"},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"cpp11","dir":"","previous_headings":"","what":"A C++11 Interface for R's C Interface","title":"A C++11 Interface for R's C Interface","text":"cpp11 helps interact R objects using C++ code. goals syntax similar excellent Rcpp package.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"using-cpp11-in-a-package","dir":"","previous_headings":"","what":"Using cpp11 in a package","title":"A C++11 Interface for R's C Interface","text":"add cpp11 existing package, put C++ files src/ directory add following DESCRIPTION file: decorate C++ functions want expose R [[cpp11::register]]. Note C++11 attribute, comment like used Rcpp. cpp11 header library hard dependencies use shared library, straightforward reliable use packages without fear compile-time run-time mismatches. Alternatively, can vendor current installed version cpp11 headers package cpp11::vendor_cpp11(). ensures headers remain unchanged explicitly update .","code":"LinkingTo: cpp11"},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"getting-started","dir":"","previous_headings":"","what":"Getting started","title":"A C++11 Interface for R's C Interface","text":"See vignette(“cpp11”) get started using cpp11 scripts, particularly new C++ programming.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"getting-help","dir":"","previous_headings":"","what":"Getting help","title":"A C++11 Interface for R's C Interface","text":"Posit Community best place ask help using cpp11 interfacing C++ R.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"motivations","dir":"","previous_headings":"","what":"Motivations","title":"A C++11 Interface for R's C Interface","text":"Rcpp widely successful project, however years number issues additional C++ features arisen. Adding features Rcpp require great deal work, cases impossible without severely breaking backwards compatibility. cpp11 ground rewrite C++ bindings R different design trade-offs features. Changes motivated cpp11 include: Enforcing copy--write semantics. Improving safety using R API C++ code. Supporting ALTREP objects. Using UTF-8 strings everywhere. Applying newer C++11 features. straightforward, simpler implementation. Faster compilation time lower memory requirements. completely header avoid ABI issues. Capable vendoring desired. robust protection using much efficient linked list data structure. Growing vectors efficiently. See vignette(“motivations”) full details motivations writing cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"conversion-from-rcpp","dir":"","previous_headings":"","what":"Conversion from Rcpp","title":"A C++11 Interface for R's C Interface","text":"See vignette(“converting”) already familiar Rcpp existing package uses Rcpp want convert use cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"learning-more","dir":"","previous_headings":"","what":"Learning More","title":"A C++11 Interface for R's C Interface","text":"Welding R C++ - Presentation SatRday Columbus (slides)","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"internals","dir":"","previous_headings":"","what":"Internals","title":"A C++11 Interface for R's C Interface","text":"See vignette(“internals”) details cpp11 implementation like contribute cpp11.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"A C++11 Interface for R's C Interface","text":"Please note cpp11 project released Contributor Code Conduct. contributing project, agree abide terms.","code":""},{"path":"https://cpp11.r-lib.org/dev/index.html","id":"thanks","dir":"","previous_headings":"","what":"Thanks","title":"A C++11 Interface for R's C Interface","text":"cpp11 exist without Rcpp. Thanks Rcpp authors, Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Douglas Bates John Chambers work writing maintaining Rcpp.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp11-package.html","id":null,"dir":"Reference","previous_headings":"","what":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","title":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","text":"Provides header , C++11 interface R's C interface. Compared approaches 'cpp11' strives safe long jumps C API well C++ exceptions, conform normal R function semantics supports interaction 'ALTREP' vectors.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/reference/cpp11-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"cpp11: A C++11 Interface for R's C Interface — cpp11-package","text":"Maintainer: Davis Vaughan davis@posit.co (ORCID) Authors: Jim Hester (ORCID) Romain François (ORCID) contributors: Benjamin Kietzman [contributor] Posit Software, PBC [copyright holder, funder]","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":null,"dir":"Reference","previous_headings":"","what":"Generates wrappers for registered C++ functions — cpp_register","title":"Generates wrappers for registered C++ functions — cpp_register","text":"Functions decorated [[cpp11::register]] files ending .cc, .cpp, .h .hpp wrapped generated code registered called R.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generates wrappers for registered C++ functions — cpp_register","text":"","code":"cpp_register( path = \".\", quiet = !is_interactive(), extension = c(\".cpp\", \".cc\") )"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generates wrappers for registered C++ functions — cpp_register","text":"path path package root directory quiet TRUE suppresses output function extension file extension use generated src/cpp11 file. .cpp default, .cc also supported.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generates wrappers for registered C++ functions — cpp_register","text":"paths generated R C++ source files (order).","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Generates wrappers for registered C++ functions — cpp_register","text":"Note registered functions exported package unless also add @export roxygen2 directive . order use cpp_register() cli, decor, desc, glue, tibble vctrs packages must also installed.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_register.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Generates wrappers for registered C++ functions — cpp_register","text":"","code":"# create a minimal package dir <- tempfile() dir.create(dir) writeLines(\"Package: testPkg\", file.path(dir, \"DESCRIPTION\")) writeLines(\"useDynLib(testPkg, .registration = TRUE)\", file.path(dir, \"NAMESPACE\")) # create a C++ file with a decorated function dir.create(file.path(dir, \"src\")) writeLines(\"[[cpp11::register]] int one() { return 1; }\", file.path(dir, \"src\", \"one.cpp\")) # register the functions in the package cpp_register(dir) # Files generated by registration file.exists(file.path(dir, \"R\", \"cpp11.R\")) #> [1] TRUE file.exists(file.path(dir, \"src\", \"cpp11.cpp\")) #> [1] TRUE # cleanup unlink(dir, recursive = TRUE)"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile C++ code — cpp_source","title":"Compile C++ code — cpp_source","text":"cpp_source() compiles loads single C++ file use R. cpp_function() compiles loads single function use R. cpp_eval() evaluates single C++ expression returns result.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile C++ code — cpp_source","text":"","code":"cpp_source( file, code = NULL, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\"), dir = tempfile() ) cpp_function( code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\") ) cpp_eval( code, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv(\"CXX_STD\", \"CXX11\") )"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile C++ code — cpp_source","text":"file file containing C++ code compile code non-null, C++ code compile env R environment R wrapping functions defined. clean TRUE, cleanup files sourcing quiet 'TRUE`, show compiler output cxx_std C++ standard use, CXX_STD make macro set value. default value queries CXX_STD environment variable, uses 'CXX11' unset. dir directory store generated source files. tempfile() used default. directory removed clean TRUE.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile C++ code — cpp_source","text":"cpp_source() [cpp_function()] results dyn.load() (invisibly). [cpp_eval()] results evaluated expression.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compile C++ code — cpp_source","text":"Within C++ code can use [[cpp11::linking_to(\"pkgxyz\")]] link external packages. equivalent putting packages LinkingTo field package DESCRIPTION.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_source.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compile C++ code — cpp_source","text":"","code":"cpp_source( code = '#include \"cpp11/integers.hpp\" [[cpp11::register]] int num_odd(cpp11::integers x) { int total = 0; for (int val : x) { if ((val % 2) == 1) { ++total; } } return total; } ') num_odd(as.integer(c(1:10, 15, 23))) #> [1] 7 if (interactive() && require(\"progress\")) { cpp_source( code = ' #include #include [[cpp11::linking_to(\"progress\")]] [[cpp11::register]] void show_progress() { RProgress::RProgress pb(\"Processing [:bar] ETA: :eta\"); pb.tick(0); for (int i = 0; i < 100; i++) { usleep(2.0 / 100 * 1000000); pb.tick(); } } ') show_progress() }"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":null,"dir":"Reference","previous_headings":"","what":"Vendor the cpp11 dependency — cpp_vendor","title":"Vendor the cpp11 dependency — cpp_vendor","text":"Vendoring act making copy 3rd party packages project using. often used go language community.","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Vendor the cpp11 dependency — cpp_vendor","text":"","code":"cpp_vendor(path = \".\")"},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Vendor the cpp11 dependency — cpp_vendor","text":"path path package root directory","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Vendor the cpp11 dependency — cpp_vendor","text":"file path vendored code (invisibly).","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Vendor the cpp11 dependency — cpp_vendor","text":"function vendors cpp11 package copying cpp11 headers inst/include folder package adding 'cpp11 version: XYZ' top files, XYZ version cpp11 currently installed machine. choose vendor headers remove LinkingTo: cpp11 DESCRIPTION. Note: vendoring places responsibility updating code . Bugfixes new features cpp11 available code run cpp_vendor() .","code":""},{"path":"https://cpp11.r-lib.org/dev/reference/cpp_vendor.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Vendor the cpp11 dependency — cpp_vendor","text":"","code":"# create a new directory dir <- tempfile() dir.create(dir) # vendor the cpp11 headers into the directory cpp_vendor(dir) list.files(file.path(dir, \"inst\", \"include\", \"cpp11\")) #> [1] \"R.hpp\" \"altrep.hpp\" \"as.hpp\" #> [4] \"attribute_proxy.hpp\" \"data_frame.hpp\" \"declarations.hpp\" #> [7] \"doubles.hpp\" \"environment.hpp\" \"external_pointer.hpp\" #> [10] \"function.hpp\" \"integers.hpp\" \"list.hpp\" #> [13] \"list_of.hpp\" \"logicals.hpp\" \"matrix.hpp\" #> [16] \"named_arg.hpp\" \"protect.hpp\" \"r_bool.hpp\" #> [19] \"r_string.hpp\" \"r_vector.hpp\" \"raws.hpp\" #> [22] \"sexp.hpp\" \"strings.hpp\" # cleanup unlink(dir, recursive = TRUE)"},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-development-version","dir":"Changelog","previous_headings":"","what":"cpp11 (development version)","title":"cpp11 (development version)","text":"cpp11::function now protects underlying function, maximum safety (#294). cpp11::writable::r_vector::proxy now implements copy assignment. Practically means x[] = y[] now works x y writable vectors (#300, #339). Implicit conversion sexp bool, size_t, double marked deprecated removed next version cpp11. 3 packages using notified sent PRs. recommended approach instead use cpp11::as_cpp, performs type length checking, making much safer use. New writable::data_frame constructor also takes number rows input. accounts edge case input list 0 columns ’d still like specify known number rows (#272). cpp11::writable::r_vector::iterator longer implicitly deletes copy assignment operator (#360). std::max_element() can now used writable vectors (#334). environment class longer uses non-API function Rf_findVarInFrame3() (#367). exists() method now uses new R_existsVarInFrame() function. SEXP conversion operator now uses new R_getVar() function. Note stricter Rf_findVarInFrame3() 3 ways. object must exist environment (.e. R_UnboundValue longer returned), object R_MissingArg, object promise, promise now evaluated. backported new strictness older versions R well. Fixed issue writable::matrix copy constructor underlying SEXP copied . now consistent behavior equivalent writable::r_vector copy constructor. Added missing implementation x.(\"name\") read vectors (#370). Constructors writable vectors initializer_list now check named_arg contains length 1 object correct type, throws either cpp11::type_error std::length_error case (#382). Repeated assignment cpp11::writable::strings vector either x[] = elt x.push_back(elt) now performant, tradeoff slightly less safety (long elt actually CHARSXP within bounds, chance failure, kind invariants placed vector types) (#378). Read r_vectors now move constructor move assignment operator (#365). Fixed issue writable vectors protected twice (#365). Removed usage following non-API functions: SETLENGTH() SET_TRUELENGTH() SET_GROWABLE_BIT() functions used part efficient growable vectors cpp11 offered, .e. happens hood use push_back(). removal non-API functions means cpp11 writable vectors pushed push_back() likely force 1 extra allocation conversion cpp11::writable::r_vector SEXP occurs (typically return result back R). affect performance push_back() , general growable vectors still quite efficient (#362). Fixed memory leak cpp11::writable::r_vector move assignment operator (#338). approach protection list managed cpp11 tweaked slightly. 0.4.6, changed approach creates one protection list per compilation unit, now believe ’ve found approach guaranteed C++ standard create one protection list per package, makes slightly sense still benefits reduced maintanence burden mentioned 0.4.6 news bullet (#364). side effect new approach preserved object exposed protect.hpp longer exists. don’t believe anyone using . also means longer see “unused variable” warnings preserved (#249). Dropped support gcc 4.8, mainly issue extremely old CentOS 7 systems used default compiler. June 2024, CentOS 7 past Vendor end support date therefore also scope Posit time (#359).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-047","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.7","title":"cpp11 0.4.7","text":"CRAN release: 2023-12-02 Internal changes requested CRAN fix invalid format string tokens (@paleolimbot, #345).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-046","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.6","title":"cpp11 0.4.6","text":"CRAN release: 2023-08-10 R >=3.5.0 now required use cpp11. line (even goes beyond) tidyverse standard supporting previous 5 minor releases R. also ensures R_UnwindProtect() available avoid C++ memory leaks (#332). cpp11::preserved.release_all() removed. intended support expert developers R <3.5.0 cpp11 used global protection list. Since cpp11 longer uses global protection list requires R >=3.5.0, longer needed. far can tell, package actively using (#332). cpp11 now creates one protection list per compilation unit, rather one global protection list shared across compilation units across packages. greatly reduces complexity managing protection list state make easier make changes protection list structure future without breaking packages compiled older versions cpp11 (#330). Nested calls cpp11::unwind_protect() longer supported encouraged. Previously, something done performance improvements, ultimately feature proven cause problems worth hard use safely. information, see new vignette(\"FAQ\") section titled “call cpp11::unwind_protect() manually?” (#327). features bug fixes cpp11 0.4.4 added back .","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-045","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.5","title":"cpp11 0.4.5","text":"CRAN release: 2023-07-20 2023-07-20, cpp11 temporarily rolled back 0.4.3 manually CRAN due bug 0.4.4 immediately fix due cpp11 maintainer vacation.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-044","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.4","title":"cpp11 0.4.4","text":"CRAN release: 2023-06-30 Davis Vaughan now maintainer. as_doubles() as_integers() now propagate missing values correctly (#265, #319). Fixed performance issue related nested unwind_protect() calls (#298). Minor performance improvements cpp11 protect code. (@kevinushey) cpp_register() gains argument extension= governing file extension src/cpp11 file. default ’s .cpp, .cc now supported well (#292, @MichaelChirico)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-043","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.3","title":"cpp11 0.4.3","text":"CRAN release: 2022-10-12 Modernized GitHub Actions workflows updated internal tests better align changes workflows latest version R (#279). cpp_source() errors non-existent file (#261). cpp_register() quiet default R non interactive (#289). updated test adapt changes R 4.2.1 (#290).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-042","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.2","title":"cpp11 0.4.2","text":"CRAN release: 2021-11-30 Romain François now maintainer.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-041","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.1","title":"cpp11 0.4.1","text":"CRAN release: 2021-11-03 Fix crash related unwind protect optimization (#244)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-040","dir":"Changelog","previous_headings":"","what":"cpp11 0.4.0","title":"cpp11 0.4.0","text":"CRAN release: 2021-09-22","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-features-0-4-0","dir":"Changelog","previous_headings":"","what":"New Features","title":"cpp11 0.4.0","text":"New opt-message formatting {fmt} C++ library cpp11::messages() cpp11::stop() cpp11::warning(). Set CPP11_USE_FMT macro use feature package. (@sbearrows, #169, #208) New as_double() as_integer() methods coerce integers doubles doubles integers doubles (@sbearrows, #46) cpp11::matrix iterators can now used either row-wise column-wise (default) depending user’s choice (@alyst, #229)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"improvements-and-fixes-0-4-0","dir":"Changelog","previous_headings":"","what":"Improvements and fixes","title":"cpp11 0.4.0","text":"Read-matrix accessors now marked const (#234) writable::r_vector default constructors now return 0 length vector converted SEXP (#166) Read-r_vector constructors now disallow implicit construction named arguments (#237) Read-r_vector.attr() methods now return const objects, compile time error try assign (#237) Fixed + += operators r_vector::[const_]iterator conform iterators concept: += updates iterator, + returns updated copy, keeping original unchanged (@alyst, #231) Remove undefined behavior constructing global cpp11::sexps (#224) Removed redundant .Call calls cpp11.cpp file (@sbearrows, #170) Error messages now output original file name rather temporary file name (@sbearrows, #194) cpp_register() now includes attribute_visible init function, packages compiled C_VISIBILITY find init function. Fixed bug running cpp_source() file (@sbearrows, #202) Allow cpp11 decorators form cpp11::linking_to (@sbearrows, #193) Removed internal instances cpp11::stop() replaced C++ exceptions (@sbearrows, #203) Names named lists now resized along list elements (@sbearrows, #206)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-031","dir":"Changelog","previous_headings":"","what":"cpp11 0.3.1","title":"cpp11 0.3.1","text":"CRAN release: 2021-06-25 Fix stringop-truncation warning generated wrapping code.","code":""},{"path":[]},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-functions-and-features-0-3-0","dir":"Changelog","previous_headings":"","what":"New functions and features","title":"cpp11 0.3.0","text":"New x.empty() method check vector empty (@sbearrows, #182) New x.named() method check vector named (@sbearrows, #186) New na() free function return NA sentinels R objects (@sbearrows, #179)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"major-fixes-0-3-0","dir":"Changelog","previous_headings":"","what":"Major fixes","title":"cpp11 0.3.0","text":"Memory longer inadvertently leaks move constructing vectors (#173)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"minor-improvements-and-fixes-0-3-0","dir":"Changelog","previous_headings":"","what":"Minor improvements and fixes","title":"cpp11 0.3.0","text":"Incorrectly formatted cpp11 decorators now output informative error message (@sbearrows, #127) Generated registration code now uses C collation avoid spurious changes tools::package_native_routine_registration_skeleton() (@sbearrows, #171) Makevars files include filenames now handle spaces paths properly (@klmr, #160)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-027","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.7","title":"cpp11 0.2.7","text":"CRAN release: 2021-03-29 Fix transient memory leak functions return values cpp11::unwind_protect() cpp11::safe (#154) cpp_source() now gets argument dir allow customized temporary directory store generated source files. makes easier debug C++ source files non-package project via source mapping. (@renkun-ken, #156)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-026","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.6","title":"cpp11 0.2.6","text":"CRAN release: 2021-01-29 cpp_register() now uses symbols exclusively .Call() interface. allows robust interactive use pkgload package.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-025","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.5","title":"cpp11 0.2.5","text":"CRAN release: 2021-01-12 cpp_source() gains cxx_std argument control C++ standard used. allows use code C++14 later standards cpp_source(). (#100) cpp11 knitr engine now allows set cxx_std chunk option control C++ standard used. cpp_source() now much informative error messages compilation fails (#125, #139) cpp_source() now uses unique name DLL, works run multiple times source file Windows (#143) writable::list_of now supports modification vectors intended (#131). Errors running tools::package_native_routine_registration_skeleton() longer swallowed (#134) cpp_source() can now accept source file called cpp11.cpp (#133) named_arg now explicitly protect values, avoiding protection issues using large inputs. tidyverse/readr#1145 r_string(std::string) now uses Rf_mkCharLenCE() instead Rf_mkChar(), avoids performance cost checking string length. Writable vector classes now properly set lengths intended copied read class (#128).","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-024","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.4","title":"cpp11 0.2.4","text":"CRAN release: 2020-11-05 preserve list now robust invalid values, XPtr address non-xptr’s stored option. fixes errors reloading packages using cpp11 RStudio’s session restores. preserve list now robust invalid values, null pointers XPtr serialized. situation occurs ‘Install Restart’ RStudio (#121)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-023","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.3","title":"cpp11 0.2.3","text":"CRAN release: 2020-10-14 r_vector::const_iterator::operator* now const method (#113, @bkietz, @xhochy) preserve list now stored XPtr, rather environment, avoid issues serializing preserve environment, happens implicitly RStudio RStudio Cloud saves options resuming session (#116)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-022","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.2","title":"cpp11 0.2.2","text":"CRAN release: 2020-10-01 r_bool added adapter bool Rboolean values (#57, @bkietz) data_frame() objects now number rows correctly set real length, reserved length (#91) Fixed potential memory leak cpp11::writable classes.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-021","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.1","title":"cpp11 0.2.1","text":"CRAN release: 2020-08-11 Ensures backwards compatibility code generation cpp11 0.1.0 (#88) push_back() now works consistently named arguments (#86)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-020","dir":"Changelog","previous_headings":"","what":"cpp11 0.2.0","title":"cpp11 0.2.0","text":"CRAN release: 2020-08-10","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"new-features-0-2-0","dir":"Changelog","previous_headings":"","what":"New features","title":"cpp11 0.2.0","text":"cpp11 now able compile gcc 4.8.5 (#69, @bkietz) cpp_source(), cpp_function() cpp_eval() now support [[cpp11::linking_to()]] syntax link third party packages C++ headers. (#48)","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"minor-improvements-and-fixes-0-2-0","dir":"Changelog","previous_headings":"","what":"Minor improvements and fixes","title":"cpp11 0.2.0","text":"as_cpp() now works enumeration types (#52, @bkietz) as_cpp() as_cpp() now implicitly coerce 3 types single NA values (#53). list::const_iterator::operator*() added iterators used list objects (#60, @romainfrancois) safe[] can now work functions return type (#70, @bkietz) END_CPP macro now includes catch(...) block catch C++ exceptions inherit std::exception (#47). Improve consistency inserting NA values r_string objects (#45) Added NEWS.md file track changes package.","code":""},{"path":"https://cpp11.r-lib.org/dev/news/index.html","id":"cpp11-010","dir":"Changelog","previous_headings":"","what":"cpp11 0.1.0","title":"cpp11 0.1.0","text":"CRAN release: 2020-07-10 Initial release","code":""}]