Thread overview
templating operators
Mar 03, 2006
Brad Roberts
Mar 03, 2006
Derek Parnell
Mar 03, 2006
Brad Roberts
Mar 03, 2006
Derek Parnell
March 03, 2006
I'm trying to create a container that will allow arbitrary key/value pair trees.  Box seems like a great start at supporting a 'holds anything' container.  The next step is making a smooth associative array of them. However, I don't seem to be able to create a nice templated opIndex or opIndexAssign.

-------- test.d ---------
import std.stdio;
import std.boxer;

class ValueContainer
{
    Box[char[]] _objects;

    template opIndex(T)
    {
        T opIndex(char[] key)
        {
            return unbox!(T)(_objects[key]);
        }
    }

    int opIndexAssign(int newValue, char[] key)
    {
        _objects[key] = box(newValue);
        return 0;
    }

    template getValue(T)
    {
        T getValue(char[] key)
        {
            return unbox!(T)(_objects[key]);
        }
    }

    template insertKeyAndValue(T)
    {
        void insertKeyAndValue(char[] key, T newValue)
        {
            _objects[key] = box(newValue);
        }
    }
}

int main()
{
    ValueContainer values = new ValueContainer();

    values["int"] = 1;
    values.insertKeyAndValue!(int)("key", 10);

    writef("int: %s\n", values["int"]);
    writef("key: %s\n", values["key"]);
    writef("key: %s\n", values.getValue!(int)("key"));

    return 0;
}
---------------

$ dmd -g test.d
test.d(46): no [] operator overload for type test.ValueContainer
test.d(47): no [] operator overload for type test.ValueContainer
test.d(48): function expected before (), not 0 of type int

Any thoughts on how to make this work well?

Thanks,
Brad
March 03, 2006
On Thu, 2 Mar 2006 18:01:07 -0800, Brad Roberts wrote:

> I'm trying to create a container that will allow arbitrary key/value pair trees.  Box seems like a great start at supporting a 'holds anything' container.  The next step is making a smooth associative array of them. However, I don't seem to be able to create a nice templated opIndex or opIndexAssign.
> 
> -------- test.d ---------
> import std.stdio;
> import std.boxer;
> 
> class ValueContainer
> {
>     Box[char[]] _objects;
> 
>     template opIndex(T)
>     {
>         T opIndex(char[] key)
>         {
>             return unbox!(T)(_objects[key]);
>         }
>     }
> 
>     int opIndexAssign(int newValue, char[] key)
>     {
>         _objects[key] = box(newValue);
>         return 0;
>     }
> 
>     template getValue(T)
>     {
>         T getValue(char[] key)
>         {
>             return unbox!(T)(_objects[key]);
>         }
>     }
> 
>     template insertKeyAndValue(T)
>     {
>         void insertKeyAndValue(char[] key, T newValue)
>         {
>             _objects[key] = box(newValue);
>         }
>     }
> }
> 
> int main()
> {
>     ValueContainer values = new ValueContainer();
> 
>     values["int"] = 1;
>     values.insertKeyAndValue!(int)("key", 10);
> 
>     writef("int: %s\n", values["int"]);
>     writef("key: %s\n", values["key"]);
>     writef("key: %s\n", values.getValue!(int)("key"));
> 
>     return 0;
> }
> ---------------
> 
> $ dmd -g test.d
> test.d(46): no [] operator overload for type test.ValueContainer
> test.d(47): no [] operator overload for type test.ValueContainer
> test.d(48): function expected before (), not 0 of type int
> 
> Any thoughts on how to make this work well?

When I did this sort of thing I had to chnage the template name to be different to the member inside the template *and* I had to instantiate the member inside the class. The instantiation didn't surprise me but the naming conflict one did. Anyhow, replace ...

     template opIndex(T)
     {
         T opIndex(char[] key)
         {
             return unbox!(T)(_objects[key]);
         }
     }

with ...

    template opIndex_T(T)
    {
        T opIndex(char[] key)
        {
            return unbox!(T)(_objects[key]);
        }
    }
    alias opIndex_T!(int).opIndex opIndex;

and it should work now.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocracy!"
3/03/2006 3:14:03 PM
March 03, 2006
On Fri, 3 Mar 2006, Derek Parnell wrote:

> When I did this sort of thing I had to chnage the template name to be different to the member inside the template *and* I had to instantiate the member inside the class. The instantiation didn't surprise me but the naming conflict one did. Anyhow, replace ...
> 
>      template opIndex(T)
>      {
>          T opIndex(char[] key)
>          {
>              return unbox!(T)(_objects[key]);
>          }
>      }
> 
> with ...
> 
>     template opIndex_T(T)
>     {
>         T opIndex(char[] key)
>         {
>             return unbox!(T)(_objects[key]);
>         }
>     }
>     alias opIndex_T!(int).opIndex opIndex;
> 
> and it should work now.
> 
> -- 
> Derek
> (skype: derek.j.parnell)
> Melbourne, Australia
> "Down with mediocracy!"
> 3/03/2006 3:14:03 PM

This works wonderfully for opIndexAssign, but not so much for multiple types of aliases for opIndex.

    alias opIndex_T!(int).opIndex opIndex;
    alias opIndex_T!(float).opIndex opIndex;

test.d(54): function alias opIndex called with argument types:
        (char[3])
matches both:
        test.ValueContainer.opIndex_T!(int).opIndex(char[])
and:
        test.ValueContainer.opIndex_T!(float).opIndex(char[])
test.d(55): function alias opIndex called with argument types:
        (char[3])
matches both:
        test.ValueContainer.opIndex_T!(int).opIndex(char[])
and:
        test.ValueContainer.opIndex_T!(float).opIndex(char[])
test.d(56): function expected before (), not 0 of type int

So close...
Brad
March 03, 2006
On Thu, 2 Mar 2006 21:38:09 -0800, Brad Roberts wrote:

> On Fri, 3 Mar 2006, Derek Parnell wrote:
> 
> This works wonderfully for opIndexAssign, but not so much for multiple types of aliases for opIndex.
> 
>     alias opIndex_T!(int).opIndex opIndex;
>     alias opIndex_T!(float).opIndex opIndex;
> 

That would because one can't overload the return type. Your code is kinda like doing ...

     int opIndex(char[] x) ...
   float opIndex(char[] x) ...

and that just ain't going to fly.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocracy!"
3/03/2006 4:45:56 PM