How to pass list of strings as compile-time parameters?
H. S. Teoh
hsteoh at quickfur.ath.cx
Tue Apr 24 11:23:19 PDT 2012
On Tue, Apr 24, 2012 at 08:03:07PM +0200, Timon Gehr wrote:
> On 04/24/2012 07:37 PM, H. S. Teoh wrote:
> >I'm trying to write a template function for doing member-wise
> >comparisons between two objects, with an optional list of members to
> >ignore. But I can't seem to figure out the syntax for passing a list of
> >strings (or an AA of strings) to the function?
> >
> >I tried this:
> >
> > bool compareByMemb(string[] ignores, T)(T obj1, T obj2) {
> > foreach (name; __traits(getAllMembers, T)) {
> > ...
> > }
> > }
> >
> >but the compiler complains:
> >
> > Error: arithmetic/string type expected for value-parameter, not string[]
[...]
> Try using an alias parameter (with an optional type constraint). imo
> the template instantiation semantics needs a clean-up.
Thanks, that did it!
For posterity, here's the code (which I think is generally usable for
many more things than I'm using it for in my code):
bool membCmp(T)(T t1, T t2) {
return membCmpIgnoring!(cast(string[])[])(t1, t2);
}
bool membCmpIgnoring(alias ignores, T)(T t1, T t2)
if (is(typeof(ignores)==string[]))
{
nextMemb: foreach (name; __traits(allMembers, T)) {
foreach (i; ignores) {
if (name == i)
continue nextMemb;
}
static if (__traits(compiles, &__traits(getMember, t1,
name)))
{
alias typeof(__traits(getMember, t1, name))
type;
static if (!is(type==function))
{
auto val1 = __traits(getMember, t1, name);
auto val2 = __traits(getMember, t2, name);
if (val1 != val2)
return false;
}
}
}
return true;
}
Given two structs or objects, X and Y, this lets you do an easy
implementation of opEquals():
bool opEquals(Object obj) {
auto o = cast(typeof(this))obj;
return obj && membCmp(this, o);
}
If you wish to ignore some fields, say x and y, in the comparison, then
just do this:
bool opEquals(Object obj) {
auto o = cast(typeof(this))obj;
return obj && membCmpIgnoring!(["x", "y"])(this, o);
}
Question: is it possible to sugar up the syntax even more, by allowing
an array of aliases? Or is that pushing the template syntax a bit too
far? I.e., can we make it possible to write:
membCmpIgnoring!(x,y)(this, o)
without the string list syntax?
T
--
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
More information about the Digitalmars-d-learn
mailing list