How can I find out, if type is created inside namespace?
-
12-12-2019 - |
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.
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.