From 64f849dfbc663da0e66eddeb61a499f3fb7b5002 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Fri, 11 Jun 2021 13:25:09 -0600 Subject: [PATCH 01/11] first attempt at adding na struct --- inst/include/cpp11/nas.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 inst/include/cpp11/nas.hpp diff --git a/inst/include/cpp11/nas.hpp b/inst/include/cpp11/nas.hpp new file mode 100644 index 00000000..18ee4e64 --- /dev/null +++ b/inst/include/cpp11/nas.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "cpp11/r_bool.hpp" +#include "cpp11/r_string.hpp" + + +namespace cpp11 { + + template struct na{}; + + template <> struct na { const static double value; }; + + template <> struct na { const static int value; }; + + template <> struct na { const static r_bool value; }; + + template <> struct na { const static r_string value; }; +} + From fb75d066c0ac75b56c001576fe6283f1f43dee25 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Mon, 14 Jun 2021 09:38:57 -0600 Subject: [PATCH 02/11] adding NA struct --- inst/include/cpp11/nas.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/inst/include/cpp11/nas.hpp b/inst/include/cpp11/nas.hpp index 18ee4e64..f516eba5 100644 --- a/inst/include/cpp11/nas.hpp +++ b/inst/include/cpp11/nas.hpp @@ -1,6 +1,7 @@ #pragma once #include "cpp11/r_bool.hpp" +#include "cpp11/logicals.hpp" #include "cpp11/r_string.hpp" @@ -9,11 +10,16 @@ namespace cpp11 { template struct na{}; template <> struct na { const static double value; }; + const double na::value = NA_REAL; template <> struct na { const static int value; }; + const int na::value = NA_INTEGER; - template <> struct na { const static r_bool value; }; + template <> struct na { const static r_bool val; }; + const r_bool na::value = NA_STRING; + + template <> struct na { const static r_string value; }; + const r_string na::value = NA_STRING; - template <> struct na { const static r_string value; }; } From 122a63d8f5f5adae1603b68b62c28c84b653fe59 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Mon, 14 Jun 2021 09:40:26 -0600 Subject: [PATCH 03/11] adding NA struct tests --- cpp11test/src/test-nas.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 cpp11test/src/test-nas.cpp diff --git a/cpp11test/src/test-nas.cpp b/cpp11test/src/test-nas.cpp new file mode 100644 index 00000000..ac2c9476 --- /dev/null +++ b/cpp11test/src/test-nas.cpp @@ -0,0 +1,23 @@ +#include +#include "cpp11/nas.hpp" +#include "cpp11/logicals.hpp" +#include "cpp11/r_bool.hpp" +#include "cpp11/r_vector.hpp" +#include "cpp11/r_string.hpp" + + +context("nas-C++") { + test_that("na integer") { + expect_true(cpp11::na::value == NA_INTEGER); + } + test_that("na double") { + expect_true(ISNA(cpp11::na::value)); + } + test_that("na bool") { + expect_true(cpp11::na::value == NA_LOGICAL); + + } + test_that("na string") { + expect_true(cpp11::na::value == NA_STRING); + } +} From 0659677b4c10e64a4ba4c80934f335caa89290a6 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Mon, 14 Jun 2021 10:04:02 -0600 Subject: [PATCH 04/11] adding NA struct --- cpp11test/src/cpp11.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp11test/src/cpp11.cpp b/cpp11test/src/cpp11.cpp index 7e426cd9..5e0365ff 100644 --- a/cpp11test/src/cpp11.cpp +++ b/cpp11test/src/cpp11.cpp @@ -352,16 +352,16 @@ extern SEXP _cpp11test_rcpp_sum_dbl_foreach_(SEXP); extern SEXP _cpp11test_rcpp_sum_int_for_(SEXP); extern SEXP _cpp11test_remove_altrep(SEXP); extern SEXP _cpp11test_row_sums(SEXP); -extern SEXP _cpp11test_sum_dbl_accumulate_(SEXP); extern SEXP _cpp11test_sum_dbl_accumulate2_(SEXP); -extern SEXP _cpp11test_sum_dbl_for_(SEXP); +extern SEXP _cpp11test_sum_dbl_accumulate_(SEXP); extern SEXP _cpp11test_sum_dbl_for2_(SEXP); extern SEXP _cpp11test_sum_dbl_for3_(SEXP); -extern SEXP _cpp11test_sum_dbl_foreach_(SEXP); +extern SEXP _cpp11test_sum_dbl_for_(SEXP); extern SEXP _cpp11test_sum_dbl_foreach2_(SEXP); +extern SEXP _cpp11test_sum_dbl_foreach_(SEXP); extern SEXP _cpp11test_sum_int_accumulate_(SEXP); -extern SEXP _cpp11test_sum_int_for_(SEXP); extern SEXP _cpp11test_sum_int_for2_(SEXP); +extern SEXP _cpp11test_sum_int_for_(SEXP); extern SEXP _cpp11test_sum_int_foreach_(SEXP); extern SEXP _cpp11test_upper_bound(SEXP, SEXP); extern SEXP run_testthat_tests(SEXP); @@ -398,16 +398,16 @@ static const R_CallMethodDef CallEntries[] = { {"_cpp11test_rcpp_sum_int_for_", (DL_FUNC) &_cpp11test_rcpp_sum_int_for_, 1}, {"_cpp11test_remove_altrep", (DL_FUNC) &_cpp11test_remove_altrep, 1}, {"_cpp11test_row_sums", (DL_FUNC) &_cpp11test_row_sums, 1}, - {"_cpp11test_sum_dbl_accumulate_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate_, 1}, {"_cpp11test_sum_dbl_accumulate2_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate2_, 1}, - {"_cpp11test_sum_dbl_for_", (DL_FUNC) &_cpp11test_sum_dbl_for_, 1}, + {"_cpp11test_sum_dbl_accumulate_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate_, 1}, {"_cpp11test_sum_dbl_for2_", (DL_FUNC) &_cpp11test_sum_dbl_for2_, 1}, {"_cpp11test_sum_dbl_for3_", (DL_FUNC) &_cpp11test_sum_dbl_for3_, 1}, - {"_cpp11test_sum_dbl_foreach_", (DL_FUNC) &_cpp11test_sum_dbl_foreach_, 1}, + {"_cpp11test_sum_dbl_for_", (DL_FUNC) &_cpp11test_sum_dbl_for_, 1}, {"_cpp11test_sum_dbl_foreach2_", (DL_FUNC) &_cpp11test_sum_dbl_foreach2_, 1}, + {"_cpp11test_sum_dbl_foreach_", (DL_FUNC) &_cpp11test_sum_dbl_foreach_, 1}, {"_cpp11test_sum_int_accumulate_", (DL_FUNC) &_cpp11test_sum_int_accumulate_, 1}, - {"_cpp11test_sum_int_for_", (DL_FUNC) &_cpp11test_sum_int_for_, 1}, {"_cpp11test_sum_int_for2_", (DL_FUNC) &_cpp11test_sum_int_for2_, 1}, + {"_cpp11test_sum_int_for_", (DL_FUNC) &_cpp11test_sum_int_for_, 1}, {"_cpp11test_sum_int_foreach_", (DL_FUNC) &_cpp11test_sum_int_foreach_, 1}, {"_cpp11test_upper_bound", (DL_FUNC) &_cpp11test_upper_bound, 2}, {"run_testthat_tests", (DL_FUNC) &run_testthat_tests, 1}, From 8004836eb7d5f07f9a9f17f0ac6fae7e2e565eed Mon Sep 17 00:00:00 2001 From: sbearrows Date: Mon, 14 Jun 2021 14:28:44 -0600 Subject: [PATCH 05/11] finished editing NA struct --- cpp11test/src/test-nas.cpp | 1 - inst/include/cpp11/nas.hpp | 4 ++-- inst/include/cpp11/r_bool.hpp | 7 +++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cpp11test/src/test-nas.cpp b/cpp11test/src/test-nas.cpp index ac2c9476..08b109bc 100644 --- a/cpp11test/src/test-nas.cpp +++ b/cpp11test/src/test-nas.cpp @@ -15,7 +15,6 @@ context("nas-C++") { } test_that("na bool") { expect_true(cpp11::na::value == NA_LOGICAL); - } test_that("na string") { expect_true(cpp11::na::value == NA_STRING); diff --git a/inst/include/cpp11/nas.hpp b/inst/include/cpp11/nas.hpp index f516eba5..dca90081 100644 --- a/inst/include/cpp11/nas.hpp +++ b/inst/include/cpp11/nas.hpp @@ -15,8 +15,8 @@ namespace cpp11 { template <> struct na { const static int value; }; const int na::value = NA_INTEGER; - template <> struct na { const static r_bool val; }; - const r_bool na::value = NA_STRING; + template <> struct na { const static r_bool value; }; + const r_bool na::value = NA_LOGICAL; template <> struct na { const static r_string value; }; const r_string na::value = NA_STRING; diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index 5087d307..df4be47d 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -2,6 +2,7 @@ #include // for numeric_limits #include // for is_convertible, enable_if +#include #include "R_ext/Boolean.h" // for Rboolean #include "cpp11/R.hpp" // for SEXP, SEXPREC, ... @@ -37,6 +38,7 @@ class r_bool { bool operator==(Rboolean rhs) const { return operator==(r_bool(rhs)); } bool operator==(int rhs) const { return operator==(r_bool(rhs)); } + private: static constexpr int na = std::numeric_limits::min(); @@ -49,6 +51,11 @@ class r_bool { int value_ = na; }; +inline std::ostream& operator << ( std::ostream& os, r_bool const& value ) { + os << ((value == TRUE) ? "TRUE" : "FALSE"); + return os; +} + inline bool is_na(r_bool x) { return x == r_bool(); } template From 093553e3148438d1a1d378f92aecc48dcaf1fa03 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Tue, 15 Jun 2021 13:44:12 -0600 Subject: [PATCH 06/11] adding updates to NEWS --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index de5e460b..1a4df805 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ # cpp11 0.2.7 +* Add NA struct for different R objects (@sbearrows, #179) * Fix spurious diffs from `tools::package_native_routine_registration_skeleton()` by temporarily using C collation (@sbearrows, #171) * Fix a transient memory leak for functions that return values from `cpp11::unwind_protect()` and `cpp11::safe` (#154) * `cpp_source()` now gets an argument `dir` to allow customized temporary directory to store generated source files. From 771dc50374af272b821ea569394489beeef4be52 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Wed, 16 Jun 2021 15:10:33 -0600 Subject: [PATCH 07/11] separate out NA structs into respective header files --- cpp11test/src/test-doubles.cpp | 3 +++ cpp11test/src/test-integers.cpp | 3 +++ cpp11test/src/test-list.cpp | 6 +++--- cpp11test/src/test-logicals.cpp | 3 +++ cpp11test/src/test-nas.cpp | 22 ---------------------- cpp11test/src/test-string.cpp | 3 +++ 6 files changed, 15 insertions(+), 25 deletions(-) delete mode 100644 cpp11test/src/test-nas.cpp diff --git a/cpp11test/src/test-doubles.cpp b/cpp11test/src/test-doubles.cpp index a5f58aee..9210944c 100644 --- a/cpp11test/src/test-doubles.cpp +++ b/cpp11test/src/test-doubles.cpp @@ -5,6 +5,9 @@ #include "cpp11/strings.hpp" context("doubles-C++") { + test_that("NA double") { + expect_true(ISNA(cpp11::na::value)); + } test_that("doubles::r_vector(SEXP)") { cpp11::doubles x(Rf_allocVector(REALSXP, 2)); expect_true(x.size() == 2); diff --git a/cpp11test/src/test-integers.cpp b/cpp11test/src/test-integers.cpp index b875bbaf..3755cb4a 100644 --- a/cpp11test/src/test-integers.cpp +++ b/cpp11test/src/test-integers.cpp @@ -3,6 +3,9 @@ #include "cpp11/integers.hpp" context("integers-C++") { + test_that("NA integer") { + expect_true(cpp11::na::value == NA_INTEGER); + } test_that("integers.push_back()") { cpp11::writable::integers x; x.push_back(1); diff --git a/cpp11test/src/test-list.cpp b/cpp11test/src/test-list.cpp index d856e8b8..6aa9760d 100644 --- a/cpp11test/src/test-list.cpp +++ b/cpp11test/src/test-list.cpp @@ -6,9 +6,9 @@ #include "cpp11/raws.hpp" #include "cpp11/strings.hpp" -namespace cpp11 { -std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); } -} // namespace cpp11 +//namespace cpp11 { +//std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); } +//} // namespace cpp11 context("list-C++") { test_that("list.push_back()") { diff --git a/cpp11test/src/test-logicals.cpp b/cpp11test/src/test-logicals.cpp index f1c874ef..58b1ec1b 100644 --- a/cpp11test/src/test-logicals.cpp +++ b/cpp11test/src/test-logicals.cpp @@ -2,6 +2,9 @@ #include "cpp11/logicals.hpp" context("logicals-C++") { + test_that("NA logicals") { + expect_true(cpp11::na::value == NA_LOGICAL); + } test_that("logicals.push_back()") { cpp11::writable::logicals x; x.push_back(TRUE); diff --git a/cpp11test/src/test-nas.cpp b/cpp11test/src/test-nas.cpp deleted file mode 100644 index 08b109bc..00000000 --- a/cpp11test/src/test-nas.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include "cpp11/nas.hpp" -#include "cpp11/logicals.hpp" -#include "cpp11/r_bool.hpp" -#include "cpp11/r_vector.hpp" -#include "cpp11/r_string.hpp" - - -context("nas-C++") { - test_that("na integer") { - expect_true(cpp11::na::value == NA_INTEGER); - } - test_that("na double") { - expect_true(ISNA(cpp11::na::value)); - } - test_that("na bool") { - expect_true(cpp11::na::value == NA_LOGICAL); - } - test_that("na string") { - expect_true(cpp11::na::value == NA_STRING); - } -} diff --git a/cpp11test/src/test-string.cpp b/cpp11test/src/test-string.cpp index d68fdcb9..ce20cfb3 100644 --- a/cpp11test/src/test-string.cpp +++ b/cpp11test/src/test-string.cpp @@ -9,4 +9,7 @@ context("string-C++") { cpp11::r_string y(NA_STRING); expect_true(cpp11::is_na(y)); } + test_that("NA for string") { + expect_true(cpp11::na::value == NA_STRING); + } } From 3c0b1ceb2b48916476d2cd1ab41476fb213b22a2 Mon Sep 17 00:00:00 2001 From: sbearrows Date: Wed, 16 Jun 2021 15:11:25 -0600 Subject: [PATCH 08/11] adding changes for Jim --- inst/include/cpp11/doubles.hpp | 4 ++++ inst/include/cpp11/integers.hpp | 4 ++++ inst/include/cpp11/nas.hpp | 25 ------------------------- inst/include/cpp11/r_bool.hpp | 5 +++++ inst/include/cpp11/r_string.hpp | 7 +++++++ inst/include/cpp11/r_vector.hpp | 3 +++ 6 files changed, 23 insertions(+), 25 deletions(-) delete mode 100644 inst/include/cpp11/nas.hpp diff --git a/inst/include/cpp11/doubles.hpp b/inst/include/cpp11/doubles.hpp index abfea8b2..f04b6ef4 100644 --- a/inst/include/cpp11/doubles.hpp +++ b/inst/include/cpp11/doubles.hpp @@ -11,6 +11,7 @@ #include "cpp11/protect.hpp" // for SEXP, SEXPREC, REAL_ELT, R_Preserve... #include "cpp11/r_vector.hpp" // for vector, vector<>::proxy, vector<>::... #include "cpp11/sexp.hpp" // for sexp + // Specializations for doubles namespace cpp11 { @@ -130,5 +131,8 @@ typedef r_vector doubles; } // namespace writable + +template <> struct na { const double value = NA_REAL; }; + inline bool is_na(double x) { return ISNA(x); } } // namespace cpp11 diff --git a/inst/include/cpp11/integers.hpp b/inst/include/cpp11/integers.hpp index f922ddd0..a36fa6a8 100644 --- a/inst/include/cpp11/integers.hpp +++ b/inst/include/cpp11/integers.hpp @@ -13,6 +13,7 @@ #include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy #include "cpp11/sexp.hpp" // for sexp + // Specializations for integers namespace cpp11 { @@ -136,5 +137,8 @@ typedef r_vector integers; } // namespace writable +template <> struct na { const static int value; }; +const int na::value = NA_INTEGER; + inline bool is_na(int x) { return x == NA_INTEGER; } } // namespace cpp11 diff --git a/inst/include/cpp11/nas.hpp b/inst/include/cpp11/nas.hpp deleted file mode 100644 index dca90081..00000000 --- a/inst/include/cpp11/nas.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "cpp11/r_bool.hpp" -#include "cpp11/logicals.hpp" -#include "cpp11/r_string.hpp" - - -namespace cpp11 { - - template struct na{}; - - template <> struct na { const static double value; }; - const double na::value = NA_REAL; - - template <> struct na { const static int value; }; - const int na::value = NA_INTEGER; - - template <> struct na { const static r_bool value; }; - const r_bool na::value = NA_LOGICAL; - - template <> struct na { const static r_string value; }; - const r_string na::value = NA_STRING; - -} - diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index df4be47d..22a9b90a 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -9,6 +9,7 @@ #include "cpp11/as.hpp" // for as_sexp #include "cpp11/protect.hpp" // for unwind_protect, preserved #include "cpp11/sexp.hpp" // for sexp +#include "cpp11/r_vector.hpp" namespace cpp11 { @@ -68,4 +69,8 @@ enable_if_r_bool as_sexp(T from) { return res; } + +template <> struct na { const static r_bool value; }; +const r_bool na::value = NA_LOGICAL; + } // namespace cpp11 diff --git a/inst/include/cpp11/r_string.hpp b/inst/include/cpp11/r_string.hpp index fb228b0b..ac7c78d5 100644 --- a/inst/include/cpp11/r_string.hpp +++ b/inst/include/cpp11/r_string.hpp @@ -8,6 +8,8 @@ #include "cpp11/as.hpp" // for as_sexp #include "cpp11/protect.hpp" // for unwind_protect, protect, protect::function #include "cpp11/sexp.hpp" // for sexp + + namespace cpp11 { class r_string { @@ -88,4 +90,9 @@ enable_if_r_string as_sexp(T from) { return res; } + +template struct na{}; + +template <> struct na { const r_string value = NA_STRING; }; + } // namespace cpp11 diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 3d9afdd9..a35a6a4d 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -990,4 +990,7 @@ bool operator!=(const r_vector& lhs, const r_vector& rhs) { return !(lhs == rhs); } + + + } // namespace cpp11 From 3d7c5eab7fbdc1976bd25f69aed39e59de22b943 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Thu, 17 Jun 2021 07:51:22 -0400 Subject: [PATCH 09/11] Revert "separate out NA structs into respective header files" This reverts commit 771dc50374af272b821ea569394489beeef4be52. --- cpp11test/src/test-doubles.cpp | 3 --- cpp11test/src/test-integers.cpp | 3 --- cpp11test/src/test-list.cpp | 6 +++--- cpp11test/src/test-logicals.cpp | 3 --- cpp11test/src/test-nas.cpp | 22 ++++++++++++++++++++++ cpp11test/src/test-string.cpp | 3 --- 6 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 cpp11test/src/test-nas.cpp diff --git a/cpp11test/src/test-doubles.cpp b/cpp11test/src/test-doubles.cpp index 9210944c..a5f58aee 100644 --- a/cpp11test/src/test-doubles.cpp +++ b/cpp11test/src/test-doubles.cpp @@ -5,9 +5,6 @@ #include "cpp11/strings.hpp" context("doubles-C++") { - test_that("NA double") { - expect_true(ISNA(cpp11::na::value)); - } test_that("doubles::r_vector(SEXP)") { cpp11::doubles x(Rf_allocVector(REALSXP, 2)); expect_true(x.size() == 2); diff --git a/cpp11test/src/test-integers.cpp b/cpp11test/src/test-integers.cpp index 3755cb4a..b875bbaf 100644 --- a/cpp11test/src/test-integers.cpp +++ b/cpp11test/src/test-integers.cpp @@ -3,9 +3,6 @@ #include "cpp11/integers.hpp" context("integers-C++") { - test_that("NA integer") { - expect_true(cpp11::na::value == NA_INTEGER); - } test_that("integers.push_back()") { cpp11::writable::integers x; x.push_back(1); diff --git a/cpp11test/src/test-list.cpp b/cpp11test/src/test-list.cpp index 6aa9760d..d856e8b8 100644 --- a/cpp11test/src/test-list.cpp +++ b/cpp11test/src/test-list.cpp @@ -6,9 +6,9 @@ #include "cpp11/raws.hpp" #include "cpp11/strings.hpp" -//namespace cpp11 { -//std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); } -//} // namespace cpp11 +namespace cpp11 { +std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); } +} // namespace cpp11 context("list-C++") { test_that("list.push_back()") { diff --git a/cpp11test/src/test-logicals.cpp b/cpp11test/src/test-logicals.cpp index 58b1ec1b..f1c874ef 100644 --- a/cpp11test/src/test-logicals.cpp +++ b/cpp11test/src/test-logicals.cpp @@ -2,9 +2,6 @@ #include "cpp11/logicals.hpp" context("logicals-C++") { - test_that("NA logicals") { - expect_true(cpp11::na::value == NA_LOGICAL); - } test_that("logicals.push_back()") { cpp11::writable::logicals x; x.push_back(TRUE); diff --git a/cpp11test/src/test-nas.cpp b/cpp11test/src/test-nas.cpp new file mode 100644 index 00000000..08b109bc --- /dev/null +++ b/cpp11test/src/test-nas.cpp @@ -0,0 +1,22 @@ +#include +#include "cpp11/nas.hpp" +#include "cpp11/logicals.hpp" +#include "cpp11/r_bool.hpp" +#include "cpp11/r_vector.hpp" +#include "cpp11/r_string.hpp" + + +context("nas-C++") { + test_that("na integer") { + expect_true(cpp11::na::value == NA_INTEGER); + } + test_that("na double") { + expect_true(ISNA(cpp11::na::value)); + } + test_that("na bool") { + expect_true(cpp11::na::value == NA_LOGICAL); + } + test_that("na string") { + expect_true(cpp11::na::value == NA_STRING); + } +} diff --git a/cpp11test/src/test-string.cpp b/cpp11test/src/test-string.cpp index ce20cfb3..d68fdcb9 100644 --- a/cpp11test/src/test-string.cpp +++ b/cpp11test/src/test-string.cpp @@ -9,7 +9,4 @@ context("string-C++") { cpp11::r_string y(NA_STRING); expect_true(cpp11::is_na(y)); } - test_that("NA for string") { - expect_true(cpp11::na::value == NA_STRING); - } } From 2eeedc1e0ee9f300059016b91b527ed3d86b6123 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Thu, 17 Jun 2021 08:35:57 -0400 Subject: [PATCH 10/11] Make `cpp11::na()` a template function We can't really use a struct because the values are not defined at compile time, it is actually simpler to just make this a template function. --- cpp11test/src/test-list.cpp | 4 ---- cpp11test/src/test-nas.cpp | 22 ++++++---------------- inst/include/cpp11/R.hpp | 9 +++++++++ inst/include/cpp11/doubles.hpp | 11 ++++++++--- inst/include/cpp11/integers.hpp | 8 ++++---- inst/include/cpp11/r_bool.hpp | 18 ++++++++---------- inst/include/cpp11/r_string.hpp | 10 ++++------ inst/include/cpp11/r_vector.hpp | 3 --- 8 files changed, 39 insertions(+), 46 deletions(-) diff --git a/cpp11test/src/test-list.cpp b/cpp11test/src/test-list.cpp index d856e8b8..73cac5ca 100644 --- a/cpp11test/src/test-list.cpp +++ b/cpp11test/src/test-list.cpp @@ -6,10 +6,6 @@ #include "cpp11/raws.hpp" #include "cpp11/strings.hpp" -namespace cpp11 { -std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); } -} // namespace cpp11 - context("list-C++") { test_that("list.push_back()") { cpp11::writable::list x; diff --git a/cpp11test/src/test-nas.cpp b/cpp11test/src/test-nas.cpp index 08b109bc..234a0c5a 100644 --- a/cpp11test/src/test-nas.cpp +++ b/cpp11test/src/test-nas.cpp @@ -1,22 +1,12 @@ #include -#include "cpp11/nas.hpp" -#include "cpp11/logicals.hpp" +#include "cpp11/doubles.hpp" +#include "cpp11/integers.hpp" #include "cpp11/r_bool.hpp" -#include "cpp11/r_vector.hpp" #include "cpp11/r_string.hpp" - context("nas-C++") { - test_that("na integer") { - expect_true(cpp11::na::value == NA_INTEGER); - } - test_that("na double") { - expect_true(ISNA(cpp11::na::value)); - } - test_that("na bool") { - expect_true(cpp11::na::value == NA_LOGICAL); - } - test_that("na string") { - expect_true(cpp11::na::value == NA_STRING); - } + test_that("na integer") { expect_true(cpp11::na() == NA_INTEGER); } + test_that("na double") { expect_true(ISNA(cpp11::na())); } + test_that("na bool") { expect_true(cpp11::na() == NA_LOGICAL); } + test_that("na string") { expect_true(cpp11::na() == NA_STRING); } } diff --git a/inst/include/cpp11/R.hpp b/inst/include/cpp11/R.hpp index 98274a2c..463256d3 100644 --- a/inst/include/cpp11/R.hpp +++ b/inst/include/cpp11/R.hpp @@ -32,4 +32,13 @@ namespace literals { constexpr R_xlen_t operator"" _xl(unsigned long long int value) { return value; } } // namespace literals + +template +inline T na(); + +template +inline bool is_na(const T& value) { + return value == na(); +} + } // namespace cpp11 diff --git a/inst/include/cpp11/doubles.hpp b/inst/include/cpp11/doubles.hpp index f04b6ef4..2d5ea9f2 100644 --- a/inst/include/cpp11/doubles.hpp +++ b/inst/include/cpp11/doubles.hpp @@ -131,8 +131,13 @@ typedef r_vector doubles; } // namespace writable +template <> +inline double na() { + return NA_REAL; +} -template <> struct na { const double value = NA_REAL; }; - -inline bool is_na(double x) { return ISNA(x); } +template <> +inline bool is_na(const double& x) { + return ISNA(x); +} } // namespace cpp11 diff --git a/inst/include/cpp11/integers.hpp b/inst/include/cpp11/integers.hpp index a36fa6a8..b063984d 100644 --- a/inst/include/cpp11/integers.hpp +++ b/inst/include/cpp11/integers.hpp @@ -13,7 +13,6 @@ #include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy #include "cpp11/sexp.hpp" // for sexp - // Specializations for integers namespace cpp11 { @@ -137,8 +136,9 @@ typedef r_vector integers; } // namespace writable -template <> struct na { const static int value; }; -const int na::value = NA_INTEGER; +template <> +inline int na() { + return NA_INTEGER; +} -inline bool is_na(int x) { return x == NA_INTEGER; } } // namespace cpp11 diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index 22a9b90a..a76a550d 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -1,15 +1,15 @@ #pragma once -#include // for numeric_limits -#include // for is_convertible, enable_if +#include // for numeric_limits #include +#include // for is_convertible, enable_if #include "R_ext/Boolean.h" // for Rboolean #include "cpp11/R.hpp" // for SEXP, SEXPREC, ... #include "cpp11/as.hpp" // for as_sexp #include "cpp11/protect.hpp" // for unwind_protect, preserved -#include "cpp11/sexp.hpp" // for sexp #include "cpp11/r_vector.hpp" +#include "cpp11/sexp.hpp" // for sexp namespace cpp11 { @@ -39,7 +39,6 @@ class r_bool { bool operator==(Rboolean rhs) const { return operator==(r_bool(rhs)); } bool operator==(int rhs) const { return operator==(r_bool(rhs)); } - private: static constexpr int na = std::numeric_limits::min(); @@ -52,13 +51,11 @@ class r_bool { int value_ = na; }; -inline std::ostream& operator << ( std::ostream& os, r_bool const& value ) { +inline std::ostream& operator<<(std::ostream& os, r_bool const& value) { os << ((value == TRUE) ? "TRUE" : "FALSE"); return os; } -inline bool is_na(r_bool x) { return x == r_bool(); } - template using enable_if_r_bool = enable_if_t::value, R>; @@ -69,8 +66,9 @@ enable_if_r_bool as_sexp(T from) { return res; } - -template <> struct na { const static r_bool value; }; -const r_bool na::value = NA_LOGICAL; +template <> +inline r_bool na() { + return NA_LOGICAL; +} } // namespace cpp11 diff --git a/inst/include/cpp11/r_string.hpp b/inst/include/cpp11/r_string.hpp index ac7c78d5..93c589a7 100644 --- a/inst/include/cpp11/r_string.hpp +++ b/inst/include/cpp11/r_string.hpp @@ -9,7 +9,6 @@ #include "cpp11/protect.hpp" // for unwind_protect, protect, protect::function #include "cpp11/sexp.hpp" // for sexp - namespace cpp11 { class r_string { @@ -69,8 +68,6 @@ inline SEXP as_sexp(std::initializer_list il) { return data; } -inline bool is_na(const r_string& x) { return x == NA_STRING; } - template using enable_if_r_string = enable_if_t::value, R>; @@ -91,8 +88,9 @@ enable_if_r_string as_sexp(T from) { return res; } -template struct na{}; - -template <> struct na { const r_string value = NA_STRING; }; +template <> +inline r_string na() { + return NA_STRING; +} } // namespace cpp11 diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index a35a6a4d..3d9afdd9 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -990,7 +990,4 @@ bool operator!=(const r_vector& lhs, const r_vector& rhs) { return !(lhs == rhs); } - - - } // namespace cpp11 From 81d8619cbef6251d3d727a2e93b31569c38160f4 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Thu, 17 Jun 2021 08:43:27 -0400 Subject: [PATCH 11/11] Re-order and tweak text of news --- NEWS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4a13abf1..5b478b8a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,13 +1,13 @@ # cpp11 (development version) -* Fix memory leak when move constructing vectors (#173) -* Fix handling of spaces in Makevars include filenames (@klmr, #160) +* New `cpp11::na()` function to return the NA sentinals for R objects(@sbearrows, #179) +* Incorrectly formatted cpp11 decorators now output a more informative error message (@sbearrows, #127) +* Generated registration code now uses C collation to avoid spurious diffs from `tools::package_native_routine_registration_skeleton()` (@sbearrows, #171) +* Memory lo longer leaks when move constructing vectors (#173) +* Makevars which include filenames now handle spaces in paths properly (@klmr, #160) # cpp11 0.2.7 -* Add NA struct for different R objects (@sbearrows, #179) -* Outputting more informative error message when cpp11 decorators are incorrectly formatted (@sbearrows, #127) -* Fix spurious diffs from `tools::package_native_routine_registration_skeleton()` by temporarily using C collation (@sbearrows, #171) * Fix a transient memory leak for functions that return values from `cpp11::unwind_protect()` and `cpp11::safe` (#154) * `cpp_source()` now gets an argument `dir` to allow customized temporary directory to store generated source files. It makes it easier to debug C++ source files in non-package project via source mapping. (@renkun-ken, #156)