Boost logo

Boost :

Subject: Re: [boost] [TypeIndex] Peer review period for library acceptance begins, ending Thurs 21st Nov
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2013-11-22 02:05:13


2013/11/21 Jan Herrmann <jherrmann79_at_[hidden]>

> On 21.11.2013 16:57, Antony Polukhin wrote:
>
>> 2013/11/21 Jan Herrmann <jherrmann79_at_[hidden]>
>>
>> Only from reading documentation I have a few questions:
>>>
>>> 1. In http://apolukhin.github.io/type_index/boost_typeindex/
>>> examples.html#boost_typeindex.examples.getting_through_the_inheritance_is
>>> written that polymorphic types can't be identified without RTTI. It
>>>
>>> should be possible for a library user to make his types compatible with
>>> Boost.TypeIndex to identify them. For example he can return
>>> boost::type_info from a virtual function inside each class:
>>>
>>> struct A {
>>> virtual ~A(){}
>>> virtual boost::type_info const& get_boost_type_info() const {
>>> return boost::type_id<A>());
>>> }
>>> };
>>> struct B: public A {
>>> virtual boost::type_info const& get_boost_type_info() const {
>>> return boost::type_id<B>());
>>> }
>>> };
>>> struct C: public B {
>>> virtual boost::type_info const& get_boost_type_info() const {
>>> return boost::type_id<C>());
>>> }
>>> };
>>>
>>> Boost.TypeIndex should provide a way to use such methods inside
>>> boost::type_id_rtti_only. Is something like this planned?
>>>
>>>
>> This looks like a *very* good addition, thanks for the idea! This will be
>> implemented as soon as possible (before the next review).
>>
>
> I think some macros can make it very easy to implement this for clients.

Yes.
I'm also thinking of an ability for client to provide it's own names for a
type. For example
boost::variant<int, double, std::basic_string< /*a lot of text*/,
boost::detail::variant::void_ /* many times*/ > uses a lot of space in
binary even in mangled representation. Instead of that user may do
something like:

typedef boost::variant<.......> my_variant_t;

template <>
class ctti<my_variant_t> {
    static const char* name() {
        return "database_row_t";
    }
};

Macro may also help in this case.

>
> 2. As far as I understand almost everything inside the library is build on
>> top of string comparison. All these strings are available at compile time.
>> Are there plans to make boost::template_info a literal type? It would help
>> with metaprogramming to have a system representing types with the same set
>> of operations and behavior at compile time and run time (I think of
>> sorting
>> classes at compile time, store boost::template_info of them in an array
>> and
>> use some binary search at run time).
>>
>>
> This can be interesting. That feature will be implemented, however I do not
> see how this could be possible to do in C++03/C++98.
>

Yes it's only possible with constexpr, but I see your work as a part for
> building better TypeIndex like systems. Users should be able to build their
> own RTTI system with information about types they need. For example a RTTI
> system could provide information about size and alignment or provide a type
> erased clone implementation (from a void* to void* with same type).

This is a very big goal and TypeIndex was not initially intended to solve
such problems. This can be added some time later (after additional mini
review), not in the initial version.

>
> 3. What are he exact reasons for storing types with const, volatile and
>> reference in boost::type_id_with_cvr?
>> As long as there is no way to query this information and remove it at run
>> time I think it would better users store them together with type_index if
>> the need this feature. It could result in hard to find errors when users
>> use type_if_with_cvr in one module and not expecting them in another.
>>
>>
> This is done for libraries that use type erasure technique a lot. Sometimes
> there may be a need to store those modifiers (there was an example in
> examples section for that case:
>
> http://apolukhin.github.io/type_index/boost_typeindex/examples.html#boost_typeindex.examples.exact_type_match_storing_type_wi
> )
>
> There must be no problems with mixing boost::type_id_with_cvr and
> boost::type_id. If there are no modifiers, result will be the same:
>
> boost::type_id_with_cvr<int>() == boost::type_id<int>()
> boost::type_id_with_cvr<user_defined>() == boost::type_id<user_defined>()
>
> Or am I missing some use case?
>
>
I see type erasure in conjunction with type recovery. And I think these
> bits of information are not worth. If it is possible that somebody calls
> boost::type_id_with_cvr in one module other modules which needs to probe
> for types have to check every type 12 times (2 (const) x 2 (volatile) x
> 3(no ref, ref, rvalue rev). Think of implementing a ad-hoc visitor (
> http://www.drdobbs.com/generic-programmingtypelists-and-applica/184403813)
> with TypeIndex and void*.
> When implementing a function which only needs a const value client has to
> probe for const and non-const types only to get a const value out of it.
> I'm not sure whether volatile should be considered. For example no
> container in std has overloads for volatile access to elements, but they
> are all const correct.
> References are another problem. In case of type erased storage they are
> very distinct form values but sometimes they should be used like values. If
> I remember correctly there where long debates about std::optional and
> references in isocpp.proposals or general this year. Arguments could be
> same here.
>
> I wouldn't feel comfortable to work with type properties without being
> able to query them. Type recovery is hard enough.
>
> But if somebody needs these information there are a few ways. One would be
> to align type_index at a 8 Byte boundary so users could store pointers and
> would have 4 bits. The other option is to let users build their own
> facilities via composition of some state variable and type_index.

Think of it in another way: its a way to preserve old functionality.

boost::type_id<T>() will remove all the cvr modifiers, but there might be
some users that rely on a behavior of their current compiler and still wish
to save those modifiers. So if we provide a function that removes cvr,
there must be an ability so save cvr.

What modifiers really matter to user - is up to user. If user needs only
references, it is possible for him to save only them:

#include <boost/type_traits/remove_cv.hpp>

using namespace boost;
type_id_with_cvr< typename remove_cv<T>::type >();

Exactly the same things can be done if user needs only const.

> Jan Herrmann
>

Thanks for the good ideas!

-- 
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