|
Boost : |
Subject: [boost] 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)
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2012-05-30 13:22:43
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_at_DU?$char_traits_at_D@std@@V?$allocator_at_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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk