Shouldn't hasSwappableElements work on char arrays?

Andrej Mitrovic andrej.mitrovich at gmail.com
Thu Feb 24 10:03:21 PST 2011


Would it be wrong if hasSwappableElements worked on char arrays?

Look:

import std.stdio;
import std.algorithm;
import std.range;
import std.traits;

void main()
{
    char[] r = "abc".dup;

    // fails:
    static assert(hasSwappableElements!(char[]));   
    
    // fails because reverse uses hasSwappableElements(r)
    // as a constraint:
    reverse(r);
    
    // But this works just fine..
    swap(r[0], r[2]);
    
    assert(r == "cba");
}

If you comment out the static assert and the reverse, you'll see that swap works fine on char arrays if you give it an index. 

Here's an experimental implementation of hasSwappableElements that could work for char[]'s:

import std.stdio;
import std.algorithm;
import std.range : isForwardRange, ElementType;
import std.traits;

template hasSwappableElements(R)
{
    enum bool hasSwappableElements = isForwardRange!(R) && is(typeof(
    {
        auto r = [ElementType!(R).init];
        swap(r[0], r[0]);
    }()));
}

void main()
{
    char[] r = "abc".dup;

    // now works:
    static assert(hasSwappableElements!(char[]));   
    
    swap(r[0], r[2]);
    assert(r == "cba");
}

Here's another thing that's interesting. If I replace "auto r" with "R r" in the modified hasSwappableElements implementation, then the assert fails:

import std.stdio;
import std.algorithm;
import std.range : isForwardRange, ElementType;
import std.traits;

template hasSwappableElements(R)
{
    enum bool hasSwappableElements = isForwardRange!(R) && is(typeof(
    {
        R r = [ElementType!(R).init];
        swap(r[0], r[0]);
    }()));
}

void main()
{
    // Fails
    static assert(hasSwappableElements!(char[]));   
}

The same thing happens if I replace "R" with "char[]". This might be some kind of bug?


More information about the Digitalmars-d mailing list