
On Monday 25 November 2013 00:44:30 Niall Douglas wrote:
On 25 Nov 2013 at 7:01, Andrey Semashev wrote:
If boost::type_id<T>() returns a reference to a non-copyable object then it is useless for me because the essential advantage of type_index is its value semantics. And in such a design boost::type_index has very different semantics from std::type_index, so it shouldn't be named as such to avoid confusion. I would vote against accepting such design. I'm not sure how you got this from my words. No one ever claimed that my proposed boost::type_id<T>() would return an uncopyable object - it returns a const boost::type_index<T>& to a statically constructed instance. One can use the static instance lref directly, take its address, or make a copy like std::type_index can. Under my design, a boost::type_index<T> has sizeof=0 and merely contains a statically constructed const char * shared by all instances. As it is zero sized, it is therefore POD.
Sorry, I completely missed the part where type_index become a template. My comments were made under impression that boost::type_index is not a template and thus cannot have no members and be copyable. So now it does not erase the type and cannot be used as a key in a container. By all measure it is now a completely different beast than std::type_index, so please, change the naming. <nitpicking>And its size is not zero anyway.</nitpicking>
Bear in mind that user code can always subclass boost::type_index and add their own name() implementation based on one or more of the above new member functions.
I don't think that mangled_name() (the last function that returns the cached mangled name) is a good idea. Requiring reimplementation of some particular mangling schemes (and by the way, why these specific ones?) is an unnecessary burden on the author (and maintainer later).
There is no need to reimplement any mangling schemes. For the MSVC and Itanium mangling schemes you simply chop the front and end off what is returned by __FUNCSIG__ or __FUNCTION__ and voila, there is your correct mangling.
And what about other platforms? Throwing an exception unconditionally doesn't look like a portable solution.
Caching the name internally as a static member complicates the design (the cache has to be thread-safe and be accessible in global constructors/destructors). Caching the name as a regular member is unacceptable bloat (people expect type_index to be as light as a pointer to type_info; no dynamic memory allocation and associated possible exceptions are allowed).
unique_name() uses no dynamic memory and won't throw. That's your only guarantee. If you want more functionality, you agree to pay its price.
My concern was related to mangled_name(), which you documented as returning a reference to a cached std::string.
Under what I proposed type_info permanently goes away. You get what TypeIndex provides and it's up to you if you want to interoperate with std::type_info. I proposed this because several reviewers felt that type_info implies some relation to std::type_info. I personally think that's daft, but that's not my role here - I am here to help reach consensus, so I tried to disappear anything called type_info.
boost::type_info is not a problem by itself, as far as I understood the reviews. The problem was the hack through which it was implemented in the proposed library and the discrepancies with std::type_info. Remove these two issues and boost::type_info becomes a type quite useful for portability.
I stand by the three functions we discussed during the review:
// Returns std::type_info::name() const char* name() const noexcept; // Returns some low-level (possibly mangled) name const char* raw_name() const noexcept; // Returns some possibly human readable name std::string pretty_name() const;
I'll add that I still think that the first one is required (at least, for compatibility with std::type_index) and has ho have exactly that semantics.
At least four people objected to name() returning anything different to what std::type_info::name() does.
And that's what I suggested, isn't it?