c++0x: Is it possible to make the compiler choose scope if unambiguous?

Discussion in 'C++' started by Johannes Bauer, Mar 2, 2011.

  1. Hi folks,

    I'm writing a microcontroller abstraction library in C++0x, mainly to
    try out how well suited it is for embedded purposes and play around with
    some of the new exciting 0x-features.

    I have a construction of nested classes, where the outermost defines a
    memory map (e.g. a memory-mapped UART representation), then that memory
    map has registers (e.g. a baudrate register), those nest bitfields (e.g.
    a enum for some clock divider values).

    This works actually very beautifully and allows me to do some neat
    tricks. There is one small thing, however, where I am not sure how to
    solve it more nicely using 0x's features. Consider this innermost class
    representing some imaginary clock divider bitfield:

    class Bf_CLKDIV {
    public:
    enum class Enum : uint32_t {
    DIVBY2 = 0 << 16,
    DIVBY4 = 1 << 16,
    DIVBY8 = 2 << 16,
    DIVBY16 = 3 << 16,
    };
    void operator=(enum class Enum aValue) {
    myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS &
    ~(0x30000)) | (uint32_t)aValue;
    }
    } CLKDIV;

    For the sake of simplicity, consider myPeriphMemory a global variable.
    Now in code, I can assign values to that enum quite nicely:

    portFoo.TESTDIR.CLKDIV = D_TEST_APB::Reg_TESTDIR::Bf_CLKDIV::Enum::DIVBY4;

    However, since "D_TEST_APB::Reg_TESTDIR::Bf_CLKDIV::Enum::" is the only
    type which matches operator= "DIVBY4" by itself would be unambiguous.
    The compiler obviously rejects

    portFoo.TESTDIR.CLKDIV = DIVBY4;

    Is there some way, maybe by using the auto keyword to make the above
    syntax look nicer? To make to compiler more willing to choose the scope
    itself, if it is unambiguous?

    And, by the way, since I declared my enum like this

    enum class Enum : uint32_t

    Is there a way to extract the underlying integer type during compile
    time without having it to restate again as I do in:

    myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    (uint32_t)aValue;

    with the explicit cast? Something like (imaginary syntax here)

    myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    (typeof(enum class Enum))aValue;

    Best regards,
    Johannes

    --
    >> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

    > Zumindest nicht öffentlich!

    Ah, der neueste und bis heute genialste Streich unsere großen
    Kosmologen: Die Geheim-Vorhersage.
    - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$>
    Johannes Bauer, Mar 2, 2011
    #1
    1. Advertising

  2. On 2 mar, 22:10, Johannes Bauer <> wrote:
    > Hi folks,
    >
    > I'm writing a microcontroller abstraction library in C++0x, mainly to
    > try out how well suited it is for embedded purposes and play around with
    > some of the new exciting 0x-features.
    >
    > I have a construction of nested classes, where the outermost defines a
    > memory map (e.g. a memory-mapped UART representation), then that memory
    > map has registers (e.g. a baudrate register), those nest bitfields (e.g.
    > a enum for some clock divider values).
    >
    > This works actually very beautifully and allows me to do some neat
    > tricks. There is one small thing, however, where I am not sure how to
    > solve it more nicely using 0x's features. Consider this innermost class
    > representing some imaginary clock divider bitfield:
    >
    > class Bf_CLKDIV {
    >     public:
    >         enum class Enum : uint32_t {
    >             DIVBY2 = 0 << 16,
    >             DIVBY4 = 1 << 16,
    >             DIVBY8 = 2 << 16,
    >             DIVBY16 = 3 << 16,
    >         };


    You are already in a class scope, IMO you don't need enum class; plain
    enum should be sufficient:

    enum Enum : uin32_t { ...

    >         void operator=(enum class Enum aValue) {
    >             myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS&
    > ~(0x30000)) | (uint32_t)aValue;
    >         }
    >
    > } CLKDIV;
    >
    > For the sake of simplicity, consider myPeriphMemory a global variable.
    > Now in code, I can assign values to that enum quite nicely:
    >
    > portFoo.TESTDIR.CLKDIV = D_TEST_APB::Reg_TESTDIR::Bf_CLKDIV::Enum::DIVBY4;


    I don't see how you can make the economy of the class specifier.

    >
    > However, since "D_TEST_APB::Reg_TESTDIR::Bf_CLKDIV::Enum::" is the only
    > type which matches operator= "DIVBY4" by itself would be unambiguous.
    > The compiler obviously rejects
    >
    > portFoo.TESTDIR.CLKDIV = DIVBY4;
    >
    > Is there some way, maybe by using the auto keyword to make the above
    > syntax look nicer? To make to compiler more willing to choose the scope
    > itself, if it is unambiguous?
    >
    > And, by the way, since I declared my enum like this
    >
    > enum class Enum : uint32_t
    >
    > Is there a way to extract the underlying integer type during compile
    > time without having it to restate again as I do in:
    >
    > myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    > (uint32_t)aValue;
    >
    > with the explicit cast? Something like (imaginary syntax here)
    >
    > myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    > (typeof(enum class Enum))aValue;


    AFAIK if you remove the 'class', you no longer needed the cast.

    --
    Michael
    Michael Doubez, Mar 2, 2011
    #2
    1. Advertising

  3. Am 02.03.2011 23:22, schrieb Michael Doubez:

    > You are already in a class scope, IMO you don't need enum class; plain
    > enum should be sufficient:
    >
    > enum Enum : uin32_t { ...


    Ah, okay, I didn't know that. I thought that if "class" was omitted the
    enum is more weakly typed than the "class enum" (i.e. implicit
    conversion to integer is possible). That a enum automatically is a
    "class enum" if it appears inside a class is new to me.

    >> myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    >> (typeof(enum class Enum))aValue;

    >
    > AFAIK if you remove the 'class', you no longer needed the cast.


    Well, but that is not what I want, I would like to disallow automatic
    conversion (i.e. force the cast). This implicit enum-to-int conversion
    has always annoyed me since it is quite error-prone. That's actually one
    thing I really like about the "class enum".

    Best regards,
    Johannes

    --
    >> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

    > Zumindest nicht öffentlich!

    Ah, der neueste und bis heute genialste Streich unsere großen
    Kosmologen: Die Geheim-Vorhersage.
    - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$>
    Johannes Bauer, Mar 2, 2011
    #3
  4. On 2 mar, 23:27, Johannes Bauer <> wrote:
    > Am 02.03.2011 23:22, schrieb Michael Doubez:
    >
    > > You are already in a class scope, IMO you don't need enum class; plain
    > > enum should be sufficient:

    >
    > > enum Enum : uin32_t { ...

    >
    > Ah, okay, I didn't know that. I thought that if "class" was omitted the
    > enum is more weakly typed than the "class enum" (i.e. implicit
    > conversion to integer is possible).


    It is weakly typed but the name doesn't leak outside the class
    namespace (just like today).

    > That a enum automatically is a
    > "class enum" if it appears inside a class is new to me.


    Sorry, my phrasing must have been misleading. My point was that I
    didn't understand why you would want strong typing, scoping is often
    enough.

    But If you do need strong typing, you could define it outside the
    enclosing class since enum class already provides name scoping. And
    use a typedef within the class.

    >
    > >> myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    > >> (typeof(enum class Enum))aValue;

    >
    > > AFAIK if you remove the 'class', you no longer needed the cast.

    >
    > Well, but that is not what I want, I would like to disallow automatic
    > conversion (i.e. force the cast). This implicit enum-to-int conversion
    > has always annoyed me since it is quite error-prone. That's actually one
    > thing I really like about the "class enum".


    Ok. You may be able to retreive the layout compatible type from the
    size and the signedness.

    And define something like:

    template<class T>
    constexpr to_value(T e) -> enumClassToBase<T>::type
    {
    return enumClassToBase<T>::type(e)
    }

    myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    to_value(aValue);

    Worth a try.

    --
    Michael
    Michael Doubez, Mar 2, 2011
    #4
  5. Johannes Bauer

    Öö Tiib Guest

    On Mar 3, 12:27 am, Johannes Bauer <> wrote:
    > Am 02.03.2011 23:22, schrieb Michael Doubez:
    >
    >
    > >> myPeriphMemory.TESTDIR = (myPeriphMemory.TESTIS & ~(0x30000)) |
    > >> (typeof(enum class Enum))aValue;

    >
    > > AFAIK if you remove the 'class', you no longer needed the cast.

    >
    > Well, but that is not what I want, I would like to disallow automatic
    > conversion (i.e. force the cast). This implicit enum-to-int conversion
    > has always annoyed me since it is quite error-prone. That's actually one
    > thing I really like about the "class enum".


    You have always disliked implicit conversion and also you want to get
    rid of verbose explicit conversion?
    Then the only way left is not to convert. Simply ... don't use your
    Enum in arithmetics with ints and other annoying types.
    Öö Tiib, Mar 2, 2011
    #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. Øyvind Isaksen
    Replies:
    3
    Views:
    3,582
    =?Utf-8?B?RWx0b24gVw==?=
    Feb 11, 2006
  2. JKop
    Replies:
    3
    Views:
    317
    Default User
    Apr 28, 2004
  3. rhmd
    Replies:
    12
    Views:
    562
  4. Nirjhar Oberoi

    Need to choose a free compiler

    Nirjhar Oberoi, Nov 16, 2006, in forum: C Programming
    Replies:
    16
    Views:
    444
    Chris Hills
    Nov 30, 2006
  5. Jason Doucette
    Replies:
    15
    Views:
    440
    Jason Doucette
    Jul 27, 2007
Loading...

Share This Page