Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 19, 2013 Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Consider a struct that may or may not have state depending on a type parameter: struct S(T) { enum hasState = FieldTypeTuple!T.length || isNested!T; static if (hasState) T _theT; else alias _theT = T; ... } This is really nice because I don't bloat S unnecessarily and I get to use _theT.method() uniformly whether or not it's the type itself or the data member. The duplication problem appears when S itself must define a method that should be static or nonstatic depending on the existence of state. Consider: struct S(T) { ... continued from above ... if (hasState) int method() { return 1 + _theT.method(); } else static int method() { return 1 + _theT.method(); } } In the general case the body of S!T.method() may be of course larger, which makes for a nasty duplication - essentially all but the "static" keyword must be duplicated. Any ideas for a clean solution? I can't get much further than string mixins, which wouldn't be clean :o). Thanks, Andrei |
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 19 September 2013 at 17:10:43 UTC, Andrei Alexandrescu wrote:
> Any ideas for a clean solution? I can't get much further than string mixins, which wouldn't be clean :o).
opDispatch comes to mind. You'd only need two of them, one marked static and the other one not.
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 2013-09-19 19:20, Andrej Mitrovic wrote: > opDispatch comes to mind. You'd only need two of them, one marked static > and the other one not. You cannot overload on "static". -- /Jacob Carlborg |
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
> On 2013-09-19 19:20, Andrej Mitrovic wrote:
>
>> opDispatch comes to mind. You'd only need two of them, one marked static and the other one not.
>
> You cannot overload on "static".
Can't you read the damn OP example? He's using a static if to introduce static/non-static functions, do the same for opDispatch and you'll cut down on code.
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Am 19.09.2013 19:10, schrieb Andrei Alexandrescu:
> Consider a struct that may or may not have state depending on a type
> parameter:
>
> struct S(T)
> {
> enum hasState = FieldTypeTuple!T.length || isNested!T;
> static if (hasState)
> T _theT;
> else
> alias _theT = T;
> ...
> }
>
> This is really nice because I don't bloat S unnecessarily and I get to
> use _theT.method() uniformly whether or not it's the type itself or the
> data member.
>
> The duplication problem appears when S itself must define a method that
> should be static or nonstatic depending on the existence of state.
> Consider:
>
> struct S(T)
> {
> ... continued from above ...
> if (hasState)
> int method() { return 1 + _theT.method(); }
> else
> static int method() { return 1 + _theT.method(); }
> }
>
> In the general case the body of S!T.method() may be of course larger,
> which makes for a nasty duplication - essentially all but the "static"
> keyword must be duplicated.
>
> Any ideas for a clean solution? I can't get much further than string
> mixins, which wouldn't be clean :o).
>
>
> Thanks,
>
> Andrei
Can't we make the compiler deduce the static attribute? If a template method or a method of a template struct / class does not access any of its members it becomes static automatically?
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 9/19/13 12:42 PM, Andrej Mitrovic wrote:
> On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
>> On 2013-09-19 19:20, Andrej Mitrovic wrote:
>>
>>> opDispatch comes to mind. You'd only need two of them, one marked static
>>> and the other one not.
>>
>> You cannot overload on "static".
>
> Can't you read the damn OP example? He's using a static if to
> introduce static/non-static functions, do the same for opDispatch and
> you'll cut down on code.
I'm not sure I understand how that would work.
Andrei
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On 9/19/13 12:44 PM, Benjamin Thaut wrote:
> Can't we make the compiler deduce the static attribute? If a template
> method or a method of a template struct / class does not access any of
> its members it becomes static automatically?
That would be nice for this case, but it's a breaking change and I'm not sure how confusing it would be in general.
Allowing static/nonstatic overloading would help because at least I could do this:
int method() { return 1 + _theT.method(); }
static if (!hasState)
static int method() { return S().method(); }
which still is quite a bit of work, but less net duplication.
Andrei
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 2013-09-19 21:42, Andrej Mitrovic wrote: > Can't you read the damn OP example? He's using a static if to > introduce static/non-static functions, do the same for opDispatch and > you'll cut down on code. Right, sorry. -- /Jacob Carlborg |
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/19/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > I'm not sure I understand how that would work. ----- module test; import std.traits; struct S(T) { enum hasState = FieldTypeTuple!T.length || isNested!T; static if (hasState) T _theT; else alias _theT = T; private mixin template OpDispatch() { auto opDispatch(string meth, Args...)(Args args) { static if (meth == "method") // specialization ? return 1 + _theT.method(); else return mixin("_theT." ~ meth)(args); } } static if (hasState) mixin OpDispatch!(); else static mixin OpDispatch!(); } struct A { static int method() { return 0; } } struct B { int i; int method() { return i; } } void main() { auto a = S!A(); auto b = S!B(B(1)); assert(a.method == 1); // 1 + A.method() == 1 assert(b.method == 2); // 1 + b.i == 2 assert(S!A.method == 1); // works due to static dispatch // assert(S!B.method == 2); // denied at CT (requires 'this') } ----- |
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
> On 2013-09-19 21:42, Andrej Mitrovic wrote:
>
>> Can't you read the damn OP example? He's using a static if to introduce static/non-static functions, do the same for opDispatch and you'll cut down on code.
>
> Right, sorry.
Sorry for the harsh response on my part, I wasn't in the mood 5 minutes ago. I shouldn't take it out on fellow D programmers.
|
Copyright © 1999-2021 by the D Language Foundation