Question

I have created Tag system, which allows tag entity in ma engine. It works based on c++ types, so every tag is a type (I have my reasons).

Now, when I want to create new tag, I have to call struct tagname{};.

If I want to use tag in other files, I use forward declaration struct name;

To make it more user friendly I created macros

#define CREATE_TAG(name) struct name{};
#define USE_TAG(name)    struct name;

But when user call one macro inside namespace and other outside namespace, I have a problem, because that are 2 different types.

I want to ensure, that user call macros outside any namespace. Since our project is in one namespace namespace root, I can use it for chcecking.

This is what I came up with so far:

namespace root
{
    const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};

#define CREATE_TAG(name)    namespace root{  struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }
#define USE_TAG(name)       namespace root{  struct name;   static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }

Now when macro is used outside root namespace, everything is fine. When called inside root namespace or other nested namespaces, it gives the error TAGS_CAN_BE... not a member.

But I do not really like it. I don't like the whole macro thing, but that is not the question. Question is: Is there a better way to find out, if macro is called in namespace? Since my macros passing in Type, I can use some typetraits, but I did not find any suitable one.

Was it helpful?

Solution 2

So it looks that

namespace root
{
    const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};

#define CREATE_TAG(name)    namespace root{  struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }
#define USE_TAG(name)       namespace root{  struct name;   static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }

is the answer...

I will wait a few days before I accept it. I am still open to your answers

OTHER TIPS

You could try something like this:

#include <type_traits>
#define DECLARE_ME(name) struct tag_##name { static_assert(!std::is_same<tag_##name, ::tag_##name>::value, "Not in global namespace"); }

You'll probably get a compiler-error that's not even the static assertion in case of a misuse, but it should catch the problem. You could probably make it more user-friendly with a more elaborate trait class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top