Boost logo

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