473,385 Members | 1,347 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Question about C++ Allocatars

I have a quastion for the C++ professionals and members of the C++ standartization commetee.

As i know C++ standart requires an allocator to be a templated parameter in every STL container.
Besides that one can pass reference to allocatior into every STL container. This raises the following questions:
1. Containers that were templatized with different allocators are considered different types and thus cannot be assigned to each other. Should this be considered a drawback or a feature?
2. It is hard to implement pool/shared memory allocation logic since every instance of any STL container will has its own copy of an allocator.

I am not entirely sure whether the first one should be qualified as a drawback or as a feature. Suppose that instead of the way STL implements allocators currently, custom allocators would be inherited from a common base class and every container would have a pointer to that base class. In this case we could easily assign containers created with different allocators to each other. Hoever, I dont know whether we should consider allocators(or pointers to allocators) part of the container data. That is, if allocators were implemented as pointers to base class, would we copy them when one container is assigned to another? Probably not, since the allocation scheme is something given to container at the initialization time and changing that does not make much sense? If we dont consider allocators part of container data, then it is a drawback that in STL we cannot assign containers to each other if they were templatized with different allocators.

As far as the second item is concerned, if allocators were implemented as pointers to base class, it would be easier to share the complicated allocation schemes (such as pool or shared memory allocation) among containers.
Currently each container gets its own copy of alolocator.

Please i would like to hear you opinion regarding this matter (allocators as template parameters vs. allocators inherited from common base class, pointer to which containers can share).
Thanks in advance,

OM

Jul 22 '05 #1
19 1672
"regisser" <om******@hotmail.com> wrote in message
news:X_*****************@fe03.private.usenetserver .com...
I have a quastion for the C++ professionals and members of the C++ standartization commetee.

I'm not a member of the standards committee but I suppose I am a C++
professional.

As i know C++ standart requires an allocator to be a templated parameter in every STL container. Besides that one can pass reference to allocatior into every STL container. This raises the following questions: 1. Containers that were templatized with different allocators are considered different types and thus cannot be assigned to each other. Should
this be considered a drawback or a feature?

It is extremely easy to copy one STL container to another -- even a list to
a vector, for instance. If you like to see the = sign, you can write your
own operator = for two specific types. Hence this point doesn't seem like a
problem to me.
2. It is hard to implement pool/shared memory allocation logic since every

instance of any STL container will has its own copy of an allocator.

I don't know enough about writing allocators to comment on this.

[snip]
--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #2
OM
Writing separate function where you will iterate through entire
container to copy its elements one by one, as you suggested is extremely
slow. Try as an example to copy one vector into another using ==
operator or copy constructor and you will see that it works hundreds of
times faster then iterating throug elements to copy them. It IS
therefore an issue.

OM

Cy Edmunds wrote:
"regisser" <om******@hotmail.com> wrote in message
news:X_*****************@fe03.private.usenetserver .com...
I have a quastion for the C++ professionals and members of the C++


standartization commetee.

I'm not a member of the standards committee but I suppose I am a C++
professional.

As i know C++ standart requires an allocator to be a templated parameter


in every STL container.
Besides that one can pass reference to allocatior into every STL


container. This raises the following questions:
1. Containers that were templatized with different allocators are


considered different types and thus cannot be assigned to each other. Should
this be considered a drawback or a feature?

It is extremely easy to copy one STL container to another -- even a list to
a vector, for instance. If you like to see the = sign, you can write your
own operator = for two specific types. Hence this point doesn't seem like a
problem to me.

2. It is hard to implement pool/shared memory allocation logic since every


instance of any STL container will has its own copy of an allocator.

I don't know enough about writing allocators to comment on this.

[snip]

Jul 22 '05 #3
OM
error: using operator =

OM wrote:
Writing separate function where you will iterate through entire
container to copy its elements one by one, as you suggested is extremely
slow. Try as an example to copy one vector into another using ==
operator or copy constructor and you will see that it works hundreds of
times faster then iterating throug elements to copy them. It IS
therefore an issue.

OM

Cy Edmunds wrote:
"regisser" <om******@hotmail.com> wrote in message
news:X_*****************@fe03.private.usenetserver .com...
I have a quastion for the C++ professionals and members of the C++

standartization commetee.

I'm not a member of the standards committee but I suppose I am a C++
professional.

As i know C++ standart requires an allocator to be a templated parameter

in every STL container.
Besides that one can pass reference to allocatior into every STL

container. This raises the following questions:
1. Containers that were templatized with different allocators are

considered different types and thus cannot be assigned to each other.
Should
this be considered a drawback or a feature?

It is extremely easy to copy one STL container to another -- even a
list to
a vector, for instance. If you like to see the = sign, you can write your
own operator = for two specific types. Hence this point doesn't seem
like a
problem to me.

2. It is hard to implement pool/shared memory allocation logic since
every

instance of any STL container will has its own copy of an allocator.

I don't know enough about writing allocators to comment on this.

[snip]


Jul 22 '05 #4
"OM" <om******@hotmail.com> wrote in message
news:fR****************@fe14.private.usenetserver. com...
Writing separate function where you will iterate through entire
container to copy its elements one by one, as you suggested is extremely
slow. Try as an example to copy one vector into another using ==
operator or copy constructor and you will see that it works hundreds of
times faster then iterating throug elements to copy them. It IS
therefore an issue.


You have an implementation of the standard library which does something else
for operator = other than copy the elements one at a time? What does it do
instead?

My implementation copies the objects one at a time whether you use a copy
constructor or an assignment operator. I don't see how it could be
otherwise.

--
Cy
http://home.rochester.rr.com/cyhome/

[snip]
Jul 22 '05 #5
OM
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous). If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.

OM

Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:fR****************@fe14.private.usenetserver. com...
Writing separate function where you will iterate through entire
container to copy its elements one by one, as you suggested is extremely
slow. Try as an example to copy one vector into another using ==
operator or copy constructor and you will see that it works hundreds of
times faster then iterating throug elements to copy them. It IS
therefore an issue.

You have an implementation of the standard library which does something else
for operator = other than copy the elements one at a time? What does it do
instead?

My implementation copies the objects one at a time whether you use a copy
constructor or an assignment operator. I don't see how it could be
otherwise.

Jul 22 '05 #6
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserver. com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).
"Copy in blocks?" You mean like memcopy? That is only safe for POD types.
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.

[snip]

OK, please post the program you used to determine the speed differences you
claim. Or show the code of a std::vector implementation which does not copy
item for item in its assignment operator.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #7
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserver. com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).

"Copy in blocks?" You mean like memcopy? That is only safe for POD types.
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.


[snip]

OK, please post the program you used to determine the speed differences you
claim. Or show the code of a std::vector implementation which does not copy
item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container; it
doesn't even have to be instantiated. The container can get everything
it needs through the static methods of an allocator class. Would it
make sense to be able to assign a list to a vector? Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.

Jul 22 '05 #8
"Jeff Schwab" <je******@comcast.net> wrote in message
news:dZ********************@comcast.com...
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserver. com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).

"Copy in blocks?" You mean like memcopy? That is only safe for POD types. >
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.


[snip]

OK, please post the program you used to determine the speed differences you claim. Or show the code of a std::vector implementation which does not copy item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.


Hehe, somebody told me not long ago that my compiler was stupid. It doesn't
have any specializations for POD types further confirming this assessment.
:)

OK, getting back to the original point, if you're using POD data and your
library uses memmove to copy but your allocators are different you can't
take advantage of this optimization. It's not the kind of thing that keeps
me awake at night.

Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container; it
doesn't even have to be instantiated. The container can get everything
it needs through the static methods of an allocator class. Would it
make sense to be able to assign a list to a vector? Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.


Right -- assigning a list to a vector would be logically inconsistent, but
provisions have still been made to copy the elements from one to another
which gives you the same capability without the logical disconnect. And I
agree that the same reasoning should apply to containers which differ only
in template arguments.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #9
Cy Edmunds wrote:
"Jeff Schwab" <je******@comcast.net> wrote in message
news:dZ********************@comcast.com...
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserv er.com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).
"Copy in blocks?" You mean like memcopy? That is only safe for POD
types.
>

If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.
[snip]

OK, please post the program you used to determine the speed differences
you
claim. Or show the code of a std::vector implementation which does not
copy
item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

Hehe, somebody told me not long ago that my compiler was stupid. It doesn't
have any specializations for POD types further confirming this assessment.
:)

OK, getting back to the original point, if you're using POD data and your
library uses memmove to copy but your allocators are different you can't
take advantage of this optimization. It's not the kind of thing that keeps
me awake at night.


Nor should it. Assignment of vectors of non-POD elements wasn't
disallowed just because memmove couldn't be used. :)
Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container; it
doesn't even have to be instantiated. The container can get everything
it needs through the static methods of an allocator class. Would it
make sense to be able to assign a list to a vector? Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.

Right -- assigning a list to a vector would be logically inconsistent, but
provisions have still been made to copy the elements from one to another
which gives you the same capability without the logical disconnect. And I
agree that the same reasoning should apply to containers which differ only
in template arguments.


You can copy vectors in the same way.

#include <memory>
#include <vector>

namespace
{
template< typename T >
class Allocator: public std::allocator< T >
{

};

template< typename C1, typename C2 >
C1& assign( C1& c1, C2 const& c2 )
{
c1.clear( );
std::copy( c2.begin( ), c2.end( ),
std::back_inserter( c1 ) );
}
}

int main( )
{
std::vector< int, std::allocator< int > > v1( 3, '1' );
std::vector< int, Allocator< int > > v2( 5, '2' );

// v = w; // Won't compile.

assign( v1, v2 );
}

Jul 22 '05 #10
On Mon, 22 Dec 2003 21:36:17 -0800, "regisser" <om******@hotmail.com>
wrote:
I have a quastion for the C++ professionals and members of the C++ standartization commetee.

As i know C++ standart requires an allocator to be a templated parameter in every STL container.
Besides that one can pass reference to allocatior into every STL container. This raises the following questions:
1. Containers that were templatized with different allocators are considered different types and thus cannot be assigned to each other. Should this be considered a drawback or a feature?
I suppose it's not that important. You can always do:

vector<params> v2(v1.begin(), v1.end());
or
v2.assign(v1.begin(), v1.end());
2. It is hard to implement pool/shared memory allocation logic since every instance of any STL container will has its own copy of an allocator.
I don't quite understand this. It is quite simple to write a pool
allocator. You can use reference counting semantics if you want the
share a pool, or use a global pool that the the allocator has a
non-counted pointer to.

I am not entirely sure whether the first one should be qualified as a drawback or as a feature. Suppose that instead of the way STL implements allocators currently, custom allocators would be inherited from a common base class and every container would have a pointer to that base class. In this case we could easily assign containers created with different allocators to each other. Hoever, I dont know whether we should consider allocators(or pointers to allocators) part of the container data. That is, if allocators were implemented as pointers to base class, would we copy them when one container is assigned to another? Probably not, since the allocation scheme is something given to container at the initialization time and changing that does not make much sense? If we dont consider allocators part of container data, then it is a drawback that in STL we cannot assign containers to each other if they were templatized with different allocators.

As far as the second item is concerned, if allocators were implemented as pointers to base class, it would be easier to share the complicated allocation schemes (such as pool or shared memory allocation) among containers.
Currently each container gets its own copy of alolocator.

Please i would like to hear you opinion regarding this matter (allocators as template parameters vs. allocators inherited from common base class, pointer to which containers can share).


allocators can't be pointers, so I don't understand your use of
inheritence. Unless you mean reference semantics:

template <class T>
class myallocator
{
//myactualallocator not a template
shared_ptr<myactualallocator> m_actualallocator;
public:
//...

T* allocate(size_type n)
{
return m_actualallocator->allocate(n * sizeof(T));
}

//...
};

Now myactualallocator could of course be an abstract base class. I
don't think that's particularly useful though, although the above
scheme is useful to use a common allocator for all types.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #11
OM
Jeff Schwab <je******@comcast.net> wrote in message news:<dZ********************@comcast.com>...
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserver. com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).

"Copy in blocks?" You mean like memcopy? That is only safe for POD types.
>
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.


[snip]

OK, please post the program you used to determine the speed differences you
claim. Or show the code of a std::vector implementation which does not copy
item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container; it
doesn't even have to be instantiated. The container can get everything
it needs through the static methods of an allocator class. Would it
make sense to be able to assign a list to a vector? Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.


Not only the type of the allocator is part of the type of the
container, but also every STL container contains the allocator
INSTANCE, reference to which can be passed into constructor of any STL
container. Take a look at the standard or any STL implementation, and
you will see that allocator IS contained by any container. Not always
can the container get "everything it needs through the static methods
of an allocator class" because allocators are not always stateless.
Therefore, allocators were not implemented as traits with static
methods in STL. Sometimes an allocator should contain state and keep
for example a handle to pool from which memory is allocated. Such an
allocator is supposed to be shared between different instances of the
same container type.

OM
Jul 22 '05 #12
"Jeff Schwab" <je******@comcast.net> wrote in message
news:dZ********************@comcast.com...
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserver. com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).

"Copy in blocks?" You mean like memcopy? That is only safe for POD types. >
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.


[snip]

OK, please post the program you used to determine the speed differences you claim. Or show the code of a std::vector implementation which does not copy item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.


I suspect it still copies one element at a time.
Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container;
Yes it does.
it
doesn't even have to be instantiated.
Yes it does.
The container can get everything
it needs through the static methods of an allocator class.
Template class allocator has no static methods.
Would it
make sense to be able to assign a list to a vector?
On an element by element basis, yes.
Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.


Now that I agree with.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 22 '05 #13
"Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:xr*****************@twister.nyroc.rr.com...
OK, getting back to the original point, if you're using POD data and your
library uses memmove to copy but your allocators are different you can't
take advantage of this optimization. It's not the kind of thing that keeps
me awake at night.


Well, you can to copy an individual element, but probably not a block
of elements.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 22 '05 #14
OM wrote:
Jeff Schwab <je******@comcast.net> wrote in message news:<dZ********************@comcast.com>...
Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserv er.com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).
"Copy in blocks?" You mean like memcopy? That is only safe for POD types.

>

If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.
[snip]

OK, please post the program you used to determine the speed differences you
claim. Or show the code of a std::vector implementation which does not copy
item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container; it
doesn't even have to be instantiated. The container can get everything
it needs through the static methods of an allocator class. Would it
make sense to be able to assign a list to a vector? Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.

Not only the type of the allocator is part of the type of the
container, but also every STL container contains the allocator
INSTANCE, reference to which can be passed into constructor of any STL
container. Take a look at the standard or any STL implementation, and
you will see that allocator IS contained by any container. Not always
can the container get "everything it needs through the static methods
of an allocator class" because allocators are not always stateless.
Therefore, allocators were not implemented as traits with static
methods in STL. Sometimes an allocator should contain state and keep
for example a handle to pool from which memory is allocated. Such an
allocator is supposed to be shared between different instances of the
same container type.

OM


Thanks for pointing that out! I misused the word "static." I mean that
the resources of the standard allocators are shared between instances.

For the record, though, my vector implementation does *not* contain the
default allocator as a member. Here's how the vector gets an instance,
when one is needed:

allocator_type
get_allocator() const { return allocator_type(); }

A traits class is used to determine whether the containter
implementations must maintain their allocators as members:

// The fully general version.
template<typename _Tp, typename _Allocator>
struct _Alloc_traits
{
static const bool _S_instanceless = false;
typedef typename _Allocator::template rebind<_Tp>::other
allocator_type;
};

template<typename _Tp, typename _Allocator>
const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;

/// The version for the default allocator.
template<typename _Tp, typename _Tp1>
struct _Alloc_traits<_Tp, allocator<_Tp1> >
{
static const bool _S_instanceless = true;
typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
typedef allocator<_Tp> allocator_type;
};

...

/// Versions for the predefined "SGI" style allocators.

...
-Jeff

Jul 22 '05 #15
P.J. Plauger wrote:
"Jeff Schwab" <je******@comcast.net> wrote in message
news:dZ********************@comcast.com...

Cy Edmunds wrote:
"OM" <om******@hotmail.com> wrote in message
news:6a****************@fe09.private.usenetserv er.com...
It definately can be otherwise. Since the container known its internals
it can take advantage of that knowledge and for example instead of
copying elements one by one, copy them in blocks (as vector may very
well do since memory occupied by element is contugous).
"Copy in blocks?" You mean like memcopy? That is only safe for POD
types.
>
If you write a
free function outside of a container, you cannot take advantage of
container internals, and, therefore, all you can do is copy elements one
by one. In any case if try to assign one vector object to another you
will see how much faster it will be, compared to writing you own free
copy function.
[snip]

OK, please post the program you used to determine the speed differences
you
claim. Or show the code of a std::vector implementation which does not
copy
item for item in its assignment operator.


Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

I suspect it still copies one element at a time.


Nope. It uses this:

inline char*
uninitialized_copy(const char* __first,
const char* __last,
char* __result)
{
memmove(__result, __first, __last - __first);
return __result + (__last - __first);
}

Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container;


Yes it does.


You mean "yes it is?" The answer is that it may or may not be. Please
see my recent reply to OM.
doesn't even have to be instantiated.

Yes it does.


I stand corrected.
The container can get everything
it needs through the static methods of an allocator class.

Template class allocator has no static methods.


Do you mean to tell me that static methods are not allowed in
allocators? Why would that be?
Would it
make sense to be able to assign a list to a vector?


On an element by element basis, yes.


Right, the same way that it makes sense to copy vectors of two different
allocator types.

Well, it certainly
could have been part of the standard, but there are good reasons it's
not, all of which come down to the fact that a list and a vector are not
of the same type. Similarly, two containers that were instantiated
from the same template, but with different template arguments, are not
the same type.

Now that I agree with.


Whew! :)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


Jul 22 '05 #16
"Jeff Schwab" <je******@comcast.net> wrote in message
news:rq********************@comcast.com...
claim. Or show the code of a std::vector implementation which does not


copy
item for item in its assignment operator.
Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.

I suspect it still copies one element at a time.


Nope. It uses this:

inline char*
uninitialized_copy(const char* __first,
const char* __last,
char* __result)
{
memmove(__result, __first, __last - __first);
return __result + (__last - __first);
}


Well, yes. That's the specialization for uninitialized_copy
when you know you're copying arrays of char. The real
question is whether vector can determine if it's okay to
use it. I just spent a few minutes staring at stl/_vector.h,
which is the SGI STL code common to libstdc++, STLPort, and
several other libraries. If I read it correctly, then it
does indeed end up performing a single memmove call when
assigning an entire vector. But the chain of logic is not
all that easy to follow. (And unfortunately, the code also
seems to perform this optimization even for a vector with a
user-supplied allocator. That rules out all sorts of smart
allocators once touted as an advantage of having allocators
separate from containers. I suspect the C++ Standard allows
this simplification, but it encourages implementors to do
better. We do, and we still do the single memmove when it's
completely safe to do so.)
Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container;


Yes it does.


You mean "yes it is?" The answer is that it may or may not be. Please
see my recent reply to OM.


Sorry, the answer was far from clear. It is true that the type of
the allocator is part of the type of the container. An
implementation that supports only memoryless allocators (which
is permitted, though not encouraged, as I mentioned above)
can construct an allocator object every time it needs it, and
hence need not store a copy of the allocator within the container
object. Implicit in this simplification is the assumption that
such construction is weightless, or at least cheap, which may
or may not be true even for memoryless allocators.
doesn't even have to be instantiated.

Yes it does.


I stand corrected.
The container can get everything
it needs through the static methods of an allocator class.

Template class allocator has no static methods.


Do you mean to tell me that static methods are not allowed in
allocators? Why would that be?


I didn't say that. What I said was the prototypical allocator,
supplied in the library as template class allocator, has no
static methods. The entire user interface is in terms of calls
on non-static member functions. Hence, you have to create an
allocator object to do all the things that allocators do for
you. You're free to add static functions, but they're not part
of the defined interface. Any container you write that makes
use of them won't conform to the rules for extending STL
containers.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 22 '05 #17
On Mon, 22 Dec 2003 22:34:06 -0800, OM <om******@hotmail.com> wrote:
Writing separate function where you will iterate through entire
container to copy its elements one by one, as you suggested is extremely
slow. Try as an example to copy one vector into another using ==

^^
I have seen = used when == was meant, but until now, I had not
seen the reverse.

[snip]

Sincerely,

Gene Wirchenko

Jul 22 '05 #18
P.J. Plauger wrote:
"Jeff Schwab" <je******@comcast.net> wrote in message
news:rq********************@comcast.com...

>claim. Or show the code of a std::vector implementation which does not

copy
>item for item in its assignment operator.
>

Take a look at your headers. My library's vectors (g++/libstdc++) use
memmove for POD types.
I suspect it still copies one element at a time.
Nope. It uses this:

inline char*
uninitialized_copy(const char* __first,
const char* __last,
char* __result)
{
memmove(__result, __first, __last - __first);
return __result + (__last - __first);
}

Well, yes. That's the specialization for uninitialized_copy
when you know you're copying arrays of char. The real
question is whether vector can determine if it's okay to
use it. I just spent a few minutes staring at stl/_vector.h,
which is the SGI STL code common to libstdc++, STLPort, and
several other libraries. If I read it correctly, then it
does indeed end up performing a single memmove call when
assigning an entire vector. But the chain of logic is not
all that easy to follow.


Agreed. I am indeed using the SGI implementation, and it sometimes
drives me to curse the notation gods. I've started using the Sun
compiler more and more, just because the headers are so much nicer. Of
course, then not all the implementation code is available for browsing
at all...
(And unfortunately, the code also
seems to perform this optimization even for a vector with a
user-supplied allocator. That rules out all sorts of smart
allocators once touted as an advantage of having allocators
separate from containers. I suspect the C++ Standard allows
this simplification, but it encourages implementors to do
better. We do, and we still do the single memmove when it's
completely safe to do so.)
I've heard vague mentions of this sort of thing... Could you give me an
example of a "smart" allocator that's been ruled out? By "we," you mean
Dinkumware?
Anyway, the point is that the type of the allocator really is part of
the type of the container. It's not contained by the container;

Yes it does.


You mean "yes it is?" The answer is that it may or may not be. Please
see my recent reply to OM.

Sorry, the answer was far from clear. It is true that the type of
the allocator is part of the type of the container. An
implementation that supports only memoryless allocators (which
is permitted, though not encouraged, as I mentioned above)
can construct an allocator object every time it needs it, and
hence need not store a copy of the allocator within the container
object. Implicit in this simplification is the assumption that
such construction is weightless, or at least cheap, which may
or may not be true even for memoryless allocators.


The STL implementation lets you define an Alloc_traits class to tell
whether it's worth keeping a local (member) instance of the allocator.
The default is to keep the allocator as a member, so I think any
assumption like "construction is cheap" is not implicit, but based on
explicit advice from the implementor of the allocator.

doesn't even have to be instantiated.
Yes it does.


I stand corrected.

The container can get everything
it needs through the static methods of an allocator class.
Template class allocator has no static methods.


Do you mean to tell me that static methods are not allowed in
allocators? Why would that be?

I didn't say that. What I said was the prototypical allocator,
supplied in the library as template class allocator, has no
static methods. The entire user interface is in terms of calls
on non-static member functions. Hence, you have to create an
allocator object to do all the things that allocators do for
you. You're free to add static functions, but they're not part
of the defined interface. Any container you write that makes
use of them won't conform to the rules for extending STL
containers.


Now I see what you mean, and of course you're absolutely right. Thanks
for clarifying!

-Jeff

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


Jul 22 '05 #19
OM
"P.J. Plauger" <pj*@dinkumware.com> wrote in message news:<Bo******************@nwrddc02.gnilink.net>.. .
"Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:xr*****************@twister.nyroc.rr.com...
OK, getting back to the original point, if you're using POD data and your
library uses memmove to copy but your allocators are different you can't
take advantage of this optimization. It's not the kind of thing that keeps
me awake at night.


Well, you can to copy an individual element, but probably not a block
of elements.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


As i have just found out STLPort implementation of STL as well as STL
from some other vendors implement a copy algorithm in such a way that
they determine whether the type ypu are working with is POD and if it
is so, does memmove. Is not it great? Essentially this gives me the
ability efficiently copy containers of PODs even if they have
different types (created with different allocators).
lexographical_compare also uses memcmp if it finds that data is POD.

OM
Jul 22 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Stevey | last post by:
I have the following XML file... <?xml version="1.0"?> <animals> <animal> <name>Tiger</name> <questions> <question index="0">true</question> <question index="1">true</question> </questions>
7
by: nospam | last post by:
Ok, 3rd or is it the 4th time I have asked this question on Partial Types, so, since it seems to me that Partial Types is still in the design or development stages at Microsoft, I am going to ask...
3
by: Ekqvist Marko | last post by:
Hi, I have one Access database table including questions and answers. Now I need to give answer id automatically to questionID column. But I don't know how it is best (fastest) to do? table...
10
by: glenn | last post by:
I am use to programming in php and the way session and post vars are past from fields on one page through to the post page automatically where I can get to their values easily to write to a...
10
by: Rider | last post by:
Hi, simple(?) question about asp.net configuration.. I've installed ASP.NET 2.0 QuickStart Sample successfully. But, When I'm first start application the follow message shown. ========= Server...
53
by: Jeff | last post by:
In the function below, can size ever be 0 (zero)? char *clc_strdup(const char * CLC_RESTRICT s) { size_t size; char *p; clc_assert_not_null(clc_strdup, s); size = strlen(s) + 1;
56
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
2
by: Allan Ebdrup | last post by:
Hi, I'm trying to render a Matrix question in my ASP.Net 2.0 page, A matrix question is a question where you have several options that can all be rated according to several possible ratings (from...
3
by: Zhang Weiwu | last post by:
Hello! I wrote this: ..required-question p:after { content: "*"; } Corresponding HTML: <div class="required-question"><p>Question Text</p><input /></div> <div...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.