Cecil
Cecil

Reputation: 155

Alias C enum and it's entries in C++ without C-style name prefixes

I'm writing a library with both a C and C++ API. I need to write many enums in the C API and wrap them in the C++ API.

typedef enum PREFIX_SomeType
{
    PREFIX_SOME_TYPE_A,
    PREFIX_SOME_TYPE_B,
    PREFIX_SOME_TYPE_C,
} PREFIX_SomeType;

In the C++ wrapper header I'd like to have a similar enum without name prefixes, since the C++ wrapping API uses a namespace called PREFIX.

namespace PREFIX
{

enum SomeType : int
{
    SOME_TYPE_A,
    SOME_TYPE_B,
    SOME_TYPE_C,
};

}

Since these two enums are different enums they don't cleanly convert to one another. Whenever I define a struct in the C api containing enums, I'd like to use a C++ alias.

typedef struct PREFIX_ApiStruct
{
    PREFIX_SomeType type;
    // ...
} PREFIX_ApiStruct;

And in the C++ wrapper:

using namespace PREFIX
{

using ApiStruct = PREFIX_ApiStruct;

}

But, when trying to use the C++ wrapper we cannot assign a C++ enum...

ApiStruct instance;
instance.type = SOME_TYPE_A; // Error!

Is there a way to let a C++ user not write type out PREFIX_ and instead use C++ namespaces, without requiring explicit casts?

Upvotes: 0

Views: 341

Answers (2)

Cecil
Cecil

Reputation: 155

The closest solution I could come up with is using C++17 to do:

inline constexpr PREFIX_SomeType SOME_TYPE_A = PREFIX_SOME_TYPE_A;
inline constexpr PREFIX_SomeType SOME_TYPE_B = PREFIX_SOME_TYPE_B;
inline constexpr PREFIX_SomeType SOME_TYPE_C = PREFIX_SOME_TYPE_C;

This does mess somewhat with syntax highlighting, but I fail to see a better alternative without re-implementing the C++ struct. This is also easy to generate via x-macro.

Upvotes: 0

David Ranieri
David Ranieri

Reputation: 41017

Does an X-MACRO help?

In a shared .h:

#define SOME_TYPE   \
    X(SOME_TYPE_A)  \
    X(SOME_TYPE_B)  \
    X(SOME_TYPE_C)

In the C part:

typedef enum PREFIX_SomeType
{
#define X(type) PREFIX_##type,
    SOME_TYPE
#undef X
} PREFIX_SomeType;

In the C++ part:

namespace PREFIX
{

enum SomeType : int
{
#define X(type) type,
    SOME_TYPE
#undef X
};

}

Upvotes: 2

Related Questions