Changelog
Source:NEWS.md
cppally (development version)
Data frames
r_dfis now fully integrated into cppallyNew variadic function
make_df()to create in-line data framesVarious
r_dfmembers have been added to allow easier data frame manipulation
Breaking changes
r_sexp.length()has been deprecated, in favour of the free functionlength()length(r_df)now returns the number of rows instead of the number of cols, marking a shift in how cppally treats data frames. They are now seen as row-wise vectorsSetting attributes on plain
SEXPis now unsupported, e.g. viacppally::attr::set_attr(). Use cppally types such asr_vector,r_factors,r_dfand in some casesr_sexpfor attribute manipulation.visit_vector,visit_sexpandview_sexphave been deprecated in favour of the more flexible constrainedr_sexpvisitors:r_sexp_visit,r_sexp_viewandr_sexp_mutate. These allow concepts and custom constraints to be applied directly on the lambda’s template parameter, e.g.r_sexp_visit(x, [&]<RVector T>(T vec){})— herexis dispatched as its concrete vector type and aborts at runtime if the underlying type isn’t anRVector.r_sexp_viewis the non-owning sibling: the wrapper handed to the lambda is a view (no extra protect), so it must not outlivex.r_sexp_mutateis for in-place mutation: it movesxinto the typed wrapper (making it the sole owner), callsf, then writes the result back.r_factorselements are now treated asr_strin member functions likeget()andset()r_sexp_visit()now visitr_nullasr_vec<r_sexp>(r_null), essentially treatingNULLas an empty list but without changing the underlying data
For example, in the below pseudo-code, when x is r_null of type r_sexp, r_sexp_visit() will disambiguate it as r_vec<r_sexp>(r_null), preserving its data as R’s NULL but assigning its type as r_vec<r_sexp> (list).
This preservation behaviour is not new, in fact all r_vec<T> vectors preserve r_null by design, allowing for efficient and easier attribute manipulation with vectors that may or may not be r_null. What is new is that previously r_null was not a visitable r_sexp object and now it is.
std::vector
- Partial support for
std::vectorcoercion. The followingstd::vectorcoercion directions are supported:-
std::vector->std::vector -
std::vector->cppally::r_vec -
cppally::r_vec->std::vector
-
Any coercion between std::vector and cppally::r_vec is possible so long as the element coercions are supported by cppally::as
Improvements and New Features
New alias of
r_vec,r_vectorFor named vectors, lookup by name has been dramatically improved in C++ by introducing a hashing approach. On second lookup, a hash map of names is created and cached, making subsequent lookups much faster. This also applies to factor levels.
cppally now supports copy-on-modify as an opt-in feature. This feature prevents accidentally overwriting data between shared objects, just like R. To opt-in, run
cppally::use_copy_on_modify()or set thecopy_on_modifytoTRUEincpp_source(). The major downside of this feature is significantly slower element setting as every set must verify the object is not referenced by another object. This check is single-threaded and thus nearly all parallel cppally code is disabled as a safety precaution. If using copy-on-modify, it is recommended to avoid writing cppally registered R functions that rely on in-place modification.Named-vector subsetting is now supported
New C++ functions
combine()andflatten().combine()is a variadic function that allows for combining multiple vectors into one, similar tobase::c()but always casts vectors to the common type among them.flatten()allows one to flatten a list of vectors into one vector of a specified type. Similar tounlist(recursive = FALSE)but it differs in that only the return type must be specified, e.g.flatten<r_vector<r_int>>(make_vec<r_sexp>(1, 2, 3))Many functions that were originally
r_vec-only members are now free functions that also work onr_sexpas well asRCompositetypes, allowing for easier manipulation of lists.All C++ reference qualifiers (T&, T&&, const T&) are now supported for registered functions, including templated ones.