diff --git a/NEWS.md b/NEWS.md index 99b463fc..abe0f9f8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # cpp11 (development version) +* Fixed `+` and `+=` operators of `r_vector::[const_]iterator` to conform the *iterators* concept: + `+=` updates the iterator, and `+` returns the updated copy, while keeping the original unchanged (@alyst, #231) * Remove undefined behavior when constructing global `cpp11::sexp`s (#224) * `cpp_register()` now includes `attribute_visible` in the init function, so packages compiled with `C_VISIBILITY` will find the init function. * added `as_double()` and `as_integer()` method to coerce integers to doubles and doubles to integers to doubles (@sbearrows, #46) diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 58b2f91d..09479010 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -149,7 +149,7 @@ class r_vector { const_iterator(const r_vector* data, R_xlen_t pos); - inline const_iterator& operator+(R_xlen_t pos); + inline const_iterator operator+(R_xlen_t pos); inline ptrdiff_t operator-(const const_iterator& other) const; inline const_iterator& operator++(); @@ -275,7 +275,8 @@ class r_vector : public cpp11::r_vector { using cpp11::r_vector::const_iterator::operator!=; - inline iterator& operator+(R_xlen_t rhs); + inline iterator& operator+=(R_xlen_t rhs); + inline iterator operator+(R_xlen_t rhs); }; r_vector() = default; @@ -498,13 +499,11 @@ inline ptrdiff_t r_vector::const_iterator::operator-( } template -inline typename r_vector::const_iterator& r_vector::const_iterator::operator+( +inline typename r_vector::const_iterator r_vector::const_iterator::operator+( R_xlen_t rhs) { - pos_ += rhs; - if (data_->is_altrep() && pos_ >= block_start_ + length_) { - fill_buf(pos_); - } - return *this; + auto it = *this; + it += rhs; + return it; } template @@ -623,7 +622,7 @@ inline typename r_vector::iterator& r_vector::iterator::operator++() { } template -inline typename r_vector::iterator& r_vector::iterator::operator+(R_xlen_t rhs) { +inline typename r_vector::iterator& r_vector::iterator::operator+=(R_xlen_t rhs) { pos_ += rhs; if (data_.is_altrep() && pos_ >= block_start_ + length_) { fill_buf(pos_); @@ -631,6 +630,13 @@ inline typename r_vector::iterator& r_vector::iterator::operator+(R_xlen_t return *this; } +template +inline typename r_vector::iterator r_vector::iterator::operator+(R_xlen_t rhs) { + auto it = *this; + it += rhs; + return it; +} + template inline typename r_vector::iterator r_vector::begin() const { return iterator(*this, 0);