Subject: Re: [boost] [poly_collection] Request for comments: fast polymorphic collections
From: Thorsten Ottosen (tottosen_at_[hidden])
Date: 2016-11-16 05:54:28
On 15-11-2016 23:53, Joaquin M López Muñoz wrote:
> El 15/11/2016 a las 18:38, Thorsten Ottosen escribió:
>> Hi Joaquin,
>> A. This is very useful.
> Thanks! Glad you find it interesting.
>> B. I'm still wondering if requirering copyability is a good thing.
>> After all, references and pointers may be used elsewere in the program
>> where copying is really not a good idea. Could it make sense to have a
>> variation of cloneable:
>> void clone( void* storage ) const;
>> // essentially a call to protected or private copy-constructor:
>> // new(storage) T( *this )
>> which is then used internally when copying is needed? And when no
>> copying is needed, the container is not copyable. To insert elements
>> that are not copyable we would just use emplace with a type argument:
>> coll.emplace<derived>( x, y );
> Strictly speaking, copyability is not required, but as concrete types
> are stored in rellocatable vectors they must be verify the following:
> * be MoveConstructible,
> * be Moveassignable or have a noexcept move constructor.
> Otherwise, segments wouldn't be able to grow beyond its initial capacity.
Right. But maybe that access to be hidden to the outside world like in
friend class boost::poly_collection::access;
Then perhaps your library could work with private and protected
copy/move operations? My point is that we are still doing
OO-programming, and copying/moving is not natural operations for objects
in that domain.
> As for your clone() proposal, I fail to see why this is preferrable to
> simply requiring (move/copy) constructibility. Please note that
> moving/copying in Boost.PolyCollection happens in a non-virtual
> environment, so we don't need the virtual-enabled clone mechanism as
> envisioned in the Clonable concept of Boost.PtrContainer. Please correct
> me if I'm missing your point.
You could always devirtualize it. Anyway, the point is, to hide the
copy/move semantics to clients of my class hierarchy. Take the following
I know what types to register and how many of each I'm going to insert.
For that case I should be able to construct, reserve and insert without
having a copyable or movable type.
Anyway, I would be ok with just being able to make copy/move operations
>> C. perhap some range versions of local iterators would be nice?
> Care to elaborate? I've basically replicated the usual interface of
> standard containers, of course open to consider justified improvements
> on that.
could be nice to write
for( auto x : c.range<warrior>() )
for( auto x : restituted_range<warrior>(c) )
>> D. I don't get the use of numeric_limits<T>::max() for capacity of an
>> empty container. I would be perfectly happy with 0 unless there is
>> something we cannot do with that definition.
> Not a strong opinon on that. Having capacity()==infinite for a
> segment-less collection makes sense from a mathematical point of view,
> but other than that 0 could work equally well. If this eventually make
> it into an official proposal I'd adopt whatever the community thinks
> makes the most sense.
ok, it confused me, so chances are that it will confuse the average
programmer and take up brain cycles for no reason.
>> E. Boost.PtrContainer does not throw exception when a container cannot
>> be cloned or compared. Maybe its must be possible to get compile
>> errors here too?
> I've re-read Boost.PtrContainer docs and seems like the containers
> require Base to be clonable, which is tantamount to requiring
> copyability for all derived classes in Boost.PolyCollection. Am I wrong
> here? What's the behavior if a Base is not clonable?
It's a compile error. But I think I don't give the compile error until
the cloning is needed.
>> that is, would that not guarantee devirtualization?
> Very good observation. Yes, that would force devirtualization. The thing
> can be packed into something more generic: