Thread overview
Obtain predicate from SortedRange
Nov 09, 2016
RazvanN
Nov 09, 2016
Jonathan M Davis
Nov 09, 2016
Ali Çehreli
November 09, 2016
Given a SortedRange object, is there a way to obtain the predicate which was used for it to be sorted?
November 09, 2016
On Wednesday, November 09, 2016 09:37:18 RazvanN via Digitalmars-d-learn wrote:
> Given a SortedRange object, is there a way to obtain the predicate which was used for it to be sorted?

No. It only exists as a template argument to SortedRange and an alias within it, not as something that's actually part of the range object, and that alias is private. If you want access to the predicate, then you're going to have to pass something to sort or SortedRange which you can access separately from the SortedRange (e.g. an actual function rather than a lambda).

- Jonathan M Davis

November 09, 2016
On 11/09/2016 02:02 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Wednesday, November 09, 2016 09:37:18 RazvanN via Digitalmars-d-learn
> wrote:
>> Given a SortedRange object, is there a way to obtain the
>> predicate which was used for it to be sorted?
>
> No. It only exists as a template argument to SortedRange and an alias within
> it, not as something that's actually part of the range object, and that
> alias is private. If you want access to the predicate, then you're going to
> have to pass something to sort or SortedRange which you can access
> separately from the SortedRange (e.g. an actual function rather than a
> lambda).
>
> - Jonathan M Davis
>

Once one knows that the predicate is the second template argument and what its semantics are, then one can hack their way through it. :)

import std.range;

import std.traits : isInstanceOf;
template predFun(alias R) {
    static if (is(R) &&
               isInstanceOf!(SortedRange, R)) {
        import std.functional : binaryFun;
        import std.traits : TemplateArgsOf;
        alias predFun = binaryFun!(TemplateArgsOf!R[1]);
    }
    else {
        alias predFun = predFun!(typeof(R));
    }
}

unittest {
    auto arr = [ 2, 1 ];
    auto r = assumeSorted!"a > b"(arr);
    alias func = predFun!r;
    assert(!func(10, 20));
    assert(func(100, 1));
}

unittest {
    auto arr = [ 1, 2, 3 ];
    auto r = assumeSorted!((a, b) => a < b)(arr);
    alias func = predFun!r;
    assert(func(2, 4));
    assert(!func(5, 3));
}

void main() {
}