Skip to content

Commit 5167fa4

Browse files
authored
Move the smarts of fill_buf() to r_vector.hpp (#379)
1 parent ba8ea8a commit 5167fa4

File tree

7 files changed

+78
-29
lines changed

7 files changed

+78
-29
lines changed

inst/include/cpp11/doubles.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,16 @@ inline typename r_vector<double>::underlying_type* r_vector<double>::get_p(bool
4444
}
4545

4646
template <>
47-
inline void r_vector<double>::const_iterator::fill_buf(R_xlen_t pos) {
48-
length_ = std::min(64_xl, data_->size() - pos);
49-
REAL_GET_REGION(data_->data_, pos, length_, buf_.data());
50-
block_start_ = pos;
47+
inline void r_vector<double>::get_region(
48+
SEXP x, R_xlen_t i, R_xlen_t n,
49+
typename traits::get_underlying_type<double>::type* buf) {
50+
// NOPROTECT: likely too costly to unwind protect here
51+
REAL_GET_REGION(x, i, n, buf);
52+
};
53+
54+
template <>
55+
inline bool r_vector<double>::const_iterator::use_buf(bool is_altrep) {
56+
return is_altrep;
5157
}
5258

5359
typedef r_vector<double> doubles;

inst/include/cpp11/integers.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@ inline typename r_vector<int>::underlying_type* r_vector<int>::get_p(bool is_alt
4545
}
4646

4747
template <>
48-
inline void r_vector<int>::const_iterator::fill_buf(R_xlen_t pos) {
49-
length_ = std::min(64_xl, data_->size() - pos);
50-
INTEGER_GET_REGION(data_->data_, pos, length_, buf_.data());
51-
block_start_ = pos;
48+
inline void r_vector<int>::get_region(
49+
SEXP x, R_xlen_t i, R_xlen_t n,
50+
typename traits::get_underlying_type<int>::type* buf) {
51+
// NOPROTECT: likely too costly to unwind protect here
52+
INTEGER_GET_REGION(x, i, n, buf);
53+
};
54+
55+
template <>
56+
inline bool r_vector<int>::const_iterator::use_buf(bool is_altrep) {
57+
return is_altrep;
5258
}
5359

5460
typedef r_vector<int> integers;

inst/include/cpp11/list.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,15 @@ inline typename r_vector<SEXP>::underlying_type* r_vector<SEXP>::get_p(bool, SEX
5050
}
5151

5252
template <>
53-
inline void r_vector<SEXP>::const_iterator::fill_buf(R_xlen_t) {
54-
return;
53+
inline void r_vector<SEXP>::get_region(
54+
SEXP x, R_xlen_t i, R_xlen_t n,
55+
typename traits::get_underlying_type<SEXP>::type* buf) {
56+
cpp11::stop("Unreachable!");
57+
};
58+
59+
template <>
60+
inline bool r_vector<SEXP>::const_iterator::use_buf(bool is_altrep) {
61+
return false;
5562
}
5663

5764
template <>

inst/include/cpp11/logicals.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@ inline typename r_vector<r_bool>::underlying_type* r_vector<r_bool>::get_p(bool
4343
}
4444

4545
template <>
46-
inline void r_vector<r_bool>::const_iterator::fill_buf(R_xlen_t pos) {
47-
length_ = std::min(64_xl, data_->size() - pos);
48-
LOGICAL_GET_REGION(data_->data_, pos, length_, buf_.data());
49-
block_start_ = pos;
46+
inline void r_vector<r_bool>::get_region(
47+
SEXP x, R_xlen_t i, R_xlen_t n,
48+
typename traits::get_underlying_type<r_bool>::type* buf) {
49+
// NOPROTECT: likely too costly to unwind protect here
50+
LOGICAL_GET_REGION(x, i, n, buf);
51+
};
52+
53+
template <>
54+
inline bool r_vector<r_bool>::const_iterator::use_buf(bool is_altrep) {
55+
return is_altrep;
5056
}
5157

5258
typedef r_vector<r_bool> logicals;

inst/include/cpp11/r_vector.hpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,16 @@ class r_vector {
138138

139139
private:
140140
/// Implemented in specialization
141+
static bool use_buf(bool is_altrep);
141142
void fill_buf(R_xlen_t pos);
142143
};
143144

144145
private:
145146
/// Implemented in specialization
146147
static underlying_type* get_p(bool is_altrep, SEXP data);
147148
/// Implemented in specialization
149+
static void get_region(SEXP x, R_xlen_t i, R_xlen_t n, underlying_type* buf);
150+
/// Implemented in specialization
148151
static SEXP valid_type(SEXP data);
149152

150153
friend class writable::r_vector<T>;
@@ -283,6 +286,7 @@ class r_vector : public cpp11::r_vector<T> {
283286
using cpp11::r_vector<T>::const_iterator::pos_;
284287
using cpp11::r_vector<T>::const_iterator::buf_;
285288
using cpp11::r_vector<T>::const_iterator::length_;
289+
using cpp11::r_vector<T>::const_iterator::use_buf;
286290
using cpp11::r_vector<T>::const_iterator::fill_buf;
287291

288292
public:
@@ -572,15 +576,15 @@ inline typename r_vector<T>::const_iterator r_vector<T>::cend() const {
572576
template <typename T>
573577
r_vector<T>::const_iterator::const_iterator(const r_vector* data, R_xlen_t pos)
574578
: data_(data), pos_(pos), buf_() {
575-
if (data_->is_altrep()) {
579+
if (use_buf(data_->is_altrep())) {
576580
fill_buf(pos);
577581
}
578582
}
579583

580584
template <typename T>
581585
inline typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operator++() {
582586
++pos_;
583-
if (data_->is_altrep() && pos_ >= block_start_ + length_) {
587+
if (use_buf(data_->is_altrep()) && pos_ >= block_start_ + length_) {
584588
fill_buf(pos_);
585589
}
586590
return *this;
@@ -589,7 +593,7 @@ inline typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operat
589593
template <typename T>
590594
inline typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operator--() {
591595
--pos_;
592-
if (data_->is_altrep() && pos_ > 0 && pos_ < block_start_) {
596+
if (use_buf(data_->is_altrep()) && pos_ > 0 && pos_ < block_start_) {
593597
fill_buf(std::max(0_xl, pos_ - 64));
594598
}
595599
return *this;
@@ -599,7 +603,7 @@ template <typename T>
599603
inline typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operator+=(
600604
R_xlen_t i) {
601605
pos_ += i;
602-
if (data_->is_altrep() && pos_ >= block_start_ + length_) {
606+
if (use_buf(data_->is_altrep()) && pos_ >= block_start_ + length_) {
603607
fill_buf(pos_);
604608
}
605609
return *this;
@@ -609,7 +613,7 @@ template <typename T>
609613
inline typename r_vector<T>::const_iterator& r_vector<T>::const_iterator::operator-=(
610614
R_xlen_t i) {
611615
pos_ -= i;
612-
if (data_->is_altrep() && pos_ >= block_start_ + length_) {
616+
if (use_buf(data_->is_altrep()) && pos_ >= block_start_ + length_) {
613617
fill_buf(std::max(0_xl, pos_ - 64));
614618
}
615619
return *this;
@@ -666,6 +670,14 @@ inline T r_vector<T>::const_iterator::operator*() const {
666670
}
667671
}
668672

673+
template <typename T>
674+
inline void r_vector<T>::const_iterator::fill_buf(R_xlen_t pos) {
675+
using namespace cpp11::literals;
676+
length_ = std::min(64_xl, data_->size() - pos);
677+
get_region(data_->data_, pos, length_, buf_.data());
678+
block_start_ = pos;
679+
}
680+
669681
namespace writable {
670682

671683
template <typename T>
@@ -1062,15 +1074,15 @@ r_vector<T>::iterator::iterator(const r_vector& data, R_xlen_t pos)
10621074
template <typename T>
10631075
inline typename r_vector<T>::iterator& r_vector<T>::iterator::operator++() {
10641076
++pos_;
1065-
if (data_.is_altrep() && pos_ >= block_start_ + length_) {
1077+
if (use_buf(data_.is_altrep()) && pos_ >= block_start_ + length_) {
10661078
fill_buf(pos_);
10671079
}
10681080
return *this;
10691081
}
10701082

10711083
template <typename T>
10721084
inline typename r_vector<T>::proxy r_vector<T>::iterator::operator*() const {
1073-
if (data_.is_altrep()) {
1085+
if (use_buf(data_.is_altrep())) {
10741086
return proxy(
10751087
data_.data(), pos_,
10761088
const_cast<typename r_vector::underlying_type*>(&buf_[pos_ - block_start_]),
@@ -1084,7 +1096,7 @@ inline typename r_vector<T>::proxy r_vector<T>::iterator::operator*() const {
10841096
template <typename T>
10851097
inline typename r_vector<T>::iterator& r_vector<T>::iterator::operator+=(R_xlen_t rhs) {
10861098
pos_ += rhs;
1087-
if (data_.is_altrep() && pos_ >= block_start_ + length_) {
1099+
if (use_buf(data_.is_altrep()) && pos_ >= block_start_ + length_) {
10881100
fill_buf(pos_);
10891101
}
10901102
return *this;

inst/include/cpp11/raws.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,16 @@ inline typename r_vector<uint8_t>::underlying_type* r_vector<uint8_t>::get_p(
5252
}
5353

5454
template <>
55-
inline void r_vector<uint8_t>::const_iterator::fill_buf(R_xlen_t pos) {
56-
using namespace cpp11::literals;
57-
length_ = std::min(64_xl, data_->size() - pos);
58-
unwind_protect([&] { RAW_GET_REGION(data_->data_, pos, length_, buf_.data()); });
59-
block_start_ = pos;
55+
inline void r_vector<uint8_t>::get_region(
56+
SEXP x, R_xlen_t i, R_xlen_t n,
57+
typename traits::get_underlying_type<uint8_t>::type* buf) {
58+
// NOPROTECT: likely too costly to unwind protect here
59+
RAW_GET_REGION(x, i, n, buf);
60+
};
61+
62+
template <>
63+
inline bool r_vector<uint8_t>::const_iterator::use_buf(bool is_altrep) {
64+
return is_altrep;
6065
}
6166

6267
typedef r_vector<uint8_t> raws;

inst/include/cpp11/strings.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,15 @@ inline typename r_vector<r_string>::underlying_type* r_vector<r_string>::get_p(b
4040
}
4141

4242
template <>
43-
inline void r_vector<r_string>::const_iterator::fill_buf(R_xlen_t) {
44-
return;
43+
inline void r_vector<r_string>::get_region(
44+
SEXP x, R_xlen_t i, R_xlen_t n,
45+
typename traits::get_underlying_type<r_string>::type* buf) {
46+
cpp11::stop("Unreachable!");
47+
};
48+
49+
template <>
50+
inline bool r_vector<r_string>::const_iterator::use_buf(bool is_altrep) {
51+
return false;
4552
}
4653

4754
template <>

0 commit comments

Comments
 (0)