Boost logo

Boost :

Subject: Re: [boost] How to create a shallow copy without calling aconstructor?
From: Michael (boost_at_[hidden])
Date: 2010-01-02 17:38:19


vicente.botet wrote:
> ----- Original Message -----
> From: "Stefan Strasser" <strasser_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Saturday, January 02, 2010 5:14 PM
> Subject: Re: [boost] How to create a shallow copy without calling aconstructor?
>
>
>
>> Am Saturday 02 January 2010 16:42:45 schrieb vicente.botet:
>>
>>> I have looked at uninitialized_copy but if I have understood it correctly,
>>> it calls the copy constructor. I have tried with
>>>
>>> class C {
>>> public:
>>> C* shallow_clone() {
>>> C* p = reinterpret_cast<C>(malloc(sizeof(C));
>>> if (p==0) {
>>> throw std::bad_alloc();
>>> }
>>> memcpy(p, this, sizeof(C));
>>> return p;
>>> }
>>> };
>>>
>>> But I suspect that this is not correct in general. Is this correct on some
>>> particular cases? if yes on witch ones? Is there a way to create such a
>>> cache instance without calling to the constructor in a portable way using
>>> some low level C++ interface?
>>>
>> new char[sizeof(T)], reinterpret_cast and std::memcpy().
>> the C++ standard explicitely requires char-arrays to be aligned appropriately
>> for objects of any type that fits in the array.
>>
>> I don't know the requirements of your cache, but there are many cases were
>> copying an object like this will fail. e.g. when the object contains a
>> boost::interprocess::offset_ptr, so this is only a portable way to copy PODs.
>>
>
> Hi,
> I don't want to require the transactional object to be Copy-Constructible,
?!
> but I need to copy it in the transactional specific cache. In addition I don't want the constructor/destructor of these copied cache instances to interfere on the user space.
>
> What I want is avoid requiring the user to defines a specific shallow copy constructor and a specific shallow copy assignement. The base class of all the transactional objects in Boost.STM is
>
> class base_transaction_object {
> public:
> virtual base_transaction_object* shallow_clone() const = 0;
> virtual void copy_state(base_transaction_object const * const) = 0;
> virtual void cache_deallocate()=0;
> virtual ~base_transaction_object() {};
> ...
> };
>
> The user can define a shallow copy himself as follows
>
> class C : public base_transaction_object {
> C(C const& rhs, shallow_copy_t) {
> // do a shallow copy
> }
> public:
> base_transaction_object* shallow_clone() {
> C* p = reinterpret_cast<C>(new char[sizeof(C)]);
> return new (p) C(*this, shallow_copy);
> }
> void copy_state(base_transaction_object const * const rhs) {
> // do a shallow assignement
> }
> void cache_deallocate() {
> delete[] reinterpret_cast<char*>(this);
> }
> };
>
> I want to define a generic mixin that define these function, something like:
>
> template <class Derived, typename Base=base_transaction_object>
> class shallow_transaction_object : public Base
> {
> typedef Base base_type;
> public:
> base_transaction_object* shallow_clone() const {
> Derived* p = reinterpret_cast<Derived*>( new char[sizeof(Derived)]);
> std::memcpy(p, static_cast<Derived const*>(this), sizeof(Derived));
> return p;
> }
>
> void cache_deallocate() {
> delete[] reinterpret_cast<char*>(this);
> }
>
> void copy_state(base_transaction_object const * const rhs) {
> std::memcpy(static_cast<Derived *>(this), static_cast<Derived const * const>(rhs), sizeof(Derived ));
> }
> };
>
> So the user can just declare its own class as
>
> class C : public shallow_transaction_object<C> {
> // members concerning the user space
> };
>
> Can this be done in a portable way?
>
> Best,
> Vicente
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
>


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