mike
mike

Reputation: 476

Custom RTTI information using templates

I have wrapper classes for SpiderMonkey API where I need to define methods with a specific signature. I have a solution based on templates. Basically, I have several template methods to handle hundreds of wrapper methods, like this (simplified):

template <typename jsType, AIErr(*Type::*Method)()>
    static bool ExecuteMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
}

I use it as follows, using macros:

#define EXECUTE_METHOD_AIERR_X(TYPE, METHOD) \
JS_FN(#METHOD, (js##TYPE::ExecuteMethod<js##TYPE, &TYPE::METHOD>), 0, 0)

If I have a situation when I need to debug, in order to know which method (*Method) of which class (*Type) was handled at a specific time, I would need to know the name of the type Type and the name of the method Method inside that template method. Due to the nature of SpiderMonkey's API, I can't alter the parameters of ExecuteMethod, just the template.

I've seen these:

C++ Get name of type in template

C++ Template Specialization with Constant Value

I've tried these, but the solution just fails for me at the typeid(T).name() step on MSVC C++ 2013 compiler. On the other hand, how to apply this on methods?

Additionally, I see this:

template<typename T>
class TypeParseTraits{
public:
    static const std::string name(){
        return typeid(T).name();
    }
};

#define REGISTER_PARSE_TYPE(X) \
    template<> class TypeParseTraits< X > \
    { public: static const std::string name(){ return #X; } };

What is this template<> class TypeParseTraits< X >? An override? A specialization?

If I would do it by templates again, it would be necessary to be dependent on jsType, Type and Method.

My question is, how should I implement (even for debug only) a RTTI info using strings? What are the most effective options, if any?

I know that simple char* is not an option as parameter for templates.

Thank you.

Upvotes: 0

Views: 1386

Answers (1)

Glib
Glib

Reputation: 304

"What is this template<> class TypeParseTraits< X >? An override? A specialization?" - it is partial specialization of template. In this particular case given macro ensures that TypeParseTraits template instantiated with 'registered' type will have method name that returns const std::string that contains the name of type, used in code instead of anything returnad by type_info.name() (which is implementation-defined and often hard to understand).

My question is, how should I implement (even for debug only) a RTTI info using strings? What are the most effective options, if any? - the best way for RTTI should be just some virtual method that will return for example a string. This method should be overriden in all derived classes (that could be simplified with static polymorphism approach) and return respective info.

I know that simple char is not an option as parameter for templates.* - not in general, but...

  • it is possible to have static const char* data in struct or class
  • is possible to fill this data with the help of template
  • it is possible to pass such struct as a template parameter and extract static data
  • it is possible to fill such strings manually if the member is constexpr (with some penalties though)

Thus you may use types (possibly templates) to pass char*s into other templates.

Example:

template<class C>
struct Named { static const char* name; };
template<class C>
const char* Named<C>::name = typeid(C).name(); // fill as you wish

template<class N>
void print() { cout<< N::name <<endl;}
...
print<Named<int>>();

Upvotes: 2

Related Questions