Extend enumeration types?

Discussion in 'C++' started by Marcel Müller, Sep 13, 2009.

  1. Hi,

    is there any smart solution for something like sub classes of
    enumeration types?

    Let's say we have

    enum A
    { Value1,
    Value2,
    Value3
    };

    enum B
    { Value1,
    Value2,
    Value3,
    Value4,
    Value5
    };

    then enum B can hold all values that A allows and a few more. (Of
    course, they cannot exist in the same namespace or class because of the
    duplicate names.)
    An implicit conversion from A to B is also reasonable. OK, one should
    not call this inheritance since the conversion is in the other direction.

    Now I would like to define a type B with exactly that properties and
    preferably without retyping all the values of A.

    I could write classes with a limited set constant values but this has
    several drawbacks. First of all no more automatic enumeration of the
    values. But also A must no longer be defined as part of a C-API. And
    last but not least I loose the automatic choice of the appropriate data
    type.

    How do others solve comparable tasks?


    Marcel
     
    Marcel Müller, Sep 13, 2009
    #1
    1. Advertising

  2. Marcel Müller

    Francesco Guest

    On 13 Set, 17:05, Marcel Müller <> wrote:
    > Hi,
    >
    > is there any smart solution for something like sub classes of
    > enumeration types?
    >
    > Let's say we have
    >
    > enum A
    > { Value1,
    >    Value2,
    >    Value3
    >
    > };
    >
    > enum B
    > { Value1,
    >    Value2,
    >    Value3,
    >    Value4,
    >    Value5
    >
    > };
    >
    > then enum B can hold all values that A allows and a few more. (Of
    > course, they cannot exist in the same namespace or class because of the
    > duplicate names.)
    > An implicit conversion from A to B is also reasonable. OK, one should
    > not call this inheritance since the conversion is in the other direction.
    >
    > Now I would like to define a type B with exactly that properties and
    > preferably without retyping all the values of A.
    >
    > I could write classes with a limited set constant values but this has
    > several drawbacks. First of all no more automatic enumeration of the
    > values. But also A must no longer be defined as part of a C-API. And
    > last but not least I loose the automatic choice of the appropriate data
    > type.
    >
    > How do others solve comparable tasks?
    >
    > Marcel


    Hi Marcel, could you please explain the task a bit deeper?

    I honestly wasn't able to figure out how you would use such an union
    of enums - well, I could, but my imagination has already proved to be
    too convolute :) - maybe you're wanting to use enums for something
    that is better expressed in C++ via some other kind of abstraction and
    somebody here could help you get the same result without having to
    merge them.

    Cheers,
    Francesco
     
    Francesco, Sep 13, 2009
    #2
    1. Advertising

  3. Francesco wrote:
    > Hi Marcel, could you please explain the task a bit deeper?
    >
    > I honestly wasn't able to figure out how you would use such an union
    > of enums - well, I could, but my imagination has already proved to be
    > too convolute :) - maybe you're wanting to use enums for something
    > that is better expressed in C++ via some other kind of abstraction and
    > somebody here could help you get the same result without having to
    > merge them.


    Let's say I have an observable pattern 'O' in a C API. It calls a
    callback function '*cb' with a event type (the enumeration 'A') and a
    few other parameters. (I am talking about notifications about
    asynchronous changes of information.)

    void set_observer(
    O obj,
    void (*cb)(O obj, A type, void* param),
    void* param );

    Now I have a C++ application which has objects 'O2' that depend on 'O'
    in a way that they add additional features. They are also observables.
    But their event type of type 'B' has additional values for changes of
    the new features. All events of the base object 'O' are forwarded to the
    observers of 'O2' but the observers may receive additional event types.

    Now I could map any possibly value of A to a value of B by a large
    switch statement or do a hard cast while making implications about the
    values of A are defined in B in the same way (as Paavo suggested). Or I
    have to use int.
    In the first case I create large code and runtime overhead, in the other
    cases I loose any type safety.


    Marcel
     
    Marcel Müller, Sep 13, 2009
    #3
  4. Marcel Müller

    Francesco Guest

    On 13 Set, 22:16, Marcel Müller <> wrote:
    > Francesco wrote:
    > > Hi Marcel, could you please explain the task a bit deeper?

    >
    > > I honestly wasn't able to figure out how you would use such an union
    > > of enums - well, I could, but my imagination has already proved to be
    > > too convolute :) - maybe you're wanting to use enums for something
    > > that is better expressed in C++ via some other kind of abstraction and
    > > somebody here could help you get the same result without having to
    > > merge them.

    >
    > Let's say I have an observable pattern 'O' in a C API. It calls a
    > callback function '*cb' with a event type (the enumeration 'A') and a
    > few other parameters. (I am talking about notifications about
    > asynchronous changes of information.)
    >
    > void set_observer(
    > O obj,
    > void (*cb)(O obj, A type, void* param),
    > void* param );
    >
    > Now I have a C++ application which has objects 'O2' that depend on 'O'
    > in a way that they add additional features. They are also observables.
    > But their event type of type 'B' has additional values for changes of
    > the new features. All events of the base object 'O' are forwarded to the
    > observers of 'O2' but the observers may receive additional event types.
    >
    > Now I could map any possibly value of A to a value of B by a large
    > switch statement or do a hard cast while making implications about the
    > values of A are defined in B in the same way (as Paavo suggested). Or I
    > have to use int.
    > In the first case I create large code and runtime overhead, in the other
    > cases I loose any type safety.


    Thanks for the explanation Marcel.

    So if I got it right, you only want to pass enum A to a function which
    accepts enum B. Since you said that the first values are the same in
    both enums, I suppose you would simply have to build a B from an A, no
    need for hard casts or for additional switch statements.

    It should work even for the other way round:
    (here I've changed it so A is "wider" than B, that should work fine
    too)

    -------
    #include <iostream>
    using namespace std;

    namespace enA {
    enum A { first, second, third, fourth };
    }

    namespace enB {
    enum B { first, second, third };
    }

    void fun(enB::B b) {
    switch (b) {
    case enB::first:
    cout << "1st";
    break;
    case enB::second:
    cout << "2nd";
    break;
    case enB::third:
    cout << "3rd";
    break;
    default:
    cout << "out-of-range";
    }
    cout << endl;
    }


    int main()
    {
    fun(enB::B(enA::second));
    fun(enB::B(enA::fourth));
    return 0;
    }
    -------

    Hope that helps, FWIW.

    Cheers,
    Francesco
     
    Francesco, Sep 13, 2009
    #4
  5. Marcel Müller <> writes:

    > Hi,
    >
    > is there any smart solution for something like sub classes of
    > enumeration types?
    >
    > Let's say we have
    >
    > enum A
    > { Value1,
    > Value2,
    > Value3
    > };
    >
    > enum B
    > { Value1,
    > Value2,
    > Value3,
    > Value4,
    > Value5
    > };
    >
    > then enum B can hold all values that A allows and a few more. (Of
    > course, they cannot exist in the same namespace or class because of
    > the duplicate names.)
    > An implicit conversion from A to B is also reasonable. OK, one should
    > not call this inheritance since the conversion is in the other
    > direction.


    This goes against the Lyskoff Substitution Principle in the case of
    return values.


    You must ensure that a method in a subclass returns only values that
    the superclass may return, otherwise you could not substitute a
    subclass for the superclass. Therefore the types defined in
    subclasses for return values must be subtypes.

    On the other hand, for parameters, you must ensure that a subclass
    accepts all the values a superclass may accept. Therefore the types
    defined in subclasses for parameters must be supertypes.


    class A{
    public:
    typedef enum { v1,v2,v3, v4,v5,v6 } ResultEnumA;
    virtual EnumA getIt(){return v5;}

    typedef enum { p1,p2,p3 } ParamEnumA;
    virtual void setThat(int p);/* p in ParamEnumA */
    // We cannot use a specific enum for the parameter p, since
    // subclasses are allowed to take additionnal values.

    };

    class B:public A{
    public:
    typedef enum { v1=A::v1,v2=A::v2,v3=A::v3 } ResultEnumB;
    virtual EnumA getIt(){return v2;}

    typedef enum { p1=A::p1,p2=A::p2,p3=A::p3, p4,p5,p6 ParamEnumB;
    virtual void setThat(int p); /* p in ParamEnumB */
    };


    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Sep 14, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Charlie

    enumeration types

    Charlie, Feb 8, 2005, in forum: VHDL
    Replies:
    4
    Views:
    563
    Charlie
    Feb 9, 2005
  2. Pleg

    Enumeration types and bits

    Pleg, Mar 7, 2006, in forum: VHDL
    Replies:
    5
    Views:
    846
  3. eXt

    Extend an enumeration

    eXt, Oct 26, 2006, in forum: C++
    Replies:
    3
    Views:
    392
  4. Markus Schickler

    Generating Enumeration Types at runtime

    Markus Schickler, May 4, 2007, in forum: Java
    Replies:
    5
    Views:
    525
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=
    Jun 9, 2007
  5. puvit82
    Replies:
    4
    Views:
    762
    puvit82
    Feb 1, 2008
Loading...

Share This Page