vctrs
vctrs copied to clipboard
POC: Using C++ in C projects
This is an exploration of how we could use C++ in C projects when templates, overloading, or parallel programming are required.
To prove the concept, the macro-templated loops of equal.c for integers and logicals have been reimplemented with C++ templates. I don't think we should pursue a C++ approach for equal.c though, the C macros and functions are not harder to understand than the templates in this case, and the C++ templates degrade performance with GCC (which apparently has troubles with inlining in some cases).
The purpose of the PR is to draft an infrastructure for mixing C and C++. In this approach, the C++ side never calls the R API.
-
cpp-rlang.h
includes some basic definitions and traits useful for genericity. Style-wise, it favours the style used in rlang, vctrs, and other packages written by Davis. It only needs very few type definitions though, mostly the type enum which is used for genericity.C++ files that include this header should work with bare C pointers and sizes. They should never call the R API to avoid longjumping over the C++ stack. However Rinternals.h is included because we need access to global variables like
NA_LOGICAL
. Usage of unsafe API functions is discouraged by undefining things likeSEXP
andRf_allocVector()
. -
cpp-utils.h
contains helpers specific to each packages, most importantly the error helpers. It defines aRETHROW()
macro to expand acatch ()
block that rethrows C++ exceptions as C longump errors. -
The C and C++ sides are bridged with an
extern "C"
function that wraps the C++ implementation withtry { } RETHROW()
. This function only takes C arrays, sizes, and other plain old data structures. This PR includesequal_fill()
as an example of bridge function.
Some infrastructure (rethrowing) is now in the rlang lib:
- https://github.com/r-lib/rlang/blob/master/src/rlang/rlang.hpp
- https://github.com/r-lib/rlang/blob/master/src/rlang/cpp/vec.cpp