11#pragma once
22
3- #include < complex> // for complex
4- #include < ostream>
5- #include < type_traits> // for is_convertible, enable_if
6-
7- #include " R_ext/Arith.h" // for NA_REAL
8- #include " R_ext/Complex.h" // for Rcomplex
9- #include " cpp11/R.hpp" // for SEXP, SEXPREC, ...
10- #include " cpp11/as.hpp" // for as_sexp
11- #include " cpp11/protect.hpp" // for unwind_protect, preserved
12- #include " cpp11/r_vector.hpp" // for r_vector
13- #include " cpp11/sexp.hpp" // for sexp
3+ #include < complex> // for std::complex
4+
5+ #include " cpp11/R.hpp" // for SEXP, SEXPREC, Rf_mkCharCE, Rf_translateCharUTF8
6+ #include " cpp11/as.hpp" // for as_sexp
7+ #include " cpp11/protect.hpp" // for unwind_protect, protect, protect::function
8+ #include " cpp11/sexp.hpp" // for sexp
149
1510namespace cpp11 {
1611
1712class r_complex {
1813 public:
19- r_complex () = default ;
20- r_complex (SEXP data) : data_(data) {}
14+ r_complex () : data_(safe[Rf_allocVector](CPLXSXP, 1 )) {
15+ COMPLEX (data_)[0 ].r = 0 ;
16+ COMPLEX (data_)[0 ].i = 0 ;
17+ }
18+ r_complex (SEXP data) : data_(data) {
19+ if (data_ == R_NilValue) {
20+ data_ = PROTECT (Rf_allocVector (CPLXSXP, 0 ));
21+ UNPROTECT (1 );
22+ }
23+ }
2124 r_complex (double real, double imag) : data_(safe[Rf_allocVector](CPLXSXP, 1 )) {
2225 COMPLEX (data_)[0 ].r = real;
2326 COMPLEX (data_)[0 ].i = imag;
@@ -28,20 +31,38 @@ class r_complex {
2831 operator SEXP () const { return data_; }
2932 operator sexp () const { return data_; }
3033 operator std::complex <double >() const {
34+ if (data_ == R_NilValue || Rf_length (data_) == 0 ) {
35+ return {NA_REAL, NA_REAL};
36+ }
3137 return {COMPLEX (data_)[0 ].r , COMPLEX (data_)[0 ].i };
3238 }
3339 operator Rcomplex () const {
3440 Rcomplex r;
35- r.r = real ();
36- r.i = imag ();
41+ if (data_ == R_NilValue || Rf_length (data_) == 0 ) {
42+ r.r = NA_REAL;
43+ r.i = NA_REAL;
44+ } else {
45+ r.r = real ();
46+ r.i = imag ();
47+ }
3748 return r;
3849 }
3950
40- double real () const { return COMPLEX (data_)[0 ].r ; }
41- double imag () const { return COMPLEX (data_)[0 ].i ; }
51+ double real () const {
52+ if (data_ == R_NilValue || Rf_length (data_) == 0 ) {
53+ return NA_REAL;
54+ }
55+ return COMPLEX (data_)[0 ].r ;
56+ }
57+ double imag () const {
58+ if (data_ == R_NilValue || Rf_length (data_) == 0 ) {
59+ return NA_REAL;
60+ }
61+ return COMPLEX (data_)[0 ].i ;
62+ }
4263
4364 bool operator ==(const r_complex& rhs) const {
44- return real () == rhs.real () && imag () == rhs.imag ();
65+ return ( is_na () && rhs. is_na ()) || ( real () == rhs.real () && imag () == rhs.imag () );
4566 }
4667
4768 bool operator !=(const r_complex& rhs) const { return !(*this == rhs); }
@@ -90,6 +111,8 @@ class r_complex {
90111 return lhs;
91112 }
92113
114+ bool is_na () const { return R_IsNA (real ()) || R_IsNA (imag ()); }
115+
93116 private:
94117 sexp data_ = R_NilValue;
95118};
0 commit comments