The Freya Programming Language

Indexers

See also

In contrast with C++, Freya doesn't allow the redefinition of the bracket "operator". On the contrary, an indexer is the official and approved trick to simulate the behavior of arrays.

Indexer declarations

Indexers share most of their features with properties: they are even declared using the property keyword. They include, however, a list of index arguments in the declaration:

BitsArray = class
public
    // ...
    property Items[Index: Integer]: Boolean;
    // ...
end

In the above example, Items has been declared as an indexer with both read and write access. You can the indexer identifier as if it were an array field:

    method GetPrimes(Max: Integer): BitsArray;
    begin
        Result := new BitsArray(2, Max);
        for var i := 2 to Max div 2 do
            if not Result.Items[i] then
            begin
                var j := i + i;
                while j <= Max do
                begin
                    Result.Items[j] := true;
                    j += i;
                end;
            end;
        Result.Invert;
    end;

As a matter of fact, Items is the predefined name for default indexers. This means you could drop the Items identifier from expressions involving the indexer:

    method GetPrimes(Max: Integer): BitsArray;
    begin
        Result := new BitsArray(2, Max);
        for var i := 2 to Max div 2 do
            if not Result[i] then
            begin
                var j := i + i;
                while j <= Max do
                begin
                    Result[j] := true;
                    j += i;
                end;
            end;
        Result.Invert;
    end;

The default indexer in a class can be changed by including the DefaultMember attribute in the class declaration, as in this example:

<DefaultMember('Items')>
BitsArray = class
public
    // ...
    property Items[Index: Integer]: Boolean;
    // ...
end

However, it is highly recommended to keep Items the default indexer, in order to avoid compatibility conflicts with C#. Freya's indexers have been modeled after VB.NET's.

Implementing an indexer

Indexers must implement their access methods in the implementation section of their classes. The read access method must feature identical parameters as in the index definition, and must return a value from the same type as the indexer declaration:

property Items(Index: Integer): Boolean;
begin
    Index -= Min;
    if Index < 0 or Index > High then
        raise new ArgumentException("Index");
    Result := (Bits[Index div 32] & (1 << (Index mod 32))) <> 0;
end;

The write access method has no return value, but adds an input parameter at the end of the parameter list, receiving the new value to be assigned:

property Items(Index: Integer; Value: Boolean);
begin
    Index -= Min;
    if Index < 0 or Index > High then
        raise new ArgumentException("Index");
    if Value then
        Bits[Index div 32] |= 1 << (Index mod 32)
    else
        Bits[Index div 32] &= ~(1 << (Index mod 32));
end;

Unlike scalar properties, indexers do not allow field-based implicit implementations.

See also

The Freya Programming Language
Type declarations
Type members
Constructors
Methods
User defined operators
Iterators
Fields
Properties
Events