Number of elements in an enum

Discussion in 'C++' started by Mark P, Jan 12, 2007.

  1. Mark P

    Mark P Guest

    I'm working on a project where I have something like

    enum Modes {mode_a, mode_b, ...};

    Due to project spec changes, the number of Modes has increased several
    times. There are a few places where it's useful to know the number of
    image modes (to set the size of bitsets, etc.) Currently I just use a
    const int to hold this size:

    enum Modes {mode_a, mode_b, mode_c};
    const int number_of_modes = 3;

    I'm wondering what the style gurus think about this alternative:

    enum Modes {mode_a, mode_b, mode_c, mode_sentinel};
    const int number_of_modes = mode_sentinel;

    The second version requires just a bit less work to maintain, but is it
    trying to be too clever? FWIW, the numerical values of the enum
    elements are otherwise not used anywhere.
    Mark P, Jan 12, 2007
    #1
    1. Advertising

  2. Mark P

    Rolf Magnus Guest

    Mark P wrote:

    > I'm working on a project where I have something like
    >
    > enum Modes {mode_a, mode_b, ...};
    >
    > Due to project spec changes, the number of Modes has increased several
    > times. There are a few places where it's useful to know the number of
    > image modes (to set the size of bitsets, etc.) Currently I just use a
    > const int to hold this size:
    >
    > enum Modes {mode_a, mode_b, mode_c};
    > const int number_of_modes = 3;
    >
    > I'm wondering what the style gurus think about this alternative:
    >
    > enum Modes {mode_a, mode_b, mode_c, mode_sentinel};
    > const int number_of_modes = mode_sentinel;
    >
    > The second version requires just a bit less work to maintain, but is it
    > trying to be too clever? FWIW, the numerical values of the enum
    > elements are otherwise not used anywhere.


    An often used way to do this is even:

    enum Modes {mode_a, mode_b, mode_c, number_of_modes};
    Rolf Magnus, Jan 12, 2007
    #2
    1. Advertising

  3. Mark P

    mlimber Guest

    Mark P wrote:
    > I'm working on a project where I have something like
    >
    > enum Modes {mode_a, mode_b, ...};
    >
    > Due to project spec changes, the number of Modes has increased several
    > times. There are a few places where it's useful to know the number of
    > image modes (to set the size of bitsets, etc.) Currently I just use a
    > const int to hold this size:
    >
    > enum Modes {mode_a, mode_b, mode_c};
    > const int number_of_modes = 3;
    >
    > I'm wondering what the style gurus think about this alternative:
    >
    > enum Modes {mode_a, mode_b, mode_c, mode_sentinel};
    > const int number_of_modes = mode_sentinel;
    >
    > The second version requires just a bit less work to maintain, but is it
    > trying to be too clever? FWIW, the numerical values of the enum
    > elements are otherwise not used anywhere.


    The only problem with that is that the sentinel is a valid enum, so

    void SetMode( Modes );

    void Foo()
    {
    SetMode( mode_sentinel ); // Ok, but probably won't work
    }

    Enums aren't perfect in any case [the compiler needn't complain about
    "(Modes)0xfffff" either], but I prefer this style:

    enum Modes
    {
    mode_min = 0,
    mode_a = mode_min,
    mode_b,
    mode_c,
    mode_max = mode_c
    };
    enum { n_modes = (mode_max - mode_min) + 1 };

    void Bar()
    {
    SetMode( n_modes ); // Compile-time error
    }

    It also allows one to iterate relatively easily:

    for( Modes m = mode_min; m <= mode_max; m = Modes(m+1) )
    {
    // ...
    }

    Cheers! --M
    mlimber, Jan 12, 2007
    #3
  4. Mark P

    noone Guest

    On Fri, 12 Jan 2007 20:52:59 +0100, Rolf Magnus wrote:


    > An often used way to do this is even:
    >
    > enum Modes {mode_a, mode_b, mode_c, number_of_modes};


    but does this work when literal values are assigned to the members of the
    enumeration, such as when mapping "power of two" bitfields?
    noone, Jan 13, 2007
    #4
  5. Mark P

    noone Guest

    On Fri, 12 Jan 2007 19:50:42 +0000, Mark P wrote:

    > I'm working on a project where I have something like
    >
    > enum Modes {mode_a, mode_b, ...};
    >
    > Due to project spec changes, the number of Modes has increased several
    > times. There are a few places where it's useful to know the number of
    > image modes (to set the size of bitsets, etc.) Currently I just use a
    > const int to hold this size:



    Just the other day a guy I work with asked me a related question about
    whether there is an equivalent in C++ of the Pascal ORD() function to
    return the element position of an enumeration member. I don't think there
    is, if you assign a non-uniform distribution of literal values to the
    members of the enumeration in question. Can someone confirm this?

    enum modes { a=12, b=27, c=30, d=900};

    How do you determine the (position) of (a)?
    noone, Jan 13, 2007
    #5
  6. Mark P

    Gavin Deane Guest

    noone wrote:
    > On Fri, 12 Jan 2007 20:52:59 +0100, Rolf Magnus wrote:
    >
    >
    > > An often used way to do this is even:
    > >
    > > enum Modes {mode_a, mode_b, mode_c, number_of_modes};

    >
    > but does this work when literal values are assigned to the members of the
    > enumeration, such as when mapping "power of two" bitfields?


    No. This relies on the default behaviour that the first enumerator has
    the numerical value zero and succesive enumerators have their numerical
    value increasing by one each time. If you need to assign arbitrary
    values to your enumerators, as far as I know there is no way to
    programmatically determine the total number of enumerators in the enum.

    Gavin Deane
    Gavin Deane, Jan 13, 2007
    #6
  7. Mark P

    Gavin Deane Guest

    noone wrote:
    > Just the other day a guy I work with asked me a related question about
    > whether there is an equivalent in C++ of the Pascal ORD() function to
    > return the element position of an enumeration member. I don't think there
    > is, if you assign a non-uniform distribution of literal values to the
    > members of the enumeration in question. Can someone confirm this?
    >
    > enum modes { a=12, b=27, c=30, d=900};
    >
    > How do you determine the (position) of (a)?


    You can't. But then, what code can you write that depends on the
    position of a?

    Gavin Deane
    Gavin Deane, Jan 13, 2007
    #7
  8. Mark P

    noone Guest

    On Fri, 12 Jan 2007 16:42:11 -0800, Gavin Deane wrote:

    >
    > noone wrote:
    >> Just the other day a guy I work with asked me a related question about
    >> whether there is an equivalent in C++ of the Pascal ORD() function to
    >> return the element position of an enumeration member. I don't think
    >> there is, if you assign a non-uniform distribution of literal values to
    >> the members of the enumeration in question. Can someone confirm this?
    >>
    >> enum modes { a=12, b=27, c=30, d=900};
    >>
    >> How do you determine the (position) of (a)?

    >
    > You can't. But then, what code can you write that depends on the position
    > of a?



    I tend to agree with you...just wanted more input for the discussion with
    my programmer. If you need element position within a predefined set of
    values then there are other constructs in the language that can retrieve
    that information.

    I really think that enums as a feature of C++ are of limited utility and
    don't use them often. I think that wrapping the functionality of enum
    in a container class adds a lot more flexibility on the long run....yeah,
    I know, dereferencing an object member/value is generally a heavier
    process than referencing an enum element. :^)

    I know that from an early age the comp sci professors beat enumerated
    types into our heads, but other than as a (human readable abstraction) I
    don't see much utility that can't be emulated by other means...

    But I suppose we could degenerate this into an argument over whether
    abstract data types are necessary since they all degenerate to list or
    array processing in system memory.

    Smiles
    noone, Jan 13, 2007
    #8
  9. Gavin Deane wrote:

    >> > An often used way to do this is even:
    >> >
    >> > enum Modes {mode_a, mode_b, mode_c, number_of_modes};

    >>
    >> but does this work when literal values are assigned to the members of the
    >> enumeration, such as when mapping "power of two" bitfields?

    >
    > No. This relies on the default behaviour that the first enumerator has
    > the numerical value zero and succesive enumerators have their numerical
    > value increasing by one each time. If you need to assign arbitrary
    > values to your enumerators, as far as I know there is no way to
    > programmatically determine the total number of enumerators in the enum.


    In case anyone is interested, I've implemented such a check a while ago
    for some project of mine where knowing this was very important. (Actually,
    I needed a minor variant of this check, where every enum value had to be
    present in some array.)
    My check is based on the idea of Duff's device and depends on the compiler
    giving a warning if some value of the enum is not handled in a "switch".
    It then goes like this:

    enum eOption { OPT_FOO, OPT_BAR, OPT_BAZ, OPT_XXX };

    static void check_enum(enum eOption opt)
    {
    int count = 0;
    int first = 0;
    int i = 0;
    switch (opt) {
    do {
    default:
    case OPT_FOO: count += 1;
    case OPT_BAR: count += 1;
    case OPT_BAZ: count += 1;
    case OPT_XXX: count += 1;
    if (first == 0)
    first = count;
    } while (++i < 2);
    }
    int num = count - first;
    printf("This enum has %d entries.\n", num);
    }

    You have to specify every value of the enum in the switch, but you get
    warned by the compiler (use -Wswitch-enum in the case of gcc) if you forgot
    one.
    I believe this to be safe to use in all circumstances:
    - You can reorder the 'case's as you like. (That's why the switch is run
    twice.)
    - You need not even pass a valid enum value to check_enum().
    Any value will do. (The placement of 'default' takes care of that.)

    Since enums are static data, you only need to do this check once on program
    startup. Of course, if the enum has a lot of entries, you have to do a lot
    of typing...

    Martin Willers
    Martin Willers, Jan 17, 2007
    #9
    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. -

    enum within an enum

    -, Jun 12, 2005, in forum: Java
    Replies:
    6
    Views:
    533
  2. Jerminia
    Replies:
    3
    Views:
    622
    Roedy Green
    Oct 7, 2005
  3. Ernst Murnleitner

    How to enum an enum?

    Ernst Murnleitner, Nov 12, 2003, in forum: C++
    Replies:
    5
    Views:
    457
    Rolf Magnus
    Nov 13, 2003
  4. mrhicks
    Replies:
    2
    Views:
    414
    Dave Thompson
    Jun 10, 2004
  5. Hicham Mouline
    Replies:
    1
    Views:
    389
    Kai-Uwe Bux
    Apr 11, 2010
Loading...

Share This Page