Steven Schveighoffer:
> lol!!! 

I know, I know... :-) But when people do errors so often, the error is 
elsewhere, in the original choice of that word to denote how many items an 
iterable has.

In my libs I have defined len() like this, that I use now and then (where 
running speed isn't essential):

long len(TyItems)(TyItems items) {
    static if (HasLength!(TyItems))
        return items.length;
    else {
        long len;
        // this generates: foreach (p1, p2, p3; items) len++;  with a variable 
number of p1, p2...
        mixin("foreach (" ~ SeriesGen1!("p", ", ", OpApplyCount!(TyItems), 1) ~ 
"; items) len++;");
        return len;
    }
} // End of len(items)

/// ditto
long len(TyItems, TyFun)(TyItems items, TyFun pred) {
    static assert(IsCallable!(TyFun), "len(): predicate must be a callable");
    long len;

    static if (IsAA!(TyItems)) {
        foreach (key, val; items)
            if (pred(key, val))
                len++;
    } else static if (is(typeof(TyItems.opApply))) {
        mixin("foreach (" ~ SeriesGen1!("p", ", ", OpApplyCount!(TyItems), 1) ~ 
"; items)
            if (pred(" ~ SeriesGen1!("p", ", ", OpApplyCount!(TyItems), 1) ~ "))
                len++;");
    } else {
        foreach (el; items)
            if (pred(el))
                len++;
    }

    return len;
} // End of len(items, pred)

alias len!(string) strLen; /// ditto
alias len!(int[]) intLen; /// ditto
alias len!(float[]) floatLen; /// ditto

Having a global callable like len() instead of an attribute is (sometimes) 
better, because you can use it for example like this (this is working syntax of 
my dlibs):

children.sort(&len!(string));
That sorts the array of strings "children" according to the given callable key, 
that is the len of the strings.

Bye,
bearophile

Reply via email to