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