Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Help with STL allocators
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(pointer 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(pointer p, const T&
val)


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

~mar00ned

Report this thread to moderator Post Follow-up to this message
Old Post
mar00ned
09-24-04 01:58 PM


Re: Help with STL allocators
"mar00ned" <rohit.mattoo@gmail.com> wrote in message
news:84a5039d.0409240036.55935e31@posting.google.com...
> 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(pointer 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(pointer 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



Report this thread to moderator Post Follow-up to this message
Old Post
John Harrison
09-24-04 01:58 PM


Re: Help with STL allocators
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" <john_andronicus@hotmail.com> wrote in message
news:2ri5tfF1aqki7U1@uni-berlin.de...
>
> "mar00ned" <rohit.mattoo@gmail.com> wrote in message
> news:84a5039d.0409240036.55935e31@posting.google.com... 
>
> 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
>
>



Report this thread to moderator Post Follow-up to this message
Old Post
Rohit Mattoo
09-24-04 01:58 PM


Re: Help with STL allocators
"Rohit Mattoo" <jimmee@gmail.com> wrote in message
news:1096027158.981849@cswreg.cos.agilent.com...
> 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



Report this thread to moderator Post Follow-up to this message
Old Post
John Harrison
09-24-04 01:58 PM


Re: Help with STL allocators
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" <john_andronicus@hotmail.com> wrote in message
news:2rihirF1b41dkU1@uni-berlin.de...
>
> "Rohit Mattoo" <jimmee@gmail.com> wrote in message
> news:1096027158.981849@cswreg.cos.agilent.com... 
>
> I think you should put your specialised template after your generic one,
not
> before.
>
> john
>
>



Report this thread to moderator Post Follow-up to this message
Old Post
Rohit Mattoo
09-24-04 09:01 PM


Re: Help with STL allocators
On Fri, 24 Sep 2004 14:06:41 +0100, "Rohit Mattoo" <jimmee@gmail.com>
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

Report this thread to moderator Post Follow-up to this message
Old Post
Tom Widmer
09-24-04 09:01 PM


Re: Help with STL allocators
"Rohit Mattoo" <jimmee@gmail.com> wrote in message
news:1096031203.630822@cswreg.cos.agilent.com...
> 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::pair<int, float> >
> m;


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


John



Report this thread to moderator Post Follow-up to this message
Old Post
John Harrison
09-24-04 09:01 PM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

C++ archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 02:57 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.