www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12134] New: std.string.split(string) assignment to immutable

https://d.puremagic.com/issues/show_bug.cgi?id=12134

           Summary: std.string.split(string) assignment to immutable
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc


--- Comment #0 from bearophile_hugs eml.cc 2014-02-11 16:07:25 PST ---
I have tagged this as a D enhancement.

I'd like this code to be accepted:


void main() {
    import std.string: split;
    immutable r = "AB CD".split;
}


DMD 2.065beta2 gives:

test.d(3): Error: cannot implicitly convert expression (split("AB CD")) of type
string[] to immutable(char[][])


split(string) should return a string[] that is implicitly castable to
immutable(string)[] and immutable(string[]).

split comes from std.array, and the problem boils down to:


S[] split(S)(S s) pure {
    S[] result;
    return result;
}
void main() {
    char[][] r1 = "AB CD".dup.split;
    const string[] r2 = "AB CD".split;
}



This is a first try at finding a solution:


import std.traits: isMutable, Select, ForeachType;
import std.traits: isSomeString;
import std.uni: isWhite;

Select!(isMutable!(ForeachType!S), S, immutable S)[]
split(S)(S s)  safe pure
if (isSomeString!S) {
    size_t istart;
    bool inword = false;
    typeof(return) result;

    foreach (i, dchar c; s) {
        if (isWhite(c)) {
            if (inword) {
                result ~= s[istart .. i];
                inword = false;
            }
        } else {
            if (!inword) {
                istart = i;
                inword = true;
            }
        }
    }

    if (inword)
        result ~= s[istart .. $];
    return result;
}

void main() {
    string s = "AB CD";
    char[] m = s.dup;
    char[][] r1 = m.split;
    immutable r2 = s.split;
    auto r3 = s.split;
    pragma(msg, typeof(r3)); // Output: immutable(char[])[]
    const(string)[] r4 = s.split; // OK
    string[] r5 = s.split; // Error
}


The code works correctly with r1, you can assign it to a mutable array because
the input is mutable.

But the problem is shown with r5, what if you instead want a mutable array of
regular strings?

So, can the D type system be modified for such situations? And is it a good
idea to modify it like this?

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