Skip to content

Commit 8e044f6

Browse files
committed
trying to add push_back for cplx
1 parent ea98a87 commit 8e044f6

File tree

2 files changed

+39
-130
lines changed

2 files changed

+39
-130
lines changed

inst/include/cpp11/complexes.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ inline SEXPTYPE r_vector<r_complex>::get_sexptype() {
2626
template <>
2727
inline typename r_vector<r_complex>::underlying_type r_vector<r_complex>::get_elt(
2828
SEXP x, R_xlen_t i) {
29-
return COMPLEX_ELT(x, i);
29+
return r_complex(COMPLEX_ELT(x, i));
3030
}
3131

3232
template <>
@@ -35,20 +35,20 @@ inline typename r_vector<r_complex>::underlying_type* r_vector<r_complex>::get_p
3535
if (is_altrep) {
3636
return nullptr;
3737
} else {
38-
return COMPLEX(data);
38+
return reinterpret_cast<r_complex*>(COMPLEX(data));
3939
}
4040
}
4141

4242
template <>
4343
inline typename r_vector<r_complex>::underlying_type const*
4444
r_vector<r_complex>::get_const_p(bool is_altrep, SEXP data) {
45-
return COMPLEX_OR_NULL(data);
45+
return reinterpret_cast<const r_complex*>(COMPLEX_OR_NULL(data));
4646
}
4747

4848
template <>
4949
inline void r_vector<r_complex>::get_region(SEXP x, R_xlen_t i, R_xlen_t n,
5050
typename r_vector::underlying_type* buf) {
51-
COMPLEX_GET_REGION(x, i, n, buf);
51+
COMPLEX_GET_REGION(x, i, n, reinterpret_cast<Rcomplex*>(buf));
5252
}
5353

5454
template <>
@@ -63,7 +63,7 @@ namespace writable {
6363
template <>
6464
inline void r_vector<r_complex>::set_elt(
6565
SEXP x, R_xlen_t i, typename r_vector<r_complex>::underlying_type value) {
66-
SET_COMPLEX_ELT(x, i, value);
66+
SET_COMPLEX_ELT(x, i, static_cast<Rcomplex>(value));
6767
}
6868

6969
typedef r_vector<r_complex> complexes;

inst/include/cpp11/r_complex.hpp

Lines changed: 34 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4,151 +4,60 @@
44
#include <ostream>
55
#include <type_traits> // for is_convertible, enable_if
66

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/sexp.hpp" // for sexp
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
1314

1415
namespace cpp11 {
1516

1617
class r_complex {
1718
public:
18-
r_complex() = default;
19+
r_complex() : r_(NA_REAL), i_(NA_REAL) {}
20+
r_complex(double r, double i) : r_(r), i_(i) {}
21+
r_complex(const std::complex<double>& c) : r_(c.real()), i_(c.imag()) {}
22+
r_complex(const Rcomplex& rc) : r_(rc.r), i_(rc.i) {}
1923

20-
r_complex(SEXP data) {
21-
if (Rf_isComplex(data) && Rf_xlength(data) == 1) {
22-
Rcomplex elt = COMPLEX_ELT(data, 0);
23-
real_ = elt.r;
24-
imag_ = elt.i;
25-
} else {
26-
throw std::invalid_argument("Invalid r_complex value");
27-
}
28-
}
29-
30-
r_complex(double real, double imag) : real_(real), imag_(imag) {}
31-
32-
explicit r_complex(Rcomplex value) : real_(value.r), imag_(value.i) {}
33-
explicit r_complex(std::complex<double> value)
34-
: real_(value.real()), imag_(value.imag()) {}
35-
36-
explicit operator Rcomplex() const { return Rcomplex{real_, imag_}; }
37-
explicit operator std::complex<double>() const {
38-
return std::complex<double>(real_, imag_);
39-
}
40-
41-
double real() const { return real_; }
42-
double imag() const { return imag_; }
43-
44-
r_complex& operator+=(const r_complex& other) {
45-
real_ += other.real_;
46-
imag_ += other.imag_;
47-
return *this;
48-
}
49-
50-
r_complex& operator-=(const r_complex& other) {
51-
real_ -= other.real_;
52-
imag_ -= other.imag_;
53-
return *this;
54-
}
24+
double real() const { return r_; }
25+
double imag() const { return i_; }
5526

56-
r_complex& operator*=(const r_complex& other) {
57-
double r = real_ * other.real_ - imag_ * other.imag_;
58-
double i = real_ * other.imag_ + imag_ * other.real_;
59-
real_ = r;
60-
imag_ = i;
61-
return *this;
62-
}
27+
operator std::complex<double>() const { return std::complex<double>(r_, i_); }
28+
operator Rcomplex() const { return {r_, i_}; }
6329

64-
r_complex& operator/=(const r_complex& other) {
65-
double denom = other.real_ * other.real_ + other.imag_ * other.imag_;
66-
double r = (real_ * other.real_ + imag_ * other.imag_) / denom;
67-
double i = (imag_ * other.real_ - real_ * other.imag_) / denom;
68-
real_ = r;
69-
imag_ = i;
70-
return *this;
30+
bool operator==(const r_complex& other) const {
31+
return r_ == other.r_ && i_ == other.i_;
7132
}
7233

7334
private:
74-
double real_;
75-
double imag_;
35+
double r_;
36+
double i_;
7637
};
7738

78-
inline r_complex operator+(r_complex lhs, const r_complex& rhs) {
79-
lhs += rhs;
80-
return lhs;
81-
}
82-
83-
inline r_complex operator-(r_complex lhs, const r_complex& rhs) {
84-
lhs -= rhs;
85-
return lhs;
86-
}
87-
88-
inline r_complex operator*(r_complex lhs, const r_complex& rhs) {
89-
lhs *= rhs;
90-
return lhs;
91-
}
92-
93-
inline r_complex operator/(r_complex lhs, const r_complex& rhs) {
94-
lhs /= rhs;
95-
return lhs;
96-
}
97-
98-
inline bool operator==(const r_complex& x, const r_complex& y) {
99-
return (x.real() == y.real()) && (x.imag() == y.imag());
100-
}
101-
102-
inline std::ostream& operator<<(std::ostream& os, const r_complex& value) {
103-
os << value.real() << "+" << value.imag() << "i";
104-
return os;
105-
}
106-
39+
// Specialization for r_complex
10740
template <>
108-
inline r_complex na() {
109-
return r_complex(NA_REAL, NA_REAL);
110-
}
111-
112-
template <>
113-
inline bool is_na(const r_complex& x) {
114-
return ISNA(x.real()) || ISNA(x.imag());
115-
}
116-
117-
template <typename T>
118-
struct is_r_complex : std::false_type {};
41+
inline void writable::r_vector<r_complex>::push_back(r_complex value) {
42+
while (this->length_ >= this->capacity_) {
43+
this->reserve(this->capacity_ == 0 ? 1 : this->capacity_ * 2);
44+
}
11945

120-
template <>
121-
struct is_r_complex<r_complex> : std::true_type {};
46+
Rcomplex r_value = static_cast<Rcomplex>(value);
12247

123-
template <typename T, typename R = void>
124-
using enable_if_r_complex = std::enable_if_t<is_r_complex<T>::value, R>;
48+
if (this->data_p_ != nullptr) {
49+
this->data_p_[this->length_] = r_value;
50+
} else {
51+
this->set_elt(this->data_, this->length_, r_value);
52+
}
12553

126-
template <typename T>
127-
enable_if_r_complex<T, SEXP> as_sexp(T from) {
128-
SEXP res = PROTECT(Rf_allocVector(CPLXSXP, 1));
129-
Rcomplex* r = COMPLEX(res);
130-
r[0].r = from.real();
131-
r[0].i = from.imag();
132-
UNPROTECT(1);
133-
return res;
54+
++this->length_;
13455
}
13556

136-
namespace traits {
57+
// Specialization for std::complex<double>
13758
template <>
138-
struct get_underlying_type<r_complex> {
139-
using type = Rcomplex;
140-
};
141-
} // namespace traits
142-
143-
// Define operator+ for std::complex<double> and r_complex
144-
inline std::complex<double> operator+(const std::complex<double>& lhs,
145-
const r_complex& rhs) {
146-
return std::complex<double>(lhs.real() + rhs.real(), lhs.imag() + rhs.imag());
147-
}
148-
149-
inline std::complex<double> operator+(const r_complex& lhs,
150-
const std::complex<double>& rhs) {
151-
return std::complex<double>(lhs.real() + rhs.real(), lhs.imag() + rhs.imag());
59+
inline void writable::r_vector<r_complex>::push_back(const std::complex<double>& value) {
60+
this->push_back(r_complex(value.real(), value.imag()));
15261
}
15362

15463
} // namespace cpp11

0 commit comments

Comments
 (0)