1
1
/*
2
2
* R : A Computer Language for Statistical Data Analysis
3
- * Copyright (C) 2016--2017 The R Core Team
3
+ * Copyright (C) 2016--2023 The R Core Team
4
4
*
5
5
* This program is free software; you can redistribute it and/or modify
6
6
* it under the terms of the GNU General Public License as published by
@@ -134,6 +134,7 @@ static void SET_ALTREP_CLASS(SEXP x, SEXP class)
134
134
#define ALTRAW_METHODS_TABLE (x ) GENERIC_METHODS_TABLE(x, altraw)
135
135
#define ALTCOMPLEX_METHODS_TABLE (x ) GENERIC_METHODS_TABLE(x, altcomplex)
136
136
#define ALTSTRING_METHODS_TABLE (x ) GENERIC_METHODS_TABLE(x, altstring)
137
+ #define ALTLIST_METHODS_TABLE (x ) GENERIC_METHODS_TABLE(x, altlist)
137
138
138
139
#define ALTREP_METHODS \
139
140
R_altrep_UnserializeEX_method_t UnserializeEX; \
@@ -196,6 +197,11 @@ static void SET_ALTREP_CLASS(SEXP x, SEXP class)
196
197
R_altstring_Is_sorted_method_t Is_sorted; \
197
198
R_altstring_No_NA_method_t No_NA
198
199
200
+ #define ALTLIST_METHODS \
201
+ ALTVEC_METHODS; \
202
+ R_altlist_Elt_method_t Elt; \
203
+ R_altlist_Set_elt_method_t Set_elt
204
+
199
205
typedef struct { ALTREP_METHODS ; } altrep_methods_t ;
200
206
typedef struct { ALTVEC_METHODS ; } altvec_methods_t ;
201
207
typedef struct { ALTINTEGER_METHODS ; } altinteger_methods_t ;
@@ -204,6 +210,7 @@ typedef struct { ALTLOGICAL_METHODS; } altlogical_methods_t;
204
210
typedef struct { ALTRAW_METHODS ; } altraw_methods_t ;
205
211
typedef struct { ALTCOMPLEX_METHODS ; } altcomplex_methods_t ;
206
212
typedef struct { ALTSTRING_METHODS ; } altstring_methods_t ;
213
+ typedef struct { ALTLIST_METHODS ; } altlist_methods_t ;
207
214
208
215
/* Macro to extract first element from ... macro argument.
209
216
From Richard Hansen's answer in
@@ -223,6 +230,7 @@ typedef struct { ALTSTRING_METHODS; } altstring_methods_t;
223
230
#define ALTRAW_DISPATCH (fun , ...) DO_DISPATCH(ALTRAW, fun, __VA_ARGS__)
224
231
#define ALTCOMPLEX_DISPATCH (fun , ...) DO_DISPATCH(ALTCOMPLEX, fun, __VA_ARGS__)
225
232
#define ALTSTRING_DISPATCH (fun , ...) DO_DISPATCH(ALTSTRING, fun, __VA_ARGS__)
233
+ #define ALTLIST_DISPATCH (fun , ...) DO_DISPATCH(ALTLIST, fun, __VA_ARGS__)
226
234
227
235
228
236
/*
@@ -541,6 +549,37 @@ int STRING_NO_NA(SEXP x)
541
549
return ALTREP (x ) ? ALTSTRING_DISPATCH (No_NA , x ) : 0 ;
542
550
}
543
551
552
+ SEXP /*attribute_hidden*/ ALTLIST_ELT (SEXP x , R_xlen_t i )
553
+ {
554
+ SEXP val = NULL ;
555
+
556
+ /**** move GC disabling into method? */
557
+ if (R_in_gc )
558
+ error ("cannot get ALTLIST_ELT during GC" );
559
+ R_CHECK_THREAD ;
560
+ int enabled = R_GCEnabled ;
561
+ R_GCEnabled = FALSE;
562
+
563
+ val = ALTLIST_DISPATCH (Elt , x , i );
564
+
565
+ R_GCEnabled = enabled ;
566
+ return val ;
567
+ }
568
+
569
+ void attribute_hidden ALTLIST_SET_ELT (SEXP x , R_xlen_t i , SEXP v )
570
+ {
571
+ /**** move GC disabling into method? */
572
+ if (R_in_gc )
573
+ error ("cannot set ALTLIST_ELT during GC" );
574
+ R_CHECK_THREAD ;
575
+ int enabled = R_GCEnabled ;
576
+ R_GCEnabled = FALSE;
577
+
578
+ ALTLIST_DISPATCH (Set_elt , x , i , v );
579
+
580
+ R_GCEnabled = enabled ;
581
+ }
582
+
544
583
SEXP ALTINTEGER_SUM (SEXP x , Rboolean narm )
545
584
{
546
585
return ALTINTEGER_DISPATCH (Sum , x , narm );
@@ -801,6 +840,25 @@ static void altstring_Set_elt_default(SEXP x, R_xlen_t i, SEXP v)
801
840
static int altstring_Is_sorted_default (SEXP x ) { return UNKNOWN_SORTEDNESS ; }
802
841
static int altstring_No_NA_default (SEXP x ) { return 0 ; }
803
842
843
+ static SEXP altlist_Elt_default (SEXP x , R_xlen_t i )
844
+ {
845
+ error ("ALTLIST classes must provide an Elt method" );
846
+ }
847
+
848
+ static void altlist_Set_elt_default (SEXP x , R_xlen_t i , SEXP v )
849
+ {
850
+ error ("ALTLIST classes must provide a Set_elt method" );
851
+ }
852
+
853
+ static void * altlist_Dataptr_default (SEXP x , Rboolean writeable )
854
+ {
855
+ error ("ALTLIST classes do not have a Dataptr method" );
856
+ }
857
+
858
+ static const void * altlist_Dataptr_or_null_default (SEXP x )
859
+ {
860
+ error ("ALTLIST classes do not have a Dataptr_or_null method" );
861
+ }
804
862
805
863
/**
806
864
** ALTREP Initial Method Tables
@@ -925,6 +983,24 @@ static altstring_methods_t altstring_default_methods = {
925
983
};
926
984
927
985
986
+
987
+ static altlist_methods_t altlist_default_methods = {
988
+ .UnserializeEX = altrep_UnserializeEX_default ,
989
+ .Unserialize = altrep_Unserialize_default ,
990
+ .Serialized_state = altrep_Serialized_state_default ,
991
+ .DuplicateEX = altrep_DuplicateEX_default ,
992
+ .Duplicate = altrep_Duplicate_default ,
993
+ .Coerce = altrep_Coerce_default ,
994
+ .Inspect = altrep_Inspect_default ,
995
+ .Length = altrep_Length_default ,
996
+ .Dataptr = altlist_Dataptr_default ,
997
+ .Dataptr_or_null = altlist_Dataptr_or_null_default ,
998
+ .Extract_subset = altvec_Extract_subset_default ,
999
+ .Elt = altlist_Elt_default ,
1000
+ .Set_elt = altlist_Set_elt_default
1001
+ };
1002
+
1003
+
928
1004
/**
929
1005
** Class Constructors
930
1006
**/
@@ -958,6 +1034,7 @@ make_altrep_class(int type, const char *cname, const char *pname, DllInfo *dll)
958
1034
case RAWSXP : MAKE_CLASS (class , altraw ); break ;
959
1035
case CPLXSXP : MAKE_CLASS (class , altcomplex ); break ;
960
1036
case STRSXP : MAKE_CLASS (class , altstring ); break ;
1037
+ case VECSXP : MAKE_CLASS (class , altlist ); break ;
961
1038
default : error ("unsupported ALTREP class" );
962
1039
}
963
1040
RegisterClass (class , type , cname , pname , dll );
@@ -976,6 +1053,7 @@ make_altrep_class(int type, const char *cname, const char *pname, DllInfo *dll)
976
1053
}
977
1054
978
1055
DEFINE_CLASS_CONSTRUCTOR (altstring , STRSXP )
1056
+ DEFINE_CLASS_CONSTRUCTOR (altlist , VECSXP )
979
1057
DEFINE_CLASS_CONSTRUCTOR (altinteger , INTSXP )
980
1058
DEFINE_CLASS_CONSTRUCTOR (altreal , REALSXP )
981
1059
DEFINE_CLASS_CONSTRUCTOR (altlogical , LGLSXP )
@@ -991,6 +1069,7 @@ static void reinit_altrep_class(SEXP class)
991
1069
case LGLSXP : INIT_CLASS (class , altlogical ); break ;
992
1070
case RAWSXP : INIT_CLASS (class , altraw ); break ;
993
1071
case CPLXSXP : INIT_CLASS (class , altcomplex ); break ;
1072
+ case VECSXP : INIT_CLASS (class , altlist ); break ;
994
1073
default : error ("unsupported ALTREP class" );
995
1074
}
996
1075
}
@@ -1008,6 +1087,18 @@ static void reinit_altrep_class(SEXP class)
1008
1087
m->MNAME = fun; \
1009
1088
}
1010
1089
1090
+ #define DEFINE_METHOD_SETTER_NOLIST (CNAME , MNAME ) \
1091
+ void R_set_##CNAME##_##MNAME##_method(R_altrep_class_t cls, \
1092
+ R_##CNAME##_##MNAME##_method_t fun) \
1093
+ { \
1094
+ CNAME##_methods_t *m = CLASS_METHODS_TABLE(R_SEXP(cls)); \
1095
+ if (m->MNAME == altlist_##MNAME##_default) { \
1096
+ error("ALTLIST classes do not have a ##MNAME## method"); \
1097
+ } else { \
1098
+ m->MNAME = fun; \
1099
+ } \
1100
+ }
1101
+
1011
1102
DEFINE_METHOD_SETTER (altrep , UnserializeEX )
1012
1103
DEFINE_METHOD_SETTER (altrep , Unserialize )
1013
1104
DEFINE_METHOD_SETTER (altrep , Serialized_state )
@@ -1017,8 +1108,8 @@ DEFINE_METHOD_SETTER(altrep, Coerce)
1017
1108
DEFINE_METHOD_SETTER (altrep , Inspect )
1018
1109
DEFINE_METHOD_SETTER (altrep , Length )
1019
1110
1020
- DEFINE_METHOD_SETTER (altvec , Dataptr )
1021
- DEFINE_METHOD_SETTER (altvec , Dataptr_or_null )
1111
+ DEFINE_METHOD_SETTER_NOLIST (altvec , Dataptr )
1112
+ DEFINE_METHOD_SETTER_NOLIST (altvec , Dataptr_or_null )
1022
1113
DEFINE_METHOD_SETTER (altvec , Extract_subset )
1023
1114
1024
1115
DEFINE_METHOD_SETTER (altinteger , Elt )
@@ -1054,6 +1145,8 @@ DEFINE_METHOD_SETTER(altstring, Set_elt)
1054
1145
DEFINE_METHOD_SETTER (altstring , Is_sorted )
1055
1146
DEFINE_METHOD_SETTER (altstring , No_NA )
1056
1147
1148
+ DEFINE_METHOD_SETTER (altlist , Elt )
1149
+ DEFINE_METHOD_SETTER (altlist , Set_elt )
1057
1150
1058
1151
/**
1059
1152
** ALTREP Object Constructor and Utility Functions
0 commit comments