Jump to page: 1 2
Thread overview
Limiting template functions to template instantiations of a struct
Nov 06, 2013
Atila Neves
Nov 06, 2013
Namespace
Nov 06, 2013
Atila Neves
Nov 06, 2013
Dicebot
Nov 06, 2013
Atila Neves
Nov 06, 2013
Dicebot
Nov 06, 2013
Namespace
Nov 06, 2013
H. S. Teoh
Nov 07, 2013
Timon Gehr
Nov 06, 2013
simendsjo
Nov 07, 2013
Marco Leise
Nov 07, 2013
simendsjo
November 06, 2013
The title isn't very clear but I wasn't sure how to phrase it without code. Basically what I want to do is this (won't compile):

struct Foo(int N) {
}

void func(T)(T obj) if(is(T:Foo)) {
}

void func(T)(T obj) if(!is(T:Foo)) {
}

Foo by itself isn't a type, but I don't want to limit func instantiation in the 1st case to just e.g. Foo!3 but to _any_ Foo regardless of N. I came up with two workarouds: make Foo a class that derives from an empty FooBase (then is(T:FooBase) works), or adding a "secret" enum within Foo that I can check with std.traits.hasMember in a static if. I don't really like either of them. Is what I want to do possible?

Atila
November 06, 2013
On Wednesday, 6 November 2013 at 13:00:17 UTC, Atila Neves wrote:
> The title isn't very clear but I wasn't sure how to phrase it without code. Basically what I want to do is this (won't compile):
>
> struct Foo(int N) {
> }
>
> void func(T)(T obj) if(is(T:Foo)) {
> }
>
> void func(T)(T obj) if(!is(T:Foo)) {
> }
>
> Foo by itself isn't a type, but I don't want to limit func instantiation in the 1st case to just e.g. Foo!3 but to _any_ Foo regardless of N. I came up with two workarouds: make Foo a class that derives from an empty FooBase (then is(T:FooBase) works), or adding a "secret" enum within Foo that I can check with std.traits.hasMember in a static if. I don't really like either of them. Is what I want to do possible?
>
> Atila

This works:
http://dpaste.dzfl.pl/f98f4783
November 06, 2013
On Wednesday, 6 November 2013 at 13:00:17 UTC, Atila Neves wrote:
> The title isn't very clear but I wasn't sure how to phrase it without code. Basically what I want to do is this (won't compile):
>
> struct Foo(int N) {
> }
>
> void func(T)(T obj) if(is(T:Foo)) {
> }
>
> void func(T)(T obj) if(!is(T:Foo)) {
> }
>
> Foo by itself isn't a type, but I don't want to limit func instantiation in the 1st case to just e.g. Foo!3 but to _any_ Foo regardless of N. I came up with two workarouds: make Foo a class that derives from an empty FooBase (then is(T:FooBase) works), or adding a "secret" enum within Foo that I can check with std.traits.hasMember in a static if. I don't really like either of them. Is what I want to do possible?
>
> Atila

Here's a couple of different ways to do this.

    import std.stdio;

    struct Foo(int N) {
    }

    void func(T)(T obj) if(is(T:Foo!U, int U)) {
        writeln("It's a Foo!");
    }

    void func(T)(T obj) if(!is(T:Foo!U, int U)) {
        writeln("No Foo :(");
    }

    template isFoo(T) {
        static if(is(T:Foo!U, int U))
            enum isFoo = true;
        else
            enum isFoo = false;
    }

    void gunc(T)(T obj) if(isFoo!T) {
        writeln("Gunc isFoo");
    }

    void gunc(T)(T obj) if(!isFoo!T) {
        writeln("Gunc !isFoo");
    }

    void hunk(T)(T obj) {
        static if(isFoo!T)
            writeln("Hunk!");
        else
            writeln("No hunk!");
    }

    void main() {
        Foo!3 f;
        func(f); // It's a Foo!

        struct S {}
        S s;
        func(s); // No Foo :(

        gunc(f); // Gunc isFoo
        gunc(s); // Gunc !isFoo

        hunk(f); // Hunk!
        hunk(s); // No hunk!
    }
November 06, 2013
Wow. It didn't even occur to me that `is` could be used like that. I think that operator is the hardest part of the language for me to grok. Thanks guys!
November 06, 2013
On Wednesday, 6 November 2013 at 21:49:52 UTC, Atila Neves wrote:
> Wow. It didn't even occur to me that `is` could be used like that. I think that operator is the hardest part of the language for me to grok. Thanks guys!

http://dlang.org/expression.html#IsExpression ;)
November 06, 2013
On Wednesday, 6 November 2013 at 21:52:04 UTC, Dicebot wrote:
> On Wednesday, 6 November 2013 at 21:49:52 UTC, Atila Neves wrote:
>> Wow. It didn't even occur to me that `is` could be used like that. I think that operator is the hardest part of the language for me to grok. Thanks guys!
>
> http://dlang.org/expression.html#IsExpression ;)

I know, but I keep having to refer back to that and even then I didn't know about the syntax these guys just posted! ;)
November 06, 2013
On Wednesday, 6 November 2013 at 22:41:08 UTC, Atila Neves wrote:
> I know, but I keep having to refer back to that and even then I didn't know about the syntax these guys just posted! ;)

Well, it is mentioned in the list of `is` usage cases down that link. It is very ugly part of the language but definitely worth spending some time to carefully investigate all the patterns - damn powerful stuff.
November 06, 2013
On Wednesday, 6 November 2013 at 22:43:18 UTC, Dicebot wrote:
> On Wednesday, 6 November 2013 at 22:41:08 UTC, Atila Neves wrote:
>> I know, but I keep having to refer back to that and even then I didn't know about the syntax these guys just posted! ;)
>
> Well, it is mentioned in the list of `is` usage cases down that link. It is very ugly part of the language but definitely worth spending some time to carefully investigate all the patterns - damn powerful stuff.

There are so much more uglier things ... :P
Take a look at the scoped or ref counted implementation.
November 06, 2013
On Wed, Nov 06, 2013 at 11:52:56PM +0100, Namespace wrote:
> On Wednesday, 6 November 2013 at 22:43:18 UTC, Dicebot wrote:
> >On Wednesday, 6 November 2013 at 22:41:08 UTC, Atila Neves wrote:
> >>I know, but I keep having to refer back to that and even then I didn't know about the syntax these guys just posted! ;)
> >
> >Well, it is mentioned in the list of `is` usage cases down that link. It is very ugly part of the language but definitely worth spending some time to carefully investigate all the patterns - damn powerful stuff.
> 
> There are so much more uglier things ... :P
> Take a look at the scoped or ref counted implementation.

Are you sure about that? Do you know that this does?

	int func(ref int x, string y, float z = 3.14159) { ... }

	// This is possibly the single nastiest bit of syntax in all of D:
	static if (is(func X == __parameters)) {
		// Quick, without looking at the docs: what does X refer
		// to?

		// If you manage to figure that one out, can you say
		// with certainty what's the type of X? Are you sure? :P

		alias Y = X[0];

		// Quick, without looking at the docs: what is Y?
		// (If your answer was, the first element of X, you're
		// wrong!)

		// Quiz: how do you get a single element of X? (And no,
		// X[i] is the wrong answer, see above.)

		// If you got it right thus far: how do you access the
		// name of a single element of X? The default value?
		// (Note: if you didn't get the previous questions
		// right, don't even attempt this one; it's one of those
		// things that nobody can possibly guess unless they've
		// seen it before.)
	}

Almost every part of the above is so completely counterintuitive and impossible to predict from the syntax that I honestly doubt if the scoped or RefCounted implementation could beat it for ugliness. :P


T

-- 
Notwithstanding the eloquent discontent that you have just respectfully expressed at length against my verbal capabilities, I am afraid that I must unfortunately bring it to your attention that I am, in fact, NOT verbose.
November 07, 2013
Am Wed, 06 Nov 2013 14:22:13 +0100
schrieb "simendsjo" <simendsjo@gmail.com>:

>      template isFoo(T) {
>          static if(is(T:Foo!U, int U))
>              enum isFoo = true;
>          else
>              enum isFoo = false;
>      }

enum isFoo(T) = is(T:Foo!U, int U);

correct ?

-- 
Marco

« First   ‹ Prev
1 2