Enhanced C#
Language of your choice: library documentation
|
A read-only list of characters plus a Slice(int,int) method. More...
A read-only list of characters plus a Slice(int,int) method.
To get an instance of this interface from a string, write new StringSlice("string")
or (UString)"string"
.
This is the standard interface for lexers to use as a source of characters; is it defined in Loyc.Essentials rather than Loyc.Syntax so that UString can implement it, and because it might be useful in other contexts.
This interface was created to read characters more efficiently. Although a lexer could read characters one-at-a-time from IReadOnlyList{char} or IListSource{char}, it requires dynamic interface dispatch for every character. On the other hand, if lexers avoid this overhead by requiring the entire file in the form of a string, it becomes necessary to hold the entire file in memory at once, in a very specific format (a string).
Slice() allows the lexer to request small pieces of the file that it can read without dynamic dispatch. Typically a lexer will be derived from Loyc.Syntax.Lexing.BaseLexer, which requests somewhat small chunks; the ICharSource implementation is is free to read larger blocks at once, since the return type, UString, can be a slice of a larger string.
This interface provides good efficiency when reading from strings, or from data structures composed of large strings (most notably, this interface could efficiently return sections of a gap buffer), but unlike String itself, it is flexible, and does not require the entire file to be held in memory as a single contiguous block.
It's unfortunate that .NET treats strings as something completely different than arrays. Otherwise, this interface could support not just substrings, but subarrays of any element type, which would be useful any time you want to optimize your code by reducing dynamic dispatch.
Note about Count: if ICharSource represents to a file or other Stream, reading Count forces the entire stream to be scanned in order to determine the number of characters in the file (which may be different from the number of bytes). Rather than do a test like if (index >= charSource.Count)
it is better to use if (Slice(index, 1).Count == 0)
, or better yet, TryGet(index, out fail)
.
Public Member Functions | |
new UString | Slice (int startIndex, int length) |
Returns a substring from the character source. If some of the requested characters are past the end of the stream, the string is truncated to the available number of characters. More... | |
Public Member Functions inherited from Loyc.Collections.IListSource< char > | |
IRange< T > | Slice (int start, int count=int.MaxValue) |
Returns a sub-range of this list. More... | |
new UString Loyc.Collections.ICharSource.Slice | ( | int | startIndex, |
int | length | ||
) |
Returns a substring from the character source. If some of the requested characters are past the end of the stream, the string is truncated to the available number of characters.
startIndex | Index of first character to return. If startIndex >= Count, an empty string is returned. |
length | Number of characters desired. |
ArgumentException | Thrown if startIndex or length are negative. |
Implemented in Loyc.Syntax.StreamCharSource, Loyc.UString, and Loyc.UString.
Referenced by Loyc.Syntax.Lexing.Token.SourceText(), Loyc.Syntax.Lexing.Token.TextValue(), Loyc.Syntax.Les.TokenExt.ToString(), and Loyc.Ecs.Parser.TokenExt.ToString().