vector(modifiers/clear)

42_Cursus·2022년 5월 20일
0

STL_Containers

목록 보기
10/13

Modifiers

1. assign
2. push_back
3. pop_back
4. insert
5. erase
6. swap
7. clear

1. assign

1. vector의 모든요소를 삭제한 후에, 파라미터로 들어온
    iterator first,  last의 요소들을 복사.
2. vector의 모든요소를 삭제한 후에, val을 n개만큼 벡터에 복사.

1. Iterator

template<class Iterator>
void	assign(
			Iterator first,
            Iterator last,
            typename ft::enable_if<!ft::is_interal<Iterator>::value,
            Iterator>::type*=0)
{
	difference_type	n = 0;
    for (Iterator it(first); it != last; it++)
    	n++;
    this->clear();
    this->reserve(n);
    for (; first != last; first++)
    	push_back(*first);
 }
  	

2. size_type n, value_type val

void	assign(size_type n, const value_type &val)
{
	this->clear();
    this->reserve(n);
    for (size_type i = 0; i < n; i++)
    	push_back(val);
}

2. push_back

vector 끝에 요소를 추가
void	push_back(const value_type &val)
{
	if (_size == _capacity)
    	reallocate(extend(_size + 1);
    _alloc.construct(&_head[_size++], val);
}

size_type	extend(size_type new_size)
{
	size_type new_capacity(_capacity);
    if (!new_capacity)
    	new_capacity = 1;
    while (new_capacity < new_size)
    	new_capacity *= 2;
    return (new_capacity);
}

3. push_back

vector 끝에있는 요소를 삭제
void	pop_back(void)
{
	_alloc.destroy(&_head[--_size];
}

4. insert

1. vector의 position에 val을 삽입.
2. vector의 position에 val을 n개 만큼 삽입.
3. vector의 position에 Iterator first~last까지 삽입.

1. val

// 왜 offset을 만들까?  position이랑같은데
// 그건 reallocator를 호출하여,  여기서 begin()이 달라지기 
// 때문이다.
iterator insert(
			iterator position,
            const value_type	&val)
{
	difference_type	offset( position - this->begin() );
    if (_size == _capacity)
    	reallocator(extend(_size + 1);
    this->insert(this->begin() + offset), 1, val);
    return (iterator(this->begin() + offset);
}

2. n, val

void	insert(
			iterator position,
            size_type	n,
            const value_type 7val)
 {
 	if (n)
    {
    	difference_type offset = position - this->begin();
        // resize이후에, 시작점에서의 길이를 저장
        difference_type diffrence_type_tmp	= this->end() - this->begin();
        this->resize(this->_size + n);
        
        iterator end_iterator = this->end();
        // ...position.....0000000<- end_iterator
        position = this->begin() + offset;
        // ...position.....<- end
        iterator tmp_end_iterator = this->begin() + difference_type_tmp;
        while (tmp_end_iterator != position)
        {
        	--end_iterator;
            --tmp_end_iterator;
            *end_iterator = *tmp_end_iterator;
        }
        while (n--)
        	*position++ = val;
    }
 }

3.Iterator first, last

template<class Iter>
void	insert(
			Iter position,
            Iter first,
            Iter last,
            typename ft::enable_if<!ft::is_integral<Iter>::value, Iter>::type8=0)
{
	diffrence_type offset = position - this->begin();
    size_type	n(0);
    Iter tmp(first);
    // first ~ last사이의 갯수
    while (tmp != last)
    {
    	++tmp;
        ++n;
    }
    if ((_size + n) > _capacity)
    	reallocate((_size + n > _size * 2) ? _size + n: _size * 2)
    size_type destroyIndex = size;
    // 원래 vector 마지막에서, position까지 역방향으로 가는 iter
    Iter	itToInsertPos(&_head[_size]);
    _size += n;
    // vector에서 position자리 (reallocate했기때문에 다시 position을 잡아준다)
    Iter insertPos(this->begin() + offset);
    // itToInsertPos와 같이 역방향으로가는 iter.
    // 여기에 itToInsertPos의 역참조값을 대입함.
    Iter itForInsert = this->end();
    while (itToInsertPos >= insertPos)
    {
    	*--itForInsert = *--itToInserPos;
        _alloc.destroy(&_head[destroyIndex--]);
    }
    while (first != last)
    	_alloc.construct(&_head[&(*insertPos++), *first++);
}

4. erase

1. position
2. Iterator first, last

1. position

iterator erase(iterator position)
{
	return this->erase(position, position + 1);
}

2. Iterator first, last

iterator erase(iterator first, iterator last)
{
	if (this->empty())
    	return last;
    difference_type	n = last - first;
    iterator ret(first);
    while (last != this->end())
    	*(first++) = *(last++);
    while (n--)
    	this->pop_back();
    return (ret);

5. swap

template<class U>
void swap(U &a, U&b)
{
	U tmp = a;
    a = b;
    b = tmp;
}

//  임의 벡터를만들어서 대입생성자를사용하면, 새로 주소를받기때문에,
// 다르다.
// 대입 복사생성자는 쓰면안되다.
// 여기서의 swap은  _head의 주소도 완전히 가져오는것이다.
// 하지만 대입복사생성자는 deep copy가 아니기때문 (새롭게 allocate로 할당)
void	swap(vector &x)
{	
	swap(_size, x._size);
    swap(_capacity, x._capacity);
    swap(_alloc, x._alloc);
    swap(_head, x._head);
}

6. clear

void	clear()
{
	for (size_type i = 0; i < _size; i++)
    	this->pop_back();
    _size = 0;
}
profile
etudiant_42

0개의 댓글