Jump to page: 1 2
Thread overview
How to specialize templates for l-value and non-l-value arguments?
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Timon Gehr
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Timon Gehr
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
bearophile
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Roman D. Boiko
Jun 14, 2012
Roman D. Boiko
June 14, 2012
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
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
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
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
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
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
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
Roman D. Boiko:

>> You have found a compiler bug.
>
> Looks like :)

Please report it in bugzilla :-)

Bye,
bearophile
June 14, 2012
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
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