Boost logo

Boost :

Subject: Re: [boost] [cpo-proposal] presentation of the idea
From: Larry Evans (cppljevans_at_[hidden])
Date: 2013-08-22 10:52:27


On 08/20/13 07:44, Thorsten Ottosen wrote:
> On 20-08-2013 14:11, Larry Evans wrote:
>> On 08/20/13 06:55, Larry Evans wrote:
>>> On 08/20/13 04:23, Thorsten Ottosen wrote:
>>>> On 20-08-2013 11:04, Rob Stewart wrote:
>>>>> On Aug 19, 2013, at 9:44 AM, Thorsten Ottosen
>>>>> <thorsten.ottosen_at_[hidden]> wrote:
>>>>
>>>>>> Yes, at this level it is nice to take advantage of the memcopying
>>>>>> built into vector<char>.
>>>>>
>>>>> Here's the problem. Replicating the bits of and object isn't the same
>>>>> as copying it. Many classes store a this pointer or rely on a data
>>>>> member address as a unique key, etc. Copy constructors must run.
>>>
>>> Good catch. Thanks Rob.
>>>
>> However, this is a specific case of a more general problem.
>> Suppose the polymorphic_object at container[i+j] contains a
>> pointer of the polymorphic_obect at container[i]. Then
>> after resizing, the pointer will become invalid. The
>> specific case Rob mentions is when j=0.
>>
>> Maybe the class should just warn the user not to do this
>> or suggest a workaround, maybe instead of storing a pointer,
>> just store the index into the container?
>
> Pointer stability is an /inherent/ "problem" compared to using e.g.
> ptr_vector<T>. I see no other solution than warning the user about
> pointer invalidation, and advice the user to fill the container before
> storing any pointers in other places, or as you say, to use indexes.
>
> Since we need a base class, then maybe somthing like this is a starting
> point:
>
> class polymorphic_object
> {
> public:
> virtual ~polymorphic_object() {}
>
> private:
> polymorphic_object( const polymorphic_object& );
> polymorphic_object& operator=( const polymorphic_object& );
>
> public:
> static void copy( const polymorphic_object& this_, char* to )
> {
> // preconditions
> this_.do_copy( to );
> // postconditions
> }
>
> static void move( polymorphic_object& this_, char* to )
> {
> // preconditions
> this_.do_move( to );
> // postconditions
> }
>
> private:
> virtual polymorphic_object* do_copy( char* to ) const = 0;
> virtual polymorphic_object* do_move( char* to ) = 0;
> };
>
> regards
>
> Thorsten
>
Hi Thorsten,

I'm not sure how these do_copy and do_move virtual member functions
would work differently than just using the derived copy CTOR's.
The do_{copy,move} would still have to know how to map the
old pointer to the new pointer, if pointers were used.
OTOH, if only offsets were used, then wouldn't simply using
the vector<char>::swap work? OTOH, the problem with using
offsets is that any function taking the offset argument
to access the actual polymorphic_object in the container
of polymorphic_object's would have to be given, in addition,
a pointer to that container.

OTOH, I'm wondering if borrowing from the code in a copying
garbage collector would provide a solution. For example,
if the:

  std::vector<char> storage;

was the storage in the container, then when it was resized
such that a new storage region needed to be used, then
wouldn't the code in a copying garbage collector which
changes all pointers in the from space to pointers in
the to space solve the problem?

Just a thought. I've never written a copying garbage
collector; hence, I may be missing something obvious.

-regards,
Larry


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk