Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Help with STL allocators

Reply
Thread Tools

Help with STL allocators

 
 
mar00ned
Guest
Posts: n/a
 
      09-24-2004
Hi,

I have a written a custom allocator for STL, on the lines of default
allocator as follows :

template <class T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template <class U>
struct rebind { typedef pool_allocator<U> other; };

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <class U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}


size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}


void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

//template <class T> pool pool_allocator<T>::mem_;

template <class T, class U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <class T, class U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

I do a simple thing like : map<int, float, less<int>,
pool_allocator<pair<int, float> > > m;
I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
). But unfortunately, I am facing following errors :

Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef T& reference;
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef const T& const_reference;
^^^^^^^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)


I am not very good at this ... any reasons why this could be happening
?

~mar00ned
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      09-24-2004

"mar00ned" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi,
>
> I have a written a custom allocator for STL, on the lines of default
> allocator as follows :
>
> template <class T>
> class pool_allocator
> {
> public:
> typedef size_t size_type;
> typedef ptrdiff_t difference_type;
> typedef T* pointer;
> typedef const T* const_pointer;
> typedef T& reference;
> typedef const T& const_reference;
> typedef T value_type;
>
> template <class U>
> struct rebind { typedef pool_allocator<U> other; };
>
> pointer address(reference x) const {return &x;}
> const_pointer address(const_reference x) const {return &x;}
>
> pool_allocator(){}
> pool_allocator(const pool_allocator&) {}
> template <class U>
> pool_allocator (const pool_allocator<U>&) {}
> ~pool_allocator(){}
>
>
> size_type max_size() const throw() {return size_t(-1) /
> sizeof(value_type);}
>
> pointer allocate(size_type size, const void* hint = 0)
> return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
> }
>
> void construct(pointer p, const T& val)
> {
> new(static_cast<void*>(p)) T(val);
> }
> void construct(pointer p)
> {
> new(static_cast<void*>(p)) T();
> }
>
> void destroy(pointer p){p->~T();}
> void destroy(char* ){}
> void destroy(void* ){}
>
>
> void deallocate(pointer p, size_type n)
> {
> mem_.deallocate(p, n);
> }
> void deallocate(void *p, size_type n)
> {
> mem_.deallocate(p, n);
> }
> void deallocate(pointer p)
> {
> mem_.deallocate(p);
> }
> void deallocate(void *p)
> {
> mem_.deallocate(p);
> }
>
> static void dump(){
> mem_.dump();
> }
>
> private:
>
> static pool mem_;
> };
>
> //template <class T> pool pool_allocator<T>::mem_;
>
> template <class T, class U>
> inline bool operator==(const pool_allocator<T>&, const
> pool_allocator<U>){return true;}
>
> template <class T, class U>
> inline bool operator!=(const pool_allocator<T>&, const
> pool_allocator<U>){return false;}
>
> I do a simple thing like : map<int, float, less<int>,
> pool_allocator<pair<int, float> > > m;
> I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
> ). But unfortunately, I am facing following errors :
>
> Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> typedef T& reference;
> ^^^^^^^^^
> Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> typedef const T& const_reference;
> ^^^^^^^^^^^^^^^
> Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> pointer address (T& x)
> ^^^^^^^
> Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> pointer address (T& x)
> ^^^^^^^
> Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> allocator_interface<Allocator,T>::construct(pointe r p, const T&
> val)
> ^^^^^^^^^
> Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
> required for specialization instead of 'void' since the template
> creates a reference to that type.
> allocator_interface<Allocator,T>::construct(pointe r p, const T&
> val)
>
>
> I am not very good at this ... any reasons why this could be happening
> ?
>


You need to create a specialised void allocator. Since you cannot allocate
void objects this allocator is very simple.

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;

template <class U>
struct rebind { typedef pool_allocator<U> other; };

};

Something like that anyway. The particular error you were getting were
because the compiler was trying to substitute void for T in your
unspecialised template and coming up with code like this

typedef void& reference;

which is illegal because you cannot have a void reference.

john


 
Reply With Quote
 
 
 
 
Rohit Mattoo
Guest
Posts: n/a
 
      09-24-2004
My allocator looks like this now :



template <class T> class pool_allocator;
template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <class U>
struct rebind { typedef pool_allocator<U> other; };

};

template <class T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
....

but unfortunately the error havent stopped.

Thanks and regards,
~mar00ned





"John Harrison" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> "mar00ned" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
> > Hi,
> >
> > I have a written a custom allocator for STL, on the lines of default
> > allocator as follows :
> >
> > template <class T>
> > class pool_allocator
> > {
> > public:
> > typedef size_t size_type;
> > typedef ptrdiff_t difference_type;
> > typedef T* pointer;
> > typedef const T* const_pointer;
> > typedef T& reference;
> > typedef const T& const_reference;
> > typedef T value_type;
> >
> > template <class U>
> > struct rebind { typedef pool_allocator<U> other; };
> >
> > pointer address(reference x) const {return &x;}
> > const_pointer address(const_reference x) const {return &x;}
> >
> > pool_allocator(){}
> > pool_allocator(const pool_allocator&) {}
> > template <class U>
> > pool_allocator (const pool_allocator<U>&) {}
> > ~pool_allocator(){}
> >
> >
> > size_type max_size() const throw() {return size_t(-1) /
> > sizeof(value_type);}
> >
> > pointer allocate(size_type size, const void* hint = 0)
> > return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
> > }
> >
> > void construct(pointer p, const T& val)
> > {
> > new(static_cast<void*>(p)) T(val);
> > }
> > void construct(pointer p)
> > {
> > new(static_cast<void*>(p)) T();
> > }
> >
> > void destroy(pointer p){p->~T();}
> > void destroy(char* ){}
> > void destroy(void* ){}
> >
> >
> > void deallocate(pointer p, size_type n)
> > {
> > mem_.deallocate(p, n);
> > }
> > void deallocate(void *p, size_type n)
> > {
> > mem_.deallocate(p, n);
> > }
> > void deallocate(pointer p)
> > {
> > mem_.deallocate(p);
> > }
> > void deallocate(void *p)
> > {
> > mem_.deallocate(p);
> > }
> >
> > static void dump(){
> > mem_.dump();
> > }
> >
> > private:
> >
> > static pool mem_;
> > };
> >
> > //template <class T> pool pool_allocator<T>::mem_;
> >
> > template <class T, class U>
> > inline bool operator==(const pool_allocator<T>&, const
> > pool_allocator<U>){return true;}
> >
> > template <class T, class U>
> > inline bool operator!=(const pool_allocator<T>&, const
> > pool_allocator<U>){return false;}
> >
> > I do a simple thing like : map<int, float, less<int>,
> > pool_allocator<pair<int, float> > > m;
> > I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
> > ). But unfortunately, I am facing following errors :
> >
> > Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > typedef T& reference;
> > ^^^^^^^^^
> > Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > typedef const T& const_reference;
> > ^^^^^^^^^^^^^^^
> > Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > pointer address (T& x)
> > ^^^^^^^
> > Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > pointer address (T& x)
> > ^^^^^^^
> > Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > allocator_interface<Allocator,T>::construct(pointe r p, const T&
> > val)
> > ^^^^^^^^^
> > Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
> > required for specialization instead of 'void' since the template
> > creates a reference to that type.
> > allocator_interface<Allocator,T>::construct(pointe r p, const T&
> > val)
> >
> >
> > I am not very good at this ... any reasons why this could be happening
> > ?
> >

>
> You need to create a specialised void allocator. Since you cannot allocate
> void objects this allocator is very simple.
>
> template <>
> class pool_allocator<void>
> {
> public:
> typedef size_t size_type;
> typedef ptrdiff_t difference_type;
> typedef void* pointer;
> typedef const void* const_pointer;
>
> template <class U>
> struct rebind { typedef pool_allocator<U> other; };
>
> };
>
> Something like that anyway. The particular error you were getting were
> because the compiler was trying to substitute void for T in your
> unspecialised template and coming up with code like this
>
> typedef void& reference;
>
> which is illegal because you cannot have a void reference.
>
> john
>
>



 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      09-24-2004

"Rohit Mattoo" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> My allocator looks like this now :
>
>
>
> template <class T> class pool_allocator;
> template <>
> class pool_allocator<void>
> {
> public:
> typedef size_t size_type;
> typedef ptrdiff_t difference_type;
> typedef void* pointer;
> typedef const void* const_pointer;
> template <class U>
> struct rebind { typedef pool_allocator<U> other; };
>
> };
>
> template <class T>
> class pool_allocator
> {
> public:
> typedef size_t size_type;
> typedef ptrdiff_t difference_type;
> ....
>
> but unfortunately the error havent stopped.
>
> Thanks and regards,
> ~mar00ned
>
>


I think you should put your specialised template after your generic one, not
before.

john


 
Reply With Quote
 
Rohit Mattoo
Guest
Posts: n/a
 
      09-24-2004
Unfortunately this hasnt worked either :

#ifndef POOL_ALLOCATOR_H_INCLUDED_GF
#define POOL_ALLOCATOR_H_INCLUDED_GF

#include <map>
#include "pool.h"


template <typename T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template <typename U>
struct rebind { typedef pool_allocator<U> other; };

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <typename U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}


size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
{
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}


void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <typename U>
struct rebind { typedef pool_allocator<U> other; };
pool_allocator() {}
~pool_allocator() {}
};



template <typename T> pool pool_allocator<T>::mem_;

template <typename T, typename U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <typename T, typename U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

template<typename Key, typename Value, class Traits = less<Key> >
struct PooledMap
{
typedef map<Key, Value, Traits,pool_allocator<pair<Key, Value> > > Type;
};
#endif






"John Harrison" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> "Rohit Mattoo" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > My allocator looks like this now :
> >
> >
> >
> > template <class T> class pool_allocator;
> > template <>
> > class pool_allocator<void>
> > {
> > public:
> > typedef size_t size_type;
> > typedef ptrdiff_t difference_type;
> > typedef void* pointer;
> > typedef const void* const_pointer;
> > template <class U>
> > struct rebind { typedef pool_allocator<U> other; };
> >
> > };
> >
> > template <class T>
> > class pool_allocator
> > {
> > public:
> > typedef size_t size_type;
> > typedef ptrdiff_t difference_type;
> > ....
> >
> > but unfortunately the error havent stopped.
> >
> > Thanks and regards,
> > ~mar00ned
> >
> >

>
> I think you should put your specialised template after your generic one,

not
> before.
>
> john
>
>



 
Reply With Quote
 
Tom Widmer
Guest
Posts: n/a
 
      09-24-2004
On Fri, 24 Sep 2004 14:06:41 +0100, "Rohit Mattoo" <(E-Mail Removed)>
wrote:

>template<typename Key, typename Value, class Traits = less<Key> >
>struct PooledMap
>{
> typedef map<Key, Value, Traits,pool_allocator<pair<Key, Value> > > Type;


That should be:
typedef map<Key, Value,
Traits, pool_allocator<pair<const Key, Value> > > Type;

What's the error you're getting now?

Tom
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      09-24-2004

"Rohit Mattoo" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Unfortunately this hasnt worked either :
>


I took this code (I had to fake the pool object) and it compiled fine. The
only change I had to make from your code was to remove the void* and char*
versions of destroy (I don't know why you put them there).

Maybe you have a problem with your compiler, your error messages indicate
that it is ignoring the void specialised version of pool_allocator.


#include <map>

class pool
{
public:
void* allocate(std::size_t);
void deallocate(void*, std::size_t);
};

template <typename T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template <typename U>
struct rebind { typedef pool_allocator<U> other; };

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <typename U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}


size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
{
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}


void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <typename U>
struct rebind { typedef pool_allocator<U> other; };
pool_allocator() {}
~pool_allocator() {}
};



template <typename T> pool pool_allocator<T>::mem_;

template <typename T, typename U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <typename T, typename U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

std::map<int, float, std::less<int>, pool_allocator<std:air<int, float> >
> m;



int main()
{
m[2] = 3.0;
}


John


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
a few stl container questions: allocators and comparers. sheam C++ 7 06-12-2008 10:06 AM
Containers & Allocators Ares Lagae C++ 6 02-21-2005 11:46 AM
operator= in allocators Mark A. Gibbs C++ 9 04-04-2004 02:54 PM
Re: allocators...exceptions...new/delete Richard Smith C++ 20 07-21-2003 05:38 AM
Re: allocators...exceptions...new/delete Ross Ridge C++ 2 07-07-2003 08:07 AM



Advertisments