<br><div class="gmail_quote">On Sun, Apr 11, 2010 at 04:27, BCS <span dir="ltr">&lt;<a href="mailto:none@anon.com">none@anon.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hello Ellery,<div><div></div><div class="h5"><br></div></div>
Oops, that should have been:<div><div></div><div class="h5"><br>
<br>
ret!(T) opDispatch(string s, T...)(T t) { ... }<font color="#888888"><br>
</font><br></div></div></blockquote><div>I couldn&#39;t make (string s, T...) to work, though that was the most natural way to do it. <br>Instead, I had to rely on variadic functions:<br><br>struct vector(T, uint N) {<br>
    auto ref opDispatch(string s)(...) if (s.length == 1) { // I don&#39;t think the auto ref is still necessary. It appeared during iterations on this.<br>        static if(N&gt;0 &amp;&amp; (&quot;x&quot;==s || &quot;r&quot;==s)) {<br>
            if (_arguments.length == 1) {<br>                if (_arguments[0] == typeid(T)) {<br>                    v_[0] = *cast(T*)_argptr;<br>                }<br>                else {<br>                    throw new Exception(&quot;Bad argument for vector.x, should be of type &quot; ~ T.stringof);<br>
                }<br>            }<br>            return v_[0];<br>       }<br>       static if(N&gt;1 &amp;&amp; (&quot;y&quot;==s || &quot;g&quot;==s)) return v_[1]; // TODO: the same for y,z and w...<br>       static if(N&gt;2 &amp;&amp; (&quot;z&quot;==s || &quot;b&quot;==s)) return v_[2];<br>
       static if(N&gt;3 &amp;&amp; (&quot;w&quot;==s || &quot;a&quot;==s)) return v_[3];<br><br>       static assert(&quot;boom!&quot;);<br>    }<br><br>  T[n] v_;<br>}<br><br>void main() {<br>   vector!(int, 3) v;<br>   writeln(v.x); //  0<br>
   v.x = 1;<br>   writeln(v.x); // 1<br>}<br><br><br>What&#39;s even more grand, is when you use opDispatch to generate the function for you. In this case, you can get swizzling (sp?):<br><br>// first, a helper template, needed to get a static foreach. Useful everywhere, this template.<br>
// alias it self to TypeTuple!(T,T,T,...) with n Ts<br>template TypeNuple(T, size_t n) {<br>    static if(n == 0) {<br>        alias TypeTuple!() TypeNuple;<br>    }<br>    else {<br>        alias TypeTuple!(T,TypeNuple!(T, n-1)) TypeNuple;<br>
    }<br>}<br><br>// change: Vector with a &#39;V&#39;<br>// change: opDispatch(string s) if (s.length &gt;1)<br>struct Vector(T, uint N) {<br>    auto ref opDispatch(string s)(...) if (s.length == 1) {<br>       static if(N&gt;0 &amp;&amp; (&quot;x&quot;==s || &quot;r&quot;==s)) return v_[0];<br>
       static if(N&gt;1 &amp;&amp; (&quot;y&quot;==s || &quot;g&quot;==s)) return v_[1];<br>       static if(N&gt;2 &amp;&amp; (&quot;z&quot;==s || &quot;b&quot;==s)) return v_[2];<br>       static if(N&gt;3 &amp;&amp; (&quot;w&quot;==s || &quot;a&quot;==s)) return v_[3];<br>
<br>       static assert(&quot;boom!&quot;);<br>    }<br><br>    T[s.length] opDispatch(string s)() if (s.length &gt; 1) { // s.length&gt; 1: will construct the value from the first opDispatch<br>        T[s.length] result;<br>
        alias TypeNuple!(T, s.length) TN; // to get a compile-time foreach<br>        foreach(i, Type; TN) {<br>            result[i] = this.opDispatch!(s[i..i+1])(); // that way, i is a CT index. I use s[i..i+1] to get a string<br>
        }<br>        return result;<br>    }<br><br>    private:<br>    T[N] v_;<br>}<br><br>// and then, a handy helper function to create a Vector:<br>// need import std.traits;<br>Vector!(CommonType!T, T.length) vector(T...)(T args) if (is(CommonType!T))<br>
{<br>    return Vector!(CommonType!T, T.length)([args]); // args is a tuple, so [args] dumps it into an array<br>}<br><br>usage:<br><br>void main() {<br>    auto v = vector(1,2,3); // deduced by the compiler to be a Vector!(int, 3)<br>
   auto v2 = vector(1.2,2,3,4); // deduced by the compiler to be Vector!(double, 4)<br><br>// and then, swizzling<br>   writeln(v.yzx); // &quot;231&quot;<br>  writeln(v.xxxx); // &quot;1111&quot;<br><br>}<br><br></div></div>