August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thursday, 6 August 2020 at 00:58:39 UTC, Per Nordlöw wrote:
> Is it possible to implement
>
> template maxSizeOf(T...)
> {
> static if (T.length == 1)
> enum size_t maxSizeOf = T[0].sizeof;
> else
> {
> enum size_t firstSize = T[0].sizeof;
> enum size_t maxSizeRest = maxSizeOf!(T[1 .. $]);
> enum size_t maxSizeOf = firstSize >= maxSizeRest ? firstSize : maxSizeRest;
> }
> }
>
> in a non-recursive way?
Of course. In fact, it's trivial:
------
template maxSizeOf(T...)
{
align(1) union Impl {
T t;
}
enum maxSizeOf = Impl.sizeof;
}
------
To check that this does what we expect:
------
pragma(msg, maxSizeOf!(char)); // 1LU
pragma(msg, maxSizeOf!(char, short, ubyte)); // 2LU
pragma(msg, maxSizeOf!(char, long, ubyte)); // 8LU
align(1) struct S {
long l;
ubyte b;
}
pragma(msg, maxSizeOf!(long, S)); // 9LU
pragma(msg, maxSizeOf!(int, ubyte[7])); // 7LU
pragma(msg, maxSizeOf!(int, ubyte[3])); // 4LU
------
Why bother with recursion and all of that fancy gobbledygook when the compiler already knows how to compute the maximum size of something? ;-)
|
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Thursday, 6 August 2020 at 12:51:22 UTC, H. S. Teoh wrote:
> Of course. In fact, it's trivial:
>
> ------
> template maxSizeOf(T...)
> {
> align(1) union Impl {
> T t;
> }
> enum maxSizeOf = Impl.sizeof;
> }
Clever. Thanks
|
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Thursday, 6 August 2020 at 12:51:22 UTC, H. S. Teoh wrote:
> Of course. In fact, it's trivial:
>
> ------
> template maxSizeOf(T...)
> {
> align(1) union Impl {
> T t;
> }
> enum maxSizeOf = Impl.sizeof;
> }
I originally copied my original version of `maxSizeOf` from `std.variant.maxSize` currently being
template maxSize(T...)
{
static if (T.length == 1)
{
enum size_t maxSize = T[0].sizeof;
}
else
{
import std.algorithm.comparison : max;
enum size_t maxSize = max(T[0].sizeof, maxSize!(T[1 .. $]));
}
}
.
It should be updated to use this trick.
However, your solution
template maxSize(T...)
{
align(1) union Impl { T t; }
enum maxSize = Impl.sizeof;
}
fails as
variable `std.variant.maxSize!(void, string).Impl.__t_field_0` variables cannot be of type `void`
because one of the instances of `maxSize` in std.variant has `void` as a member `T...`.
Do you have any simple solution to this, H. S. Teoh?
|
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thursday, 6 August 2020 at 13:07:14 UTC, Per Nordlöw wrote: > Do you have any simple solution to this, H. S. Teoh? I also tried template maxSize(Ts...) { align(1) union Impl { // See_Also: https://forum.dlang.org/thread/wbpnncxepehgcswhuazl@forum.dlang.org?page=1 static foreach (T; Ts) { static if (!is(T == void)) { pragma(msg, T.stringof ~ " _store" ~ T.mangleof ~ ";"); mixin(T.stringof ~ " _store" ~ T.mangleof ~ ";"); } } } enum maxSize = Impl.sizeof; } but that fails because of types not being defined in scope such as Cat _storeS3std7variant17__unittest_L96_C7FNfZ3Cat; /home/per/Work/phobos/std/variant.d-mixin-88(88,5): Error: undefined identifier `Cat` Can somebody find a better alternative? |
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thursday, 6 August 2020 at 13:18:40 UTC, Per Nordlöw wrote: > Can somebody find a better alternative? Let's continue discussion at https://github.com/dlang/phobos/pull/7582 |
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thursday, 6 August 2020 at 13:18:40 UTC, Per Nordlöw wrote:
> mixin(T.stringof ~ " _store" ~ T.mangleof ~
Never ever use mixin(T.stringof). Always just use mixin("T") instead.
mixin("T _store", T.mangleof /* or just idx is gonna be better */,";");
Though I doubt this is going to win a benchmark anyway getting this complicated.
|
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thu, Aug 06, 2020 at 01:07:14PM +0000, Per Nordlöw via Digitalmars-d-learn wrote: [...] > However, your solution > > template maxSize(T...) > { > align(1) union Impl { T t; } > enum maxSize = Impl.sizeof; > } > > fails as > > variable `std.variant.maxSize!(void, string).Impl.__t_field_0` > variables cannot be of type `void` > > because one of the instances of `maxSize` in std.variant has `void` as a member `T...`. Ugh, apparently `void` is one of those nasty inconsistent things that has all sorts of ad hoc behaviour: - void cannot be used to instantiate variables (behaves sortof like a bottom type); - But in spite of that, void.sizeof == 1, rather than the expected 0. My guess is that this has to do with the hack to make the size of void[] equal to its length; - void in void[] is a top type (but only in that context -- but its .sizeof is inconsistent with this); - void is a unit type when specified as a function return type (but in spite of that cannot be instantiated, contrary to a true unit type, and this contradicts its being a top type in void[]); IOW, void is a mishmash of ad hoc things thrown together in a way that isn't even self-consistent. A chimera of exceptions that, it would seem, always require special-casing to handle. > Do you have any simple solution to this, H. S. Teoh? Unfortunately, no. :-( Why does std.variant even support storing void in the first place?! T -- People tell me that I'm paranoid, but they're just out to get me. |
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 8/6/20 9:23 AM, Adam D. Ruppe wrote:
> On Thursday, 6 August 2020 at 13:18:40 UTC, Per Nordlöw wrote:
>> mixin(T.stringof ~ " _store" ~ T.mangleof ~
>
> Never ever use mixin(T.stringof). Always just use mixin("T") instead.
>
> mixin("T _store", T.mangleof /* or just idx is gonna be better */,";");
>
> Though I doubt this is going to win a benchmark anyway getting this complicated.
Well, one *could* do:
static if(is(union { Ts t; }))
and use the union for "normal" cases.
I think the CTFE solution is cleaner. Is there a good reason to avoid it?
-Steve
|
August 06, 2020 Re: Non-recursive maxSizeOf | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On 8/6/20 4:44 AM, Per Nordlöw wrote:
> On Thursday, 6 August 2020 at 01:13:28 UTC, Ali Çehreli wrote:
>> Boring in D. :p
>>
>> template maxSizeOf(T...) {
>> enum maxSizeOf = compute();
>>
>> auto compute() {
>> size_t result;
>> static foreach (t; T) {
>> if (t.sizeof > result) {
>> result = t.sizeof;
>> }
>> }
>> return result;
>> }
>> }
>
> Thanks. I'm gonna benchmark this against my templated solution.
I guess an anonymous function would remove the need for that creative name. :)
enum maxSizeOf = {
// ...
}();
Ali
|
Copyright © 1999-2021 by the D Language Foundation