Thread overview
[Issue 4761] New: std.array.mul()
August 29, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4761

           Summary: std.array.mul()
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: patch
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2010-08-29 15:31:21 PDT ---
In Python I use very often the * (__mul__) list operator, it's handy in many
situations (it is not lazy):

>>> "abc" * -1
''
>>> "abc" * 0
''
>>> "abc" * 1
'abc'
>>> "abc" * 5
'abcabcabcabcabc'
>>> [0] * 5
[0, 0, 0, 0, 0]


It's not a good idea to add a similar product operator to D arrays because despite vector mult operation will probably require [] (while the mul doesn't require it), the two are too much syntactically close, they risk being too much bug-prone.

So I suggest to simply add this mul() to std.array (this must be eager, not a
lazy range, otherwise it's not handy for its purposes):


/// ...
T[] mul(T)(T[] items, int times) {
    T[] result;

    static if(!is( typeof(items) == void[] )) {
        if (times > 0 && items.length > 0) {
            if (items.length == 1) {
                result.length = times;
                result[] = items[0];
            } else {
                result.length = items.length * times;
                for (size_t pos; pos < result.length; pos += items.length)
                    result[pos .. pos+items.length] = items;
            }
        }
    }

    return result;
}

// demo ----------
import std.stdio;
void main() {
    auto a1 = [0].mul(10);
    writeln(a1);
    auto a2 = [0, 5, 10].mul(4);
    writeln(a2);
}


More unittests and a ddoct on request.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 29, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4761



--- Comment #1 from bearophile_hugs@eml.cc 2010-08-29 15:44:13 PDT ---
This mul() needs more work, to be used on const arrays too. If you are interested, I may try to write this improvement.

If the given array is one of the string types, it has to call
std.string.repeat() inside.

But the second argument of std.string.repeat() must become a signed integer,
otherwise you just need repeat("ab", -1) to create a crash.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 01, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4761



--- Comment #2 from bearophile_hugs@eml.cc 2010-09-01 14:35:02 PDT ---
A more general version:


import std.traits: isArray, Unqual;

/// ...
T mul(T)(T items, int times) if(isArray!T) {
    alias Unqual!(typeof(items[0])) E; // dangerous?
    E[] result;

    static if(!is( typeof(items) == void[] )) {
        if (times > 0 && items.length > 0) {
            if (items.length == 1) {
                result.length = times;
                result[] = items[0];
            } else {
                result.length = items.length * times;
                for (size_t pos; pos < result.length; pos += items.length)
                    result[pos .. pos+items.length] = items[];
            }
        }
    }

    return cast(T)result; // assumeUnique?
}

unittest {
    assert("".mul(-10) == "");
    assert("".mul(0) == "");
    assert("".mul(1) == "");
    assert("".mul(10) == "");

    assert("a".mul(-10) == "");
    assert("a".mul(0) == "");
    assert("a".mul(1) == "a");
    assert("a".mul(10) == "aaaaaaaaaa");

    assert("abc".mul(-10) == "");
    assert("abc".mul(0) == "");
    assert("abc".mul(1) == "abc");
    assert("abc".mul(4) == "abcabcabcabc");


    assert(""w.mul(-10) == ""w);
    assert(""w.mul(0) == ""w);
    assert(""w.mul(1) == ""w);
    assert(""w.mul(10) == ""w);

    assert("a"w.mul(-10) == ""w);
    assert("a"w.mul(0) == ""w);
    assert("a"w.mul(1) == "a"w);
    assert("a"w.mul(10) == "aaaaaaaaaa"w);

    assert("abc"w.mul(-10) == ""w);
    assert("abc"w.mul(0) == ""w);
    assert("abc"w.mul(1) == "abc"w);
    assert("abc"w.mul(4) == "abcabcabcabc"w);


    assert(""d.mul(-10) == ""d);
    assert(""d.mul(0) == ""d);
    assert(""d.mul(1) == ""d);
    assert(""d.mul(10) == ""d);

    assert("a"d.mul(-10) == ""d);
    assert("a"d.mul(0) == ""d);
    assert("a"d.mul(1) == "a"d);
    assert("a"d.mul(10) == "aaaaaaaaaa"d);

    assert("abc"d.mul(-10) == ""d);
    assert("abc"d.mul(0) == ""d);
    assert("abc"d.mul(1) == "abc"d);
    assert("abc"d.mul(4) == "abcabcabcabc"d);


    assert((new int[0]).mul(-10) == (new int[0]));
    assert((new int[0]).mul(0) == (new int[0]));
    assert((new int[0]).mul(1) == (new int[0]));
    assert((new int[0]).mul(10) == (new int[0]));

    assert([1].mul(-10) == (new int[0]));
    assert([1].mul(0) == (new int[0]));
    assert([1].mul(1) == [1]);
    assert([1].mul(5) == [1,1,1,1,1]);

    assert([1.5,2.3,3.1].mul(-10) == (new double[0]));
    assert([1.5,2.3,3.1].mul(0) == (new double[0]));
    assert([1.5,2.3,3.1].mul(1) == [1.5,2.3,3.1]);
    assert([1.5,2.3,3.1].mul(2) == [1.5,2.3,3.1,1.5,2.3,3.1]);


    const int[] a1;
    assert(a1.mul(-10) == a1);
    assert(a1.mul(0) == a1);
    assert(a1.mul(1) == a1);
    assert(a1.mul(10) == a1);

    const int[] a2 = [1];
    assert(a2.mul(-10) == a1);
    assert(a2.mul(0) == a1);
    assert(a2.mul(1) == a2);
    assert(a2.mul(5) == [1,1,1,1,1]);

    const int[] a3 = [1, 2, 3];
    assert(a3.mul(-10) == a1);
    assert(a3.mul(0) == a1);
    assert(a3.mul(1) == a3);
    assert(a3.mul(4) == [1,2,3,1,2,3,1,2,3,1,2,3]);
    static assert(is(typeof(a3.mul(4)) == const int[]));


    immutable int[] a4;
    assert(a4.mul(-10) == a4);
    assert(a4.mul(0) == a4);
    assert(a4.mul(1) == a4);
    assert(a4.mul(10) == a4);

    immutable int[] a5 = [1];
    assert(a5.mul(-10) == a4);
    assert(a5.mul(0) == a4);
    assert(a5.mul(1) == a5);
    assert(a5.mul(5) == [1,1,1,1,1]);

    immutable int[] a6 = [1, 2, 3];
    assert(a6.mul(-10) == a4);
    assert(a6.mul(0) == a4);
    assert(a6.mul(1) == a6);
    assert(a6.mul(4) == [1,2,3,1,2,3,1,2,3,1,2,3]);
    static assert(is(typeof(a6.mul(4)) == immutable int[]));

    immutable(int)[] a7 = [1, 2, 3];
    static assert(is(typeof(a7.mul(0)) == immutable(int)[]));
    static assert(is(typeof(a7.mul(1)) == immutable(int)[]));
    static assert(is(typeof(a7.mul(3)) == immutable(int)[]));
}

void main() {}

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