Skip to content

Commit 93291b6

Browse files
Fix ListOf inheritance and compatibility of NamesProxy (#1464)
* fix ListOf inheritance * update ChangeLog * Refine NamesProxy setter to set only non-NULL values * allow name removal * complete test cases for setting NamesProxy --------- Co-authored-by: Dirk Eddelbuettel <edd@debian.org>
1 parent 777a34c commit 93291b6

File tree

5 files changed

+29
-26
lines changed

5 files changed

+29
-26
lines changed

ChangeLog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88

99
* inst/include/Rcpp/Function.h: Further refinement for 4.6.0 to not
1010
require R_NamespaceRegistry, using R_getRegisteredNamespace() instead
11+
2026-04-06 Iñaki Ucar <iucar@fedoraproject.org>
12+
13+
* inst/tinytest/test_vector.R: Complete test cases for setting NamesProxy
14+
* inst/tinytest/cpp/Vector.cpp: Idem
15+
16+
2026-04-03 Dirk Eddelbuettel <edd@debian.org>
17+
18+
* inst/include/Rcpp/proxy/NamesProxy.h (set): Only set non-null values
1119

1220
2026-04-01 Mattias Ellert <mattias.ellert@physics.uu.se>
1321

@@ -34,6 +42,10 @@
3442
invalid pointer for empty vectors, which causes UB in e.g. std::copy
3543
* inst/tinytest/test_vector.R: Add tests for std::copy
3644
* inst/tinytest/cpp/Vector.cpp: Idem
45+
2026-03-27 Iñaki Ucar <iucar@fedoraproject.org>
46+
47+
* inst/include/Rcpp/vector/ListOf.h: Fix inheritance
48+
* inst/include/Rcpp/proxy/NamesProxy.h: Fix compatibility
3749

3850
2026-03-26 Dirk Eddelbuettel <edd@debian.org>
3951

inst/include/Rcpp/proxy/NamesProxy.h

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// Copyright (C) 2013 Romain Francois
1+
// Copyright (C) 2013 - 2025 Romain François
2+
// Copyright (C) 2026 Romain François, Iñaki Ucar and Dirk Eddelbuettel
23
//
34
// This file is part of Rcpp.
45
//
@@ -43,23 +44,13 @@ class NamesProxyPolicy{
4344
CLASS& parent;
4445

4546
SEXP get() const {
46-
return RCPP_GET_NAMES(parent.get__()) ;
47+
return RCPP_GET_NAMES(parent) ;
4748
}
4849

4950
void set(SEXP x) {
50-
Shield<SEXP> safe_x(x);
51-
52-
/* check if we can use a fast version */
53-
if( TYPEOF(x) == STRSXP && parent.size() == Rf_length(x) ){ // #nocov start
54-
Rf_namesgets(parent, x);
55-
} else {
56-
/* use the slower and more flexible version (callback to R) */
57-
SEXP namesSym = Rf_install( "names<-" );
58-
Shield<SEXP> call(Rf_lang3(namesSym, parent, x));
59-
Shield<SEXP> new_vec(Rcpp_fast_eval(call, R_GlobalEnv));
60-
parent.set__(new_vec); // #nocov end
61-
}
62-
51+
if (!Rf_isNull(x))
52+
Rf_namesgets(parent, x);
53+
else Rf_setAttrib(parent, R_NamesSymbol, x);
6354
}
6455

6556
} ;
@@ -74,7 +65,7 @@ class NamesProxyPolicy{
7465
const CLASS& parent;
7566

7667
SEXP get() const {
77-
return RCPP_GET_NAMES(parent.get__()) ;
68+
return RCPP_GET_NAMES(parent) ;
7869
}
7970

8071
} ;

inst/include/Rcpp/vector/ListOf.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ListOf.h: Rcpp R/C++ interface class library -- templated List container
22
//
3-
// Copyright (C) 2014 Dirk Eddelbuettel, Romain Francois and Kevin Ushey
3+
// Copyright (C) 2014 - 2025 Dirk Eddelbuettel, Romain François and Kevin Ushey
4+
// Copyright (C) 2026 Dirk Eddelbuettel, Romain François, Kevin Ushey and Iñaki Ucar
45
//
56
// This file is part of Rcpp.
67
//
@@ -24,9 +25,9 @@ namespace Rcpp {
2425

2526
template <typename T>
2627
class ListOf
27-
: public NamesProxyPolicy<T>
28-
, public AttributeProxyPolicy<T>
29-
, public RObjectMethods<T>
28+
: public NamesProxyPolicy<ListOf<T>>
29+
, public AttributeProxyPolicy<ListOf<T>>
30+
, public RObjectMethods<ListOf<T>>
3031
{
3132

3233
public:

inst/tinytest/cpp/Vector.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,7 @@ IntegerVector integer_range_ctor_2(){
171171
}
172172

173173
// [[Rcpp::export]]
174-
IntegerVector integer_names_set(){
175-
IntegerVector y(2) ;
176-
std::vector<std::string> names(2) ;
177-
names[0] = "foo" ;
178-
names[1] = "bar" ;
174+
IntegerVector integer_names_set(IntegerVector y, SEXP names) {
179175
y.names() = names ;
180176
return y ;
181177
}

inst/tinytest/test_vector.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ expect_equal( fun(), 0:3, info = "assign(int*, int*)" )
118118

119119
# test.IntegerVector.names.set <- function(){
120120
fun <- integer_names_set
121-
expect_equal(names(fun()), c("foo", "bar"), info = "Vector::names" )
121+
x <- 1:2
122+
expect_equal(names(fun(x, c("foo", "bar"))), c("foo", "bar"), info = "Vector::names set" )
123+
expect_equal(names(fun(x, "foo")), c("foo", NA), info = "Vector::names set shorter" )
124+
expect_equal(names(fun(x, NULL)), NULL, info = "Vector::names unset" )
122125

123126
# test.IntegerVector.names.get <- function(){
124127
fun <- integer_names_get

0 commit comments

Comments
 (0)