Changes in version 0.1.0.9000 Data frames - r_df is now fully integrated into cppally - New variadic function make_df() to create in-line data frames - Various r_df members have been added to allow easier data frame manipulation Breaking changes - r_sexp.length() has been deprecated, in favour of the free function length() - 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 vectors - Setting attributes on plain SEXP is now unsupported, e.g. via cppally::attr::set_attr(). Use cppally types such as r_vector, r_factors, r_df and in some cases r_sexp for attribute manipulation. - visit_vector, visit_sexp and view_sexp have been deprecated in favour of the more flexible constrained r_sexp visitors: r_sexp_visit, r_sexp_view and r_sexp_mutate. These allow concepts and custom constraints to be applied directly on the lambda's template parameter, e.g. r_sexp_visit(x, [&](T vec){}) — here x is dispatched as its concrete vector type and aborts at runtime if the underlying type isn't an RVector. r_sexp_view is the non-owning sibling: the wrapper handed to the lambda is a view (no extra protect), so it must not outlive x. r_sexp_mutate is for in-place mutation: it moves x into the typed wrapper (making it the sole owner), calls f, then writes the result back. - r_factors elements are now treated as r_str in member functions like get() and set() - r_sexp_visit() now visit r_null as r_vec(r_null), essentially treating NULL as 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_null), preserving its data as R's NULL but assigning its type as r_vec (list). r_sexp_visit(x, [&](const T& vec) -> bool { return vec.is_null(); }); This preservation behaviour is not new, in fact all r_vec 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::vector coercion. The following std::vector coercion 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_vector - For 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 the copy_on_modify to TRUE in cpp_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() and flatten(). combine() is a variadic function that allows for combining multiple vectors into one, similar to base::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 to unlist(recursive = FALSE) but it differs in that only the return type must be specified, e.g. flatten>(make_vec(1, 2, 3)) - Many functions that were originally r_vec-only members are now free functions that also work on r_sexp as well as RComposite types, allowing for easier manipulation of lists. - All C++ reference qualifiers (T&, T&&, const T&) are now supported for registered functions, including templated ones. Bug fixes - When registering C++ functions, cppally.hpp is now included in the generated C++ code. Not including it caused issues when trying to compile functions that constructed factors Changes in version 0.1.0 (2026-04-28) - Initial CRAN submission.