Skip to content

Commit 9c5f71c

Browse files
authored
use read-only variants of {STRING/VECTOR}_PTR (#1317)
* use read-only variants of {STRING/VECTOR}_PTR * another const_cast * one more const * fix version checks * require newer R
1 parent 5189611 commit 9c5f71c

File tree

7 files changed

+63
-9
lines changed

7 files changed

+63
-9
lines changed

ChangeLog

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2024-07-07 Kevin Ushey <[email protected]>
2+
3+
* inst/include/Rcpp/internal/SEXP_Iterator.h: Avoid using VECTOR_PTR
4+
* inst/include/Rcpp/vector/Subsetter.h: Avoid using STRING_PTR
5+
* inst/include/RcppCommon.h: Include compatibility defines
6+
* src/barrier.cpp: Avoid using {STRING/VECTOR}_PTR
7+
* inst/include/Rcpp/r/compat.h: Include compatibility defines
8+
19
2024-06-22 Dirk Eddelbuettel <[email protected]>
210

311
* DESCRIPTION (Version, Date): Roll micro version

inst/include/Rcpp/internal/SEXP_Iterator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class SEXP_Iterator {
3737

3838
SEXP_Iterator( ): ptr(){} ;
3939
SEXP_Iterator( const SEXP_Iterator& other) : ptr(other.ptr){} ;
40-
SEXP_Iterator( const VECTOR& vec ) : ptr( get_vector_ptr(vec) ){} ;
40+
SEXP_Iterator( const VECTOR& vec ) : ptr( RCPP_VECTOR_PTR(vec) ){} ;
4141

4242
SEXP_Iterator& operator=(const SEXP_Iterator& other){ ptr = other.ptr ; return *this ;}
4343

inst/include/Rcpp/r/compat.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
//
3+
// compat.h: Rcpp R/C++ interface class library -- compatibility defines
4+
//
5+
// Copyright (C) 2024 Dirk Eddelbuettel, Kevin Ushey
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#ifndef RCPP_R_COMPAT_H
23+
#define RCPP_R_COMPAT_H
24+
25+
#include <Rversion.h>
26+
27+
#if R_VERSION >= R_Version(4, 4, 2)
28+
# define RCPP_STRING_PTR STRING_PTR_RO
29+
#else
30+
# define RCPP_STRING_PTR STRING_PTR
31+
#endif
32+
33+
#if R_VERSION >= R_Version(4, 4, 2)
34+
# define RCPP_VECTOR_PTR VECTOR_PTR_RO
35+
#else
36+
# define RCPP_VECTOR_PTR VECTOR_PTR
37+
#endif
38+
39+
#endif /* RCPP_R_COMPAT_H */

inst/include/Rcpp/vector/Subsetter.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@ class SubsetProxy {
174174
indices.reserve(rhs_n);
175175
SEXP names = Rf_getAttrib(lhs, R_NamesSymbol);
176176
if (Rf_isNull(names)) stop("names is null");
177-
SEXP* namesPtr = STRING_PTR(names);
178-
SEXP* rhsPtr = STRING_PTR(rhs);
177+
const SEXP* namesPtr = RCPP_STRING_PTR(names);
178+
const SEXP* rhsPtr = RCPP_STRING_PTR(rhs);
179179
for (R_xlen_t i = 0; i < rhs_n; ++i) {
180-
SEXP* match = std::find(namesPtr, namesPtr + lhs_n, *(rhsPtr + i));
180+
const SEXP* match = std::find(namesPtr, namesPtr + lhs_n, *(rhsPtr + i));
181181
if (match == namesPtr + lhs_n)
182182
stop("not found");
183183
indices.push_back(match - namesPtr);

inst/include/RcppCommon.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// #define RCPP_DEBUG_MODULE_LEVEL 1
2929

3030
#include <Rcpp/r/headers.h>
31+
#include <Rcpp/r/compat.h>
3132

3233
/**
3334
* \brief Rcpp API

src/api.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ namespace Rcpp {
112112
case BCODESXP: return "BCODESXP";
113113
case EXTPTRSXP: return "EXTPTRSXP";
114114
case WEAKREFSXP: return "WEAKREFSXP";
115-
#if R_Version >= R_Version(4,4,0) // replaces S4SXP in R 4.4.0
115+
#if R_VERSION >= R_Version(4,4,0) // replaces S4SXP in R 4.4.0
116116
case OBJSXP: return Rf_isS4(x) ? "S4SXP" : "OBJSXP"; // cf src/main/inspect.c
117117
#else
118118
case S4SXP: return "S4SXP";

src/barrier.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@
2222
#define COMPILING_RCPP
2323

2424
#define USE_RINTERNALS
25+
26+
#include <algorithm>
2527
#include <Rinternals.h>
28+
2629
#include <Rcpp/barrier.h>
27-
#include "internal.h"
28-
#include <algorithm>
2930
#include <Rcpp/protection/Shield.h>
31+
#include <Rcpp/r/compat.h>
32+
33+
#include "internal.h"
3034

3135
// [[Rcpp::register]]
3236
SEXP get_string_elt(SEXP x, R_xlen_t i) { // #nocov start
@@ -50,7 +54,8 @@ void char_set_string_elt(SEXP x, R_xlen_t i, const char* value) {
5054

5155
// [[Rcpp::register]]
5256
SEXP* get_string_ptr(SEXP x) {
53-
return STRING_PTR(x);
57+
// TODO: should we deprecate this?
58+
return const_cast<SEXP*>(RCPP_STRING_PTR(x));
5459
}
5560

5661
// [[Rcpp::register]]
@@ -65,7 +70,8 @@ void set_vector_elt(SEXP x, R_xlen_t i, SEXP value) {
6570

6671
// [[Rcpp::register]]
6772
SEXP* get_vector_ptr(SEXP x) {
68-
return VECTOR_PTR(x); // #nocov end
73+
// TODO: should we deprecate this?
74+
return const_cast<SEXP*>(RCPP_VECTOR_PTR(x)); // #nocov end
6975
}
7076

7177
// [[Rcpp::register]]

0 commit comments

Comments
 (0)