www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to specialize templates for l-value and non-l-value arguments?

reply "Roman D. Boiko" <rb d-coding.com> writes:
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);
}
Jun 14 2012
next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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?

welcome :) I'm not sure what would be the correct thing to do in this case.
Jun 14 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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); }
Jun 14 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
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); }


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.
Jun 14 2012
prev sibling next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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); }

Jun 14 2012
prev sibling next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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); }


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
Jun 14 2012
prev sibling next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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); }


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).
Jun 14 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Roman D. Boiko:

 You have found a compiler bug.

Looks like :)

Please report it in bugzilla :-) Bye, bearophile
Jun 14 2012
prev sibling next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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

Jun 14 2012
prev sibling next sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
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


should I report my case there, or create a new issue (but reference 6774)?
Jun 14 2012
prev sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
On Thursday, 14 June 2012 at 17:05:52 UTC, Roman D. Boiko wrote:
 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)?

Jun 14 2012