 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
E. Rosten Guest
|
Posted: Wed Jun 08, 2005 12:23 pm Post subject: Proposed extension: placement delete[] ? |
|
|
This is about implementing an efficient array placement delete.
Consider the following basic container:
template<class C> void placement_delete(C*, size_t);
template<class C> class blob
{
C* m_data;
size_t num;
public:
C* data()
{
return m_data;
}
blob(size_t n)
{
void * d = gimme_some_unusual_memory_please(n * sizeof(C));
m_data = new (d)[n];
num = n;
}
~blob()
{
placement_delete(m_data, num);
please_free_my_unusual_memory(m_data);
}
};
So, how do you implement placement_delete efficiently? Currently there are
no especially good options, but here they are:
Here's the obvious way:
template<class C> placement_delete(C* d, size_t num)
{
do
d[--num]->~C();
while(num);
}
This works as expected, and if C has a trivial destructor, then it
degenerates to an empty loop. Unfortunately, not all compilers are smart
enough to optimize this away (gcc 3.3.4 can with some options which are
`not for production use', gcc 4.0 can not, icc 8 can). Destruction
may be O(N).
Here's a less obvious way:
template <class T, int C=32> struct placement_delete
{
enum
{
Size = (1<
};
struct Array
{
T data[Size];
};
static inline void destruct(T* buf)
{
(*(Array*)buf).~Array();
}
inline placement_delete(T* buf, size_t M)
{
if (M == 0)
return;
if (M >= Size)
{
placement_delete<T,C>(buf+Size,M-Size);
destruct(buf);
}
else if (M < Size)
{
placement_delete
}
}
};
template <class T> struct placement_delete<T,-1>
{
inline placement_delete(T* buf, size_t M) {}
};
This is O(C) when 2^C >= N, for trivial destructors, but probably can not
be optimized away in the case where destruction is trivial.
If there was a working is_pod keyword, the result could be used as a
compile time switch, which would choose whether to compile in destructor
calls or not:
template<class C, int i> struct destructor
{
static void destruct(size_t){}
};
template<class C> struct destructor<C, 1>
{
static void destruct(size_t num)
{
//Call destructors in a loop
}
};
template<class C> placement_delete(C* d, size_t num)
{
destructor<C, is_pod(C)>::destruct(num);
}
-Ed
--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)
/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Thu Jun 09, 2005 9:43 am Post subject: Re: Proposed extension: placement delete[] ? |
|
|
E. Rosten wrote:
| Quote: | This is about implementing an efficient array placement delete.
There's really no placement delete (array or otherwise). The |
only time a non-default-argged deallocator is called is if a failure
occurs during object creation.
If you're going to use placement new, it is incumbant on you
to overload your allocation function to remember the additional
information required and then fix the default-argged deallocator
to do the right thing with that information.
The problem is that C++ decided that new/delete would be very
lightweight additions over what the C malloc/delete was and
don't require objects to carry the baggage of how they were
allocated.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
E. Rosten Guest
|
Posted: Fri Jun 10, 2005 10:18 am Post subject: Re: Proposed extension: placement delete[] ? |
|
|
On Thu, 09 Jun 2005 05:43:22 -0400, Ron Natalie wrote:
| Quote: | E. Rosten wrote:
This is about implementing an efficient array placement delete.
There's really no placement delete (array or otherwise).
|
Precisely, and it does not seem possible to implement an efficient one,
either.
| Quote: | The problem is that C++ decided that new/delete would be very
lightweight additions over what the C malloc/delete was and
don't require objects to carry the baggage of how they were
allocated.
|
I'm not after that. My memory comes from a different source from
new/delete. As a result, I need to manually construct and destruct the
objects. In general, there is no efficient way of performing the
destruction for arbitrary types, in the case where the arbitrary type in
question has a trivial destructor.
-Ed
--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)
/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ta0kira@yahoo.com Guest
|
Posted: Mon Jun 13, 2005 4:15 pm Post subject: Re: Proposed extension: placement delete[] ? |
|
|
template <class Type> void inplace_delete(Type *tType)
{ tType->~Type(); }
template <class Type> void inplace_delete(Type *tType, size_t sSize)
{ for (int I = 0; I < sSize; I++) inplace_delete(tType + I); }
In-place new skips the allocation and constructs an object in the
location specified, so why not just skip the deallocation and destruct
it at the location specified?
ta0kira
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
E. Rosten Guest
|
Posted: Mon Jun 13, 2005 7:52 pm Post subject: Re: Proposed extension: placement delete[] ? |
|
|
On Mon, 13 Jun 2005 12:15:11 -0400, ta0kira wrote:
| Quote: | template <class Type> void inplace_delete(Type *tType)
{ tType->~Type(); }
template <class Type> void inplace_delete(Type *tType, size_t sSize)
{ for (int I = 0; I < sSize; I++) inplace_delete(tType + I); }
In-place new skips the allocation and constructs an object in the
location specified, so why not just skip the deallocation and destruct
it at the location specified?
ta0kira
|
I am doing this. However, this is not necessarily efficient in the case
where the destructor is trivial.
-Ed
--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)
/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|