Outline
Purpose
Provide a polymorphic adaptor for STL-style allocators
Classes
AllocatorAdaptor<ALLOC>
- See also
Description
Within the BDE libraries, the prefered way to handle memory allocation is through a pointer to the polymorphic base class, 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.
This component provides a class template, 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.
Usage
Let's start with a simple class, my::FilePath
, which allocates storage using a bslma::Allocator
:
#include <cstring>
#include <cstdlib>
namespace my {
class FilePath {
char *d_data;
public:
: d_allocator(
bslma::Default::allocator(basicAllocator))
, d_data(0 ) { }
: d_allocator(
bslma::Default::allocator(basicAllocator))
{
d_data =
static_cast<char*
>(d_allocator->
allocate(std::strlen(s) + 1));
std::strcpy(d_data, s);
}
};
}
Definition bslma_allocator.h:457
virtual void * allocate(size_type size)=0
Definition balxml_encoderoptions.h:68
Next, assume that an STL-allocator exists that uses memory exactly the way you need:
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 ) {
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();
}
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
Now, if we want to create a 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);
my::FilePath usrbin("/usr/local/bin", &maa);
assert(&maa == usrbin.getAllocator());
assert(ma == maa.adaptedAllocator());
return 0;
}
Definition bslma_allocatoradaptor.h:293
◆ adaptedAllocator()
template<class STL_ALLOC >
◆ allocate()
template<class STL_ALLOC >
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.
◆ AllocatorAdaptor() [1/2]
template<class STL_ALLOC >
Constructs a polymorphic wrapper around a default-constructed STL-style allocator.
◆ AllocatorAdaptor() [2/2]
template<class STL_ALLOC >
Constructs a polymorphic wrapper around a copy of the specified 'stla' STL-style allocator.
◆ AllocatorAdaptor_Imp() [1/2]
template<class STL_ALLOC >
Construct a polymorphic wrapper around a default-constructed STL-style allocator.
◆ AllocatorAdaptor_Imp() [2/2]
template<class STL_ALLOC >
Construct a polymorphic wrapper around a copy of the specified stla
STL-style allocator.
◆ deallocate()
template<class STL_ALLOC >
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.
◆ ~AllocatorAdaptor_Imp()
template<class STL_ALLOC >