Search code examples
c++macrostype-traits

How can I find out, if type is created inside namespace?


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.


Solution

  • 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