Boost logo

Boost :

From: Matus Chochlik (chochlik_at_[hidden])
Date: 2008-06-07 03:56:50


On Fri, Jun 6, 2008 at 10:21 PM, Joel FALCOU <joel.falcou_at_[hidden]> wrote:
> Andrew James a écrit :
>> I myself have also implemented a class that has these features within a "traited" framework (explanation to follow). The challenge I have seen, that I'm not clear if it is expressed here, is what if the type whose name you want to dump is also dependent on some template parameter that a frameword user is in charge of?
> [...]
>> These things being said, I realize this is specific to my framework but it illustrates some issues a boost supported solution could provide.
>> We should be able to debug types like std::vector< SomeTypeTheDebugLibraryIsCluelessAbout > w/o requiring the user do a similar amount of work to writing the facility him/herself.
>
> I'm not sure if I understood the problem but currently my identify<>
> class can take care of user defined type or user_defined tempalte by
> using a simple register macro. I also have a on going list of
> pre-registered type for STD and parts of BOOST.
>
> Here is a small example :
>
> #include <boost/identify/identify.hpp>
> #include <boost/identify/support/std.hpp>
>
> // Some user template classes
> template<class A1,class A2,class A3,class A4,size_t A5> struct foo {};
> template<class A1,class A2> struct chu{};
>
> // some class
> struct coin {};
>
> BOOST_IDENTIFY_REGISTER_TYPE_ID(coin)
> BOOST_IDENTIFY_REGISTER_CUSTOM_TEMPLATE_TYPE_ID(
> (class)(class)(class)(class)(size_t), foo)
> BOOST_IDENTIFY_REGISTER_TEMPLATE_TYPE_ID(chu,2)
>
>
> template<class T> struct Test
> {
> static inline void Do()
> {
> cout << boost::identify<T>::Name() << endl;
> }
> };
>
> int main()
> {
> Test<char>::Do();
> Test<coin>::Do();
> Test<chu<float,coin> >::Do();
> Test< std::vector< chu<void,void*>& > >::Do();
> Test<foo<float,long*,volatile double,coin,3> >::Do();
> }
>
> The results are :
>
> char
> coin
> chu<float, coin>
> std::vector< chu<void,void*>&
> foo< float, signed long*, volatile double, coin, 3 >
>
> the identify.hpp grants the main identify class ans supports for basic
> types (POD, pointer, reference, cv qualified types, function types,
> function pointers and array mostly) while the support/std.hpp provides
> pre-registered identify overload for STD types.
>
> The macro BOOST_IDENTIFY_REGISTER_TYPE_ID declares a new user types to
> be displayed. BOOST_IDENTIFY_REGISTER_TEMPLATE_TYPE_ID does the same for
> template class with less than 5 tempalte parameters which are all of
> tpye class. BOOST_IDENTIFY_REGISTER_CUSTOM_TEMPLATE_TYPE_ID allows
> registering tempalte class with more than 5 parameters and with
> integralk parameters by specifying a BOOST_PP_SEQ of the arguments.
> The burden is no greater for me than registering a type for BOOST_TYPEOF
> and is fairly acceptable.
>
> Not sure if other cases are needed. My main concern is being able to
> display non-instanciated template class, eg:
>
> identify<std::vector>::Name() displaying std::vector
>
> but this may need another class (like incomplete_identify<> maybe).
>
> --
> Joel FALCOU
> Research Engineer @ Institut d'Electronique Fondamentale
> Université PARIS SUD XI
> France

The mirror library works from the programmer's point of view this way:

// define a rather complex type T
//
typedef tuple<int, double, const string*> T1;
typedef tuple<const bool, volatile float, void * const, char> T2;
typedef pair<T1, T2> T3;
typedef tuple<void*, const wstring& , const string&> T4;
typedef tuple<char, wchar_t, short int const> T5;
typedef pair<T4, T5> T6;
typedef vector<tuple<T1, T2, T3, T4, T5, T6> > T7;
typedef set<map<list<T1>, T7> > T;
//
// reflect the class using mirror. the "result" is a meta_class
typedef BOOST_MIRROR_REFLECT_CLASS(T) meta_T;
//
// among many other things there are member functions
// that return the typename of the reflected type
//
// the base_name returns the type/class/template
// names without nested-name-specifiers
// i.e. vector<pair<int, string> >
//
bcout << "The type name is: "<< meta_T::base_name() << endl;
//
// this version returns the fully qualified name like
// ::std::vector<::std::pair<int, ::std::string> >
bcout << "The full type name is: "<< meta_T::full_name() << endl;

there are several examples showing this in the sandbox:

http://svn.boost.org/svn/boost/sandbox/mirror/libs/mirror/example/

especially

http://svn.boost.org/svn/boost/sandbox/mirror/libs/mirror/example/special/std_pair.cpp
http://svn.boost.org/svn/boost/sandbox/mirror/libs/mirror/example/special/boost_tuple.cpp

(sry for the long links)

the meta_class specializations for the templates like pair, vector, tuple, etc.
are currently hand-coded, and using some common boilerplate to handle
the template param names, but I'm working on some registering macros
similar to Joel's.
see for example:
http://svn.boost.org/svn/boost/sandbox/mirror/boost/mirror/meta_classes/std_pair.hpp

-- 
________________
::matus_chochlik

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk