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);"
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)
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
Комментариев нет:
Отправить комментарий