www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - simple syntax issue with template

reply "Lloyd Dupont" <ld-REMOVE galador.net> writes:
I'm trying to create 2 extra method for arrays ("range" would be better, 
though I don't quite understand what is a "range")
Although I have some indecipherable (to me) compiler error...

What's wrong with the code below?
==================
import std.algorithm;

public:

void remove(T)(ref T[] array, T element)
{
    auto index = array.countUntil!("a == b", T[], T)(array, element);
    removeAt(index);
}

void removeAt(T)(ref T[] array, sizediff_t index)
{
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
}


unittest
{
    auto a = [1, 3, 4];
    a.remove(3);
    assert(a == [1, 4]);
}
====================== 
Jun 13 2011
next sibling parent "Lloyd Dupont" <ld-REMOVE galador.net> writes:
removed some obvious error, still stumped on the templated syntax ...
so.. why is it not compiling?
(error:
Error: template std.algorithm.countUntil(alias pred = "a == b",R1,R2) if 
(is(typeof(startsWith!(pred)(haystack,needle)))) does not match any function 
template declaration
)
=====
import std.algorithm;

public:

void remove(T)(ref T[] array, T element)
{
    sizediff_t index = array.countUntil!("a == b", T[], T)(array, element);
    removeAt(array, index);
}

void removeAt(T)(ref T[] array, sizediff_t index)
{
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
}


unittest
{
    auto a = [1, 3, 4];
    a.remove(3);
    assert(a == [1, 4]);
}
=====
Jun 13 2011
prev sibling next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13.06.2011 16:03, Lloyd Dupont wrote:
 I'm trying to create 2 extra method for arrays ("range" would be 
 better, though I don't quite understand what is a "range")
 Although I have some indecipherable (to me) compiler error...

 What's wrong with the code below?
 ==================
 import std.algorithm;

 public:

 void remove(T)(ref T[] array, T element)
 {
    auto index = array.countUntil!("a == b", T[], T)(array, element);
    removeAt(index);
 }

 void removeAt(T)(ref T[] array, sizediff_t index)
 {
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
 }


 unittest
 {
    auto a = [1, 3, 4];
    a.remove(3);
    assert(a == [1, 4]);
 }
 ======================
It's not exactly clear what's your problem, since you haven't put a tiniest description of what the compiler outputs. still: array.countUntil!("a == b", T[], T)(array, element); should be ether countUntil!("a == b", T[], T)(array, element); or: array.countUntil!("a == b", T[], T)( element); also drop thouse ugly explicit template params (the compiler can and would figure them out anyway): array.countUntil!"a == b"(element); //same as default array.countUntil(element); another one: removeAt(index); should be array.removeAt(index) or removeAt(array, index); And last but not least there is remove in Phobos, it's just link to it from summary table is constantly getting screwed up. -- Dmitry Olshansky
Jun 13 2011
parent reply "Lloyd Dupont" <ld-REMOVE galador.net> writes:
ho.. plenty of silly mistake indeed.. thanks for spotting them!
(maybe I should take a break and play the witcher 2 hey!?!? :)

however I still have a problem with removeAt now! :(
===
void removeAt(T)(ref T[] array, int index)
{
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
}
===
will produce the following errors:
===
Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) 
&& is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == 
immutable(T))) does not match any function template declaration
Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) 
&& is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == 
immutable(T))) cannot deduce template function from argument types 
!()(int[],int,int,void[])
===

mmm.. strangely enough the code below succeed!
====
void removeAt(T)(ref T[] array, int index)
{
    if(index < 0 || index >= array.length)
        return;
    T[] empty;
    array.replaceInPlace(index, index + 1, empty);
}
====
but T[].init didn't work either....?! ho well, thanks! :) 
Jun 13 2011
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13.06.2011 16:49, Lloyd Dupont wrote:
 ho.. plenty of silly mistake indeed.. thanks for spotting them!
 (maybe I should take a break and play the witcher 2 hey!?!? :)
Why not ? ;-)
 however I still have a problem with removeAt now! :(
 ===
 void removeAt(T)(ref T[] array, int index)
 {
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
 }
Yeah, I think I've hit this issue before, and used plain cast(T[])[]. The problem is that [] is null of type void[], and template fails to resolve type. Seems like insertInPlace probably should take this special case into account.
 ===
 will produce the following errors:
 ===
 Error: template std.array.replaceInPlace(T,Range) if 
 (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && 
 !is(T == const(T)) && !is(T == immutable(T))) does not match any 
 function template declaration
 Error: template std.array.replaceInPlace(T,Range) if 
 (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && 
 !is(T == const(T)) && !is(T == immutable(T))) cannot deduce template 
 function from argument types !()(int[],int,int,void[])
 ===

 mmm.. strangely enough the code below succeed!
 ====
 void removeAt(T)(ref T[] array, int index)
 {
    if(index < 0 || index >= array.length)
        return;
    T[] empty;
    array.replaceInPlace(index, index + 1, empty);
 }
 ====
 but T[].init didn't work either....?! ho well, thanks! :)
-- Dmitry Olshansky
Jun 13 2011
prev sibling parent Joshua Niehus <jm.niehus gmail.com> writes:
 I'm trying to create 2 extra method for arrays ("range" would be
 better, though I don't quite understand what is a "range")
 Although I have some indecipherable (to me) compiler error...

 What's wrong with the code below?
 ==================
 import std.algorithm;

 public:

 void remove(T)(ref T[] array, T element)
 {
    auto index = array.countUntil!("a == b", T[], T)(array, element);
    removeAt(index);
 }

 void removeAt(T)(ref T[] array, sizediff_t index)
 {
    if(index < 0 || index >= array.length)
        return;
    array.replaceInPlace(index, index + 1, []);
 }


 unittest
 {
    auto a = [1, 3, 4];
    a.remove(3);
    assert(a == [1, 4]);
 }
 ======================
Hi Lloyd, why not just use the built in functionality of arrays? //---------------------- import std.stdio; void main() { auto a = [1, 2, 3, 4, 5, 6, 7, 8]; remove(a, 3); foreach (i; a) { write(i, " "); } writeln(""); } void remove(T) (ref T[] myarray, int element) { auto front = myarray[0 .. (element -1)]; auto back = myarray[element .. $]; myarray = front ~ back; // or simply: myarray = myarray[0 .. (element - 1)] ~ myarray[element .. $]; } //---------------------- Josh
Jun 13 2011