=begin pod

=TITLE class Map

=SUBTITLE Immutable mapping from strings to values

    class Map does Associative is Iterable { }

A Map is an immutable mapping from string keys to values of arbitrary
types. It serves as a base class for L<Hash>, which is mutable.

In list context a Map behaves as a list of L<Pair> objects.

Note that the order in which keys, values and pairs are retrieved is
generally arbitrary, but the C<keys>, C<values> and C<pairs> methods
return them always in the same order when called on the same object.

    my %e := Map.new('a', 1, 'b', 2);
    say %e.keys;    # can print "a b\n" or "b a\n";
    say %e.values;  # prints "1 2\n" if the previous line
                    # printed "a b\n", "b a\n" otherwise

=head1 Methods

=head2 method new

Defined as:

    proto method new(*@, *%) {*}
    multi method new(*@args, *%pairs)

Usage:

    Map.new(ARGS)

Creates a new Map from a list of alternating keys and values, with
the same semantics as described for hash assigning in the L<Hash>
documentation.

=head2 method elems

Defined as:

    method elems(Map:D:) returns Int:D:

Usage:

    MAP.elems

Returns the number of pairs stored in the Map.

=head2 method ACCEPTS

Defined as:

    multi method ACCEPTS(Map:D: Positional $topic)
    multi method ACCEPTS(Map:D: Cool:D     $topic)
    multi method ACCEPTS(Map:D: Regex      $topic)
    multi method ACCEPTS(Map:D: Any        $topic)

Usage:

    MAP.ACCEPTS(TOPIC)

Used in smart-matching if the right-hand side is an C<Map>.

If the topic is list-like (L<Positional>), returns True if
any of the list elements exist as a key in the Map.

If the topic is of type C<Cool> (strings, integers etc.),
returns True if the topic exists as a key.

If the topic is a regex, returns True if any of the keys match
the regex.

As a fallback, the topic is coerced to a list, and the C<Positional>
behavior is applied.

To retrieve a value from the Map by key, use the C<{ }> postcircumfix
operator:

    my $value = $map{$key};

To check whether a given key is stored in a Map, modify the access
with the C<:exists> adverb:

    if %h{$key}:exists {
        say "%h{} has key $key";
    }

=head2 method keys

Defined as:

    method keys(Map:D:) returns List:D

Usage:

    MAP.keys

Returns a list of all keys in the Map.

=head2 method values

Defined as:

    method values(Map:D:) returns List:D

Usage:

    MAP.values

Returns a list of all values in the Map.

=head2 method pairs

Defined as:

    method pairs(Map:D:) returns List:D

Usage:

    MAP.pairs

Returns a list of all pairs in the Map.

=head2 method invert

Defined as:

    method invert(Map:D:) returns List:D

Usage:

    MAP.invert

Returns a list of pairs, but with key and value exchanged.

=head2 method kv

Defined as:

    method kv(Map:D:) returns List:D

Usage:

    MAP.kv

Returns a list of keys and values interleaved.

    Map.new('a', 1, 'b', 2).kv  # a, 1, b, 2 OR b, 2, a, 1

=end pod
