Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from Rcpp to cpp11 #966

merged 15 commits into from
Apr 12, 2021


Copy link

FYI @hadley

This is a fairly straightforward translation from Rcpp to cpp11. The main thing to note is that cpp11 is less lenient with automatic conversions, so there are cpp_*() wrapper functions that enforce certain atomic types before passing on to C++.

@vspinu if you have time to review this, that would be great! Each commit should be very self-contained.

f793787 this commit also fixes a small bug in get_current_tz(). If you set Sys.setenv(TZ = "") and then call C_local_tz(), it would error since tz_from_R_tzone() expects a tzone attribute, not a POSIXlt object.

Also removes default arguments from exported C++ signatures, since cpp11 doesn't support them.
Currently it assumes the result of `as_posixlt()` is a `tzone` attribute, when really we need to extract the `tzone` out with `tz_from_tzone_attr()`
Additionally add a `cpp_update_dt()` wrapper, since cpp11 is less lenient about automatic type conversions
Copy link

@hadley hadley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Copy link

@vspinu vspinu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guys, this is amazing. I somehow managed to miss the cpp11 initiative. My heart is singing. Thanks for all the work!

@@ -245,7 +259,8 @@ Rcpp::newDatetimeVector C_update_dt(const Rcpp::NumericVector& dt,
load_tz_or_fail(tzto, tzone2, "CCTZ: Unrecognized tzone: \"%s\"");

Rcpp::NumericVector out(N);
cpp11::writable::doubles out(N);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you use writable on output vectors? Can you even return cpp11::doubles back to R? Is there a performance penalty in writable constructor?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you even return cpp11::doubles back to R

I'm fairly certain that you can, but you can't modify them at the C++ level using the cpp11 API

Is there a performance penalty in writable constructor?

No, AFAIK it just exposes the ability write to elements with syntax like out[i] = value. The constructor itself essentially just eventually calls this reserve method that calls Rf_allocVector() and then shoves the allocated memory in a doubly linked list object that can preserve it

A few things you may find interesting

The process I went through to convert lubridate over to cpp11

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I got it.

@vspinu vspinu merged commit 5f7176a into tidyverse:master Apr 12, 2021
@DavisVaughan DavisVaughan deleted the feature/cpp11 branch September 21, 2021 18:52
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jun 5, 2023
Version 1.9.2


* [#1104](tidyverse/lubridate#1104) Fix
  incorrect parsing of months when %a format is present.


* Adapt to internal name changes in R-devel

Version 1.9.1


* `as_datetime()` accepts multiple formats in format argument, just like `as_date()` does.


* [#1091](tidyverse/lubridate#1091) Fix
  formatting of numeric inputs to parse_date_time.

* [#1092](tidyverse/lubridate#1092) Fix
  regression in `ymd_hm` on locales where `p` format is not defined.

* [#1097](tidyverse/lubridate#1097) Fix
  `as_date("character")` to work correctly with formats that include
  extra characters.

* [#1098](tidyverse/lubridate#1098) Roll
  over the month boundary in `make_dateime()` when units exceed their
  maximal values.

* [#1090](tidyverse/lubridate#1090)
  timechange has been moved from Depends to Imports.

Version 1.9.0


* `roll` argument to updating and time-zone manipulation functions is
  deprecated in favor of a new `roll_dst` parameter.

* [#1042](tidyverse/lubridate#1042)
  `as_date` with character inputs accepts multiple formats in `format`
  argument. When `format` is supplied, the input string is parsed with
  `parse_date_time` instead of the old `strptime`.

* [#1055](tidyverse/lubridate#1055)
  Implement `as.integer` method for Duration, Period and Interval

* [#1061](tidyverse/lubridate#1061) Make
  `year<-`, `month<-` etc. accessors truly generic. In order to make
  them work with arbitrary class XYZ, it's enough to define a
  `reclass_date.XYZ` method.

* [#1061](tidyverse/lubridate#1061) Add
  support for `year<-`, `month<-` etc. accessors for `data.table`'s
  IDate and ITime objects.

* [#1017](tidyverse/lubridate#1017)
  `week_start` argument in all lubridate functions now accepts full
  and abbreviated names of the days of the week.

* The assignment value `wday<-` can be a string either in English or
  as provided by the current locale.

* Date rounding functions accept a date-time `unit` argument for
  rounding to a vector of date-times.

* [#1005](tidyverse/lubridate#1005)
  `as.duration` now allows for full roundtrip `duration ->
  as.character -> as.duration`

* [#911](tidyverse/lubridate#911) C parsers
  treat multiple spaces as one (just like strptime does)

* `stamp` gained new argument `exact=FALSE` to indicate whether
  `orders` argument is an exact strptime formats string or not.

* [#1001](tidyverse/lubridate#1001) Add
  `%within` method with signature (Interval, list), which was
  documented but not implemented.

* [#941](tidyverse/lubridate#941)
  `format_ISO8601()` gained a new option `usetz="Z"` to format time
  zones with a "Z" and convert the time to the UTC time zone.

* [#931](tidyverse/lubridate#931) Usage of
  `Period` objects in rounding functions is explicitly documented.


* [#1036](tidyverse/lubridate#1036)
  `%within%` now correctly works with flipped intervals

* [#1085](tidyverse/lubridate#1085)
  `as_datetime()` now preserves the time zone of the POSIXt input.

* [#1072](tidyverse/lubridate#1072) Names
  are now handled correctly when combining multiple Period or Interval

* [#1003](tidyverse/lubridate#1003)
  Correctly handle r and R formats in locales which have no p format

* [#1074](tidyverse/lubridate#1074) Fix
  concatination of named Period, Interval and Duration vectors.

* [#1044](tidyverse/lubridate#1044) POSIXlt
  results returned by `fast_strptime()` and `parse_date_time2()` now
  have a recycled `isdst` field.

* [#1069](tidyverse/lubridate#1069) Internal
  code handling the addition of period months and years no longer
  generates partially recycled POSIXlt objects.

* Fix rounding of POSIXlt objects

* [#1007](tidyverse/lubridate#1007) Internal
  lubridate formats are no longer propagated to stamp formater.

* `train` argument in `parse_date_time` now takes effect. It was
  previously ignored.

* [#1004](tidyverse/lubridate#1004) Fix
  `c.POSIXct` and `c.Date` on empty single POSIXct and Date vectors.

* [#1013](tidyverse/lubridate#1013) Fix
  c(`POSIXct`,`POSIXlt`) heterogeneous concatenation.

* [#1002](tidyverse/lubridate#1002) Parsing
  only with format `j` now works on numeric inputs.

* `stamp()` now correctly errors when no formats could be guessed.

* Updating a date with timezone (e.g. `tzs = "UTC"`) now returns a POSIXct.


* `lubridate` is now relying on `timechange` package for update and
  time-zone computation. Google's CCTZ code is no longer part of the

* `lubridate`'s updating logic is now built on top of `timechange`

* Change implementation of `c.Period`, `c.Duration` and `c.Interval`
  from S4 to S3.

Version 1.8.0


* [#960](tidyverse/lubridate#960)
  `c.POSIXct` and `c.Date` can deal with heterogeneous object types
  (e.g `c(date, datetime)` works as expected)


* [#994](tidyverse/lubridate#994)
  Subtracting two duration or two period objects no longer results in
  an ambiguous dispatch note.

* `c.Date` and `c.POSIXct` correctly deal with empty vectors.

* `as_datetime(date, tz=XYZ)` returns the date-time object with HMS
  set to 00:00:00 in the corresponding `tz`


* [#966](tidyverse/lubridate#966) Lubridate is
  now built with cpp11 (contribution of @DavisVaughan)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

Successfully merging this pull request may close these issues.

None yet

3 participants