Is there interest in copyable type_info that does not require RTTI (was: Is there interest in typeid(TYPE).name() like function that does not require RTTI)

Hi, There is a detail/sp_typeinfo.hpp which is not documented, and has some drawbacks. This header provides type_info like class that can be used with RTTI disabled. I am proposing to refactor this header, move it to utility/template_info.hpp and document it as a separate utility. Refactored header will provide classes template_info_ptr, template_info<T>, type_info_ptr and free function get_template_info<T>() Advantages: 1) more portable and reliable than detail::sp_typeinfo (no sp_typeid_<T>::ti_ public static variable) 2) copyable type_info like classes 3) has all the type_info functions + name_demangle 4) works with disabled RTTI 5) better functionality: no need to write macros like: #if defined( BOOST_NO_TYPEID ) # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) #elif (defined(__GNUC__) && __GNUC__ >= 3) \ || defined(_AIX) \ || ( defined(__sgi) && defined(__host_mips)) # include <cstring> # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \ (std::strcmp((X).name(),(Y).name()) == 0) # else # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) #endif 6) user can explicitly chose between template_info+template_info_ptr and type_info+type_info_ptr 7) no macro (get_template_info<T>() instead of &BOOST_SP_TYPEINFO(T) ) Disadvantages: 1) Does not work with variables (but you can still use BOOST_TEMPLATE_INFO_PTR(BOOST_TYPEOF(var))) 2) BOOST_CURRENT_FUNCTION produces long strings, and that could lead to code bloat when RTTI disabled Some usage examples: int main () { // Portable way that works with and without RTTI: copyable_type_info t1 = get_template_info<std::string>(); copyable_type_info t2 = get_template_info<int>(); // class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << t1.name_demangled() << '\n'; // int std::cerr << t2.name_demangled() << '\n'; // false std::cerr << (t1 == t2) << '\n'; // true std::cerr << (t1 != t2) << '\n'; copyable_type_info t1_copy = t1; // .?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ std::cerr << get_template_info<std::string>().name() << '\n'; // class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << get_template_info<std::string>().name_demangled() << '\n'; // explicitly using no-RTTI methods // int>::name_begin(void) std::cerr << template_info<int>::name_begin() << '\n'; // int std::cerr << template_info<int>::name_demangled() << '\n'; // class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
::name_begin(void) std::cerr << template_info<std::string>::name_begin() << '\n';
// class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << template_info<std::string>::name_demangled() << '\n'; template_info_ptr p1 = template_info<int>::construct(); template_info_ptr p2 = template_info<std::string>::construct(); std::cerr << (p1 == p2) << '\n'; std::cerr << (p1 != p2) << '\n'; } If there is interest, I can commit code to sandbox and request for review. P.S.: As I know, Boost.Function, Boost.Shared_ptr and Boost.Exception use code similar to what I am proposing. Following libraries use typeid() and can benefit from using proposed classes: Boost.MSM, Boost.Math, Boost.Test, Boost.Graph, Boost.Units, Boost.XPressive, Boost.Any, Boost.Statechart -- Best regards, Antony Polukhin

Yes there is interest. I would like to disable RTTI but cannot because of boost::any and boost::function. I even wrote my own 'typeinfo' template/macro that allows me to register all of the types I care about. I think having the ability to 'override' the value returned, perhaps a pretty_name(), such that get_template_info<std::string>().pretty_name() => "std::string" or perhaps even "string" would be useful. This almost gets into some basic level of reflection. The ability to query 'parts' of the name may be useful... such as get_template_info<std::string>().namespace() => "std" Given the basic functionality you describe, it would probably only involve some extra 'one-time init' name parsing if there isn't a simpler method. A key requirement would be that the same strings be generated on all compilers such that types can be compared for RPC purposes. Even without my suggested additions, I think this would be a worthy move. Dan On May 30, 2012, at 1:22 PM, Antony Polukhin wrote:
Hi,
There is a detail/sp_typeinfo.hpp which is not documented, and has some drawbacks. This header provides type_info like class that can be used with RTTI disabled.
I am proposing to refactor this header, move it to utility/template_info.hpp and document it as a separate utility. Refactored header will provide classes template_info_ptr, template_info<T>, type_info_ptr and free function get_template_info<T>()
Advantages: 1) more portable and reliable than detail::sp_typeinfo (no sp_typeid_<T>::ti_ public static variable) 2) copyable type_info like classes 3) has all the type_info functions + name_demangle 4) works with disabled RTTI 5) better functionality: no need to write macros like: #if defined( BOOST_NO_TYPEID ) # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) #elif (defined(__GNUC__) && __GNUC__ >= 3) \ || defined(_AIX) \ || ( defined(__sgi) && defined(__host_mips)) # include <cstring> # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \ (std::strcmp((X).name(),(Y).name()) == 0) # else # define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) #endif
6) user can explicitly chose between template_info+template_info_ptr and type_info+type_info_ptr 7) no macro (get_template_info<T>() instead of &BOOST_SP_TYPEINFO(T) )
Disadvantages: 1) Does not work with variables (but you can still use BOOST_TEMPLATE_INFO_PTR(BOOST_TYPEOF(var))) 2) BOOST_CURRENT_FUNCTION produces long strings, and that could lead to code bloat when RTTI disabled
Some usage examples:
int main () { // Portable way that works with and without RTTI: copyable_type_info t1 = get_template_info<std::string>(); copyable_type_info t2 = get_template_info<int>();
// class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << t1.name_demangled() << '\n';
// int std::cerr << t2.name_demangled() << '\n'; // false std::cerr << (t1 == t2) << '\n'; // true std::cerr << (t1 != t2) << '\n';
copyable_type_info t1_copy = t1;
// .?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ std::cerr << get_template_info<std::string>().name() << '\n'; // class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << get_template_info<std::string>().name_demangled() << '\n';
// explicitly using no-RTTI methods // int>::name_begin(void) std::cerr << template_info<int>::name_begin() << '\n';
// int std::cerr << template_info<int>::name_demangled() << '\n';
// class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
::name_begin(void) std::cerr << template_info<std::string>::name_begin() << '\n';
// class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > std::cerr << template_info<std::string>::name_demangled() << '\n';
template_info_ptr p1 = template_info<int>::construct(); template_info_ptr p2 = template_info<std::string>::construct(); std::cerr << (p1 == p2) << '\n'; std::cerr << (p1 != p2) << '\n'; }
If there is interest, I can commit code to sandbox and request for review.
P.S.: As I know, Boost.Function, Boost.Shared_ptr and Boost.Exception use code similar to what I am proposing. Following libraries use typeid() and can benefit from using proposed classes: Boost.MSM, Boost.Math, Boost.Test, Boost.Graph, Boost.Units, Boost.XPressive, Boost.Any, Boost.Statechart
-- Best regards, Antony Polukhin
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Daniel Larimer wrote:
Yes there is interest. I would like to disable RTTI but cannot because of boost::any and boost::function.
I even wrote my own 'typeinfo' template/macro that allows me to register all of the types I care about. I think having the ability to 'override' the value returned, perhaps a pretty_name(), such that get_template_info<std::string>().pretty_name() => "std::string" or perhaps even "string" would be useful.
This almost gets into some basic level of reflection. The ability to query 'parts' of the name may be useful... such as get_template_info<std::string>().namespace() => "std"
Hmmm - this looks pretty similar to the "extended_type_info" facility which is documented as part of the serialization library. This facility was required to implement loading of derived classes through a base class pointer. It includes a class factory which constructs a class instance at runtime given it's name as a string. The (sub)library includes multiple implementations. One is based on rtti and another one similar to that described above. Robert Ramey

2012/5/31 Daniel Larimer <dlarimer@gmail.com>:
Yes there is interest. I would like to disable RTTI but cannot because of boost::any and boost::function.
Yeep. Thats why I started that.
This almost gets into some basic level of reflection. The ability to query 'parts' of the name may be useful... such as get_template_info<std::string>().namespace() => "std"
Interesting feature, but I won`t implement it right now.
Given the basic functionality you describe, it would probably only involve some extra 'one-time init' name parsing if there isn't a simpler method.
For raw_name() it has no extra 'one-time init' name parsing. For demangled name it require std::string construction. For comparisons it require std::strcmp on PART of the BOOST_CURRENT_FUNCTION name. hash_value() is counted on a PART of the BOOST_CURRENT_FUNCTION.
A key requirement would be that the same strings be generated on all compilers such that types can be compared for RPC purposes.
This looks currently impossible: MSVC will produce 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' GCC will produce 'std::basic_string<char>'
Even without my suggested additions, I think this would be a worthy move.
Dan
Thanks. I`ll clean up the code, add documentation and tests and commit it at this or next week to sandbox or github. -- Best regards, Antony Polukhin

Documentation is available at: http://apolukhin.github.com/type_index/index.html Sources at: https://github.com/apolukhin/type_index Main header: https://github.com/apolukhin/type_index/blob/master/boost/type_index.hpp I'll add some patches for current boost libraries to use TypeIndex to that repo, fix a few things, write some more tests and then I'll request for review. -- Best regards, Antony Polukhin
participants (3)
-
Antony Polukhin
-
Daniel Larimer
-
Robert Ramey