=begin pod

=TITLE class Str

=SUBTITLE String of characters

    class Str is Cool does Stringy { }

Built-in class for strings. Objects of type C<Str> are immutable.

=head1 Methods

=head2 routine chop

    multi sub    chop(Str:D)  returns Str:D
    multi method chop(Str:D: $chars = 1) returns Str:D

Returns the string with C<$chars> characters removed from the end.

=head2 routine chomp

Defined as:

    multi sub    chomp(Str:D ) returns Str:D
    multi method chomp(Str:D:) returns Str:D

Usage:

    chomp($string);
    $string.chomp;

Returns the string with a logical newline (any codepoint that has the
C<NEWLINE> property) removed from the end.

Examples:

    say chomp("abc\n");       # abc
    say "def\r\n".chomp;      # def  NOTE: \r\n is a single grapheme!
    say "foo\r".chomp;        # foo

=head2 routine lc

Defined as:

    multi sub    lc(Str:D ) returns Str:D
    multi method lc(Str:D:) returns Str:D

Usage:

    lc($string);
    $string.lc;

Returns a lower-case version of the string.

Examples:

    lc("A"); # returns "a"
    "A".lc   # returns "a"

=head2 routine uc

    multi sub    uc(Str:D ) returns Str:D
    multi method uc(Str:D:) returns Str:D

Returns an uppercase version of the string.

=head2 routine fc

    multi sub    fc(Str:D ) returns Str:D
    multi method fc(Str:D:) returns Str:D

Does a Unicode "fold case" operation suitable for doing caseless
string comparisons.  (In general, the returned string is unlikely to
be useful for any purpose other than comparison.)

=head2 routine tc

    multi sub    tc(Str:D ) returns Str:D
    multi method tc(Str:D:) returns Str:D

Does a Unicode "titlecase" operation, that is changes the first character in
the string to title case, or to upper case if the character has no title case
mapping

=head2 routine tclc

    multi sub    tclc(Str:D ) returns Str:D
    multi method tclc(Str:D:) returns Str:D

Turns the first character to title case, and all other characters to lower
case

=head2 routine wordcase

=for code :allow<L>
multi sub    wordcase(Cool $x)  returns Str
multi sub    wordcase(Str:D $x) returns Str
multi method wordcase(Str:D: :&filter = &L<tclc>, Mu :$where = True) returns Str

Returns a string in which C<&filter> has been applied to all the words
that match C<$where>. By default, this means that the first letter of
every word is capitalized, and all the other letters lowercased.

=head2 method lcfirst

Perl 6 does not have a C<lcfirst> function.

=head2 method ucfirst

Perl 6 does not have a C<ucfirst> function.  See L<tc>.

=head2 method unival

    multi method unival(Str:D) returns Numeric

Returns the numeric value that the first codepoint in the invocant represents,
or C<NaN> if it's not numeric.

    say '4'.unival;     # 4
    say '¾'.unival;     # 0.75
    say 'a'.unival;     # NaN

=head2 method univals

    multi method univals(Str:D) returns List

Returns a list of numeric values represented by each codepoint in the invocant
string, and C<NaN> for non-numeric characters.

    say '4a¾".univals;  # 4 NaN 0.75

=head2 method length

Perl 6 does not have a C<length> function.  See L<chars>, L<elems>,
 or L<codes>.

=head2 routine chars

    multi sub    chars(Cool $x)  returns Int:D
    multi sub    chars(Str:D $x) returns Int:D
    multi sub    chars(str $x)   returns int
    multi method chars(Str:D:)   returns Int:D

Returns the number of characters in the string in graphemes. On the JVM, this
currently erroneously returns the number of codepoints instead.

=head2 method encode

    multi method encode(Str:D: $encoding = $?ENC, $nf = $?NF) returns Blob

Returns a L<Blob> which represents the original string in the given encoding
and normal form. The actual return type is as specific as possible, so
C<$str.encode('UTF-8')> returns a C<utf8> object,
C<$str.encode('ISO-8859-1')> a C<buf8>.

=head2 routine index

    multi sub    index(Cool $s, Str:D $needle, Cool $startpos = 0) returns Int
    multi method index(Cool $needle, Cool $startpos = 0) returns Int

Searches for C<$needle> in the string starting from C<$startpos>. It returns
the offset into the string where C<$needle> was found, and an undefined value
if it was not found.

Examples:

    say index "Camelia is a butterfly", "a";     # 1
    say index "Camelia is a butterfly", "a", 2;  # 6
    say index "Camelia is a butterfly", "er";    # 17
    say index "Camelia is a butterfly", "Camel"; # 0
    say index "Camelia is a butterfly", "Onion"; # Int()

    say index("Camelia is a butterfly", "Onion").defined ?? 'OK' !! 'NOT'; # NOT

=head2 routine rindex

    multi sub    rindex(Str:D $haystack, Str:D $needle, Int $startpos = $haystack.chars) returns StrPos
    multi method rindex(Str:D $haystack: Str:D $needle, Int $startpos = $haystack.chars) returns StrPos

Returns the last position of C<$needle> in C<$haystack> not after C<$startpos>.
Returns an undefined value if C<$needle> wasn't found.

Examples:

    say rindex "Camelia is a butterfly", "a";     # 11
    say rindex "Camelia is a butterfly", "a", 10; # 6

=head2 routine split

    multi sub    split(  Str:D $delimiter, Str:D $input, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional
    multi sub    split(Regex:D $delimiter, Str:D $input, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional
    multi sub    split(List:D $delimiters, Str:D $input, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional
    multi method split(Str:D:   Str:D $delimiter, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional
    multi method split(Str:D: Regex:D $delimiter, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional
    multi method split(Str:D: List:D $delimiters, $limit = Inf,
      :$skip-empty, :$v, :$k, :$kv, :$p) returns Positional

Usage:

    split( DELIMITER,  STRING [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )
    split( /PATTERN/,  STRING [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )
    split( DELIMITERS, STRING [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )
    STRING.split( DELIMITER  [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )
    STRING.split( /PATTERN/  [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )
    STRING.split( DELIMITERS [,LIMIT] [,:v] [,:k] [,:kv] [,:p] [,:skip-empty] )

Splits a string up into pieces based on delimiters found in the string.

If C<DELIMITER> is a string, it is searched for literally and not treated
as a regex.  If C<DELIMITER> is the empty string, it effectively returns all
characters of the string separately (plus an empty string at the begin and at
the end).  If C<PATTERN> is a regular expression, then that will be used
to split up the string.  If C<DELIMITERS> is a list, then all of its elements
will be considered a delimiter (either a string or a regular expression) to
split the string on.

The optional C<LIMIT> indicates in how many segments the string should be
split, if possible.  It defaults to B<Inf> (or B<*>, whichever way you look at
it), which means "as many as possible".

A number of optional named parameters can be specified, which alter the
result being returned.  The C<:v>, C<:k>, C<:kv> and C<:p> named parameters
all perform a special action with regards to the delimiter found.

=item :skip-empty

If specified, do not return empty strings before or after a delimiter.

=item :v

Also return the delimiter.  If the delimiter was a regular expression, then
this will be the associated C<Match> object. Since this stringifies as the
delimiter string found, you can always assume it is the delimiter string if
you're not interested in further information about that particular match.

=item :k

Also return the B<index> of the delimiter.  Only makes sense if a list of
delimiters was specified: in all other cases, this will be B<0>.

=item :kv

Also return both the B<index> of the delimiter, as well as the delimiter.

=item :p

Also return the B<index> of the delimiter and the delimiter as a C<Pair>.

Examples:

=begin code

    say split(";", "a;b;c").perl            # ("a", "b", "c")
    say split(";", "a;b;c", :v).perl        # ("a", ";", "b", ";", "c")
    say split(";", "a;b;c", 2).perl         # ("a", "b;c").Seq
    say split(";", "a;b;c", 2, :v).perl     # ("a", ";", "b;c")
    say split(";", "a;b;c,d").perl          # ("a", "b", "c,d")
    say split(/\;/, "a;b;c,d").perl         # ("a", "b", "c,d")
    say split(<; ,>, "a;b;c,d").perl        # ("a", "b", "c", "d")
    say split(/<[;,]>/, "a;b;c,d").perl     # ("a", "b", "c", "d")
    say split(<; ,>, "a;b;c,d", :k).perl    # ("a", 0, "b", 0, "c", 1, "d")
    say split(<; ,>, "a;b;c,d", :kv).perl   # ("a", 0, ";", "b", 0, ";", "c", 1, ",", "d")

    say "".split("x").perl                  # ("",)
    say "".split("x", :skip-empty).perl     # ("",)

    say "abcde".split("").perl              # ("", "a", "b", "c", "d", "e", "")
    say "abcde".split("",:skip-empty).perl  # ("a", "b", "c", "d", "e")

=end code

=head2 routine comb

    multi sub    comb(Str:D   $matcher, Str:D $input, $limit = Inf)
    multi sub    comb(Regex:D $matcher, Str:D $input, $limit = Inf, Bool :$match)
    multi sub    comb(Int:D $size, Str:D $input, $limit = Inf)

    multi method comb(Str:D $input:)
    multi method comb(Str:D $input: Str:D   $matcher, $limit = Inf)
    multi method comb(Str:D $input: Regex:D $matcher, $limit = Inf, Bool :$match)
    multi method comb(Str:D $input: Int:D $size, $limit = Inf)

Searches for C<$matcher> in C<$input> and returns a list of all matches
(as C<Str> by default, or as L<Match> if C<$match> is True), limited to at most
C<$limit> matches.

If no matcher is supplied, a list of characters in the string
(e.g. C<$matcher = rx/./>) is returned.

Examples:

    comb(/\w/, "a;b;c").perl;        # ("a", "b", "c").list
    comb(/\N/, "a;b;c").perl;        # ("a", ";", "b", ";", "c").list
    comb(/\w/, "a;b;c", 2).perl;     # ("a", "b").list
    comb(/\w\;\w/, "a;b;c", 2).perl; # ("a;b",).list

If the matcher is an integer value, it is considered to be a matcher that
is similar to / . ** matcher /, but which is about 30x faster.

=head2 routine lines

    multi sub    lines(Str:D $input, $limit = Inf) returns Positional
    multi method lines(Str:D $input: $limit = Inf) returns Positional

Returns a list of lines (without trailing newline characters), i.e. the
same as a call to C<$input.comb( / ^^ \N* /, $limit )> would.

Examples:

    lines("a\nb").perl;    # ("a", "b").list
    lines("a\nb").elems;   # 2
    "a\nb".lines.elems;    # 2
    "a\n".lines.elems;     # 1

=head2 routine words

    multi sub    words(Str:D $input, $limit = Inf) returns Positional
    multi method words(Str:D $input: $limit = Inf) returns Positional

Returns a list of non-whitespace bits, i.e. the same as a call to
C<$input.comb( / \S+ /, $limit )> would.

Examples:

    "a\nb\n".words.perl;       # ("a", "b").list
    "hello world".words.perl;  # ("hello", "world").list
    "foo:bar".words.perl;      # ("foo:bar",).list
    "foo:bar\tbaz".words.perl; # ("foo:bar", "baz").list

=head2 routine flip

    multi sub    flip(Str:D ) returns Str:D
    multi method flip(Str:D:) returns Str:D

Returns the string reversed character by character.

Examples:

    "Perl".flip;  # lreP
    "ABBA".flip;  # ABBA

=head2 sub printf

 multi sub printf (Str:D $format, *@args)

This function is mostly identical to the C library printf function.

The C<$format> is scanned for C<%> characters. Any C<%> introduces a
format token. Format tokens have the following grammar:

 grammar Str::PrintfFormat {
  regex format_token { '%': <index>? <precision>? <modifier>? <directive> }
  token index { \d+ '$' }
  token precision { <flags>? <vector>? <precision_count> }
  token flags { <[ \x20 + 0 \# \- ]>+ }
  token precision_count { [ <[1..9]>\d* | '*' ]? [ '.' [ \d* | '*' ] ]? }
  token vector { '*'? v }
  token modifier { < ll l h V q L > }
  token directive { < % c s d u o x e f g X E G b p n i D U O F > }
 }

Directives guide the use (if any) of the arguments. When a directive
(other than C<%>) is used, it indicates how the next argument
passed is to be formatted into the string to be printed.

The directives are:

=begin table

 %   a literal percent sign
 c   a character with the given codepoint
 s   a string
 d   a signed integer, in decimal
 u   an unsigned integer, in decimal
 o   an unsigned integer, in octal
 x   an unsigned integer, in hexadecimal
 e   a floating-point number, in scientific notation
 f   a floating-point number, in fixed decimal notation
 g   a floating-point number, in %e or %f notation
 X   like x, but using uppercase letters
 E   like e, but using an uppercase "E"
 G   like g, but with an uppercase "E" (if applicable)
 b   an unsigned integer, in binary

=end table

Compatibility:

=begin table

 i   a synonym for %d
 D   a synonym for %ld
 U   a synonym for %lu
 O   a synonym for %lo
 F   a synonym for %f

=end table

Perl 5 (non-)compatibility:

=begin table

 n   produces a runtime exception
 p   produces a runtime exception

=end table

Modifiers change the meaning of format directives, but are largely
no-ops (the semantics are still being determined).

=begin table

 h  interpret integer as native "short" (typically int16)
 l  interpret integer as native "long" (typically int32 or int64)
 ll interpret integer as native "long long" (typically int64)
 L  interpret integer as native "long long" (typically uint64)
 q  interpret integer as native "quads" (typically int64 or larger)

=end table

Examples:

 printf('%c', [97]);                  # a
 printf("%.2f", [1.969]);             # 1.97
 printf("%+.3f", [3.141592]);         # +3.142
 printf('%2$d %1$d', [12, 34]);       # 34 12
 printf("%x", [255]);                 # ff

Special case:  printf("<b>%s</b>\n", "Perl 6")  will not work use either of the following:

 printf Q:b "<b>%s</b>\n",  "Perl 6";
 printf     "<b>\%s</b>\n", "Perl 6";
 printf     "<b>%s\</b>\n", "Perl 6";

=head2 sub sprintf

 multi sub sprintf ( Str:D $format, *@args) returns Str:D

This function is mostly identical to the C library sprintf function.

The C<$format> is scanned for C<%> characters. Any C<%> introduces a
format token. Format tokens have the following grammar:

 grammar Str::SprintfFormat {
  regex format_token { '%': <index>? <precision>? <modifier>? <directive> }
  token index { \d+ '$' }
  token precision { <flags>? <vector>? <precision_count> }
  token flags { <[ \x20 + 0 \# \- ]>+ }
  token precision_count { [ <[1..9]>\d* | '*' ]? [ '.' [ \d* | '*' ] ]? }
  token vector { '*'? v }
  token modifier { < ll l h V q L > }
  token directive { < % c s d u o x e f g X E G b p n i D U O F > }
 }

Directives guide the use (if any) of the arguments. When a directive
(other than C<%>) is used, it indicates how the next argument
passed is to be formatted into the string.

The directives are:

=begin table

 %   a literal percent sign
 c   a character with the given codepoint
 s   a string
 d   a signed integer, in decimal
 u   an unsigned integer, in decimal
 o   an unsigned integer, in octal
 x   an unsigned integer, in hexadecimal
 e   a floating-point number, in scientific notation
 f   a floating-point number, in fixed decimal notation
 g   a floating-point number, in %e or %f notation
 X   like x, but using uppercase letters
 E   like e, but using an uppercase "E"
 G   like g, but with an uppercase "E" (if applicable)
 b   an unsigned integer, in binary

=end table

Compatibility:

=begin table

 i   a synonym for %d
 D   a synonym for %ld
 U   a synonym for %lu
 O   a synonym for %lo
 F   a synonym for %f

=end table

Perl 5 (non-)compatibility:

=begin table

 n   produces a runtime exception
 p   produces a runtime exception

=end table

Modifiers change the meaning of format directives, but are largely
no-ops (the semantics are still being determined).

=begin table

 h  interpret integer as native "short" (typically int16)
 l  interpret integer as native "long" (typically int32 or int64)
 ll interpret integer as native "long long" (typically int64)
 L  interpret integer as native "long long" (typically uint64)
 q  interpret integer as native "quads" (typically int64 or larger)

=end table

Examples:

 sprintf "%ld a big number, %lld a bigger number\n", 4294967295, 4294967296;

Special case:  sprintf("<b>%s</b>\n", "Perl 6")  will not work use either of the following:

 sprintf Q:b "<b>%s</b>\n",  "Perl 6";
 sprintf     "<b>\%s</b>\n", "Perl 6";
 sprintf     "<b>%s\</b>\n", "Perl 6";

=head2 method starts-with

    multi method starts-with(Str:D: Str(Cool) $needle) returns True:D

Returns True if the invocant is identical to or starts with C<$needle>.

    say "Hello, World".starts-with("Hello");    # True
    say "http://perl6.org/".starts-with('ftp'); # False

=head2 method ends-with

    multi method ends-with(Str:D: Str(Cool) $needle) returns True:D

Returns True if the invocant is identical to or ends with C<$needle>.

    say "Hello, World".ends-with('Hello');      # False
    say "Hello, World".ends-with('ld');         # True

=head2 method contains

    multi method contains(Str:D: Str(Cool) $needle) returns True:D

Returns True if the invocant contains the C<$needle> at any position within
the string.

    say "Hello, World".contains('hello');      # False
    say "Hello, World".contains(',');          # True

=head2 method subst

    multi method subst(Str:D: $matcher, $replacement, *%opts)

Returns the invocant string where C<$matcher> is replaced by C<$replacement>
(or the original string, if no match was found).

There is an in-place syntactic variant of C<subst> spelled
C<s/matcher/replacement>.

C<$matcher> can be a L<Regex>, or a literal C<Str>. Non-Str matcher arguments
of type L<Cool> are coerced to C<Str> for literal matching.

    my $some-string = "Some foo";
    my $another-string = $some-string.subst(/foo/, "string"); # gives 'Some string'
    $some-string.=subst(/foo/, "string"); # in-place substitution. $some-string is now 'Some string'

The replacement can be a closure:

    my $i = 41;
    my $str = "The answer is secret.";
    my $real-answer = $str.subst(/secret/, {++$i}); # The answer to everything

Here are other examples of usage:

    my $str = "Hey foo foo foo";
    $str.subst(/foo/, "bar", :g); # global substitution - returns Hey bar bar bar

    $str.subst(/foo/, "no subst", :x(0)); # targeted substitution. Number of times to substitute. Returns back unmodified.
    $str.subst(/foo/, "bar", :x(1)); #replace just the first occurrence.

    $str.subst(/foo/, "bar", :nth(3)); # replace nth match alone. Replaces the third foo. Returns Hey foo foo bar

The following adverbs are supported

=begin table

    short       long        meaning
    =====       ====        =======
    :g          :global     tries to match as often as possible
    :nth(Int)               only substitute the nth's match
    :ss         :samespace  preserves whitespace on substitution
    :ii         :samecase   preserves case on substitution
    :x(Int)                 substitute exactly $x matches

=end table

Note that only in the C<s///> form C<:ii> implies C<:i> and C<:ss> implies
C<:s>. In the method form, the C<:s> and C<:i> modifiers must be added to the
regex, not the C<subst> method call.

=head2 method subst-mutate

Where C<subst> returns the modified string and leaves the original
unchanged, it is possible to mutate the original string by using
C<subst-mutate>.  If the match is successful, the method returns a C<Match>
object representing the successful match, or C<Any> otherwise.

    my $some-string = "Some foo";
    my $match = $some-string.subst-mutate(/foo/, "string");
    say $some-string;  #-> Some string
    say $match;        #-> ｢foo｣
    $some-string.subst-mutate(/<[oe]>/, '', :g); # remove all o'ss and e's, notice the :g named argument from .subst

=head2 routine substr

    multi sub    substr(Str:D $s, Int:D $from, Int:D $chars = $s.chars - $from) returns Str:D
    multi sub    substr(Str:D $s, Range $from-to) returns Str:D
    multi method substr(Str:D $s: Int:D $from, Int:D $chars = $s.chars - $from) returns Str:D
    multi method substr(Str:D $s: Range $from-to) returns Str:D

Returns a part of the string, starting from the character with index C<$from>
(where the first character has index 0) and with length C<$chars>.  If a range is
specified, its first and last indices are used to determine the size of the substring.

Examples:

    substr("Long string", 6, 3);     # tri
    substr("Long string", 6);        # tring
    substr("Long string", 6, *-1);   # trin
    substr("Long string", *-3, *-1); # in

=head2 method substr-eq

    multi method substr-eq(Str:D:  Str(Cool) $test-string, Int(Cool) $from) returns Bool
    multi method substr-eq(Cool:D: Str(Cool) $test-string, Int(Cool) $from) returns Bool

Returns C<True> if the C<$test-string> exactly matches the C<String> object,
starting from the given initial index C<$from>.  For example, beginning with
the string C<"foobar">, the substring C<"bar"> will match from index 3:

    my $string = "foobar";
    say $string.substr-eq("bar", 3);  #-> True

However, the substring C<"barz"> starting from index 3 won't match even
though the first three letters of the substring do match:

    my $string = "foobar";
    say $string.substr-eq("barz", 3);  #-> False

Naturally, to match the entire string, one merely matches from index 0:

    my $string = "foobar";
    say $string.substr-eq("foobar", 0);  #-> True

Since this method is inherited from the C<Cool> type, it also works on
integers.  Thus the integer C<42> will match the value C<342> starting from
index 1:

    my $integer = 342;
    say $integer.substr-eq(42, 1);  #-> True

As expected, one can match the entire value by starting at index 0:

    my $integer = 342;
    say $integer.substr-eq(342, 0);  #-> True

Also using a different value or an incorrect starting index won't match:

    my $integer = 342;
    say $integer.substr-eq(42, 3);  #-> False
    say $integer.substr-eq(7342, 0);  #-> False

=head2 method substr-rw

    method substr-rw($from, $length?)

A version of C<substr> that returns a writable reference to a part of a
string variable.  Its first argument, C<$from> specifies the index in the
string from which a substitution should occur, and its last argument,
C<$length> specifies how many characters are to be replaced.

For example, in its method form, if one wants to take the string C<"abc">
and replace the second character (at index 1) with the letter C<"z">, then
one do this:

    my $string = "abc";
    $string.substr-rw(1, 1) = "z";
    $string.say;                    #-> azc

C<substr-rw> also has a function form, so the above example can also be
written like so:

    my $string = "abc";
    substr-rw($string, 1, 1) = "z";
    $string.say;                    #-> azc

It is also possible to alias the writable reference returned by C<substr-rw>
for repeated operations:

    my $string = "A character in the 'Flintstones' is: barney";
    $string ~~ /(barney)/;
    my $ref := substr-rw($string, $0.from, $0.to);
    $string.say;
    #-> A character in the 'Flintstones' is: barney
    $ref = "fred";
    $string.say;
    #-> A character in the 'Flintstones' is: fred
    $ref = "wilma";
    $string.say;
    #-> A character in the 'Flintstones' is: wilma

Notice that the start position and length of string to replace has been
specified via the C<.from> and C<.to> methods on the C<Match> object, C<$0>.
It is thus not necessary to count characters in order to replace a
substring, hence making the code more flexible.

=head2 method succ

    method succ(Str:D) returns Str:D

Returns the string incremented by one.

String increment is "magical". It searches for the last alphanumeric
sequence that is not preceded by a dot, and increments it.

    '12.34'.succ      # 13.34
    'img001.png'.succ # img002.png

The actual increment step works by mapping the last alphanumeric
character to a character range it belongs to, and choosing the next
character in that range, carrying to the previous letter on overflow.

    'aa'.succ   # ab
    'az'.succ   # ba
    '109'.succ  # 110
    'α'.succ    # β
    'a9'.succ   # b0

String increment is Unicode-aware, and generally works for scripts where a
character can be uniquely classified as belonging to one range of characters.

=head2 method pred

    method pred(Str:D:) returns Str:D

Returns the string decremented by one.

String decrementing is "magical" just like string increment (see
L<succ>). It fails on underflow

    'b0'.pred           # a9
    'a0'.pred           # Failure
    'img002.png'.pred   # img001.png

=head2 routine ord

    multi sub ord   (Str:D)  returns Int:D
    multi method ord(Str:D:) returns Int:D

Returns the codepoint number of the base characters of the first grapheme
in the string.

Example:

    ord("A") # 65
    "«".ord  # 171

=head2 method ords

    multi method ords(Str:D:) returns Positional

Returns a list of codepoint numbers, one for the base character of each
grapheme in the string.

Example:

    "aå«".ords # (97 229 171)

=head2 method trans

    proto method trans(|) { $/ := nqp::getlexcaller('$/'); {*} }
    multi method trans(Str:D: Pair:D \what, *%n) returns Str
    multi method trans(Str:D: *@changes, :complement(:$c), :squash(:$s), :delete(:$d)) returns Str

Replaces one or many characters with one or many characters. Ranges are
supported, both for keys and values. Regexes work as keys. In case a list of
keys and values is used, substrings can be replaced aswell. When called with
C<:complement> anything but the matched value or range is replaced with a
single value. With C<:delete> the matched characters are removed.  Combining
C<:complement> and C<:delete> will remove anything but the matched values.  The
adverb C<:squash> will reduce repeated matched characters to a single
character. 

Example:

    my $str = 'say $x<b> && $y<a>';
    $str.=trans( '<' => '«' );
    $str.=trans( '<' => '«', '>' => '»' );
    
    $str.=trans( [ '<'   , '>'   , '&' ] =>
                 [ '&lt;', '&gt;', '&amp;' ]);
    
    $str.=trans( ['a'..'y'] => ['A'..'z'] );

    "abcdefghij".trans(/<[aeiou]> \w/ => ''); # «cdgh»

    "a123b123c".trans(['a'..'z'] => 'x', :complement); # «axxxbxxxc»
    "a123b123c".trans('23' => '', :delete); # «a1b1c»
    "aaa1123bb123c".trans('a'..'z' => 'A'..'Z', :squash); # «A1123B123C»
    "aaa1123bb123c".trans('a'..'z' => 'x', :complement, :squash); # «aaaxbbxc»

=head2 method indent

    proto method indent($)
    multi method indent(Int $steps where { $_ == 0 } )
    multi method indent(Int $steps where { $_ > 0  } )
    multi method indent($steps where { .isa(Whatever) || .isa(Int) && $_ < 0 )

Indents each line of the string by C<$steps>. If C<$steps> is negative,
it outdents instead. If C<$steps> is L<C<*>|*>, then the string is
outdented to the margin:

    =begin code
    "  indented by 2 spaces\n    indented even more".indent(*)
        eq "indented by 2 spaces\n  indented even more"
    =end code

=head2 method trim

    method trim(Str:D:) returns Str

Remove leading and trailing whitespace. It can be use both as a method
on strings and as a function. When used as a method it will return
the trimmed string. In order to do in-place trimming, once needs to write
C<.=trim>


    my $line = '   hello world    ';
    say '<' ~ $line.trim ~ '>';        # <hello world>
    say '<' ~ trim($line) ~ '>';       # <hello world>
    $line.trim;
    say '<' ~ $line ~ '>';             # <   hello world    >
    $line.=trim;
    say '<' ~ $line ~ '>';             # <hello world>

See also L<trim-trailing> and L<trim-leading>

=head2 method trim-trailing

Remove the whitespace characters from the end of a string. See also L<trim>.

=head2 method trim-leading

Remove the whitespace characters from the beginning of a string. See also L<trim>.

=head2 method NFC

    method NFC(Str:D:) returns NFC:D

Returns a codepoint string in L<NFC|/type/NFC> format (Unicode Normalization
Form C / Composed).

=head2 method NFD

    method NFD(Str:D:) returns NFD:D

Returns a codepoint string in L<NFC|/type/NFD> format (Unicode Normalization
Form D / Decomposed).

=head2 method NFKC

    method NFKC(Str:D:) returns NFKC:D

Returns a codepoint string in L<NFKC|/type/NFKC> format (Unicode Normalization
Form KC / Compatibility Composed).

=head2 method NFKD

    method NFKD(Str:D:) returns NFKD:D

Returns a codepoint string in L<NFC|/type/NFKD> format (Unicode Normalization
Form KD / Compatibility Decomposed).

=head2 method ACCEPTS

    multi method ACCEPTS(Str:D: $other)

Returns C<True> if the string is L<the same as|eq> C<$other>.

=end pod

# vim: expandtab shiftwidth=4 ft=perl6
