Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Append one enum to another?

53 views
Skip to first unread message

Peter Olcott

unread,
May 8, 2009, 11:07:18 AM5/8/09
to
I have two enumerations, one is an exact proper subset of
the other, I would like to have a way to define the first
one in terms of the second one. Is there a simple way to do
this?


Victor Bazarov

unread,
May 8, 2009, 11:19:56 AM5/8/09
to

Simple? Not sure.

enum A { a, b, c, d };
enum A_extended { ae = a, be = b, ce = c, de = d, ee, fe };

The problem with this, of course, is that if you edit 'A', then you will
have to manually edit 'A_extended'. Since they are not "related", there
is no "inheriting" of values. You *could* wrap them both in classes and
then derive the A_extended wrapper from the A wrapper... That would
bring all A wrapper enums into A_extended wrapper's scope. What exactly
are you trying to accomplish?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Peter Olcott

unread,
May 8, 2009, 12:28:26 PM5/8/09
to

"Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
news:gu1ii5$vkk$1...@news.datemas.de...

> Peter Olcott wrote:
>> I have two enumerations, one is an exact proper subset of
>> the other, I would like to have a way to define the first
>> one in terms of the second one. Is there a simple way to
>> do this?
>
> Simple? Not sure.
>
> enum A { a, b, c, d };
> enum A_extended { ae = a, be = b, ce = c, de = d, ee,
> fe };
>
> The problem with this, of course, is that if you edit 'A',
> then you will have to manually edit 'A_extended'. Since
> they are not "related", there is no "inheriting" of
> values. You *could* wrap them both in classes and then
> derive the A_extended wrapper from the A wrapper... That
> would bring all A wrapper enums into A_extended wrapper's
> scope. What exactly are you trying to accomplish?

enum A {a, b, c, d};

enum B = A + {e, f, g, h};

I want to have the compiler keep these two in sync for me so
that any changes to A will automatically be incorporated
into B;

Chris M. Thomasson

unread,
May 8, 2009, 1:15:26 PM5/8/09
to

"Peter Olcott" <NoS...@SeeScreen.com> wrote in message
news:l_CdnctTW98xwJnX...@giganews.com...

>
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
> news:gu1ii5$vkk$1...@news.datemas.de...
>> Peter Olcott wrote:
>>> I have two enumerations, one is an exact proper subset of the other, I
>>> would like to have a way to define the first one in terms of the second
>>> one. Is there a simple way to do this?
>>
>> Simple? Not sure.
>>
>> enum A { a, b, c, d };
>> enum A_extended { ae = a, be = b, ce = c, de = d, ee, fe };
>>
>> The problem with this, of course, is that if you edit 'A', then you will
>> have to manually edit 'A_extended'. Since they are not "related", there
>> is no "inheriting" of values. You *could* wrap them both in classes and
>> then derive the A_extended wrapper from the A wrapper... That would
>> bring all A wrapper enums into A_extended wrapper's scope. What exactly
>> are you trying to accomplish?
>
> enum A {a, b, c, d};
> enum B = A + {e, f, g, h};
>
> I want to have the compiler keep these two in sync for me so that any
> changes to A will automatically be incorporated into B;
> [...]


I guess you can try something like this:
___________________________________________________________________
#include <cstdio>


struct enum_a {
enum constant {
a, b, c, d,
end_of_enum_a = d
};
};


struct enum_b : public enum_a {
enum constant {
e = end_of_enum_a + 1,
f, g, h
};
};


int main() {
std::printf("enum_a: a(%d), b(%d), c(%d), d(%d)\n",
enum_b::a, enum_b::b, enum_b::c, enum_b::d);

std::printf("enum_b: e(%d), f(%d), g(%d), h(%d)\n",
enum_b::e, enum_b::f, enum_b::g, enum_b::h);

return 0;
}
___________________________________________________________________


If you change `enum_a' you would need to update `enum_a::end_of_enum_a'
accordingly. This is assuming that you want to keep a monotonically
increasing value that spills from `enum_a' into `enum_b'.

Victor Bazarov

unread,
May 8, 2009, 2:21:16 PM5/8/09
to
Peter Olcott wrote:
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
> news:gu1ii5$vkk$1...@news.datemas.de...
>> Peter Olcott wrote:
>>> I have two enumerations, one is an exact proper subset of
>>> the other, I would like to have a way to define the first
>>> one in terms of the second one. Is there a simple way to
>>> do this?
>> Simple? Not sure.
>>
>> enum A { a, b, c, d };
>> enum A_extended { ae = a, be = b, ce = c, de = d, ee,
>> fe };
>>
>> The problem with this, of course, is that if you edit 'A',
>> then you will have to manually edit 'A_extended'. Since
>> they are not "related", there is no "inheriting" of
>> values. You *could* wrap them both in classes and then
>> derive the A_extended wrapper from the A wrapper... That
>> would bring all A wrapper enums into A_extended wrapper's
>> scope. What exactly are you trying to accomplish?
>
> enum A {a, b, c, d};
> enum B = A + {e, f, g, h};
>
> I want to have the compiler keep these two in sync for me so
> that any changes to A will automatically be incorporated
> into B;

Well, it doesn't make them the same type, so you can't reuse 'a' where
'B' is expected. Chris published a solution where those are wrapped,
like I suggested, but that doesn't make them the same type either. What
is the point of having those enums? Are the sequential numbers with
symbolic representation all you need? How would you use those enums?
What is the reason, the goal, to have one "extend" the other?

When I (or somebody else) ask[s] what you're trying to accomplish,
please don't answer in terms of some impossible solution that you've
thought up. Explain the problem you're trying to solve.

Peter Olcott

unread,
May 11, 2009, 10:53:37 PM5/11/09
to

"Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
news:gu1t71$ebs$1...@news.datemas.de...


I need to create two sets of enumerated constants where one
is always a proper subset of the other. I am aiming to
minimize errors with ongoing code maintenance by trying to
find a way such that the superset inherits the subset. It
looks like simply having to keep these two manually in sync
is the only reasonably easy way to go.

Victor Bazarov

unread,
May 12, 2009, 8:59:23 AM5/12/09
to
Peter Olcott wrote:
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
>> [..]

>> When I (or somebody else) ask[s] what you're trying to
>> accomplish, please don't answer in terms of some
>> impossible solution that you've thought up. Explain the
>> problem you're trying to solve.
>
>
> I need to create two sets of enumerated constants where one
> is always a proper subset of the other.

You said that already. What problem does that solve? *Why* do they
need to be *different* sets of constants? *Why* should one be a subset
of the other? What problem does that solve for you? Could it be that
there is a different solution to what you're trying to accomplish with
the two enumerations?

Don't get me wrong; I don't really care to know your secret if the
problem you're solving is secret. I am trying to get you to explain the
actual problem because you seem to be hung up on the *solution* that
does not necessarily work, or, rather brings forth other problems (like
the need to maintain the dependency)...

> I am aiming to
> minimize errors with ongoing code maintenance by trying to
> find a way such that the superset inherits the subset.

Isn't everybody [aiming to minimize errors]? But you're limiting your
options by not looking (and not letting us look by not explaining the
problem) at any other possible solution.

> It
> looks like simply having to keep these two manually in sync
> is the only reasonably easy way to go.

Fine. The law of diminishing returns says that one has to stop looking
at some point. Just make sure to place enough comment in your code to
explain your rationale and possibly encourage revisiting your approach,
for anybody who decides to do so when maintaining your code down the road.

REH

unread,
May 12, 2009, 11:52:13 AM5/12/09
to

You could use the old "x macros" technique to keep them in sync.

REH

Peter Olcott

unread,
May 14, 2009, 9:03:30 AM5/14/09
to

"Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
news:gubrqg$n91$1...@news.datemas.de...

> Peter Olcott wrote:
>> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in
>> message
>>> [..]
>>> When I (or somebody else) ask[s] what you're trying to
>>> accomplish, please don't answer in terms of some
>>> impossible solution that you've thought up. Explain the
>>> problem you're trying to solve.
>>
>>
>> I need to create two sets of enumerated constants where
>> one is always a proper subset of the other.
>
> You said that already. What problem does that solve?
> *Why* do they need to be *different* sets of constants?
> *Why* should one be a subset of the other? What problem
> does that solve for you? Could it be that there is a
> different solution to what you're trying to accomplish
> with the two enumerations?
>
> Don't get me wrong; I don't really care to know your
> secret if the problem you're solving is secret. I am
> trying to get you to explain the actual problem because
> you seem to be hung up on the *solution* that does not
> necessarily work, or, rather brings forth other problems
> (like the need to maintain the dependency)...

I have two sets of concepts whereas one set of concepts
naturally forms a mathematical proper subset of the other. I
must represent these concepts in code, and enums are the
most efficient and concise.

In the specific case I am creating a greatly simplified C++
interpreter and the subset concepts are data types and the
superset concepts are SymbolTable types, the SymbolTable has
some of its own specialized types such as Function
ProtoType.

Victor Bazarov

unread,
May 14, 2009, 9:27:03 AM5/14/09
to
Peter Olcott wrote:
> I have two sets of concepts whereas one set of concepts naturally
> forms a mathematical proper subset of the other. I must represent
> these concepts in code, and enums are the most efficient and concise.

You say nothing about the way[s] those "concepts" or enums are going
to be used. Perhaps wrapping those in a class (or in two classes) is
what you need (or have already done). Keep in mind that inheritance is
a tricky thing.

In your second post you mentioned the form 'enum B = A + { blah };'.
What would it give you? What do you mean by "automatically
incorporated"? And what about Chris' suggestion with the
'end_of_enum_a' value used in 'B' to start the enumeration? Also, you
didn't at all respond to my comment that those enums are still two
different types.

Could it be that you simply need a set of numbers? What if you use an
array of int and a bunch of [named] references to its elements? You can
then use 'sizeof' to generate the second, bigger, array.

I can understand efficiency, I can understand conciseness. And it seems
that you're after ease of maintaining those as well. I don't know the
problems you're facing in the maintenance phase, but perhaps if you post
the code (before and after) and your maintenance concerns, something can
be proposed, like a couple of compile-time assertions and plenty of code
comments...

> In the specific case I am creating a greatly simplified C++
> interpreter and the subset concepts are data types and the superset
> concepts are SymbolTable types, the SymbolTable has some of its own
> specialized types such as Function ProtoType.

V

Peter Olcott

unread,
May 14, 2009, 1:34:58 PM5/14/09
to

"Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
news:guh66c$5l0$1...@news.datemas.de...

> Peter Olcott wrote:
>> I have two sets of concepts whereas one set of concepts
>> naturally
>> forms a mathematical proper subset of the other. I must
>> represent
>> these concepts in code, and enums are the most efficient
>> and concise.
>
> You say nothing about the way[s] those "concepts" or enums
> are going
> to be used.

You have to read the whole post, this is already listed
below:


In the specific case I am creating a greatly simplified C++
interpreter and the subset concepts are data types and the
superset
concepts are SymbolTable types, the SymbolTable has some of
its own
specialized types such as Function ProtoType.

The enums will be used in switch statements.

Victor Bazarov

unread,
May 14, 2009, 9:39:44 PM5/14/09
to
Peter Olcott wrote:
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
> news:guh66c$5l0$1...@news.datemas.de...
>> Peter Olcott wrote:
>>> I have two sets of concepts whereas one set of concepts
>>> naturally
>>> forms a mathematical proper subset of the other. I must
>>> represent
>>> these concepts in code, and enums are the most efficient
>>> and concise.
>> You say nothing about the way[s] those "concepts" or enums
>> are going
>> to be used.
>
> You have to read the whole post, this is already listed
> below:
> In the specific case I am creating a greatly simplified C++
> interpreter and the subset concepts are data types and the
> superset
> concepts are SymbolTable types, the SymbolTable has some of
> its own
> specialized types such as Function ProtoType.

<sigh> Why do you presume I didn't read the post? How do you design
your classes? Do you pick a language element, like "a virtual function"
and build your program around it? Like here, you just say, "Today I'll
use enums, they go nicely with a switch statement". Is that all? No
interface? No messaging? No states?

Why do you have classes? Take SymbolTable class, why does it need those
enums? Are you implementing some kind of dispatch mechanism with those?
Why not with indices or function pointers? Does the "simplified" in
your description of what you're programming relate to "C++" or to
"interpreter"?

> The enums will be used in switch statements.

Well, duh.

There are other things that can be use in switch statements, you know,
like characters or other integral values. Dispatch can also be done
using virtual functions and pointers to member functions... Arrays
(vectors) are much easier to append to each other than enums...

Christopher Dearlove

unread,
May 15, 2009, 5:54:38 AM5/15/09
to
"Peter Olcott" <NoS...@SeeScreen.com> wrote in message
news:l_CdnctTW98xwJnX...@giganews.com...
>
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
> news:gu1ii5$vkk$1...@news.datemas.de...
>> Peter Olcott wrote:
>>> I have two enumerations, one is an exact proper subset of the other, I
>>> would like to have a way to define the first one in terms of the second
>>> one. Is there a simple way to do this?
>>
>> Simple? Not sure.
>>
>> enum A { a, b, c, d };
>> enum A_extended { ae = a, be = b, ce = c, de = d, ee, fe };
>>
>> The problem with this, of course, is that if you edit 'A', then you will
>> have to manually edit 'A_extended'. Since they are not "related", there
>> is no "inheriting" of values. You *could* wrap them both in classes and
>> then derive the A_extended wrapper from the A wrapper... That would
>> bring all A wrapper enums into A_extended wrapper's scope. What exactly
>> are you trying to accomplish?
>
> enum A {a, b, c, d};
> enum B = A + {e, f, g, h};
>
> I want to have the compiler keep these two in sync for me so that any
> changes to A will automatically be incorporated into B;

The cure is almost certainly worse than the disease, and I don't
think I'll ever be doing it, but ...

In a.h

a,b,c,d

In b.h

e,f,g,h

In ab.h

enum A {
#include "a.h"
};

enum B {
#include "a.h"
,
#include "b.h"
};


Pascal J. Bourguignon

unread,
May 15, 2009, 8:22:05 AM5/15/09
to
"Christopher Dearlove" <chris.d...@baesystems.com> writes:

Assuming an operator to define a enum type A:

(defenum A
a b c d)

you can trivially do what you want as:

(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter *enum-constants* (make-hash-table)))

(defmacro define-enumeration (name super-enums &rest constants)
`(defenum ,name
,@(setf (gethash name *enum-constants*)
(remove-duplicates
(append constants
(mapcan (lambda (enum) (copy-list (gethash enum *enum-constants*)))
super-enums))))))


C/USER[13]> (define-enumeration a () a b c d)
A
C/USER[14]> (define-enumeration b (a) e f g h)
B
C/USER[15]> (typep 'b 'a)
T
C/USER[16]> (typep 'e 'a)
NIL
C/USER[17]> (typep 'b 'b)
T
C/USER[18]> (typep 'e 'b)
T
C/USER[19]>


Ah yes, it's not C++. But it's hardly my fault if you keep needing
features not present in C++ but in Lisp...


Remember as soon as you want the compiler to do something for you, you
actually need Lisp: Lisp has macros, which are compiler hooks allowing
you to program the compiler to let it do what you need it to do.

--
__Pascal Bourguignon__

0 new messages