Compile typedef-ed substrings

Discussion in 'C++' started by mrstephengross, Apr 4, 2005.

  1. Hi folks! I'm trying to do something that I'm pretty sure you can't do
    in C++. But what the heck! Maybe it can work...

    I want to figure out how to use macros and templates to turn the
    following code snippet:

    void SomeClass::someFunction() { /* ... */ }

    Into:

    void SomeClass::someFunction() { typeid(SomeClass); }

    So far, I haven't figured much out. Consider the following macro:

    #define FOO(f) f typeid(#f);

    It will turn:

    void FOO(SomeClass::someFunction() {) /* ... */ }

    into:

    void SomeClass::someFunction() { typeid(SomeClass::someFunction {); }

    Which of course won't compile. The preprocessor is very limited, and
    can't parse apart macro arguments. I'm wondering if there's some way to
    do it with templates. For instance:

    #define FOO(f) f typeid(mymagictemplate<#f>::type);

    Any ideas? So far I've come up short.

    Thanks,
    --Steve ()
     
    mrstephengross, Apr 4, 2005
    #1
    1. Advertising

  2. mrstephengross wrote:
    > Hi folks! I'm trying to do something that I'm pretty sure you can't do
    > in C++. But what the heck! Maybe it can work...
    >
    > I want to figure out how to use macros and templates to turn the
    > following code snippet:
    >
    > void SomeClass::someFunction() { /* ... */ }
    >
    > Into:
    >
    > void SomeClass::someFunction() { typeid(SomeClass); }


    Huh? Perhaps you should simply use the search-and-replace feature of
    your text editor?

    > So far, I haven't figured much out. Consider the following macro:
    >
    > #define FOO(f) f typeid(#f);
    >
    > It will turn:
    >
    > void FOO(SomeClass::someFunction() {) /* ... */ }
    >
    > into:
    >
    > void SomeClass::someFunction() { typeid(SomeClass::someFunction {); }


    No joke... :-/

    > Which of course won't compile. The preprocessor is very limited, and
    > can't parse apart macro arguments. I'm wondering if there's some way to
    > do it with templates. For instance:
    >
    > #define FOO(f) f typeid(mymagictemplate<#f>::type);


    Something similar to

    template<void (T::*f)()> struct mymagictemplate {
    typedef T type;
    };

    but do lose the #.

    > Any ideas? So far I've come up short.


    Can you maybe specify the problem you're trying to solve instead of giving
    a non-working "solution" and make use *guess* the problem?

    V
     
    Victor Bazarov, Apr 4, 2005
    #2
    1. Advertising

  3. > Can you maybe specify the problem you're trying to solve instead of
    giving
    > a non-working "solution" and make use *guess* the problem?


    Sure... We want to automagically extract the class name from any given
    function definition and *use* it in the code. So for any given
    function:

    SomeClass::foo() { /* ... */ }

    We want to automagically turn it into:

    SomeClass::foo() { typeid(SomeClass); }

    Or even:

    SomeClass::foo() { std::cout << typeid(SomeClass).name(); }
    (For debugging purposes)

    We need to find a way to do it automatically so that we can apply it
    across-the-board to the whole program and produce complete debugging
    information.

    Ideas?

    --Steve
     
    mrstephengross, Apr 4, 2005
    #3
  4. mrstephengross wrote:
    >>Can you maybe specify the problem you're trying to solve instead of

    >
    > giving
    >
    >>a non-working "solution" and make use *guess* the problem?

    >
    >
    > Sure... We want to automagically extract the class name from any given
    > function definition and *use* it in the code. So for any given
    > function:
    >
    > SomeClass::foo() { /* ... */ }
    >
    > We want to automagically turn it into:
    >
    > SomeClass::foo() { typeid(SomeClass); }
    >
    > Or even:
    >
    > SomeClass::foo() { std::cout << typeid(SomeClass).name(); }
    > (For debugging purposes)
    >
    > We need to find a way to do it automatically so that we can apply it
    > across-the-board to the whole program and produce complete debugging
    > information.
    >
    > Ideas?


    How about 'typeid(*this)' ? There are other things that can help
    extracting class out of references (if you're so inclined)...

    template<class T> struct deref { typedef T type; };
    template<class T> struct deref<T&> { typedef T type; };
    template<class T> struct deref<T const&> { typedef T type; };
    ...

    (this is for illustration only, I've seen it somewhere, you should try
    it before you buy)

    Later on, you will actually have 'decltype', it's in the works.

    Keep in mind that 'type_info::name' doesn't have to return anything of
    any value to the debugger. It's not specified to be extremely useful,
    just barely, and depends very much on the implementation.

    V
     
    Victor Bazarov, Apr 4, 2005
    #4
  5. The problem with 'typeid(*this)' is that the function may be static, in
    which case 'this' is not available...

    --Steve
     
    mrstephengross, Apr 4, 2005
    #5
  6. mrstephengross wrote:
    > The problem with 'typeid(*this)' is that the function may be static, in
    > which case 'this' is not available...


    I am honestly not sure what you hope to get out of it. If you have to
    edit your code *anyway*, why don't you just use the class name instead of
    some obscure macro or a template?

    V
     
    Victor Bazarov, Apr 4, 2005
    #6
  7. > > The problem with 'typeid(*this)' is that the function may be
    static, in
    > > which case 'this' is not available...

    >
    > I am honestly not sure what you hope to get out of it. If you have

    to
    > edit your code *anyway*, why don't you just use the class name

    instead of
    > some obscure macro or a template?


    Let's say you've got the following code:

    ==========================================
    class foo { void func1(); void func2(); void func3(); ... void funcX();
    };

    void foo::func1() { ... }
    void foo::func2() { ... }
    void foo::func3() { ... }
    ....
    void foo::funcX() { ... }
    ==========================================

    I'm trying to find a *quick* way to get the class name printed when
    each function executes. If I do it with a macro, then I want that macro
    to be very short and easy to insert, given the large number of
    functions I'm dealing with:

    ==========================================
    class foo { void func1(); void func2(); void func3(); ... void funcX();
    };

    #define MACRO(f) f std::cout << typeid(magictemplate<#f>::type);

    void MACRO(foo::func1() {) ... }
    void MACRO(foo::func2() {) ... }
    void MACRO(foo::func3() {) ... }
    ....
    void MACRO(foo::funcX() {) ... }
    ==========================================

    Obviously, I could make the macro take class name as an argument, but
    the code will get wordier and less readable:


    ==========================================
    class foo { void func1(); void func2(); void func3(); ... void funcX();
    };

    #define MACRO(classname, f) f std::cout << typeid(classname);

    void MACRO(foo, foo::func1() {) ... }
    void MACRO(foo, foo::func2() {) ... }
    void MACRO(foo, foo::func3() {) ... }
    ....
    void MACRO(foo, foo::funcX() {) ... }
    ==========================================

    Since I want the macro to be as non-intrusive as possible, I want to
    see if there's a way to extract the classname portion of the function
    definition at compile time. (I can do it at runtime, but I'll run into
    namespace issues: NAMESPACE1::fooclass might be reported as 'fooclass'
    instead of 'NAMESPACE1::fooclass').

    --Steve
     
    mrstephengross, Apr 4, 2005
    #7
  8. mrstephengross

    Guest

    mrstephengross wrote:

    > I'm trying to find a *quick* way to get the class name printed when
    > each function executes.

    [...]
    > I want to
    > see if there's a way to extract the classname portion of the function
    > definition at compile time. (I can do it at runtime, but I'll run

    into
    > namespace issues: NAMESPACE1::fooclass might be reported as

    'fooclass'
    > instead of 'NAMESPACE1::fooclass').


    The following method seems to be easier than what you have in mind, and
    works with namespaces. It uses g++'s __PRETTY_FUNCTION__ variable. You
    should be able to find similar features if your compiler is different.

    Ali

    #include <iostream>
    #include <ostream>
    #include <string>
    #include <assert.h>

    #define FUNCTION_INFO \
    do \
    { \
    std::cout \
    << "::" \
    << pluckClassName(__PRETTY_FUNCTION__) \
    << '\n'; \
    } \
    while (0);

    std::string pluckClassName(std::string const & prettyName)
    {
    using std::string;

    string::size_type beg = prettyName.find(" ");

    // We expect a space after the return type
    assert(beg != string::npos);

    ++beg; // Jump over the space
    string::size_type end = prettyName.rfind("::");

    return ((end == string::npos)
    ? ""
    : prettyName.substr(beg, end - beg));
    }

    namespace Namespace
    {

    class Class
    {
    public:

    void foo() { FUNCTION_INFO; }
    };

    } // Namespace

    class FreeClass
    {
    public:

    void bar() { FUNCTION_INFO; }
    };

    int freeFunction()
    {
    FUNCTION_INFO;
    return 0;
    }

    int main()
    {
    Namespace::Class nc;
    nc.foo();

    FreeClass fc;
    fc.bar();

    freeFunction();
    }
     
    , Apr 6, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Leandro Pardini

    Binary files, substrings and (un)packing.

    Leandro Pardini, Oct 25, 2003, in forum: Perl
    Replies:
    1
    Views:
    598
    Jim Gibson
    Oct 27, 2003
  2. Nagaraj
    Replies:
    1
    Views:
    893
    Lionel B
    Mar 1, 2007
  3. Replies:
    1
    Views:
    2,359
  4. oor
    Replies:
    0
    Views:
    1,376
  5. Brian Cole
    Replies:
    8
    Views:
    4,408
    James Kanze
    May 20, 2009
Loading...

Share This Page