Skip to content

Commit 17ba519

Browse files
committed
handle cpp complex <-> R sexp
1 parent ca9c11e commit 17ba519

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

inst/include/cpp11/complexes.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <algorithm> // for min
44
#include <array> // for array
5+
#include <complex> // for std::complex
56
#include <initializer_list> // for initializer_list
67

78
#include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_allocVector
@@ -122,6 +123,19 @@ class r_vector<r_complex>::proxy {
122123
return *this;
123124
}
124125

126+
proxy& operator=(const std::complex<double>& value) {
127+
if (is_altrep_ && buf_ != nullptr) {
128+
buf_->r = value.real();
129+
buf_->i = value.imag();
130+
} else {
131+
Rcomplex r;
132+
r.r = value.real();
133+
r.i = value.imag();
134+
SET_COMPLEX_ELT(data_, index_, r);
135+
}
136+
return *this;
137+
}
138+
125139
proxy& operator+=(const r_complex& value) {
126140
*this = static_cast<r_complex>(*this) + value;
127141
return *this;
@@ -179,4 +193,27 @@ class r_vector<r_complex>::proxy {
179193

180194
} // namespace writable
181195

196+
// New complex_vector class for handling complex numbers in SEXP
197+
class complex_vector {
198+
public:
199+
explicit complex_vector(SEXP x)
200+
: data_(reinterpret_cast<Rcomplex*>(DATAPTR(x))), size_(Rf_length(x)) {}
201+
202+
std::complex<double> operator[](R_xlen_t i) const { return {data_[i].r, data_[i].i}; }
203+
204+
size_t size() const { return size_; }
205+
206+
private:
207+
Rcomplex* data_;
208+
size_t size_;
209+
};
210+
211+
// Template specialization for adding cpp11::r_complex to std::complex<double>
212+
template <typename T>
213+
inline std::complex<T>& operator+=(std::complex<T>& lhs, const cpp11::r_complex& rhs) {
214+
lhs.real(lhs.real() + rhs.real());
215+
lhs.imag(lhs.imag() + rhs.imag());
216+
return lhs;
217+
}
218+
182219
} // namespace cpp11

0 commit comments

Comments
 (0)