"%u" <wfunct...@hotmail.com> wrote in message news:ik7slf$2q2u$1...@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.