Proxy sorting

bearophile bearophileHUGS at lycos.com
Fri Feb 18 16:59:41 PST 2011


> Thank you for your answers. Second try, it doesn't work yet, I'm looking for the problem:

Third try, this seems to work:

import std.stdio, std.array, std.algorithm, std.range;

struct IndirectArray(Tdata, Tindexes) {
    Tdata[] data;
    Tindexes[] indexes;

    bool empty() { return indexes.empty(); }
    void popFront() { indexes.popFront(); }
    ref Tdata front() { return data[indexes.front()]; }
    IndirectArray save() { return this; }
    void popBack() { indexes.popBack(); }
    ref Tdata back() { return data[indexes.back()]; }
    @property size_t length() { return indexes.length; }

    Tdata opIndex(size_t i) {
        return data[indexes[i]];
    }

    void opIndexAssign(Tdata value, size_t i) {
        data[indexes[i]] = value;
    }

    IndirectArray opSlice(size_t x, size_t y) {
        return IndirectArray(data, indexes[x .. y]);
    }
}

static assert(isRandomAccessRange!(IndirectArray!(double, int))); // OK

void disjointSort(Tdata, Tindexes)(Tdata[] arr, Tindexes[] idxSet) {
    auto proxy = IndirectArray!(Tdata, Tindexes)(arr, idxSet);
    sort(proxy);
}

void main() {
    auto data = [7, 6, 5, 4, 3, 2, 1, 0];
    writeln("orig:     ", [7, 6, 5, 4, 3, 2, 1, 0]);
    auto indexes = [1, 6, 7];
    disjointSort(data, indexes);
    writeln("result:   ", data);
    auto expected = [7, 0, 5, 4, 3, 2, 1, 6];
    writeln("expected: ", expected);
    assert(data == expected);
}

I don't know yet how much efficient it is, things like opSlice() copy size_t.sizeof*4 bytes.

front() and back() must return by ref, and opSlice() too is needed. I think this requirements need to be added to the template constraints of sort().

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list