Quick Links: |
Provide a polymorphic adaptor for STL-style allocators. More...
Namespaces | |
namespace | bslma |
Functions | |
bslma::AllocatorAdaptor_Imp::AllocatorAdaptor_Imp () | |
bslma::AllocatorAdaptor_Imp::AllocatorAdaptor_Imp (const StlAllocatorType &stla) | |
virtual | bslma::AllocatorAdaptor_Imp::~AllocatorAdaptor_Imp () |
virtual void * | bslma::AllocatorAdaptor_Imp::allocate (size_type size) |
virtual void | bslma::AllocatorAdaptor_Imp::deallocate (void *address) |
STL_ALLOC | bslma::AllocatorAdaptor_Imp::adaptedAllocator () const |
bslma::AllocatorAdaptor::AllocatorAdaptor () | |
bslma::AllocatorAdaptor::AllocatorAdaptor (const STL_ALLOC &stla) |
bslma::Allocator
. The use of a run-time polymorphism for the allocator has numerous advantages over the compile-time polymorphism used by the STL components. However, there are times when client code may have an STL-style allocator available and needs to use it with a BDE component. AllocatorAdaptor
that wraps the STL-style allocator in an object of class derived from bslma::Allocator
. A pointer to the object can thus be used with any component that uses BDE-style memory allocation. my::FilePath
, which allocates storage using a bslma::Allocator
: #include <bslma_allocator.h> #include <bslma_default.h> #include <bsls_nullptr.h> #include <cstring> #include <cstdlib> namespace my { class FilePath { // Store the path of a file or directory bslma::Allocator *d_allocator; char *d_data; public: FilePath(bslma::Allocator* basicAllocator = 0 /* nullptr */) : d_allocator(bslma::Default::allocator(basicAllocator)) , d_data(0 /* nullptr */) { } FilePath(const char* s, bslma::Allocator* basicAllocator = 0) : d_allocator(bslma::Default::allocator(basicAllocator)) { d_data = static_cast<char*>(d_allocator->allocate(std::strlen(s) + 1)); std::strcpy(d_data, s); } bslma::Allocator *getAllocator() const { return d_allocator; } //... }; } // close namespace my
template <class TYPE> class MagicAllocator { bool d_useMalloc; public: typedef TYPE value_type; typedef TYPE *pointer; typedef const TYPE *const_pointer; typedef unsigned size_type; typedef int difference_type; template <class U> struct rebind { typedef MagicAllocator<U> other; }; explicit MagicAllocator(bool useMalloc = false) : d_useMalloc(useMalloc) { } template <class U> MagicAllocator(const MagicAllocator<U>& other) : d_useMalloc(other.getUseMalloc()) { } value_type *allocate(std::size_t n, void* = 0 /* nullptr */) { if (d_useMalloc) return (value_type*) std::malloc(n * sizeof(value_type)); else return (value_type*) ::operator new(n * sizeof(value_type)); } void deallocate(value_type *p, std::size_t) { if (d_useMalloc) std::free(p); else ::operator delete(p); } static size_type max_size() { return UINT_MAX / sizeof(TYPE); } void construct(pointer p, const TYPE& value) { new((void *)p) TYPE(value); } void destroy(pointer p) { p->~TYPE(); } int getUseMalloc() const { return d_useMalloc; } }; template <class T, class U> inline bool operator==(const MagicAllocator<T>& a, const MagicAllocator<U>& b) { return a.getUseMalloc() == b.getUseMalloc(); } template <class T, class U> inline bool operator!=(const MagicAllocator<T>& a, const MagicAllocator<U>& b) { return a.getUseMalloc() != b.getUseMalloc(); }
FilePath
using a MagicAllocator
, we need to adapt the MagicAllocator
to the bslma::Allocator
protocol. This is where bslma::AllocatorAdaptor
comes in: int main() { MagicAllocator<char> ma(true); bslma::AllocatorAdaptor<MagicAllocator<char> >::Type maa(ma); my::FilePath usrbin("/usr/local/bin", &maa); assert(&maa == usrbin.getAllocator()); assert(ma == maa.adaptedAllocator()); return 0; }
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp | ( | ) | [inline, inherited] |
= default
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp | ( | const StlAllocatorType & | stla | ) | [inline, inherited] |
Construct a polymorphic wrapper around a copy of the specified stla
STL-style allocator.
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::~AllocatorAdaptor_Imp | ( | ) | [inline, virtual, inherited] |
Destroy this object and the STL-style allocator that it wraps.
void * bslma::AllocatorAdaptor_Imp< STL_ALLOC >::allocate | ( | size_type | size | ) | [virtual, inherited] |
Return a maximally-aligned block of memory no smaller than size
bytes allocated from the STL-style allocator that was supplied to this object's constructor. Any exceptions thrown by the underlying STL-style allocator are propagated out from this member.
Implements bslma::Allocator.
void bslma::AllocatorAdaptor_Imp< STL_ALLOC >::deallocate | ( | void * | address | ) | [virtual, inherited] |
Return the memory block at the specified address
back to the STL-allocator. If address
is null, this funciton has no effect. The behavior is undefined unless address
was allocated using this allocator object and has not already been deallocated.
Implements bslma::Allocator.
STL_ALLOC bslma::AllocatorAdaptor_Imp< STL_ALLOC >::adaptedAllocator | ( | ) | const [inherited] |
Return a copy of the STL allocator stored within this object.
bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor | ( | ) | [inline, inherited] |
= default
bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor | ( | const STL_ALLOC & | stla | ) | [inline, inherited] |
Constructs a polymorphic wrapper around a copy of the specified stla
STL-style allocator.