473,803 Members | 2,946 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

std::vector::_M _insert_aux() code

template<typena me _Tp, typename _Alloc>
void
vector<_Tp, _Alloc>::
_M_insert_aux(i terator __position, const _Tp& __x)
{
if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
{
this->_M_impl.constr uct(this->_M_impl._M_fin ish,
*(this->_M_impl._M_fin ish - 1));
++this->_M_impl._M_fin ish;
_Tp __x_copy = __x;
std::copy_backw ard(__position,
iterator(this->_M_impl._M_fin ish-2),
iterator(this->_M_impl._M_fin ish-1));
*__position = __x_copy;
}
else ...

I had a couple of doubts with regard to code pasted here from
stl_vector.h
a) I was curious why a copy of x is created in the statement:
_Tp __x_copy = __x;
and that is assigned to *position, rather than directly doing
*position = __x ;

b) is it necessary to increment finish ++this->_M_impl._M_fin ish
before the copy_backward.
operation, is there anything wrong in doing the copy backwards first
like this

std::copy_backw ard(__position,
iterator(this->_M_impl._M_fin ish-1),
iterator(this->_M_impl._M_fin ish));
and then
++this->_M_impl._M_fin ish;

Thx
Digz

Apr 8 '07 #1
7 5716
digz wrote:
:: template<typena me _Tp, typename _Alloc>
:: void
:: vector<_Tp, _Alloc>::
:: _M_insert_aux(i terator __position, const _Tp& __x)
:: {
:: if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
:: {
:: this->_M_impl.constr uct(this->_M_impl._M_fin ish,
:: *(this->_M_impl._M_fin ish - 1));
:: ++this->_M_impl._M_fin ish;
:: _Tp __x_copy = __x;
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-2),
:: iterator(this->_M_impl._M_fin ish-1));
:: *__position = __x_copy;
:: }
:: else ...
::
:: I had a couple of doubts with regard to code pasted here from
:: stl_vector.h
:: a) I was curious why a copy of x is created in the statement:
:: _Tp __x_copy = __x;
:: and that is assigned to *position, rather than directly doing
:: *position = __x ;

It could be that __x is a reference to an element already in the vector. In
that case you have to save the value, before doing the copy_backward() .

It must handle code like:

v.insert(v.begi n(), v[5]);

::
:: b) is it necessary to increment finish ++this->_M_impl._M_fin ish
:: before the copy_backward.
:: operation, is there anything wrong in doing the copy backwards first
:: like this
::
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-1),
:: iterator(this->_M_impl._M_fin ish));
:: and then
:: ++this->_M_impl._M_fin ish;
::

Yes. The increment is connected to the construction of a new object:

this->_M_impl.constr uct(this->_M_impl._M_fin ish,
*(this->_M_impl._M_fin ish - 1));
++this->_M_impl._M_fin ish;

This adds a new object to the vector, so it must also add 1 to the size of
the vector (by incrementing the end pointer).

If it didn't, and something bad happened in copy_backward, the newly created
object could be left created but never destroyed.
Bo Persson
Apr 8 '07 #2
On 2007-04-08 02:07, digz wrote:
template<typena me _Tp, typename _Alloc>
void
vector<_Tp, _Alloc>::
_M_insert_aux(i terator __position, const _Tp& __x)
{
if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
{
this->_M_impl.constr uct(this->_M_impl._M_fin ish,
*(this->_M_impl._M_fin ish - 1));
++this->_M_impl._M_fin ish;
_Tp __x_copy = __x;
std::copy_backw ard(__position,
iterator(this->_M_impl._M_fin ish-2),
iterator(this->_M_impl._M_fin ish-1));
*__position = __x_copy;
}
else ...

I had a couple of doubts with regard to code pasted here from
stl_vector.h
a) I was curious why a copy of x is created in the statement:
_Tp __x_copy = __x;
and that is assigned to *position, rather than directly doing
*position = __x ;
A copy have to be made before copy_backwards( ) is called in case the
copy-constructor would throw an exception or we would be left with a
inconsistent vector.

--
Erik Wikström
Apr 8 '07 #3
In article <57************ *@mid.individua l.net>,
"Bo Persson" <bo*@gmb.dkwrot e:
digz wrote:
:: template<typena me _Tp, typename _Alloc>
:: void
:: vector<_Tp, _Alloc>::
:: _M_insert_aux(i terator __position, const _Tp& __x)
:: {
:: if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
:: {
:: this->_M_impl.constr uct(this->_M_impl._M_fin ish,
:: *(this->_M_impl._M_fin ish - 1));
:: ++this->_M_impl._M_fin ish;
:: _Tp __x_copy = __x;
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-2),
:: iterator(this->_M_impl._M_fin ish-1));
:: *__position = __x_copy;
:: }
:: else ...
::
:: I had a couple of doubts with regard to code pasted here from
:: stl_vector.h
:: a) I was curious why a copy of x is created in the statement:
:: _Tp __x_copy = __x;
:: and that is assigned to *position, rather than directly doing
:: *position = __x ;

It could be that __x is a reference to an element already in the vector. In
that case you have to save the value, before doing the copy_backward() .

It must handle code like:

v.insert(v.begi n(), v[5]);
Yes. But this is a poor (imho) implementation of how to handle that
problem. The copy constructor of _Tp may be arbitrarily expensive and
you want to try and minimize calls to a function of unknown expense.

It is cheap and easy to detect whether __x is self referencing or not.
And if it self referencing, it is also cheap and easy to compute its new
location after shuffling things around.

-Howard
Apr 8 '07 #4
On Apr 8, 12:17 pm, Howard Hinnant <howard.hinn... @gmail.comwrote :
In article <57rsrkF2d4fn.. .@mid.individua l.net>,
"Bo Persson" <b...@gmb.dkwro te:
digz wrote:
:: template<typena me _Tp, typename _Alloc>
:: void
:: vector<_Tp, _Alloc>::
:: _M_insert_aux(i terator __position, const _Tp& __x)
:: {
:: if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
:: {
:: this->_M_impl.constr uct(this->_M_impl._M_fin ish,
:: *(this->_M_impl._M_fin ish - 1));
:: ++this->_M_impl._M_fin ish;
:: _Tp __x_copy = __x;
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-2),
:: iterator(this->_M_impl._M_fin ish-1));
:: *__position = __x_copy;
:: }
:: else ...
::
:: I had a couple of doubts with regard to code pasted here from
:: stl_vector.h
:: a) I was curious why a copy of x is created in the statement:
:: _Tp __x_copy = __x;
:: and that is assigned to *position, rather than directly doing
:: *position = __x ;
It could be that __x is a reference to an element already in the vector. In
that case you have to save the value, before doing the copy_backward() .
It must handle code like:
v.insert(v.begi n(), v[5]);

Yes. But this is a poor (imho) implementation of how to handle that
problem. The copy constructor of _Tp may be arbitrarily expensive and
you want to try and minimize calls to a function of unknown expense.

It is cheap and easy to detect whether __x is self referencing or not.
And if it self referencing, it is also cheap and easy to compute its new
location after shuffling things around.

-Howard
But I copied this block of code from STL shipped with Suse-
Linux-10.0 ,
Are you saying that the std::vector code is not optimal enough.What
could be a better/cheaper implementation
for the problem the block of code above is trying to address ??

--Digz

Apr 11 '07 #5
In article <11************ **********@e65g 2000hsc.googleg roups.com>,
"digz" <Di********@gma il.comwrote:
On Apr 8, 12:17 pm, Howard Hinnant <howard.hinn... @gmail.comwrote :
In article <57rsrkF2d4fn.. .@mid.individua l.net>,
"Bo Persson" <b...@gmb.dkwro te:
digz wrote:
:: template<typena me _Tp, typename _Alloc>
:: void
:: vector<_Tp, _Alloc>::
:: _M_insert_aux(i terator __position, const _Tp& __x)
:: {
:: if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
:: {
:: this->_M_impl.constr uct(this->_M_impl._M_fin ish,
:: *(this->_M_impl._M_fin ish - 1));
:: ++this->_M_impl._M_fin ish;
:: _Tp __x_copy = __x;
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-2),
:: iterator(this->_M_impl._M_fin ish-1));
:: *__position = __x_copy;
:: }
:: else ...
::
:: I had a couple of doubts with regard to code pasted here from
:: stl_vector.h
:: a) I was curious why a copy of x is created in the statement:
:: _Tp __x_copy = __x;
:: and that is assigned to *position, rather than directly doing
:: *position = __x ;
It could be that __x is a reference to an element already in the vector.
In
that case you have to save the value, before doing the copy_backward() .
It must handle code like:
v.insert(v.begi n(), v[5]);
Yes. But this is a poor (imho) implementation of how to handle that
problem. The copy constructor of _Tp may be arbitrarily expensive and
you want to try and minimize calls to a function of unknown expense.

It is cheap and easy to detect whether __x is self referencing or not.
And if it self referencing, it is also cheap and easy to compute its new
location after shuffling things around.

-Howard

But I copied this block of code from STL shipped with Suse-
Linux-10.0 ,
Are you saying that the std::vector code is not optimal enough.
I'm saying *this* implementation of std::vector is not optimal. I've
seen better (I've written better).
What
could be a better/cheaper implementation
for the problem the block of code above is trying to address ??
It would be better to detect the self reference by comparing the address
of __x with the address of the insertion point and the address of the
end of the buffer. If the address of __x lies within that range, it is
self referencing. And in this case, the address of __x is going to
change during the reshuffling to make room for the new copy of __x.
Computing the final address of __x after the reshuffle is trivial: it
is going to move in the buffer by one position.

-Howard
Apr 11 '07 #6
On Apr 11, 9:11 am, Howard Hinnant <howard.hinn... @gmail.comwrote :
In article <1176292518.653 052.110...@e65g 2000hsc.googleg roups.com>,

"digz" <Digvijo...@gma il.comwrote:
On Apr 8, 12:17 pm, Howard Hinnant <howard.hinn... @gmail.comwrote :
In article <57rsrkF2d4fn.. .@mid.individua l.net>,
"Bo Persson" <b...@gmb.dkwro te:
digz wrote:
:: template<typena me _Tp, typename _Alloc>
:: void
:: vector<_Tp, _Alloc>::
:: _M_insert_aux(i terator __position, const _Tp& __x)
:: {
:: if (this->_M_impl._M_fin ish != this->_M_impl._M_end _of_storage)
:: {
:: this->_M_impl.constr uct(this->_M_impl._M_fin ish,
:: *(this->_M_impl._M_fin ish - 1));
:: ++this->_M_impl._M_fin ish;
:: _Tp __x_copy = __x;
:: std::copy_backw ard(__position,
:: iterator(this->_M_impl._M_fin ish-2),
:: iterator(this->_M_impl._M_fin ish-1));
:: *__position = __x_copy;
:: }
:: else ...
::
:: I had a couple of doubts with regard to code pasted here from
:: stl_vector.h
:: a) I was curious why a copy of x is created in the statement:
:: _Tp __x_copy = __x;
:: and that is assigned to *position, rather than directly doing
:: *position = __x ;
It could be that __x is a reference to an element already in the vector.
In
that case you have to save the value, before doing the copy_backward() .
It must handle code like:
v.insert(v.begi n(), v[5]);
Yes. But this is a poor (imho) implementation of how to handle that
problem. The copy constructor of _Tp may be arbitrarily expensive and
you want to try and minimize calls to a function of unknown expense.
It is cheap and easy to detect whether __x is self referencing or not.
And if it self referencing, it is also cheap and easy to compute its new
location after shuffling things around.
-Howard
But I copied this block of code from STL shipped with Suse-
Linux-10.0 ,
Are you saying that the std::vector code is not optimal enough.

I'm saying *this* implementation of std::vector is not optimal. I've
seen better (I've written better).
What
could be a better/cheaper implementation
for the problem the block of code above is trying to address ??

It would be better to detect the self reference by comparing the address
of __x with the address of the insertion point and the address of the
end of the buffer. If the address of __x lies within that range, it is
self referencing. And in this case, the address of __x is going to
change during the reshuffling to make room for the new copy of __x.
Computing the final address of __x after the reshuffle is trivial: it
is going to move in the buffer by one position.

-Howard
Thanks a lot for clarifying this.

This is libstdc++-3.3 , g++-4.0.1 on x86_64-pc-linux-gnu
Is gcc-help the right mailing list to follow up on opensource libstdc+
+ implementations ??
coz after your explanation I cannot imagine how g++ developers are
producing this code and shipping
it with RedHat, Debian, Suse..etc..all Linux Vendors have the same
STL, and on a bad day
a super slow copy constructor can make std::vector really suffer !!

--Digz

Apr 12 '07 #7
In article <11************ **********@q75g 2000hsh.googleg roups.com>,
"digz" <Di********@gma il.comwrote:
This is libstdc++-3.3 , g++-4.0.1 on x86_64-pc-linux-gnu
Is gcc-help the right mailing list to follow up on opensource libstdc+
+ implementations ??
coz after your explanation I cannot imagine how g++ developers are
producing this code and shipping
it with RedHat, Debian, Suse..etc..all Linux Vendors have the same
STL, and on a bad day
a super slow copy constructor can make std::vector really suffer !!
Sorry for the slow response. Yes, gcc-help or libstdc++ would be good
followup lists.

-Howard
Apr 24 '07 #8

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

Similar topics

27
5988
by: Jason Heyes | last post by:
To my understanding, std::vector does not use reference counting to avoid the overhead of copying and initialisation. Where can I get a reference counted implementation of std::vector? Thanks.
9
8898
by: aaragon | last post by:
I am trying to create a vector of type T and everything goes fine until I try to iterate over it. For some reason, the compiler gives me an error when I declare std::vector<T>::iterator iter; Any ideas why is tihs happening? The code is as follows: template <class T> struct StdVectorStorage { std::vector<T>* _storage;
6
3267
by: lokchan | last post by:
i want to create a vector of pointer s.t. it can handle new and delete but also have std::vector interface can i implement by partial specialization and inherence like follow ? #include <vector> #include <algorithm> template <typename T> struct delete_ptr {
3
2421
by: DevNull | last post by:
I have a program where we load a mapfile, comprised of a .csv with numbers which represent object types at a given position. Each position is in the map is called a Cell, a cell contains only a position struct with it's own x,y and an int called CellType which determines if the Cell is a solid i.e. a wall, or a nonsolid, i.e. empty space. Given... <code>
0
9703
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9566
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10317
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10300
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7607
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5503
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4277
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3802
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2974
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.