diff options
author | maruel@google.com <maruel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-14 01:41:04 +0000 |
---|---|---|
committer | maruel@google.com <maruel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-14 01:41:04 +0000 |
commit | 1456372b7f52d49751535bc096d7590b10141f87 (patch) | |
tree | 0dbb15d06c29e0c2cd80ddde40d79987e5392e41 /base/stack_container.h | |
parent | 37936eefdf1bf98d1a4458d8f3b85233d28c37e4 (diff) | |
download | chromium_src-1456372b7f52d49751535bc096d7590b10141f87.zip chromium_src-1456372b7f52d49751535bc096d7590b10141f87.tar.gz chromium_src-1456372b7f52d49751535bc096d7590b10141f87.tar.bz2 |
Provide necessary constructors in StackAllocator and PrivateHookAllocator to permit release mode building in VC++2008 SP1. The current allocators do not conform with the C++ spec for allocators, and unlike previous versions, VC++2008 requires conformant allocators.
The reason that the allocators are not conformant is that any allocator, say, template<typename T> struct Alloc; must have a constructor of the following form:
template<typename U> Alloc(const Alloc<U>& other)
to allow construction of an Alloc<T> from an Alloc<U>. The constructors cannot be explicit, because they're (essentially) copy constructors, and so are not called explicitly.
StackAllocator has no converting copy constructor at all, and PrivateHookAllocator's is declared explicit, preventing it from being usable.
Without the StackAllocator constructor, StackVectors fail (due to the std::vector member, base\stack_container.h(216)).
Patch by Peter Bright <drpizza@quiscalusmexicanus.org>.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2175 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/stack_container.h')
-rw-r--r-- | base/stack_container.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/base/stack_container.h b/base/stack_container.h index 2822d12..98c4ac0 100644 --- a/base/stack_container.h +++ b/base/stack_container.h @@ -70,16 +70,34 @@ class StackAllocator : public std::allocator<T> { typedef StackAllocator<U, stack_capacity> other; }; - StackAllocator(Source* source) : source_(source) { + // For the straight up copy c-tor, we can share storage. + StackAllocator(const StackAllocator<T, stack_capacity>& rhs) + : source_(rhs.source_) { } - StackAllocator(const StackAllocator& other) : source_(other.source_) { + + // ISO C++ requires the following constructor to be defined, + // and std::vector in VC++2008SP1 Release fails with an error + // in the class _Container_base_aux_alloc_real (from <xutility>) + // if the constructor does not exist. + // For this constructor, we cannot share storage; there's + // no guarantee that the Source buffer of Ts is large enough + // for Us. + // TODO: If we were fancy pants, perhaps we could share storage + // iff sizeof(T) == sizeof(U). + template<typename U, size_t other_capacity> + StackAllocator(const StackAllocator<U, other_capacity>& other) + : source_(NULL) { + } + + explicit StackAllocator(Source* source) : source_(source) { } // Actually do the allocation. Use the stack buffer if nobody has used it yet // and the size requested fits. Otherwise, fall through to the standard // allocator. pointer allocate(size_type n, void* hint = 0) { - if (!source_->used_stack_buffer_ && n <= stack_capacity) { + if (source_ != NULL && !source_->used_stack_buffer_ + && n <= stack_capacity) { source_->used_stack_buffer_ = true; return source_->stack_buffer(); } else { @@ -90,7 +108,7 @@ class StackAllocator : public std::allocator<T> { // Free: when trying to free the stack buffer, just mark it as free. For // non-stack-buffer pointers, just fall though to the standard allocator. void deallocate(pointer p, size_type n) { - if (p == source_->stack_buffer()) + if (source_ != NULL && p == source_->stack_buffer()) source_->used_stack_buffer_ = false; else std::allocator<T>::deallocate(p, n); |