How to specialize templates for l-value and non-l-value arguments?
Roman D. Boiko
rb at d-coding.com
Thu Jun 14 08:27:22 PDT 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);
}
More information about the Digitalmars-d-learn
mailing list