### Some utility functions to operate on strings
### Safe alternative to 'strsplit(x, NULL, fixed=TRUE)[[1L]]'.
### strsplitAsListOfIntegerVectors(x) is an alternative to:
###   lapply(strsplit(x, ",", fixed=TRUE), as.integer)
###  - strsplit() accepts NAs, we don't (raise an error);
###  - as.integer() introduces NAs by coercion (with a warning), we don't
###  - as.integer() supports "inaccurate integer conversion in coercion"
###    when the value to coerce is > INT_MAX (then it's coerced to INT_MAX),
###  - as.integer() will coerce non-integer values (e.g. 10.3) to an int
###    by truncating them, we don't (raise an error).
### When it fails, strsplit_as_list_of_ints() will print a detailed parse
### It's also faster and uses much less memory. E.g. it's 8x faster and uses
### < 1 Mb versus > 60 Mb on the character vector 'biginput' created with:
###   query <- ucscTableQuery(session, "UCSC Genes")
###   biginput <- c(tx$exonStarts, tx$exonEnds)  # 133606 elements
"'sep' must be a string containing just one single-byte character"
### svn.time() returns the time in Subversion format, e.g.:
### The -0800 part will be adjusted if daylight saving time is in effect.
### TODO: Find a better home for this function.

substring(x, 1L, 1L) <- toupper(substring(x, 1L, 1L))
function(x, sep="") .Call2("unstrsplit_list", x, sep, PACKAGE="IRanges")
if (!isSingleString(sep) || nchar(sep) != 1L)
stop("'sep' must be a string containing just one single-byte character")
ans <- .Call2("strsplit_as_list_of_ints", x, sep, PACKAGE="IRanges")
svn.time <- function() .Call2("svn_time", PACKAGE="IRanges")

### Returns an integer vector with values >= 1 and <= N, where N = length(x)
### if 'byrow=FALSE' and N = nrow(x) if 'byrow=TRUE'.
"cannot mix negative with positive indices"
## From here, indices are guaranteed to be either all positive or
"subscript is a logical vector with out of bounds "
### Supported types for 'i': single NA, numeric and character vectors only.
### Always returns a single integer. When called with 'error.if.nomatch=FALSE',
### returns an NA_integer_ if no match is found. Otherwise (the default),
### raises an error if no match is found so the returned integer is guaranteed
### to be a non-NA positive integer referring to a valid position in 'x'.
"'error.if.nomatch' must be TRUE or FALSE"
"attempt to extract less than one element"
"attempt to extract more than one element"
"attempt to extract by name when elements have no names"
## Because 'i' has length 1, it doesn't matter whether we use
## 'duplicates.ok=FALSE' (the default) or 'duplicates.ok=TRUE' but
## the latter seems to be just a little bit faster.
"  but first make sure this coercion does what you want."
### 2 internal generics to ease implementation of [ and [<- subsetting for
### Most new Vector subclasses should only need to implement an "extractROWS"
### and a "replaceROWS" method to have "[" and "[<-" work out-of-the-box,
### Must support the following 'i' types: missing, Ranges and anything that
### can be handled by normalizeSingleBracketSubscript().
### For replaceROWS(), it's OK to assume that 'value' is "compatible" i.e.
### that it has gone thru normalizeSingleBracketReplacementValue().
### See "extractROWS" and "replaceROWS" methods for IRanges objects for an
### 2 internal generics to ease implementation of [[ and [[<- subsetting for