Enum "Inheritance"?
Nick Sabalausky
a at a.a
Sat Feb 26 18:56:58 PST 2011
"%u" <wfunction at hotmail.com> wrote in message
news:ik7slf$2q2u$1 at digitalmars.com...
>> What exactly is it that you're trying to do?
>
>
>>> (1) I'm not going to create a new instance of an entire class
> every single time I need to check an access mask, that's wasteful.
>> I meant, you write File.open or File.isReadable which do the job
> for you and don't expose OS cruft.
>
>
> That's what I'm doing! I'm precisely trying to wrap the Windows NT
> API, and so I'm making classes like NtObject, NtFile, NtToken, etc.,
> to wrap functions like NtOpenFile, NtQueryObject, etc. (I'm aware
> that some of them are undocumented, but I live with that.)
>
> So I have different kinds of access masks:
> 1. Generic access masks that can be passed to _any_ procedure and
> combined with any other access masks, like GENERIC_READ,
> MAXIMUM_ALLOWED, etc.
> 2. Object-specific access masks that can be only used for specific
> objects and that can be combined with each other and with generic
> access masks, like FILE_READ_DATA, TOKEN_ALL_ACCESS, etc.
>
> So I'm trying to avoid redundant code here, because any member of an
> AccessMask enumeration would also be inside the FileAccess enum, the
> TokenAccess enum, the ThreadAccess enum, etc. But at the same time,
> I need to be able to pass both specific and generic access masks to
> functions that take in specific access masks.
>
> So the question is, what's the best way to do it?
I know some people don't like using mixins, but I think that's really the
best way to achieve that effect without loosing DIY and without resorting to
something more heavy-weight:
void funcA(A a) {}
void funcB(B b) {}
enum stdAccess = q{
STD_ELEMENT_1 = 17,
STD_ELEMENT_2 = 42,
};
enum A {
mixin(stdAccess);
A_ACCESS_1 = 0x80,
}
enum B {
mixin(stdAccess);
B_ACCESS_1 = 0x80,
}
Or, if you really don't want mixins, or if you really want
STD_ELEMENT_1/etc... to always be of one single type, then make the std ones
their own distict type and use either function overloading or algebraic
types:
enum STD {
STD_ELEMENT_1 = 17,
STD_ELEMENT_2 = 42,
}
enum A {
A_ACCESS_1 = 0x80,
}
enum B {
B_ACCESS_1 = 0x80,
}
void funcA(A a) {}
void funcA(STD a) {}
void funcB(B b) {}
void funcB(STD b) {}
// Or:
void funcA(Algebraic!(A,STD) a) {}
void funcB(Algebraic!(B,STD) b) {}
I think your main original problem was that there isn't really a way to
compose enums additively, only subtractive.
Although, maybe you could experiment with something like:
enum X : Algebraic!(...) {}
Not sure if that would help get what you want, though, or if it would even
work at all.
More information about the Digitalmars-d
mailing list