New content are available at http://tis-method.org/. All articles from this site will be moved to the new location.

четверг, 23 сентября 2010 г.

C++ type string representation


During integration CInt & C++ i found very interesting task. I saw it before in "C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond, By David Abrahams, Aleksey Gurtovoy" as exercises to chapter 2.

Task statement
Generation full function call signature string representation, including type description and parameters value.
When i call CInt script function from C++ code, like this
call< void >( "func10", 0, 'A', 1.f, 1, 'B', 2.f, 3, 'C', 3.f, true );

i have to build string
"func10((int)0,(char)'A',(float)1,(int)1,(char)'B',(float)2,(int)3,(char)'C',(float)3,(bool)1);"
and then exec it in CInt sandbox, using G__calc (CInt API function).

For each function argument i have to generate type string representation and argument value in the valid form.
call<void>( "f1", 1 ); -> "f1( (int)1 );"
int i = 1;
call<void>( "f2",  &i ); -> "f2( (int*)0x00FC0632 );"

Additionally, will be great, if i can process user defined types too.
struct my_struct {} v;
call<int>( "f3", &v ); -> "f3( (my_struct*)0x00DFCC02 );"

Step by step
The basis of the solution is set of template partial specializations
template < typename > struct term_;

 This define is used for quick setup types recognition partial specialization
#define Z3D_TYPE_NAME_DEF_TERM( t ) \
 template <>\
 struct term_< t >\
 {\
  enum { length = sizeof( #t ) - 1 };\
  std::ostream& name( std::ostream& os ) const { return( os << #t ); }\
 };

This done for all basic types: void, bool, char, signed char, unsigned char, wchar_t, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double.
Z3D_TYPE_NAME_DEF_TERM( void );
...
Z3D_TYPE_NAME_DEF_TERM( long double );

Next define should be use to add user defined type into types recognition scope:
Z3D_TYPE_NAME_DEF_TERM_USER( my_struct );

The same mechanic used to recognizing
  • const, volatile, &, *, [], [N]
  • function from R(*)() to R(*)(P1, ..., P10)
  • pointer to the member T C::*
  • pointer to the member function from R(C::*)() to R(C::*)(P1, ..., P10)
Template class type_ is intended for collect whole type information. Template function format_ should be use for getting string represent of pair "type description" & "value"

How to use
It's very simple.
std::cout << z3d::type_name::type_< unsigned char(*)( void*(*)(int&) ) >::name() << std::endl;

will output
unsigned char(*)(void *(*)(int &))

and
std::cout << z3d::type_name::param_( L"abcdef" ) << std::endl;

will print something like that
(wchar_t const *)0x01180EF8

Sources
z3d::type_name.hpp

Use cases:
z3d/utests/type_name_ut01.hpp


Комментариев нет:

Отправить комментарий