BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_allocatoradaptor

Functions

 bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp ()
 
 bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp (const StlAllocatorType &stla)
 
 bslma::AllocatorAdaptor_Imp< STL_ALLOC >::~AllocatorAdaptor_Imp () BSLS_KEYWORD_OVERRIDE
 Destroy this object and the STL-style allocator that it wraps.
 
void * bslma::AllocatorAdaptor_Imp< STL_ALLOC >::allocate (size_type size) BSLS_KEYWORD_OVERRIDE
 
void bslma::AllocatorAdaptor_Imp< STL_ALLOC >::deallocate (void *address) BSLS_KEYWORD_OVERRIDE
 
STL_ALLOC bslma::AllocatorAdaptor_Imp< STL_ALLOC >::adaptedAllocator () const
 Return a copy of the STL allocator stored within this object.
 
 bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor ()
 
 bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor (const STL_ALLOC &stla)
 

Detailed Description

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 <bslma_default.h>
#include <bsls_nullptr.h>
#include <cstring>
#include <cstdlib>
namespace my {
/// Store the path of a file or directory.
class FilePath {
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
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 /* 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();
}
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

Function Documentation

◆ adaptedAllocator()

template<class STL_ALLOC >
STL_ALLOC bslma::AllocatorAdaptor_Imp< STL_ALLOC >::adaptedAllocator ( ) const

◆ allocate()

template<class STL_ALLOC >
void * bslma::AllocatorAdaptor_Imp< STL_ALLOC >::allocate ( size_type  size)
virtual

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 >
bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor ( )
inline

Constructs a polymorphic wrapper around a default-constructed STL-style allocator.

◆ AllocatorAdaptor() [2/2]

template<class STL_ALLOC >
bslma::AllocatorAdaptor< STL_ALLOC >::AllocatorAdaptor ( const STL_ALLOC &  stla)
inline

Constructs a polymorphic wrapper around a copy of the specified 'stla' STL-style allocator.

◆ AllocatorAdaptor_Imp() [1/2]

template<class STL_ALLOC >
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp ( )
inline

Construct a polymorphic wrapper around a default-constructed STL-style allocator.

◆ AllocatorAdaptor_Imp() [2/2]

template<class STL_ALLOC >
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::AllocatorAdaptor_Imp ( const StlAllocatorType stla)
inline

Construct a polymorphic wrapper around a copy of the specified stla STL-style allocator.

◆ deallocate()

template<class STL_ALLOC >
void bslma::AllocatorAdaptor_Imp< STL_ALLOC >::deallocate ( void *  address)
virtual

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 >
bslma::AllocatorAdaptor_Imp< STL_ALLOC >::~AllocatorAdaptor_Imp ( )
inline