Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 01, 2015 Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
How do I check that a template parameter is a CT-value or an enum symbol? I want this to restrict the following template: /** Returns: true iff all values $(D V) are the same. */ template allSame(V...) // TODO restrict to values only { static if (V.length <= 1) enum bool allSame = true; else enum bool allSame = V[0] == V[1] && allSame!(V[1..$]); } unittest { static assert(!allSame!(41, 42)); static assert(allSame!(42, 42, 42)); } |
October 01, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 1 October 2015 at 00:04:18 UTC, Nordlöw wrote: > How do I check that a template parameter is a CT-value or an enum symbol? > > I want this to restrict the following template: > > /** Returns: true iff all values $(D V) are the same. */ > template allSame(V...) // TODO restrict to values only > { > static if (V.length <= 1) > enum bool allSame = true; > else > enum bool allSame = V[0] == V[1] && allSame!(V[1..$]); > } > > unittest > { > static assert(!allSame!(41, 42)); > static assert(allSame!(42, 42, 42)); > } std.traits to the rescue! http://dlang.org/phobos/std_traits.html#isExpressions Using isExpressions!V as a template constraint looks like the behavior you're looking for. |
October 01, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fusxfaranto | On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:
>> /** Returns: true iff all values $(D V) are the same. */
>> template allSame(V...) // TODO restrict to values only
>> {
>> static if (V.length <= 1)
>> enum bool allSame = true;
>> else
>> enum bool allSame = V[0] == V[1] && allSame!(V[1..$]);
>> }
>
> std.traits to the rescue!
>
> http://dlang.org/phobos/std_traits.html#isExpressions
>
> Using isExpressions!V as a template constraint looks like the behavior you're looking for.
Thanks!
BTW: Is there some way to turn the recursive definition of `allSame` into an iterative definition?
|
October 01, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fusxfaranto | On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:
>> /** Returns: true iff all values $(D V) are the same. */
>> template allSame(V...) // TODO restrict to values only
>> {
>> static if (V.length <= 1)
>> enum bool allSame = true;
>> else
>> enum bool allSame = V[0] == V[1] && allSame!(V[1..$]);
>> }
>
> std.traits to the rescue!
>
> http://dlang.org/phobos/std_traits.html#isExpressions
>
> Using isExpressions!V as a template constraint looks like the behavior you're looking for.
Thanks!
BTW: Is there some way to turn the recursive definition of `allSame`
template allSame(V...)
if (isExpressions!(V))
{
static if (V.length <= 1)
enum allSame = true;
else
enum allSame = V[0] == V[1] && allSame!(V[1..$]);
}
into an iterative definition?
|
October 01, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 10/01/2015 03:26 PM, Nordlöw wrote:
> On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:
>>> /** Returns: true iff all values $(D V) are the same. */
>>> template allSame(V...) // TODO restrict to values only
>>> {
>>> static if (V.length <= 1)
>>> enum bool allSame = true;
>>> else
>>> enum bool allSame = V[0] == V[1] && allSame!(V[1..$]);
>>> }
>>
>> std.traits to the rescue!
>>
>> http://dlang.org/phobos/std_traits.html#isExpressions
>>
>> Using isExpressions!V as a template constraint looks like the behavior
>> you're looking for.
>
> Thanks!
>
> BTW: Is there some way to turn the recursive definition of `allSame`
>
> template allSame(V...)
> if (isExpressions!(V))
> {
> static if (V.length <= 1)
> enum allSame = true;
> else
> enum allSame = V[0] == V[1] && allSame!(V[1..$]);
> }
>
> into an iterative definition?
Very quickly:
import std.traits;
template allSame(V...)
if (isExpressions!(V))
{
bool impl_(V...)() {
static if (V.length > 1) {
foreach (i, _; V[0 .. $ - 1]) {
if (V[i] != V[i + 1]) {
return false;
}
}
return true;
} else {
return true;
}
}
enum allSame = impl_!V();
}
unittest
{
static assert( allSame!());
static assert( allSame!(42));
static assert( allSame!(42, 42, 42));
static assert(!allSame!(42, 43, 42));
}
Ali
|
October 01, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Thursday, 1 October 2015 at 22:37:57 UTC, Ali Çehreli wrote:
> Very quickly:
>
> import std.traits;
>
> template allSame(V...)
> if (isExpressions!(V))
> {
> bool impl_(V...)() {
> static if (V.length > 1) {
> foreach (i, _; V[0 .. $ - 1]) {
> if (V[i] != V[i + 1]) {
> return false;
> }
> }
>
> return true;
>
> } else {
> return true;
> }
> }
>
> enum allSame = impl_!V();
> }
Will this spare memory in DMD? If so there are a few traits that should be update accordingly, for instance `allSatisfy` and `anySatisfy`.
Thanks!
|
October 02, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 1 October 2015 at 22:41:21 UTC, Nordlöw wrote:
> Will this spare memory in DMD? If so there are a few traits that should be update accordingly, for instance `allSatisfy` and `anySatisfy`.
>
> Thanks!
Highly doubtful as CTFE already allocates like there's no tomorrow.
|
October 02, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Friday, 2 October 2015 at 02:39:56 UTC, Meta wrote:
> Highly doubtful as CTFE already allocates like there's no tomorrow.
Could that memory usage be tested somehow?
|
October 02, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 1 October 2015 at 22:26:39 UTC, Nordlöw wrote:
> On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:
>>> /** Returns: true iff all values $(D V) are the same. */
>>> template allSame(V...) // TODO restrict to values only
>>> {
>>> static if (V.length <= 1)
>>> enum bool allSame = true;
>>> else
>>> enum bool allSame = V[0] == V[1] && allSame!(V[1..$]);
>>> }
>>
>> std.traits to the rescue!
>>
>> http://dlang.org/phobos/std_traits.html#isExpressions
>>
>> Using isExpressions!V as a template constraint looks like the behavior you're looking for.
>
> Thanks!
>
> BTW: Is there some way to turn the recursive definition of `allSame`
>
> template allSame(V...)
> if (isExpressions!(V))
> {
> static if (V.length <= 1)
> enum allSame = true;
> else
> enum allSame = V[0] == V[1] && allSame!(V[1..$]);
> }
>
> into an iterative definition?
Why? To avoid slowing down compilation with all those template instantiations?
How about a O(log2(N)) depth recursive version, something like this:
template allSame(V ...)
if (isExpressions!V)
{
static if (V.length <= 1)
enum allSame = true;
else static if(V.length & 1)
enum allSame = V[$-1] == V[0]
&& V[0 .. $/2] == V[$/2 .. $-1]
&& allSame!(V[0 .. $/2]);
else
enum allSame = V[0..$/2] == V[$/2 .. $]
&& allSame!(V[0 .. $/2]);
}
|
October 02, 2015 Re: Checking that a template parameter is an enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Friday, 2 October 2015 at 08:13:00 UTC, John Colvin wrote:
> On Thursday, 1 October 2015 at 22:26:39 UTC, Nordlöw wrote:
>> On Thursday, 1 October 2015 at 02:06:48 UTC, Fusxfaranto wrote:
>>> [...]
>>
>> Thanks!
>>
>> BTW: Is there some way to turn the recursive definition of `allSame`
>>
>> template allSame(V...)
>> if (isExpressions!(V))
>> {
>> static if (V.length <= 1)
>> enum allSame = true;
>> else
>> enum allSame = V[0] == V[1] && allSame!(V[1..$]);
>> }
>>
>> into an iterative definition?
>
> Why? To avoid slowing down compilation with all those template instantiations?
>
> How about a O(log2(N)) depth recursive version, something like this:
>
> template allSame(V ...)
> if (isExpressions!V)
> {
> static if (V.length <= 1)
> enum allSame = true;
> else static if(V.length & 1)
> enum allSame = V[$-1] == V[0]
> && V[0 .. $/2] == V[$/2 .. $-1]
> && allSame!(V[0 .. $/2]);
> else
> enum allSame = V[0..$/2] == V[$/2 .. $]
> && allSame!(V[0 .. $/2]);
> }
Although you should consider that isExpressions is instantiating V.length templates anyway (it uses a binary split to avoid excessive template recursion depth, but it ends up checking them all one-per-template in the end anyway.
|
Copyright © 1999-2021 by the D Language Foundation