digitalmars.D - isIterable(T)
- dsimcha <dsimcha yahoo.com> Apr 26 2009
- "Denis Koroskin" <2korden gmail.com> Apr 26 2009
- dsimcha <dsimcha yahoo.com> Apr 26 2009
- bearophile <bearophileHUGS lycos.com> Apr 26 2009
- dsimcha <dsimcha yahoo.com> Apr 26 2009
- bearophile <bearophileHUGS lycos.com> Apr 26 2009
- dsimcha <dsimcha yahoo.com> Apr 26 2009
- downs <default_357-line yahoo.de> Apr 27 2009
I've been thinking a little more about ranges, etc. and it would be nice to
have a template for isIterable(T) that simply tells whether an object can be
iterated over with foreach, without caring how this iteration works (ranges,
opApply, builtin array/AA). I have some use cases where I'm writing very
generic functionality and all I need is the lowest common denominator that,
given an object T, the following will compile, and to know what type elem
would be:
foreach(elem; T.init) {}
This functionality does not require any of the more advanced features of
ranges, just iteration. Is there any good way to write a template for this?
Since foreach is a statement, is(typeof()) and __traits(compiles) are out.
Apr 26 2009
On Sun, 26 Apr 2009 21:44:31 +0400, dsimcha <dsimcha yahoo.com> wrote:I've been thinking a little more about ranges, etc. and it would be nice to have a template for isIterable(T) that simply tells whether an object can be iterated over with foreach, without caring how this iteration works (ranges, opApply, builtin array/AA). I have some use cases where I'm writing very generic functionality and all I need is the lowest common denominator that, given an object T, the following will compile, and to know what type elem would be: foreach(elem; T.init) {} This functionality does not require any of the more advanced features of ranges, just iteration. Is there any good way to write a template for this? Since foreach is a statement, is(typeof()) and __traits(compiles) are out.
// Not tested template isIterable(T) { static if (is(typeof({foreach(elem; T.init) {}})) { const bool isIterable = true; } else { const bool isIterable = false; } }
Apr 26 2009
== Quote from Denis Koroskin (2korden gmail.com)'s articleOn Sun, 26 Apr 2009 21:44:31 +0400, dsimcha <dsimcha yahoo.com> wrote:I've been thinking a little more about ranges, etc. and it would be nice to have a template for isIterable(T) that simply tells whether an object can be iterated over with foreach, without caring how this iteration works (ranges, opApply, builtin array/AA). I have some use cases where I'm writing very generic functionality and all I need is the lowest common denominator that, given an object T, the following will compile, and to know what type elem would be: foreach(elem; T.init) {} This functionality does not require any of the more advanced features of ranges, just iteration. Is there any good way to write a template for this? Since foreach is a statement, is(typeof()) and __traits(compiles) are out.
template isIterable(T) { static if (is(typeof({foreach(elem; T.init) {}})) { const bool isIterable = true; } else { const bool isIterable = false; } }
Wow, IDK why I thought that wouldn't work. I must have made some minor syntactical error b/c I tried the same thing a few minutes ago, yet somehow yours works. Only thing is, you forgot a ) at the end. Also, enum is more efficient than const. Here's a tested version. template isIterable(T) { static if (is(typeof({foreach(elem; T.init) {}}))) { enum bool isIterable = true; } else { enum bool isIterable = false; } } import std.range; // For testing. struct Foo { // For testing opApply. // For testing. int opApply(int delegate(ref uint) dg) { assert(0); } } static assert(isIterable!(uint[])); static assert(!isIterable!(uint)); static assert(isIterable!(Foo)); static assert(isIterable!(uint[string])); static assert(isIterable!(Chain!(uint[], uint[])));
Apr 26 2009
dsimcha Wrote:I've been thinking a little more about ranges, etc. and it would be nice to have a template for isIterable(T)
I agree. IsIterable is already inside my dlibs (as the xkeys/xvalues you talk about in another post of yours, but in the "func" module), into the "templates" module: http://www.fantascienza.net/leonardo/so/dlibs/templates.html I suggest you to take a good look at those dlibs, you will probably find stuff you are going to think tomorrow and the day after tomorrow. Bye, bearophile
Apr 26 2009
== Quote from bearophile (bearophileHUGS lycos.com)'s articledsimcha Wrote:I've been thinking a little more about ranges, etc. and it would be nice to have a template for isIterable(T)
IsIterable is already inside my dlibs (as the xkeys/xvalues you talk about in
http://www.fantascienza.net/leonardo/so/dlibs/templates.html I suggest you to take a good look at those dlibs, you will probably find stuff
Bye, bearophile
Thanks. The other part of the question, which all of us seemed to neglected was how to get the type of elem. I just got that to work, too. import std.traits, std.range; template IterType(T) { alias ReturnType!( { foreach(elem; T.init) { return elem; } }) IterType; } unittest { struct Foo { // For testing opApply. // For testing. int opApply(int delegate(ref uint) dg) { assert(0); } } static assert(is(IterType!(uint[]) == uint)); static assert(is(IterType!(Foo) == uint)); static assert(is(IterType!(uint[string]) == uint)); static assert(is(IterType!(Chain!(uint[], uint[])) == uint)); }
Apr 26 2009
dsimcha:Thanks. The other part of the question, which all of us seemed to neglected was how to get the type of elem.
See BaseType and BaseType1 in my "templates" module (I think you are talking about BaseType1 here, later you will probably feel the need of BaseType too, so I avoid posting another post later). Bye, bearophile
Apr 26 2009
== Quote from bearophile (bearophileHUGS lycos.com)'s articledsimcha:Thanks. The other part of the question, which all of us seemed to neglected was how to get the type of elem.
avoid posting another post later).Bye, bearophile
Thanks. I haven't looked at your dlibs much, mostly because they're supposed to be for D1, and all my code is in D2. I guess there are some good template code snippets that generalize to D2 in there, though.
Apr 26 2009
bearophile wrote:dsimcha Wrote:I've been thinking a little more about ranges, etc. and it would be nice to have a template for isIterable(T)
I agree. IsIterable is already inside my dlibs (as the xkeys/xvalues you talk about in another post of yours, but in the "func" module), into the "templates" module: http://www.fantascienza.net/leonardo/so/dlibs/templates.html I suggest you to take a good look at those dlibs, you will probably find stuff you are going to think tomorrow and the day after tomorrow. Bye, bearophile
See title :)
Apr 27 2009









dsimcha <dsimcha yahoo.com> 