Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a universal reserve() method #373

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions inst/include/cpp11/doubles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ typedef r_vector<double> doubles;

namespace writable {

template <>
inline SEXPTYPE r_vector<double>::get_sexptype() {
return REALSXP;
}

template <>
inline typename r_vector<double>::proxy& r_vector<double>::proxy::operator=(
const double& rhs) {
Expand Down Expand Up @@ -104,18 +109,6 @@ inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
}
}

template <>
inline void r_vector<double>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](REALSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
SEXP old_protect = protect_;
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

data_p_ = REAL(data_);
capacity_ = new_capacity;
}

template <>
inline void r_vector<double>::push_back(double value) {
while (length_ >= capacity_) {
Expand Down
21 changes: 5 additions & 16 deletions inst/include/cpp11/integers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ typedef r_vector<int> integers;

namespace writable {

template <>
inline SEXPTYPE r_vector<int>::get_sexptype() {
return INTSXP;
}

template <>
inline typename r_vector<int>::proxy& r_vector<int>::proxy::operator=(const int& rhs) {
if (is_altrep_) {
Expand All @@ -80,22 +85,6 @@ template <>
inline r_vector<int>::r_vector(std::initializer_list<int> il)
: cpp11::r_vector<int>(as_sexp(il)), capacity_(il.size()) {}

template <>
inline void r_vector<int>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](INTSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
SEXP old_protect = protect_;

// Protect the new data
protect_ = detail::store::insert(data_);

// Release the old protection;
detail::store::release(old_protect);

data_p_ = INTEGER(data_);
capacity_ = new_capacity;
}

template <>
inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
: cpp11::r_vector<int>(safe[Rf_allocVector](INTSXP, il.size())),
Expand Down
17 changes: 5 additions & 12 deletions inst/include/cpp11/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ typedef r_vector<SEXP> list;

namespace writable {

template <>
inline SEXPTYPE r_vector<SEXP>::get_sexptype() {
return VECSXP;
}

template <>
inline typename r_vector<SEXP>::proxy& r_vector<SEXP>::proxy::operator=(const SEXP& rhs) {
SET_VECTOR_ELT(data_, index_, rhs);
Expand Down Expand Up @@ -108,18 +113,6 @@ inline r_vector<SEXP>::r_vector(std::initializer_list<named_arg> il)
}
}

template <>
inline void r_vector<SEXP>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](VECSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);

SEXP old_protect = protect_;
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

capacity_ = new_capacity;
}

template <>
inline void r_vector<SEXP>::push_back(SEXP value) {
while (length_ >= capacity_) {
Expand Down
18 changes: 5 additions & 13 deletions inst/include/cpp11/logicals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ typedef r_vector<r_bool> logicals;

namespace writable {

template <>
inline SEXPTYPE r_vector<r_bool>::get_sexptype() {
return LGLSXP;
}

template <>
inline typename r_vector<r_bool>::proxy& r_vector<r_bool>::proxy::operator=(
const r_bool& rhs) {
Expand Down Expand Up @@ -110,19 +115,6 @@ inline r_vector<r_bool>::r_vector(std::initializer_list<named_arg> il)
}
}

template <>
inline void r_vector<r_bool>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](LGLSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
SEXP old_protect = protect_;
protect_ = detail::store::insert(data_);

detail::store::release(old_protect);

data_p_ = LOGICAL(data_);
capacity_ = new_capacity;
}

template <>
inline void r_vector<r_bool>::push_back(r_bool value) {
while (length_ >= capacity_) {
Expand Down
25 changes: 23 additions & 2 deletions inst/include/cpp11/r_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,6 @@ class r_vector : public cpp11::r_vector<T> {
void pop_back();

void resize(R_xlen_t count);

/// Implemented in specialization
void reserve(R_xlen_t new_capacity);

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

private:
/// Implemented in specialization
static SEXPTYPE get_sexptype();

using cpp11::r_vector<T>::get_p;
};
} // namespace writable
Expand Down Expand Up @@ -886,6 +887,26 @@ inline void r_vector<T>::resize(R_xlen_t count) {
length_ = count;
}

/// Reserve a new capacity and copy all elements over
///
/// SAFETY: The new capacity is allowed to be smaller than the current capacity, which
/// is used in the `SEXP` conversion operator during truncation, but if that occurs then
/// we also need to update the `length_`, so if you need to truncate then you should call
/// `resize()` instead.
template <typename T>
inline void r_vector<T>::reserve(R_xlen_t new_capacity) {
SEXP old_protect = protect_;

data_ = (data_ == R_NilValue) ? safe[Rf_allocVector](get_sexptype(), new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
protect_ = detail::store::insert(data_);
is_altrep_ = ALTREP(data_);
data_p_ = get_p(is_altrep_, data_);
capacity_ = new_capacity;

detail::store::release(old_protect);
}

template <typename T>
inline typename r_vector<T>::iterator r_vector<T>::insert(R_xlen_t pos, T value) {
push_back(value);
Expand Down
18 changes: 5 additions & 13 deletions inst/include/cpp11/raws.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ typedef r_vector<uint8_t> raws;

namespace writable {

template <>
inline SEXPTYPE r_vector<uint8_t>::get_sexptype() {
return RAWSXP;
}

template <>
inline typename r_vector<uint8_t>::proxy& r_vector<uint8_t>::proxy::operator=(
const uint8_t& rhs) {
Expand Down Expand Up @@ -119,19 +124,6 @@ inline r_vector<uint8_t>::r_vector(std::initializer_list<named_arg> il)
}
}

template <>
inline void r_vector<uint8_t>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](RAWSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);

SEXP old_protect = protect_;
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

data_p_ = RAW(data_);
capacity_ = new_capacity;
}

template <>
inline void r_vector<uint8_t>::push_back(uint8_t value) {
while (length_ >= capacity_) {
Expand Down
17 changes: 5 additions & 12 deletions inst/include/cpp11/strings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ typedef r_vector<r_string> strings;

namespace writable {

template <>
inline SEXPTYPE r_vector<r_string>::get_sexptype() {
return STRSXP;
}

template <>
inline typename r_vector<r_string>::proxy& r_vector<r_string>::proxy::operator=(
const r_string& rhs) {
Expand Down Expand Up @@ -136,18 +141,6 @@ inline r_vector<r_string>::r_vector(std::initializer_list<named_arg> il)
}
}

template <>
inline void r_vector<r_string>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](STRSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);

SEXP old_protect = protect_;
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

capacity_ = new_capacity;
}

template <>
inline void r_vector<r_string>::push_back(r_string value) {
while (length_ >= capacity_) {
Expand Down
Loading