The R Project SVN R

Rev

Rev 87901 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 87901 Rev 89130
Line 584... Line 584...
584
 
584
 
585
 
585
 
586
static SEXP
586
static SEXP
587
logicalSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch, SEXP call)
587
logicalSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch, SEXP call)
588
{
588
{
589
    R_xlen_t count, i, nmax, i1, i2;
-
 
590
    int canstretch;
-
 
591
    SEXP indx;
-
 
592
    canstretch = *stretch > 0;
589
    bool canstretch = *stretch > 0;
593
    if (!canstretch && ns > nx) {
590
    if (!canstretch && ns > nx) {
594
	ECALL(call, _("(subscript) logical subscript too long"));
591
	ECALL(call, _("(subscript) logical subscript too long"));
595
    }
592
    }
596
    nmax = (ns > nx) ? ns : nx;
-
 
597
    *stretch = (ns > nx) ? ns : 0;
593
    *stretch = (ns > nx) ? ns : 0;
598
    if (ns == 0) return(allocVector(INTSXP, 0));
594
    if (ns == 0) return(allocVector(INTSXP, 0));
-
 
595
    R_xlen_t count, i, i1, i2,
-
 
596
	nmax = (ns > nx) ? ns : nx;
-
 
597
    SEXP indx; // result
-
 
598
 
599
    const int *ps = LOGICAL_RO(s);    /* Calling LOCICAL_RO here may force a
599
    const int *ps = LOGICAL_RO(s);    /* Calling LOCICAL_RO here may force a
600
					 large allocation, but no larger than
600
					 large allocation, but no larger than
601
					 the one made by R_alloc below. This
601
					 the one made by R_alloc below. This
602
					 could use rewriting to better handle
602
					 could use rewriting to better handle
603
					 a sparse logical index. */
603
					 a sparse logical index. */
Line 707... Line 707...
707
    return indx;
707
    return indx;
708
}
708
}
709
 
709
 
710
static SEXP negativeSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, SEXP call)
710
static SEXP negativeSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, SEXP call)
711
{
711
{
712
    SEXP indx;
-
 
713
    R_xlen_t stretch = 0;
-
 
714
    R_xlen_t i;
-
 
715
    PROTECT(indx = allocVector(LGLSXP, nx));
712
    SEXP indx = PROTECT(allocVector(LGLSXP, nx));
716
    int *pindx = LOGICAL(indx);
713
    int *pindx = LOGICAL(indx);
-
 
714
    R_xlen_t i;
717
    for (i = 0; i < nx; i++)
715
    for (i = 0; i < nx; i++)
718
	pindx[i] = 1;
716
	pindx[i] = 1;
719
    const int *ps = INTEGER_RO(s);
717
    const int *ps = INTEGER_RO(s);
720
    for (i = 0; i < ns; i++) {
718
    for (i = 0; i < ns; i++) {
721
	int ix = ps[i];
719
	int ix = ps[i];
722
	if (ix != 0 && ix != NA_INTEGER && -ix <= nx)
720
	if (ix != 0 && ix != NA_INTEGER && -ix <= nx)
723
	    pindx[-ix - 1] = 0;
721
	    pindx[-ix - 1] = 0;
724
    }
722
    }
-
 
723
    R_xlen_t stretch = 0;
725
    s = logicalSubscript(indx, nx, nx, &stretch, call);
724
    s = logicalSubscript(indx, nx, nx, &stretch, call);
726
    UNPROTECT(1);
725
    UNPROTECT(1);
727
    return s;
726
    return s;
728
}
727
}
729
 
728
 
730
static SEXP positiveSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx)
729
static SEXP positiveSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx)
731
{
730
{
732
    SEXP indx;
-
 
733
    R_xlen_t i, zct = 0;
731
    R_xlen_t i, zct = 0;
734
    const int *ps = INTEGER_RO(s);
732
    const int *ps = INTEGER_RO(s);
735
    for (i = 0; i < ns; i++) if (ps[i] == 0) zct++;
733
    for (i = 0; i < ns; i++) if (ps[i] == 0) zct++;
736
    if (zct) {
734
    if (zct) {
737
	indx = allocVector(INTSXP, (ns - zct));
735
	SEXP indx = allocVector(INTSXP, (ns - zct));
738
	int *pindx = INTEGER(indx);
736
	int *pindx = INTEGER(indx);
739
	for (i = 0, zct = 0; i < ns; i++)
737
	for (i = 0, zct = 0; i < ns; i++)
740
	    if (ps[i] != 0)
738
	    if (ps[i] != 0)
741
		pindx[zct++] = ps[i];
739
		pindx[zct++] = ps[i];
742
	return indx;
740
	return indx;
Line 746... Line 744...
746
 
744
 
747
static SEXP
745
static SEXP
748
integerSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch,
746
integerSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch,
749
		 SEXP call, SEXP x)
747
		 SEXP call, SEXP x)
750
{
748
{
751
    R_xlen_t i;
-
 
752
    int ii, max, canstretch;
-
 
753
    bool isna = false, neg = false;
749
    bool isna = false, neg = false,
754
    canstretch = *stretch > 0;
750
	canstretch = *stretch > 0;
755
    *stretch = 0;
751
    *stretch = 0;
756
    max = 0;
752
    int max = 0;
757
    const int *ps = INTEGER_RO(s);
753
    const int *ps = INTEGER_RO(s);
758
    for (i = 0; i < ns; i++) {
754
    for (R_xlen_t i = 0; i < ns; i++) {
759
	ii = ps[i];
755
	int ii = ps[i];
760
	if (ii < 0) {
756
	if (ii < 0) {
761
	    if (ii == NA_INTEGER)
757
	    if (ii == NA_INTEGER)
762
		isna = true;
758
		isna = true;
763
	    else
759
	    else
764
		neg = true;
760
		neg = true;
Line 784... Line 780...
784
 
780
 
785
static SEXP
781
static SEXP
786
realSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch,
782
realSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, R_xlen_t *stretch,
787
	      SEXP call, SEXP x)
783
	      SEXP call, SEXP x)
788
{
784
{
789
    int canstretch = *stretch > 0;
785
    bool canstretch = *stretch > 0;
790
    *stretch = 0;
786
    *stretch = 0;
791
    double min = 0, max = 0;
787
    double min = 0, max = 0;
792
    const double *ps = REAL_RO(s);
788
    const double *ps = REAL_RO(s);
793
    bool isna = false;
789
    bool isna = false;
794
    for (R_xlen_t i = 0; i < ns; i++) {
790
    for (R_xlen_t i = 0; i < ns; i++) {
Line 884... Line 880...
884
 * bytes) so it is only worth doing if ns * nx is large.  If nx is
880
 * bytes) so it is only worth doing if ns * nx is large.  If nx is
885
 * large, then it will be too slow unless ns is very small.
881
 * large, then it will be too slow unless ns is very small.
886
 */
882
 */
887
 
883
 
888
static SEXP
884
static SEXP
889
stringSubscript(SEXP s, R_xlen_t ns, R_xlen_t nx, SEXP names,
885
stringSubscript(SEXP s, R_xlen_t ns /* = xlength(s) */, R_xlen_t nx /* = xlength(x) */,
-
 
886
		SEXP names,
890
		R_xlen_t *stretch, SEXP call, SEXP x, int dim)
887
		R_xlen_t *stretch, SEXP call, SEXP x, int dim)
891
{
888
{
892
    SEXP indx, indexnames = R_NilValue;
-
 
893
    R_xlen_t i, j, nnames, extra, sub;
-
 
894
    int canstretch = *stretch > 0;
-
 
895
    /* product may overflow, so check factors as well. */
889
    /* product may overflow, so check factors as well. */
896
    bool usehashing = ( ((ns > 1000 && nx) || (nx > 1000 && ns)) || (ns * nx > 15*nx + ns) );
890
    bool usehashing = ( ((ns > 1000 && nx) || (nx > 1000 && ns)) || (ns * nx > 15*nx + ns) );
897
    int nprotect = 0;
891
    int nprotect = 0;
898
 
-
 
899
    PROTECT(s);
892
    PROTECT(s);
900
    PROTECT(names);
893
    PROTECT(names);
901
    nprotect += 2;
894
    nprotect += 2;
-
 
895
 
-
 
896
    SEXP indx, indexnames = R_NilValue;
-
 
897
    bool canstretch = *stretch > 0;
-
 
898
    *stretch = 0;
-
 
899
    R_xlen_t i, sub,
902
    nnames = nx;
900
	nnames = nx,
903
    extra = nnames;
901
	extra = nnames;
904
 
902
 
905
    /* Process each of the subscripts. First we compare with the names
903
    /* Process each of the subscripts. First we compare with the names
906
     * on the vector and then (if there is no match) with each of the
904
     * on the vector and then (if there is no match) with each of the
907
     * previous subscripts, since (if assigning) we may have already
905
     * previous subscripts, since (if assigning) we may have already
908
     * added an element of that name. (If we are not assigning, any
906
     * added an element of that name. (If we are not assigning, any
Line 925... Line 923...
925
	nprotect++;
923
	nprotect++;
926
	int *pindx = INTEGER(indx);
924
	int *pindx = INTEGER(indx);
927
	for (i = 0; i < ns; i++) {
925
	for (i = 0; i < ns; i++) {
928
	    sub = 0;
926
	    sub = 0;
929
	    if (names != R_NilValue) {
927
	    if (names != R_NilValue) {
930
		for (j = 0; j < nnames; j++) {
928
		for (R_xlen_t j = 0; j < nnames; j++) {
931
		    SEXP names_j = STRING_ELT(names, j);
929
		    SEXP names_j = STRING_ELT(names, j);
932
		    if (NonNullStringMatch(STRING_ELT(s, i), names_j)) {
930
		    if (NonNullStringMatch(STRING_ELT(s, i), names_j)) {
933
			sub = j + 1;
931
			sub = j + 1;
934
			break;
932
			break;
935
		    }
933
		    }
Line 967... Line 965...
967
	}
965
	}
968
	pindx[i] = (int) sub;
966
	pindx[i] = (int) sub;
969
    }
967
    }
970
    /* We return the new names as the names attribute of the returned
968
    /* We return the new names as the names attribute of the returned
971
       subscript vector. */
969
       subscript vector. */
972
    if (extra != nnames)
970
    if (extra != nnames) {
973
	setAttrib(indx, R_UseNamesSymbol, indexnames);
971
	setAttrib(indx, R_UseNamesSymbol, indexnames);
974
    if (canstretch)
972
	if (canstretch)
975
	*stretch = extra;
973
	    *stretch = extra;
-
 
974
    }
976
    UNPROTECT(nprotect);
975
    UNPROTECT(nprotect);
977
    return indx;
976
    return indx;
978
}
977
}
979
 
978
 
980
/* Array Subscripts.
979
/* Array Subscripts.
Line 1088... Line 1087...
1088
	ans = realSubscript(s, ns, nx, stretch, call, x);
1087
	ans = realSubscript(s, ns, nx, stretch, call, x);
1089
	break;
1088
	break;
1090
    case STRSXP:
1089
    case STRSXP:
1091
    {
1090
    {
1092
	SEXP names = PROTECT(getAttrib(x, R_NamesSymbol));
1091
	SEXP names = PROTECT(getAttrib(x, R_NamesSymbol));
1093
	/* *stretch = 0; */
-
 
1094
	ans = stringSubscript(s, ns, nx, names, stretch, call, x, -1);
1092
	ans = stringSubscript(s, ns, nx, names, stretch, call, x, -1);
1095
	UNPROTECT(1); /* names */
1093
	UNPROTECT(1); /* names */
1096
	break;
1094
	break;
1097
    }
1095
    }
1098
    case SYMSXP:
1096
    case SYMSXP: