Skip to content

Commit e2c1768

Browse files
sbearrowsjimhester
andauthored
Add na helper functions (#183)
Co-authored-by: Jim Hester <[email protected]>
1 parent 7a7da57 commit e2c1768

File tree

9 files changed

+69
-23
lines changed

9 files changed

+69
-23
lines changed

NEWS.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# cpp11 (development version)
22

3-
* Fix memory leak when move constructing vectors (#173)
4-
* Fix handling of spaces in Makevars include filenames (@klmr, #160)
3+
* New `cpp11::na()` function to return the NA sentinals for R objects(@sbearrows, #179)
4+
* Incorrectly formatted cpp11 decorators now output a more informative error message (@sbearrows, #127)
5+
* Generated registration code now uses C collation to avoid spurious diffs from `tools::package_native_routine_registration_skeleton()` (@sbearrows, #171)
6+
* Memory lo longer leaks when move constructing vectors (#173)
7+
* Makevars which include filenames now handle spaces in paths properly (@klmr, #160)
58

69
# cpp11 0.2.7
710

8-
* Outputting more informative error message when cpp11 decorators are incorrectly formatted (@sbearrows, #127)
9-
* Fix spurious diffs from `tools::package_native_routine_registration_skeleton()` by temporarily using C collation (@sbearrows, #171)
1011
* Fix a transient memory leak for functions that return values from `cpp11::unwind_protect()` and `cpp11::safe` (#154)
1112
* `cpp_source()` now gets an argument `dir` to allow customized temporary directory to store generated source files.
1213
It makes it easier to debug C++ source files in non-package project via source mapping. (@renkun-ken, #156)

cpp11test/src/cpp11.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -352,16 +352,16 @@ extern SEXP _cpp11test_rcpp_sum_dbl_foreach_(SEXP);
352352
extern SEXP _cpp11test_rcpp_sum_int_for_(SEXP);
353353
extern SEXP _cpp11test_remove_altrep(SEXP);
354354
extern SEXP _cpp11test_row_sums(SEXP);
355-
extern SEXP _cpp11test_sum_dbl_accumulate_(SEXP);
356355
extern SEXP _cpp11test_sum_dbl_accumulate2_(SEXP);
357-
extern SEXP _cpp11test_sum_dbl_for_(SEXP);
356+
extern SEXP _cpp11test_sum_dbl_accumulate_(SEXP);
358357
extern SEXP _cpp11test_sum_dbl_for2_(SEXP);
359358
extern SEXP _cpp11test_sum_dbl_for3_(SEXP);
360-
extern SEXP _cpp11test_sum_dbl_foreach_(SEXP);
359+
extern SEXP _cpp11test_sum_dbl_for_(SEXP);
361360
extern SEXP _cpp11test_sum_dbl_foreach2_(SEXP);
361+
extern SEXP _cpp11test_sum_dbl_foreach_(SEXP);
362362
extern SEXP _cpp11test_sum_int_accumulate_(SEXP);
363-
extern SEXP _cpp11test_sum_int_for_(SEXP);
364363
extern SEXP _cpp11test_sum_int_for2_(SEXP);
364+
extern SEXP _cpp11test_sum_int_for_(SEXP);
365365
extern SEXP _cpp11test_sum_int_foreach_(SEXP);
366366
extern SEXP _cpp11test_upper_bound(SEXP, SEXP);
367367
extern SEXP run_testthat_tests(SEXP);
@@ -398,16 +398,16 @@ static const R_CallMethodDef CallEntries[] = {
398398
{"_cpp11test_rcpp_sum_int_for_", (DL_FUNC) &_cpp11test_rcpp_sum_int_for_, 1},
399399
{"_cpp11test_remove_altrep", (DL_FUNC) &_cpp11test_remove_altrep, 1},
400400
{"_cpp11test_row_sums", (DL_FUNC) &_cpp11test_row_sums, 1},
401-
{"_cpp11test_sum_dbl_accumulate_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate_, 1},
402401
{"_cpp11test_sum_dbl_accumulate2_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate2_, 1},
403-
{"_cpp11test_sum_dbl_for_", (DL_FUNC) &_cpp11test_sum_dbl_for_, 1},
402+
{"_cpp11test_sum_dbl_accumulate_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate_, 1},
404403
{"_cpp11test_sum_dbl_for2_", (DL_FUNC) &_cpp11test_sum_dbl_for2_, 1},
405404
{"_cpp11test_sum_dbl_for3_", (DL_FUNC) &_cpp11test_sum_dbl_for3_, 1},
406-
{"_cpp11test_sum_dbl_foreach_", (DL_FUNC) &_cpp11test_sum_dbl_foreach_, 1},
405+
{"_cpp11test_sum_dbl_for_", (DL_FUNC) &_cpp11test_sum_dbl_for_, 1},
407406
{"_cpp11test_sum_dbl_foreach2_", (DL_FUNC) &_cpp11test_sum_dbl_foreach2_, 1},
407+
{"_cpp11test_sum_dbl_foreach_", (DL_FUNC) &_cpp11test_sum_dbl_foreach_, 1},
408408
{"_cpp11test_sum_int_accumulate_", (DL_FUNC) &_cpp11test_sum_int_accumulate_, 1},
409-
{"_cpp11test_sum_int_for_", (DL_FUNC) &_cpp11test_sum_int_for_, 1},
410409
{"_cpp11test_sum_int_for2_", (DL_FUNC) &_cpp11test_sum_int_for2_, 1},
410+
{"_cpp11test_sum_int_for_", (DL_FUNC) &_cpp11test_sum_int_for_, 1},
411411
{"_cpp11test_sum_int_foreach_", (DL_FUNC) &_cpp11test_sum_int_foreach_, 1},
412412
{"_cpp11test_upper_bound", (DL_FUNC) &_cpp11test_upper_bound, 2},
413413
{"run_testthat_tests", (DL_FUNC) &run_testthat_tests, 1},

cpp11test/src/test-list.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
#include "cpp11/raws.hpp"
77
#include "cpp11/strings.hpp"
88

9-
namespace cpp11 {
10-
std::ostream& operator<<(std::ostream& os, r_bool b) { return os << int(b); }
11-
} // namespace cpp11
12-
139
context("list-C++") {
1410
test_that("list.push_back()") {
1511
cpp11::writable::list x;

cpp11test/src/test-nas.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <testthat.h>
2+
#include "cpp11/doubles.hpp"
3+
#include "cpp11/integers.hpp"
4+
#include "cpp11/r_bool.hpp"
5+
#include "cpp11/r_string.hpp"
6+
7+
context("nas-C++") {
8+
test_that("na integer") { expect_true(cpp11::na<int>() == NA_INTEGER); }
9+
test_that("na double") { expect_true(ISNA(cpp11::na<double>())); }
10+
test_that("na bool") { expect_true(cpp11::na<cpp11::r_bool>() == NA_LOGICAL); }
11+
test_that("na string") { expect_true(cpp11::na<cpp11::r_string>() == NA_STRING); }
12+
}

inst/include/cpp11/R.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,13 @@ namespace literals {
3232
constexpr R_xlen_t operator"" _xl(unsigned long long int value) { return value; }
3333

3434
} // namespace literals
35+
36+
template <typename T>
37+
inline T na();
38+
39+
template <typename T>
40+
inline bool is_na(const T& value) {
41+
return value == na<T>();
42+
}
43+
3544
} // namespace cpp11

inst/include/cpp11/doubles.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "cpp11/protect.hpp" // for SEXP, SEXPREC, REAL_ELT, R_Preserve...
1212
#include "cpp11/r_vector.hpp" // for vector, vector<>::proxy, vector<>::...
1313
#include "cpp11/sexp.hpp" // for sexp
14+
1415
// Specializations for doubles
1516

1617
namespace cpp11 {
@@ -130,5 +131,13 @@ typedef r_vector<double> doubles;
130131

131132
} // namespace writable
132133

133-
inline bool is_na(double x) { return ISNA(x); }
134+
template <>
135+
inline double na() {
136+
return NA_REAL;
137+
}
138+
139+
template <>
140+
inline bool is_na(const double& x) {
141+
return ISNA(x);
142+
}
134143
} // namespace cpp11

inst/include/cpp11/integers.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,9 @@ typedef r_vector<int> integers;
136136

137137
} // namespace writable
138138

139-
inline bool is_na(int x) { return x == NA_INTEGER; }
139+
template <>
140+
inline int na() {
141+
return NA_INTEGER;
142+
}
143+
140144
} // namespace cpp11

inst/include/cpp11/r_bool.hpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#pragma once
22

3-
#include <limits> // for numeric_limits
3+
#include <limits> // for numeric_limits
4+
#include <ostream>
45
#include <type_traits> // for is_convertible, enable_if
56

67
#include "R_ext/Boolean.h" // for Rboolean
78
#include "cpp11/R.hpp" // for SEXP, SEXPREC, ...
89
#include "cpp11/as.hpp" // for as_sexp
910
#include "cpp11/protect.hpp" // for unwind_protect, preserved
10-
#include "cpp11/sexp.hpp" // for sexp
11+
#include "cpp11/r_vector.hpp"
12+
#include "cpp11/sexp.hpp" // for sexp
1113

1214
namespace cpp11 {
1315

@@ -49,7 +51,10 @@ class r_bool {
4951
int value_ = na;
5052
};
5153

52-
inline bool is_na(r_bool x) { return x == r_bool(); }
54+
inline std::ostream& operator<<(std::ostream& os, r_bool const& value) {
55+
os << ((value == TRUE) ? "TRUE" : "FALSE");
56+
return os;
57+
}
5358

5459
template <typename T, typename R = void>
5560
using enable_if_r_bool = enable_if_t<std::is_same<T, r_bool>::value, R>;
@@ -61,4 +66,9 @@ enable_if_r_bool<T, SEXP> as_sexp(T from) {
6166
return res;
6267
}
6368

69+
template <>
70+
inline r_bool na() {
71+
return NA_LOGICAL;
72+
}
73+
6474
} // namespace cpp11

inst/include/cpp11/r_string.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "cpp11/as.hpp" // for as_sexp
99
#include "cpp11/protect.hpp" // for unwind_protect, protect, protect::function
1010
#include "cpp11/sexp.hpp" // for sexp
11+
1112
namespace cpp11 {
1213

1314
class r_string {
@@ -67,8 +68,6 @@ inline SEXP as_sexp(std::initializer_list<r_string> il) {
6768
return data;
6869
}
6970

70-
inline bool is_na(const r_string& x) { return x == NA_STRING; }
71-
7271
template <typename T, typename R = void>
7372
using enable_if_r_string = enable_if_t<std::is_same<T, cpp11::r_string>::value, R>;
7473

@@ -88,4 +87,10 @@ enable_if_r_string<T, SEXP> as_sexp(T from) {
8887

8988
return res;
9089
}
90+
91+
template <>
92+
inline r_string na() {
93+
return NA_STRING;
94+
}
95+
9196
} // namespace cpp11

0 commit comments

Comments
 (0)