Skip to content

Commit d412399

Browse files
authored
Names of named args in list are now resized along with list elements (#212)
1 parent b484a55 commit d412399

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Error messages now output original file name rather than the temporary file name (@sbearrows, #194)
66
* Fixed bug when running `cpp_source()` on the same file more than once (@sbearrows, #202)
77
* Removed internal instances of `cpp11::stop()` and replaced with C++ exceptions (@sbearrows, #203)
8+
* Names of named lists are now resized along with the list elements (@sbearrows, #206)
89
* Added optionally formatting to `stop()` and `warning()` using {fmt} library (@sbearrows, #169)
910

1011
# cpp11 0.3.1

cpp11test/src/test-list.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,17 @@ context("list-C++") {
141141

142142
expect_false(y.empty());
143143
}
144+
145+
test_that("names of named lists are also resized") {
146+
cpp11::writable::list x;
147+
x.push_back({"n1"_nm = 1});
148+
x.push_back({"n2"_nm = 2});
149+
x.push_back({"n3"_nm = 3});
150+
x.push_back({"n4"_nm = 4});
151+
x.push_back({"n5"_nm = 5});
152+
x = SEXP(x);
153+
154+
cpp11::strings nms(x.names());
155+
expect_true(x.size() == nms.size());
156+
}
144157
}

inst/include/cpp11/r_vector.hpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -878,17 +878,28 @@ inline void r_vector<T>::clear() {
878878
length_ = 0;
879879
}
880880

881+
inline SEXP truncate(SEXP x, R_xlen_t length, R_xlen_t capacity) {
882+
#if R_VERSION >= R_Version(3, 4, 0)
883+
SETLENGTH(x, length);
884+
SET_TRUELENGTH(x, capacity);
885+
SET_GROWABLE_BIT(x);
886+
#else
887+
x = safe[Rf_lengthgets](x, length_);
888+
#endif
889+
return x;
890+
}
891+
881892
template <typename T>
882893
inline r_vector<T>::operator SEXP() const {
883894
if (length_ < capacity_) {
884-
#if R_VERSION >= R_Version(3, 4, 0)
885-
SETLENGTH(data_, length_);
886-
SET_TRUELENGTH(data_, capacity_);
887-
SET_GROWABLE_BIT(data_);
888-
#else
889895
auto* p = const_cast<r_vector<T>*>(this);
890-
p->data_ = safe[Rf_lengthgets](data_, length_);
891-
#endif
896+
p->data_ = truncate(p->data_, length_, capacity_);
897+
SEXP nms = names();
898+
auto nms_size = Rf_xlength(nms);
899+
if ((nms_size > 0) && (length_ < nms_size)) {
900+
nms = truncate(nms, length_, capacity_);
901+
names() = nms;
902+
}
892903
}
893904
return data_;
894905
}

0 commit comments

Comments
 (0)