Skip to content

Commit 457c441

Browse files
authored
Use a universal reserve() method (#373)
1 parent 758683c commit 457c441

File tree

7 files changed

+53
-80
lines changed

7 files changed

+53
-80
lines changed

inst/include/cpp11/doubles.hpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ typedef r_vector<double> doubles;
5454

5555
namespace writable {
5656

57+
template <>
58+
inline SEXPTYPE r_vector<double>::get_sexptype() {
59+
return REALSXP;
60+
}
61+
5762
template <>
5863
inline typename r_vector<double>::proxy& r_vector<double>::proxy::operator=(
5964
const double& rhs) {
@@ -104,18 +109,6 @@ inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
104109
}
105110
}
106111

107-
template <>
108-
inline void r_vector<double>::reserve(R_xlen_t new_capacity) {
109-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](REALSXP, new_capacity)
110-
: safe[Rf_xlengthgets](data_, new_capacity);
111-
SEXP old_protect = protect_;
112-
protect_ = detail::store::insert(data_);
113-
detail::store::release(old_protect);
114-
115-
data_p_ = REAL(data_);
116-
capacity_ = new_capacity;
117-
}
118-
119112
template <>
120113
inline void r_vector<double>::push_back(double value) {
121114
while (length_ >= capacity_) {

inst/include/cpp11/integers.hpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ typedef r_vector<int> integers;
5555

5656
namespace writable {
5757

58+
template <>
59+
inline SEXPTYPE r_vector<int>::get_sexptype() {
60+
return INTSXP;
61+
}
62+
5863
template <>
5964
inline typename r_vector<int>::proxy& r_vector<int>::proxy::operator=(const int& rhs) {
6065
if (is_altrep_) {
@@ -80,22 +85,6 @@ template <>
8085
inline r_vector<int>::r_vector(std::initializer_list<int> il)
8186
: cpp11::r_vector<int>(as_sexp(il)), capacity_(il.size()) {}
8287

83-
template <>
84-
inline void r_vector<int>::reserve(R_xlen_t new_capacity) {
85-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](INTSXP, new_capacity)
86-
: safe[Rf_xlengthgets](data_, new_capacity);
87-
SEXP old_protect = protect_;
88-
89-
// Protect the new data
90-
protect_ = detail::store::insert(data_);
91-
92-
// Release the old protection;
93-
detail::store::release(old_protect);
94-
95-
data_p_ = INTEGER(data_);
96-
capacity_ = new_capacity;
97-
}
98-
9988
template <>
10089
inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
10190
: cpp11::r_vector<int>(safe[Rf_allocVector](INTSXP, il.size())),

inst/include/cpp11/list.hpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ typedef r_vector<SEXP> list;
6363

6464
namespace writable {
6565

66+
template <>
67+
inline SEXPTYPE r_vector<SEXP>::get_sexptype() {
68+
return VECSXP;
69+
}
70+
6671
template <>
6772
inline typename r_vector<SEXP>::proxy& r_vector<SEXP>::proxy::operator=(const SEXP& rhs) {
6873
SET_VECTOR_ELT(data_, index_, rhs);
@@ -108,18 +113,6 @@ inline r_vector<SEXP>::r_vector(std::initializer_list<named_arg> il)
108113
}
109114
}
110115

111-
template <>
112-
inline void r_vector<SEXP>::reserve(R_xlen_t new_capacity) {
113-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](VECSXP, new_capacity)
114-
: safe[Rf_xlengthgets](data_, new_capacity);
115-
116-
SEXP old_protect = protect_;
117-
protect_ = detail::store::insert(data_);
118-
detail::store::release(old_protect);
119-
120-
capacity_ = new_capacity;
121-
}
122-
123116
template <>
124117
inline void r_vector<SEXP>::push_back(SEXP value) {
125118
while (length_ >= capacity_) {

inst/include/cpp11/logicals.hpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ typedef r_vector<r_bool> logicals;
5353

5454
namespace writable {
5555

56+
template <>
57+
inline SEXPTYPE r_vector<r_bool>::get_sexptype() {
58+
return LGLSXP;
59+
}
60+
5661
template <>
5762
inline typename r_vector<r_bool>::proxy& r_vector<r_bool>::proxy::operator=(
5863
const r_bool& rhs) {
@@ -110,19 +115,6 @@ inline r_vector<r_bool>::r_vector(std::initializer_list<named_arg> il)
110115
}
111116
}
112117

113-
template <>
114-
inline void r_vector<r_bool>::reserve(R_xlen_t new_capacity) {
115-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](LGLSXP, new_capacity)
116-
: safe[Rf_xlengthgets](data_, new_capacity);
117-
SEXP old_protect = protect_;
118-
protect_ = detail::store::insert(data_);
119-
120-
detail::store::release(old_protect);
121-
122-
data_p_ = LOGICAL(data_);
123-
capacity_ = new_capacity;
124-
}
125-
126118
template <>
127119
inline void r_vector<r_bool>::push_back(r_bool value) {
128120
while (length_ >= capacity_) {

inst/include/cpp11/r_vector.hpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ class r_vector : public cpp11::r_vector<T> {
228228
void pop_back();
229229

230230
void resize(R_xlen_t count);
231-
232-
/// Implemented in specialization
233231
void reserve(R_xlen_t new_capacity);
234232

235233
iterator insert(R_xlen_t pos, T value);
@@ -308,6 +306,9 @@ class r_vector : public cpp11::r_vector<T> {
308306
};
309307

310308
private:
309+
/// Implemented in specialization
310+
static SEXPTYPE get_sexptype();
311+
311312
using cpp11::r_vector<T>::get_p;
312313
};
313314
} // namespace writable
@@ -886,6 +887,26 @@ inline void r_vector<T>::resize(R_xlen_t count) {
886887
length_ = count;
887888
}
888889

890+
/// Reserve a new capacity and copy all elements over
891+
///
892+
/// SAFETY: The new capacity is allowed to be smaller than the current capacity, which
893+
/// is used in the `SEXP` conversion operator during truncation, but if that occurs then
894+
/// we also need to update the `length_`, so if you need to truncate then you should call
895+
/// `resize()` instead.
896+
template <typename T>
897+
inline void r_vector<T>::reserve(R_xlen_t new_capacity) {
898+
SEXP old_protect = protect_;
899+
900+
data_ = (data_ == R_NilValue) ? safe[Rf_allocVector](get_sexptype(), new_capacity)
901+
: safe[Rf_xlengthgets](data_, new_capacity);
902+
protect_ = detail::store::insert(data_);
903+
is_altrep_ = ALTREP(data_);
904+
data_p_ = get_p(is_altrep_, data_);
905+
capacity_ = new_capacity;
906+
907+
detail::store::release(old_protect);
908+
}
909+
889910
template <typename T>
890911
inline typename r_vector<T>::iterator r_vector<T>::insert(R_xlen_t pos, T value) {
891912
push_back(value);

inst/include/cpp11/raws.hpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ typedef r_vector<uint8_t> raws;
6262

6363
namespace writable {
6464

65+
template <>
66+
inline SEXPTYPE r_vector<uint8_t>::get_sexptype() {
67+
return RAWSXP;
68+
}
69+
6570
template <>
6671
inline typename r_vector<uint8_t>::proxy& r_vector<uint8_t>::proxy::operator=(
6772
const uint8_t& rhs) {
@@ -119,19 +124,6 @@ inline r_vector<uint8_t>::r_vector(std::initializer_list<named_arg> il)
119124
}
120125
}
121126

122-
template <>
123-
inline void r_vector<uint8_t>::reserve(R_xlen_t new_capacity) {
124-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](RAWSXP, new_capacity)
125-
: safe[Rf_xlengthgets](data_, new_capacity);
126-
127-
SEXP old_protect = protect_;
128-
protect_ = detail::store::insert(data_);
129-
detail::store::release(old_protect);
130-
131-
data_p_ = RAW(data_);
132-
capacity_ = new_capacity;
133-
}
134-
135127
template <>
136128
inline void r_vector<uint8_t>::push_back(uint8_t value) {
137129
while (length_ >= capacity_) {

inst/include/cpp11/strings.hpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ typedef r_vector<r_string> strings;
5353

5454
namespace writable {
5555

56+
template <>
57+
inline SEXPTYPE r_vector<r_string>::get_sexptype() {
58+
return STRSXP;
59+
}
60+
5661
template <>
5762
inline typename r_vector<r_string>::proxy& r_vector<r_string>::proxy::operator=(
5863
const r_string& rhs) {
@@ -136,18 +141,6 @@ inline r_vector<r_string>::r_vector(std::initializer_list<named_arg> il)
136141
}
137142
}
138143

139-
template <>
140-
inline void r_vector<r_string>::reserve(R_xlen_t new_capacity) {
141-
data_ = data_ == R_NilValue ? safe[Rf_allocVector](STRSXP, new_capacity)
142-
: safe[Rf_xlengthgets](data_, new_capacity);
143-
144-
SEXP old_protect = protect_;
145-
protect_ = detail::store::insert(data_);
146-
detail::store::release(old_protect);
147-
148-
capacity_ = new_capacity;
149-
}
150-
151144
template <>
152145
inline void r_vector<r_string>::push_back(r_string value) {
153146
while (length_ >= capacity_) {

0 commit comments

Comments
 (0)