|
2 | 2 |
|
3 | 3 | #include <algorithm> // for min |
4 | 4 | #include <array> // for array |
| 5 | +#include <complex> // for std::complex |
5 | 6 | #include <initializer_list> // for initializer_list |
6 | 7 |
|
7 | 8 | #include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_allocVector |
@@ -122,6 +123,19 @@ class r_vector<r_complex>::proxy { |
122 | 123 | return *this; |
123 | 124 | } |
124 | 125 |
|
| 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 | + |
125 | 139 | proxy& operator+=(const r_complex& value) { |
126 | 140 | *this = static_cast<r_complex>(*this) + value; |
127 | 141 | return *this; |
@@ -179,4 +193,27 @@ class r_vector<r_complex>::proxy { |
179 | 193 |
|
180 | 194 | } // namespace writable |
181 | 195 |
|
| 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 | + |
182 | 219 | } // namespace cpp11 |
0 commit comments