|
Boost : |
Subject: Re: [boost] How to create a shallow copy without calling aconstructor?
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-01-02 17:34:51
----- 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk