View mode: basic / threaded / horizontal-split · Log in · Help
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?
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?
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?
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?
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?
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?
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?
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?
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?
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
Top | Discussion index | About this forum | D home