@@ -328,18 +328,16 @@ static struct {
328
328
329
329
static SEXP list_ = get_preserve_list ();
330
330
331
- // Get references to head, tail of the precious list.
332
- SEXP head = list_;
333
- SEXP tail = CDR (list_);
331
+ // Add a new cell that points to the previous end.
332
+ SEXP cell = PROTECT (Rf_cons (list_, CDR (list_)));
334
333
335
- // Add a new cell that points to the current head + tail.
336
- SEXP cell = PROTECT (Rf_cons (head, tail));
337
334
SET_TAG (cell, obj);
338
335
339
- // Update the head + tail to point at the newly-created cell,
340
- // effectively inserting that cell between the current head + tail.
341
- SETCDR (head, cell);
342
- SETCAR (tail, cell);
336
+ SETCDR (list_, cell);
337
+
338
+ if (CDR (cell) != R_NilValue) {
339
+ SETCAR (CDR (cell), cell);
340
+ }
343
341
344
342
UNPROTECT (2 );
345
343
@@ -367,25 +365,29 @@ static struct {
367
365
#endif
368
366
}
369
367
370
- void release (SEXP cell ) {
371
- if (cell == R_NilValue) {
368
+ void release (SEXP token ) {
369
+ if (token == R_NilValue) {
372
370
return ;
373
371
}
374
372
375
373
#ifdef CPP11_USE_PRESERVE_OBJECT
376
- R_ReleaseObject (cell );
374
+ R_ReleaseObject (token );
377
375
return ;
378
376
#endif
379
377
380
- // Get a reference to the cells before and after the token.
381
- SEXP lhs = CAR (cell);
382
- SEXP rhs = CDR (cell);
378
+ SEXP before = CAR (token);
379
+
380
+ SEXP after = CDR (token);
381
+
382
+ if (before == R_NilValue && after == R_NilValue) {
383
+ Rf_error (" should never happen" );
384
+ }
385
+
386
+ SETCDR (before, after);
383
387
384
- // Remove the cell from the precious list -- effectively, we do this
385
- // by updating the 'lhs' and 'rhs' references to point at each-other,
386
- // effectively removing any references to the cell in the pairlist.
387
- SETCDR (lhs, rhs);
388
- SETCAR (rhs, lhs);
388
+ if (after != R_NilValue) {
389
+ SETCAR (after, before);
390
+ }
389
391
}
390
392
391
393
private:
@@ -425,24 +427,18 @@ static struct {
425
427
426
428
static SEXP get_preserve_list () {
427
429
static SEXP preserve_list = R_NilValue;
430
+
428
431
if (TYPEOF (preserve_list) != LISTSXP) {
429
432
preserve_list = get_preserve_xptr_addr ();
430
433
if (TYPEOF (preserve_list) != LISTSXP) {
431
- preserve_list = Rf_cons (R_NilValue, Rf_cons ( R_NilValue, R_NilValue) );
434
+ preserve_list = Rf_cons (R_NilValue, R_NilValue);
432
435
R_PreserveObject (preserve_list);
433
436
set_preserve_xptr (preserve_list);
434
437
}
435
-
436
- // NOTE: Because older versions of cpp11 (<= 0.4.2) initialized the
437
- // precious_list with a single cell, we might need to detect and update
438
- // an existing empty precious list so that we have a second cell following.
439
- if (CDR (preserve_list) == R_NilValue)
440
- SETCDR (preserve_list, Rf_cons (R_NilValue, R_NilValue));
441
438
}
442
439
443
440
return preserve_list;
444
441
}
445
-
446
- } preserved;
447
-
442
+ } // namespace cpp11
443
+ preserved;
448
444
} // namespace cpp11
0 commit comments