www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9849] New: Introduce BaseElementType and BaseRangeType

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9849

           Summary: Introduce BaseElementType and BaseRangeType
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrej.mitrovich gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-31
14:45:32 PDT ---
Implementation:

template BaseElementType(Type)
{
    static if(is(Type T : T[N], size_t N))
    {
        alias BaseElementType = BaseElementType!T;
    }
    else
    static if(is(Type T : T[]))
    {
        alias BaseElementType = BaseElementType!T;
    }
    else
    static if(is(Type T : T*))
    {
        alias BaseElementType = BaseElementType!T;
    }
    else
    {
        alias BaseElementType = Type;
    }
}

///
unittest
{
    static assert(is(BaseElementType!int == int));
    static assert(is(BaseElementType!(int[]) == int));
    static assert(is(BaseElementType!(int[][]) == int));
    static assert(is(BaseElementType!(int[1][2]) == int));
    static assert(is(BaseElementType!(int**) == int));
}

Note how this is different from ElementType in std.range. Here we're looking
for the furthest element type, and we do it through type introspection rather
than trying to invoke a .front property.

The above is used for types, however this can also be implemented for ranges,
where we would look recursively into a range until its front property does not
return a range. An implementation:

template BaseRangeType(R)
    if (isInputRange!R)
{
    static if (is(typeof((inout int = 0){ R r = void; return r.front; }()) T))
    {
        static if (isInputRange!T)
            alias BaseRangeType = .BaseRangeType!T;
        else
            alias BaseRangeType = T;
    }
    else static assert(0);
}

struct Range1
{
    int front();
    void popFront();
    bool empty;
}

struct Range2
{
    Range1 front();
    void popFront();
    bool empty;
}

static assert(is(BaseRangeType!Range1 == int));
static assert(is(BaseRangeType!Range2 == int));

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 31 2013
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9849



--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-31
14:46:38 PDT ---
Apologies for forgetting to include imports, add these:

import std.array;
import std.traits;
import std.range;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 31 2013