Code:

module vector;

import std.stdio;
import std.traits;

struct SVector(size_t dim, T = float)
{
private:
    T[dim] _arr;
public:
    alias dim dimension;
    alias dim size;

    this(this)
    {
        debug(SVector)
            writeln("postblit constructor");
    }

    this(const T[dim] arr)
    {
        debug(SVector)
            writeln("constructor from static array");
        _arr = arr;
    }

    this(ref const T[dim] arr)
    {
        debug(SVector)
            writeln("constructor from ref static array");
        _arr = arr;
    }

    this(const(T)[] arr)
    {
        debug(SVector)
            writeln("constructor from slice");
        assert(arr.length == dim);
        _arr = arr;
    }

    ref SVector opAssign(const SVector other)
    {
        debug(SVector)
            writeln("assign other vector");
        _arr = other._arr;
        return this;
    }

    ref SVector opAssign(ref const SVector other)
    {
        debug(SVector)
            writeln("assign other ref vector");
        _arr = other._arr;
        return this;
    }

    ref SVector opAssign(const T[dim] arr)
    {
        debug(SVector)
            writeln("assign static array");
        _arr = arr;
        return this;
    }

    ref SVector opAssign(ref const T[dim] arr)
    {
        debug(SVector)
            writeln("assign ref static array");
        _arr = arr;
        return this;
    }

    ref SVector opAssign(const(T)[] arr)
    {
        debug(SVector)
            writeln("assign dynamic array");
        assert(arr.length == dim);
        _arr = arr;
        return this;
    }

    T[] opSlice()
    {
        return _arr[];
    }
    T[] opSlice(size_t begin, size_t end)
    {
        return _arr[begin..end];
    }

    const(T)[] opSlice() const
    {
        return _arr[];
    }
    const(T)[] opSlice(size_t begin, size_t end) const
    {
        return _arr[begin..end];
    }

    T opIndex(size_t i) const
    {
        return _arr[i];
    }
    T opIndexAssign(const(T) value, size_t i)
    {
        return _arr[i] = value;
    }

    size_t opDollar() const
    {
        return dim;
    }
}

unittest
{
    alias float scalar;
    alias SVector!(3, scalar) vec;

    vec v = [1,2,3];

    writeln(v);
}

int main()
{
    return 0;
}

This type has simple postblit constructor, but what if it needs to allocate memory? Simple example is this._arr = _arr.dup if we would use dynamic array. We have really big overhead here.

By the way, why does writeln able to print this struct? It has no toString() method and its data is private. How does writeln have access to it?

Reply via email to