Skip to content

Bug cpp11 decorators #197

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

Merged
merged 12 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# cpp11 (development version)
* Allow cpp11 decorators of the form `cpp11::linking_to` (@sbearrows, #193)

# cpp11 0.3.1

Expand Down
5 changes: 3 additions & 2 deletions R/register.R
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ get_cpp_register_needs <- function() {

check_valid_attributes <- function(decorations) {

bad_decor <- !decorations$decoration %in% c("cpp11::register", "cpp11::init")
bad_decor <- startsWith(decorations$decoration, "cpp11::") &
(!decorations$decoration %in% c("cpp11::register", "cpp11::init", "cpp11::linking_to"))

if(any(bad_decor)) {
lines <- decorations$line[bad_decor]
Expand All @@ -288,7 +289,7 @@ check_valid_attributes <- function(decorations) {
bad_lines <- glue::glue_collapse(glue::glue("- Invalid attribute `{names}` on
line {lines} in file '{file}'."), "\n")

msg <- glue::glue("cpp11 attributes must be either `cpp11::register` or `cpp11::init`:
msg <- glue::glue("cpp11 attributes must be one of `cpp11::register`, `cpp11::init` or `cpp11::linking_to`:
{bad_lines}
")
stop(msg, call. = FALSE)
Expand Down
6 changes: 3 additions & 3 deletions R/source.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#' [dyn.load()] (invisibly). For `[cpp_eval()]` the results of the evaluated
#' expression.
#' @examples
#' \dontrun{
#'
#' cpp_source(
#' code = '#include "cpp11/integers.hpp"
#'
Expand Down Expand Up @@ -51,7 +51,7 @@
#'
#' [[cpp11::register]] void
#' show_progress() {
#' RProgress::RProgress pb("Downloading [:bar] ETA: :eta");
#' RProgress::RProgress pb("Processing [:bar] ETA: :eta");
#'
#' pb.tick(0);
#' for (int i = 0; i < 100; i++) {
Expand All @@ -63,7 +63,7 @@
#'
#' show_progress()
#' }
#' }
#'
#' @export
cpp_source <- function(file, code = NULL, env = parent.frame(), clean = TRUE, quiet = TRUE, cxx_std = Sys.getenv("CXX_STD", "CXX11"), dir = tempfile()) {
stop_unless_installed(c("brio", "callr", "cli", "decor", "desc", "glue", "tibble", "vctrs"))
Expand Down
1 change: 1 addition & 0 deletions man/cpp11-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tests/testthat/linking_to_incorrect_registers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[[cpp11::link_to("progress")]]

[[cpp11::register]] void
show_progress() {
RProgress::RProgress pb("Processing [:bar] ETA: :eta");

pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep(2.0 / 100 * 1000000);
pb.tick();
}
}
12 changes: 12 additions & 0 deletions tests/testthat/linking_to_registers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[[cpp11::linking_to("progress")]]

[[cpp11::register]] void
show_progress() {
RProgress::RProgress pb("Processing [:bar] ETA: :eta");

pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep(2.0 / 100 * 1000000);
pb.tick();
}
}
6 changes: 3 additions & 3 deletions tests/testthat/multiple_incorrect.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[cpp11:register]] int foo() { return 1; }
[[cpp11::registe]] int foo() { return 1; }

[[cpp11:register]] double bar(bool run) { return 1.0; }
[[cpp11::register]] double bar(bool run) { return 1.0; }

[[cpp11::register]] bool baz(bool run, int value = 0) { return true; }
[[cpp11::reg]] bool baz(bool run, int value = 0) { return true; }
2 changes: 1 addition & 1 deletion tests/testthat/single_incorrect.cpp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[[cpp11:register]] int foo() { return 1; }
[[cpp11::registe]] int foo() { return 1; }
14 changes: 14 additions & 0 deletions tests/testthat/test-register.R
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,13 @@ test_that("check_valid_attributes does not return an error if all registers are
file.copy(test_path("multiple.cpp"), file.path(p, "src", "multiple.cpp"))

expect_error_free(cpp_register(p))

pkg <- local_package()
p <- pkg_path(pkg)
dir.create(file.path(p, "src"))
file.copy(test_path("linking_to_registers.cpp"), file.path(p, "src", "linking_to_registers.cpp"))

expect_error_free(cpp_register(p))
})


Expand All @@ -735,4 +742,11 @@ test_that("check_valid_attributes returns an error if one or more registers is i
file.copy(test_path("multiple_incorrect.cpp"), file.path(p, "src", "multiple_incorrect.cpp"))

expect_error(cpp_register(p))

pkg <- local_package()
p <- pkg_path(pkg)
dir.create(file.path(p, "src"))
file.copy(test_path("linking_to_incorrect_registers.cpp"), file.path(p, "src", "linking_to_incorrect_registers.cpp"))

expect_error(cpp_register(p))
})
51 changes: 48 additions & 3 deletions tests/testthat/test-source.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,31 @@ test_that("check_valid_attributes does not return an error if all registers are
x.push_back({"foo"_nm = 1});
return x;
}'))
expect_error_free(
cpp11::cpp_source(
code = '#include <cpp11/R.hpp>
#include <RProgress.h>

[[cpp11::linking_to("progress")]]

[[cpp11::register]] void show_progress() {
RProgress::RProgress pb("Processing [:bar] ETA: :eta");

pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep(2.0 / 100 * 1000000);
pb.tick();
}
}
')
)
})

test_that("check_valid_attributes returns an error if one or more registers is incorrect", {
expect_error(
cpp11::cpp_source(code = '#include <cpp11.hpp>
using namespace cpp11::literals;
[[cpp11:register]]
[[cpp11::reg]]
cpp11::list fn() {
cpp11::writable::list x;
x.push_back({"foo"_nm = 1});
Expand All @@ -140,7 +158,17 @@ test_that("check_valid_attributes returns an error if one or more registers is i
expect_error(
cpp11::cpp_source(code = '#include <cpp11.hpp>
using namespace cpp11::literals;
[[cpp11:register]]
[[cpp11::reg]]
cpp11::list fn() {
cpp11::writable::list x;
x.push_back({"foo"_nm = 1});
return x;
}'))

expect_error(
cpp11::cpp_source(code = '#include <cpp11.hpp>
using namespace cpp11::literals;
[[cpp11::reg]]
cpp11::list fn() {
cpp11::writable::list x;
x.push_back({"foo"_nm = 1});
Expand All @@ -152,4 +180,21 @@ test_that("check_valid_attributes returns an error if one or more registers is i
x.push_back({"foo"_nm = 1});
return x;
}'))
})

expect_error(
cpp11::cpp_source(
code = '
#include <cpp11/R.hpp>
#include <RProgress.h>
[[cpp11::link_to("progress")]]
[[cpp11::register]] void show_progress() {
RProgress::RProgress pb("Processing [:bar] ETA: :eta");
pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep(2.0 / 100 * 1000000);
pb.tick();
}
}
')
)
})