Search code examples
constantsd

How to use front() on a const array


I have this function, extract(), which takes a range and the name of a member, then attempts to create a wrapping range whose front() provides access only to the named member.

The problem lies in Range.front(), when R is of the form const(T)[]. The compiler indicates that the the function r.front() does not exist. I'm fairly certain there is something wrong with the interaction between the non-const R and the const r.front(), but I am not certain how to resolve it.

So, is my intuition correct? And in either case, what exactly is wrong, and how can I fix it?

auto extract (string member, R)(R range) {
    import std.traits: hasMember;
    import std.range: ElementType, isInputRange;

    static assert(hasMember!(ElementType!R, member));
    static assert(isInputRange!R);

    struct Range {
        R r;
        bool empty ()() { return r.empty; }
        void popFront ()() { r.popFront; }
        ElementType!R front () { mixin("return r.front." ~ member ~ ";"); }
    }

    return Range(range);
}

Solution

  • First. If you want to keep your implementation, you should to replace

    import std.range: ElementType, isInputRange;
    

    on

    import std.range: ElementType, isInputRange, front;
    

    and

    ElementType!R front () { mixin("return r.front." ~ member ~ ";"); }
    

    on

    auto front () { mixin("return r.front." ~ member ~ ";"); }
    

    But. Your implementation is too complexity

    It may be more simplify.

    Just

    auto extract1 (string member, R)(R range)
        if((hasMember!(ElementType!R, member)) && isInputRange!R)
    {
        return range.map!("a." ~ member);
    }