Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 14, 2012 How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
I have a struct that holds an immutable pointer to some data. I would like to initialize it with a pointer to anything that is passed inside, so if it is a not an l-value, I would need to copy it to the heap first. How can I determine if it is an l-value? How to implement copying correctly? Below is my code, with commented unit tests at the bottom that show what I cannot do without specializing template functions. struct Maybe(T) { immutable T* payload; // pointer to data static immutable Maybe!T _nothing = Maybe!T(null); pure nothrow this(immutable(T*) payload) immutable { this.payload = payload; } pure nothrow @property bool empty() const { return payload == null; } pure nothrow @property immutable(T) front() const in{ assert(!empty); } body{ return *payload; } // factory methods pure nothrow static @property immutable(Maybe!T) nothing() { return _nothing;} pure nothrow static immutable(Maybe!T) just(ref immutable(T) data) { return Maybe!T(&data); } pure nothrow static immutable(Maybe!T) create(T)(immutable(T*) payload) {return payload == null ? _nothing : Maybe!T(payload); } } pure nothrow immutable(Maybe!T) nothing(T)() { return Maybe!T.nothing; } pure nothrow immutable(Maybe!T) just(T)(ref immutable(T) data) { return Maybe!T.just(data); } pure nothrow immutable(Maybe!T) maybeCreate(T)(immutable(T*) payload) { return Maybe!T.create(payload); } unittest { // nothing auto x0 = Maybe!int.nothing; assert(x0.empty); // using free factory function auto x1 = nothing!double; assert(x1.empty); // only l-value can be passed inside static assert(!is(typeof(Maybe!double.just(2.0)))); //// just //immutable a = 2.0f; //auto y0 = Maybe!float.just(a); //assert(!y0.empty); //assert(y0.front == a); // using free factory function //auto y1 = just!float(a); //assert(!y1.empty); //assert(y1.front == a); } |
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Thursday, 14 June 2012 at 15:27:24 UTC, Roman D. Boiko wrote:
> I have a struct that holds an immutable pointer to some data. I would like to initialize it with a pointer to anything that is passed inside, so if it is a not an l-value, I would need to copy it to the heap first. How can I determine if it is an l-value? How to implement copying correctly?
Comments like "this is bullshit, you don't want to do that" are welcome :) I'm not sure what would be the correct thing to do in this case.
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | You can overload based on 'ref'. auto just(ref immutable(T) data) { return Maybe!T(&data); } auto just(immutable(T) data) { return Maybe!T([data].ptr); } |
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 14 June 2012 at 16:05:52 UTC, Timon Gehr wrote:
> You can overload based on 'ref'.
>
> auto just(ref immutable(T) data) { return Maybe!T(&data); }
> auto just(immutable(T) data) { return Maybe!T([data].ptr); }
Great! Thanks
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Thursday, 14 June 2012 at 16:08:54 UTC, Roman D. Boiko wrote: > On Thursday, 14 June 2012 at 16:05:52 UTC, Timon Gehr wrote: >> You can overload based on 'ref'. >> >> auto just(ref immutable(T) data) { return Maybe!T(&data); } >> auto just(immutable(T) data) { return Maybe!T([data].ptr); } > Great! Thanks Hmm... seems to fail for immutable: immutable a = 2.0f; #line 121 auto y0 = Maybe!float.just(a); assert(!y0.empty); assert(y0.front == a); Compiler output: fds/persistent.d(121): Error: 2 is not an lvalue dmd: glue.c:1114: virtual unsigned int Type::totym(): Assertion `0' failed. Aborted (core dumped) make: *** [build/client] Error 134 |
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On 06/14/2012 06:20 PM, Roman D. Boiko wrote:
> On Thursday, 14 June 2012 at 16:08:54 UTC, Roman D. Boiko wrote:
>> On Thursday, 14 June 2012 at 16:05:52 UTC, Timon Gehr wrote:
>>> You can overload based on 'ref'.
>>>
>>> auto just(ref immutable(T) data) { return Maybe!T(&data); }
>>> auto just(immutable(T) data) { return Maybe!T([data].ptr); }
>> Great! Thanks
> Hmm... seems to fail for immutable:
>
> immutable a = 2.0f;
> #line 121
> auto y0 = Maybe!float.just(a);
> assert(!y0.empty);
> assert(y0.front == a);
>
> Compiler output:
> fds/persistent.d(121): Error: 2 is not an lvalue
> dmd: glue.c:1114: virtual unsigned int Type::totym(): Assertion `0' failed.
> Aborted (core dumped)
> make: *** [build/client] Error 134
>
You have found a compiler bug.
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 14 June 2012 at 16:29:31 UTC, Timon Gehr wrote:
> On 06/14/2012 06:20 PM, Roman D. Boiko wrote:
>> On Thursday, 14 June 2012 at 16:08:54 UTC, Roman D. Boiko wrote:
>>> On Thursday, 14 June 2012 at 16:05:52 UTC, Timon Gehr wrote:
>>>> You can overload based on 'ref'.
>>>>
>>>> auto just(ref immutable(T) data) { return Maybe!T(&data); }
>>>> auto just(immutable(T) data) { return Maybe!T([data].ptr); }
>>> Great! Thanks
>> Hmm... seems to fail for immutable:
>>
>> immutable a = 2.0f;
>> #line 121
>> auto y0 = Maybe!float.just(a);
>> assert(!y0.empty);
>> assert(y0.front == a);
>>
>> Compiler output:
>> fds/persistent.d(121): Error: 2 is not an lvalue
>> dmd: glue.c:1114: virtual unsigned int Type::totym(): Assertion `0' failed.
>> Aborted (core dumped)
>> make: *** [build/client] Error 134
>>
>
> You have found a compiler bug.
Looks like :) So far I decided to remove ref overload. If I want to avoid copying, I can use maybeCreate(Immutable(T*) payload).
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | Roman D. Boiko:
>> You have found a compiler bug.
>
> Looks like :)
Please report it in bugzilla :-)
Bye,
bearophile
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Thursday, 14 June 2012 at 16:50:43 UTC, bearophile wrote:
> Roman D. Boiko:
>
>>> You have found a compiler bug.
>>
>> Looks like :)
>
> Please report it in bugzilla :-)
>
> Bye,
> bearophile
I want to, just figuring out how to check for duplicates.
|
June 14, 2012 Re: How to specialize templates for l-value and non-l-value arguments? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Thursday, 14 June 2012 at 16:55:26 UTC, Roman D. Boiko wrote: > On Thursday, 14 June 2012 at 16:50:43 UTC, bearophile wrote: >> Roman D. Boiko: >> >>>> You have found a compiler bug. >>> >>> Looks like :) >> >> Please report it in bugzilla :-) >> >> Bye, >> bearophile > I want to, just figuring out how to check for duplicates. Looks like http://d.puremagic.com/issues/show_bug.cgi?id=6774, should I report my case there, or create a new issue (but reference 6774)? |
Copyright © 1999-2021 by the D Language Foundation