|
Boost Users : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-12-01 11:05:17
On Saturday 01 December 2001 10:41 am, you wrote:
> I want to make this explanation short so I will skip details.
> In a nutshell, during destruction or resize, a destructor
> is explicitly called from a loop for each element which has
> been constructed. Obviously this is desireable much of the time,
> but it is true even if the element type has an *empty* destructor.
> This can take a lot of unecessary time, like 10's or even a few 100
> milliseconds, which can make a big difference in, say, inspection
> software used in an industrial production line.
This isn't really a problem with the specification of std::vector, but is a
quality-of-implementation issue. If one knows that the destructor is trivial,
one can compile a version of the destruction/resize code that does not
contain a destruction loop.
> I wrote a replacement vector class which uses delete[] internally but
> otherwise acts like std::vector just to get around this problem.
> There are some drawbacks and limitations during resizing, but
> there are times when this behavior is essential.
Does it meet the criteria for std::vector with respect to reserve(n)? It
seems that would present a problem...
In any case, I believe the solution is this:
template<bool> truth_type {};
template<typename InputIterator>
inline void destruct_elements_in_range(
InputIterator first,
InputIterator last,
truth_type<true>)
{
// The elements in the range have trivial destructors, so do nothing
}
template<typename InputIterator>
inline void destruct_elements_in_range(
InputIterator first,
InputIterator last,
truth_type<false>)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
for(; first != last; ++first) {
T* victim = &(*first);
victim->~T();
}
}
template<typename T>
class vector {
private:
void destruct_elements() {
destruct_elements_in_range(begin(), end(),
truth_type<boost::has_trivial_destructor<T>::value>());
}
};
The user will generally need to add a specialization for any type with a
trivial destructor (or some compilers may support this, eventually).
> Unfortunately, containers like the graph boost library use std::vector
> as containers and that is hardcoded. So the destructor for a graph might
> take 100 or 200 ms, when it should take almost nothing because there is
> nothing dangerous which really needs to be cleaned up.
Most Boost libraries that use containers allow you to supply your own
container.
Doug
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net