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)? |
« First ‹ Prev 1 2 |
|---|

Reply