Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1897

Show
Ignore:
Timestamp:
08/19/10 00:48:56 (14 years ago)
Author:
dsimcha
Message:

Added isIterable, ForeachType? to std.traits in preparation for improvements to std.array.array.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/docsrc/changelog.dd

    r1896 r1897  
    44 
    55$(VERSION 049, Aug 11, 2010, =================================================, 
    66 
    77 
    88    $(WHATSNEW 
    99    $(LI Added FFT to std.numeric.) 
    1010    $(LI Added convenience functions for Rebindable.) 
    1111    $(LI std.process: Added environment, an AA-like interface for environment variables.) 
    1212    $(LI std.range:  Iota, Stride, Transversal, FrontTransveral now support slicing where possible.) 
    1313    $(LI std.range:  Added Lockstep, hasLvalueElements.) 
     14    $(L1 std.traits:  Added isIterable, ForeachType.) 
    1415    $(LI std.typetuple:  Added anySatisfy.)  
    1516    ) 
    1617    $(BUGSFIXED 
    1718    $(LI Unlisted Bug:  std.math.pow doesn't work on immutable numbers.) 
    1819    $(LI Unlisted Bug:  std.math.pow floating point overload expects both arguments to be exact same type.) 
    1920    $(LI Unlisted Bug:  std.path.join("", "foo") returns "/foo" instead of "foo" on Posix.) 
    2021    $(LI Unlisted Bug:  std.range.iota() random access primitives inconsistent after popFront on floating point version) 
    2122    $(LI Several unlisted bugs in std.range.chain) 
    2223    $(LI $(BUGZILLA 2903): Splitter should be bi-dir if the input range is bi-dir.) 
    2324    $(LI $(BUGZILLA 2951): std.random.dice() should be templated on proportions.) 
  • trunk/phobos/std/traits.d

    r1870 r1897  
    23102310unittest 
    23112311{ 
    23122312    static assert(isPointer!(int*)); 
    23132313    static assert(!isPointer!(uint)); 
    23142314    static assert(!isPointer!(uint[uint])); 
    23152315    static assert(!isPointer!(char[])); 
    23162316    static assert(isPointer!(void*)); 
    23172317} 
    23182318 
    23192319/** 
     2320 * Returns $(D true) if T can be iterated over using a $(D foreach) loop with 
     2321 * a single loop variable of automatically inferred type, regardless of how 
     2322 * the $(D foreach) loop is implemented.  This includes ranges, structs/classes 
     2323 * that define $(D opApply) with a single loop variable, and builtin dynamic, 
     2324 * static and associative arrays. 
     2325 */ 
     2326template isIterable(T) 
     2327{ 
     2328    static if (is(typeof({foreach(elem; T.init) {}}))) { 
     2329        enum bool isIterable = true; 
     2330    } else { 
     2331        enum bool isIterable = false; 
     2332    } 
     2333} 
     2334 
     2335unittest { 
     2336    struct OpApply 
     2337    { 
     2338        int opApply(int delegate(ref uint) dg) { assert(0); } 
     2339    } 
     2340 
     2341    struct Range 
     2342    { 
     2343        uint front() { assert(0); } 
     2344        void popFront() { assert(0); } 
     2345        enum bool empty = false; 
     2346    } 
     2347 
     2348    static assert(isIterable!(uint[])); 
     2349    static assert(!isIterable!(uint)); 
     2350    static assert(isIterable!(OpApply)); 
     2351    static assert(isIterable!(uint[string])); 
     2352    static assert(isIterable!(Range)); 
     2353} 
     2354 
     2355/** 
    23202356 * Tells whether the tuple T is an expression tuple. 
    23212357 */ 
    23222358template isExpressionTuple(T ...) 
    23232359{ 
    23242360    static if (T.length > 0) 
    23252361        enum bool isExpressionTuple = 
    23262362            !is(T[0]) && __traits(compiles, { auto ex = T[0]; }) && 
    23272363            isExpressionTuple!(T[1 .. $]); 
    23282364    else 
    23292365        enum bool isExpressionTuple = true; // default 
     
    25852621} 
    25862622 
    25872623unittest 
    25882624{ 
    25892625    static assert(is(ModifyTypePreservingSTC!(Intify, const real) == const int)); 
    25902626    static assert(is(ModifyTypePreservingSTC!(Intify, immutable real) == immutable int)); 
    25912627    static assert(is(ModifyTypePreservingSTC!(Intify, shared real) == shared int)); 
    25922628    static assert(is(ModifyTypePreservingSTC!(Intify, shared(const real)) == shared(const int))); 
    25932629} 
    25942630version (unittest) private template Intify(T) { alias int Intify; } 
     2631 
     2632/** 
     2633Returns the inferred type of the loop variable when a variable of type T 
     2634is iterated over using a $(D foreach) loop with a single loop variable and 
     2635automatically inferred return type.  Note that this may not be the same as 
     2636$(D std.range.ElementType!(Range)) in the case of narrow strings, or if T 
     2637has both opApply and a range interface. 
     2638*/ 
     2639template ForeachType(T) 
     2640{ 
     2641    alias ReturnType!(typeof( 
     2642    { 
     2643        foreach(elem; T.init) { 
     2644            return elem; 
     2645        } 
     2646        assert(0); 
     2647    })) ForeachType; 
     2648} 
     2649 
     2650unittest 
     2651{ 
     2652    static assert(is(ForeachType!(uint[]) == uint)); 
     2653    static assert(is(ForeachType!(string) == immutable(char))); 
     2654    static assert(is(ForeachType!(string[string]) == string)); 
     2655} 
    25952656 
    25962657 
    25972658/** 
    25982659Strips off all $(D typedef)s (including $(D enum) ones) from type $(D T). 
    25992660 
    26002661Example: 
    26012662-------------------- 
    26022663enum E : int { a } 
    26032664typedef E F; 
    26042665typedef const F G;