Title: A 'C++20' API for R
Version: 0.1.0
Maintainer: Nick Christofides <nick.christofides.r@gmail.com>
Description: A header-only 'C++20' API for manipulating R data structures from 'C++'. Provides 'C++20' concepts specific to R, custom scalar and vector classes with built-in NA handling, automatic object protection, 'SIMD' (single-instruction-multiple-data), parallelisation, and a streamlined system for registering 'C++' functions, including templates, to R. Full API reference and documentation are available at https://nicchr.github.io/cppally/.
License: MIT + file LICENSE
URL: https://nicchr.github.io/cppally/
BugReports: https://github.com/NicChr/cppally/issues/
Depends: R (≥ 4.5.0)
Suggests: bench, bit64, brio, callr, cli, cpp11, decor, desc, devtools, fs, glue, knitr, pkgload, purrr, readr, rmarkdown, roxygen2, rstudioapi, stringr, testthat (≥ 3.0.0), usethis, vctrs, withr
VignetteBuilder: knitr
Config/Needs/cppally/cpp_register: brio, cli, decor, desc, glue, purrr, readr, stringr, vctrs, withr
Config/testthat/edition: 3
Encoding: UTF-8
RoxygenNote: 7.3.3
SystemRequirements: C++20
NeedsCompilation: no
Packaged: 2026-04-25 19:09:28 UTC; Nmc5
Author: Nick Christofides ORCID iD [aut, cre, cph], Martin Leitner-Ankerl [cph] (Author of bundled ankerl::unordered_dense library), Malte Skarupke [cph] (Author of bundled ska_sort library), Posit Software, PBC [cph] (SEXP protection mechanism in r_protect.h inspired by cpp11)
Repository: CRAN
Date/Publication: 2026-04-28 19:20:20 UTC

cppally: A 'C++20' API for R

Description

A header-only 'C++20' API for manipulating R data structures from 'C++'. Provides 'C++20' concepts specific to R, custom scalar and vector classes with built-in NA handling, automatic object protection, 'SIMD' (single-instruction-multiple-data), parallelisation, and a streamlined system for registering 'C++' functions, including templates, to R. Full API reference and documentation are available at https://nicchr.github.io/cppally/.

Author(s)

Maintainer: Nick Christofides nick.christofides.r@gmail.com (ORCID) [copyright holder]

Other contributors:

See Also

Useful links:


Generates wrappers for registered C++ functions

Description

Register C++ functions to be callable from R. C++ functions decorated with ⁠[[cppally::register]]⁠ will be registered (including template functions).

Usage

cpp_register(
  path = ".",
  quiet = !is_interactive(),
  extension = c(".cpp", ".cc")
)

Arguments

path

Path to package root directory.

quiet

If TRUE suppresses output from this function.

extension

The file extension to use for the generated src/cppally file. Options are either '.cpp' (the default) or '.cc'.

Value

The paths to the generated R and C++ source files.


Compile C++20 code

Description

cpp11-style helpers to compile cppally code outside of a cppally-linked package context.

cpp_source() compiles and loads a single C++ file for use in R, either from an expression or a cpp file. This may include multiple C++ functions.

cpp_eval() evaluates a single C++ expression and returns the result. For example cpp_eval('get_threads()') will run the C++ function cppally::get_threads() and return the number of OMP threads currently set for use. For expressions no return result, the call is evaluated and returns NULL invisibly.

Usage

cpp_source(
  file,
  code = NULL,
  env = parent.frame(),
  clean = TRUE,
  quiet = TRUE,
  debug = FALSE,
  preserve_altrep = FALSE,
  cxx_std = Sys.getenv("CXX_STD", "CXX20"),
  dir = tempfile()
)

cpp_eval(
  code,
  env = curr_env(),
  clean = TRUE,
  quiet = TRUE,
  debug = FALSE,
  preserve_altrep = FALSE,
  simplify = TRUE,
  cxx_std = Sys.getenv("CXX_STD", "CXX20")
)

Arguments

file

C++ file.

code

For cpp_source() - If file is NULL then a string of C++ code to compile. This can include the contents of a cpp file which can contain multiple ⁠[[cppally::register]]⁠ tagged functions. For cpp_eval - This can be a character vector of single-line expressions.

env

Environment where R functions should be defined.

clean

Should files be cleaned up after sourcing? Default is TRUE.

quiet

Should compiler output be suppressed? Default is TRUE.

debug

Should C++ code be compiled in a debug build? Default is FALSE.

preserve_altrep

Should ALTREP vectors be preserved by avoiding materialisation where possible? Default is FALSE.

cxx_std

C++ standard to use. Should be >= C++20.

dir

Directory to store the source files. The default is a temporary directory via tempfile() which is removed when clean = TRUE.

simplify

Applies to cpp_eval. A list of results is returned unless length(code) == 1 and simplify = TRUE.

Value

cpp_source() invisibly compiles the C++ code and registers the ⁠[[cppally::register]]⁠ tagged functions to R.
cpp_eval() returns the results of the evaluated C++ expressions.

Examples


library(cppally)
library(bit64)

cpp_eval('print("hello world!")')

# Default values of all cppally scalars
cpp_eval(c(
  'r_lgl()',
  'r_int()',
  'r_dbl()',
  'r_int64()',
  'r_str()',
  'r_raw()',
  'r_cplx()',
  'r_date()',
  'r_psxct()'
))

cpp_source(code = '
  #include <cppally.hpp>
  using namespace cppally;

  [[cppally::register]]
  r_dbl add(r_dbl x, r_dbl y){
    return x + y;
  }
', debug = TRUE)
add(1, 2)
add(2, NA)

### ALTREP ###

# cppally also supports lazy ALTREP materialisation as an opt-in feature.
# To opt-in, set `preserve_altrep = TRUE`

cpp_source(
  code = '
  #include <cppally.hpp>
  using namespace cppally;

  [[cppally::register]]
  r_int last_altrep_unaware(r_vec<r_int> x){
    r_int out;
    r_size_t n = x.length();

    if (n > 0){
      out = x.get(n - 1);
    }
    return out;
  }
', debug = TRUE
)

cpp_source(
  code = '
  #include <cppally.hpp>
  using namespace cppally;

  [[cppally::register]]
  r_int last_altrep_aware(r_vec<r_int> x){
    r_int out;
    r_size_t n = x.length();

    if (n > 0){
      out = x.get(n - 1);
    }
    return out;
  }
', debug = TRUE,
  preserve_altrep = TRUE
)

library(bench)
mark(last_altrep_aware(1:10^5)) # No materialisation
mark(last_altrep_unaware(1:10^5)) # Materialises full vector




A wrapper around devtools::document() to support cppally package development

Description

A wrapper around devtools::document() to support cppally package development

Usage

document(pkg = ".", roclets = NULL, quiet = FALSE)

Arguments

pkg

See ?devtools::document

roclets

See ?devtools::document

quiet

See ?devtools::document

Value

Invisibly updates roxygen documentation, compiles C++ code and exports cppally tagged functions to R.


A wrapper around devtools::load_all() specifically for cppally

Description

A wrapper around devtools::load_all() specifically for cppally

Usage

load_all(path = ".", debug = FALSE, ...)

Arguments

path

Path to package.

debug

Should package be built without optimisations? Default is FALSE which builds with optimisations.

...

Further arguments passed on to pkgload::load_all()

Value

Invisibly registers cppally tagged functions and compiles C++ code.


Helper for developing packages with cppally

Description

usethis style helper to add the necessary setup to a new package to help users get started with writing C++ code.

Usage

use_cppally()

Value

Invisibly sets up the necessary conditions for developing a package with cppally.


Adds the CPPALLY_PRESERVE_ALTREP flag to Makevars

Description

Adds a flag to Makevars which enables lazy materialisation of ALTREP vectors.

Usage

use_preserve_altrep_flag()

Value

Invisibly adds the CPPALLY_PRESERVE_ALTREP flag to Makevars.