Generics in AngelScript

Starting with version 1.18, AngelScript has added support for generics, also known as type parameters.

As an example of a generic function, SlicesIndex takes a slice of any comparable type and an element of that type and returns the index of the first occurrence of v in s, or -1 if not present. The comparable constraint means that we can compare values of this type with the == and != operators.

template<class S, class E>
int SlicesIndex(S& s, E v)
{
    for (uint i = 0; i < s.length(); i++)
    {
        if (v == s[i])
        {
            return i;
        }
    }
    return -1;
}

As an example of a generic type, List is a singly-linked list with values of any type.

template<class T>
class List
{
    private Element@[] elements;

    void Push(T v)
    {
        elements.insertLast(Element(v));
    }

    array<T> AllElements()
    {
        array<T> elems;
        for (uint i = 0; i < elements.length(); i++)
        {
            elems.insertLast(elements[i].val);
        }
        return elems;
    }
}

template<class T>
class Element
{
    T val;
    Element(T v) { val = v; }
}

We can define methods on generic types just like we do on regular types, but we have to keep the type parameters in place.

When invoking generic functions, we often rely on type inference. Note that we don’t have to specify the types when calling SlicesIndex - the compiler infers them automatically.

void main()
{
    array<string> s = {"foo", "bar", "zoo"};
    print("index of zoo: " + SlicesIndex(s, "zoo"));

    List<int> lst;
    lst.Push(10);
    lst.Push(13);
    lst.Push(23);
    print("list: " + lst.AllElements());
}

When you run this script, you should see output similar to:

index of zoo: 2
list: [10, 13, 23]

This example demonstrates how to use generics in AngelScript to create flexible, reusable code that can work with different data types. The SlicesIndex function can work with any array type, and the List class can store elements of any type.