2009/11/15 Roman Yakovenko <roman.yakovenko@gmail.com>
On Sun, Nov 15, 2009 at 6:22 PM, Gustavo Carneiro <gjcarneiro@gmail.com> wrote:
> Hi, I have a problem here that I do not know where to begin to solve.  I use
> pygccxml.declarations.templates.split(), but it returns a list of template
> parameters as strings, while I need to declarations of the classes listed as
> template arguments (long story, but I really do).

Been there, done it :-)

>  Is there a simple API in
> pygccxml that would allow me to go from a string like
> "ns3::dot11s::IeBeaconTimingUnit" to the actual declaration of the class?
> Or any other method rather than templates.split() that would give me the
> template args already as declarations?

May be, lets see.

In general I found 2 different ways to solve this problem.

The first one is deterministic - if you have template instantiated
class in your hands and it has typedef for its template parameters,
then you can use this fact:

template< class T>
struct Wrapper{
   typedef T value_type;

pygccxml provides "internal_type_traits.get_by_name" method to get
reference to "type_t"

The second way: start parsing and searching :-).

I suggest you to take a look on container_traits.py module. It tries
to extract [value|element] type from std::[container]. It treats 2 use
* the input is class definition - so using typedef's defined in the
container class, it finds the actual template parameter type
* the input is class declaration ( in case in code was written forward
declaration ) - in this case the parsing of arguments is done and then
global namespace is searched. Take a look on
type_traits.impl_details.find_value_type method.

It looks like type_traits.impl_details.find_value_type is what I need.  It seems to work fine for my needs, i.e. template arguments are user classes.

I am only concerned about two things:

   - I'm not too fond of using "implementation details"

  - The function is relatively slow (almost half a second each query, and I have a few dozen queries)

But other than that, I guess my problem is solved.

Thanks! :-)

The second way works most of the time, when it doesn't you have few choices:
* create dummy type (dummy_type_t), which will return parameter string
as-is. In some of my cases, I use meta-programming to select the
desired functionality
* raise an exception and ask user to specify the type explicitly -
good error message will solve you headache and simplify a few things
for the user :-)


Roman Yakovenko
C++ Python language binding

Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert