📄 yasli_vector.h
字号:
end_ = ebo_.beg_ + s;
eos_ = ebo_.beg_ + n;
assert(capacity() >= n);
assert(size() == s);
}
bool reserve_inplace_nstd(size_type n)
{
if (capacity() >= n) return true;
if (!yasli_nstd::allocator_traits<Allocator>::reallocate_inplace(
ebo_, ebo_.beg_, n))
{
return false;
}
eos_ = ebo_.beg_ + n;
return true;
}
// element access:
reference operator[](size_type n)
{
assert(n < size());
return ebo_.beg_[n];
}
const_reference operator[](size_type n) const
{
assert(n < size());
return ebo_.beg_[n];
}
const_reference at(size_type n) const
{
// Fix by Joseph Canedo
if (n >= size()) throw std::range_error("vector<>::at");
return ebo_.beg_[n];
}
reference at(size_type n)
{
// Fix by Joseph Canedo
if (n >= size()) throw std::range_error("vector<>::at");
return ebo_.beg_[n];
}
reference front()
{
assert(!empty());
return *ebo_.beg_;
}
const_reference front() const
{
assert(!empty());
return *ebo_.beg_;
}
reference back()
{
assert(!empty());
return end_[-1];
}
const_reference back() const
{
assert(!empty());
return end_[-1];
}
private:
void prepare_growth(size_type delta)
{
const size_type s = size();
// @@@ todo: replace magic constant with something meaningful
const size_type smallThreshold = 8;
if (s < smallThreshold)
{
reserve(std::max(smallThreshold, delta));
}
else
{
const size_type multiply = 3;
const size_type divide = 2;
const size_type suggestedSize = (s * multiply) / divide;
reserve(std::max(s + delta, suggestedSize));
}
}
public:
// 23.2.4.3 modifiers:
void push_back(const T& x)
{
if (size() == capacity())
{
prepare_growth(1);
}
new(end_) T(x);
++end_;
}
void pop_back()
{
assert(!empty());
ebo_.destroy(--end_);
}
void move_back_nstd(T& x)
{
if (size() == capacity())
{
prepare_growth(1);
}
yasli_protocols::move_traits<T>::nondestructive_move(&x, &x + 1, end_);
}
// 23.2.4.3 modifiers:
iterator insert(iterator position, const T& x)
{
// @@@ be smarter about this reservation
reserve(size() + 1);
const size_type pos = position - begin();
insert(position, (size_type)1, x);
return ebo_.beg_ + pos;
}
void insert(iterator position, size_type n, const T& x)
{
insert(position,
yasli_nstd::fill_iterator<const T&>(x),
yasli_nstd::fill_iterator<const T&>(x, n)
);
}
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last)
{
insert_pre_impl(position, first, last,
Loki::Int2Type<yasli_nstd::is_class<InputIterator>::value||
yasli_nstd::is_pointer<InputIterator>::value>());
}
private:
template<class InputIterator, class looks_like_iterator>
void
insert_pre_impl(iterator position, InputIterator first, InputIterator last,
looks_like_iterator)
{
insert_impl(position, first, last,
typename std::iterator_traits<InputIterator>::iterator_category());
}
template <class non_iterator>
void insert_pre_impl(iterator position, non_iterator n, non_iterator x,
Loki::Int2Type<false>)
{ //used if e.g. T is int and insert(itr, 10, 6) is called
insert(position, static_cast<size_type>(n),
static_cast<value_type>(x));
}
template <class InputIterator>
void insert_impl(iterator position,
InputIterator first, InputIterator last, std::input_iterator_tag)
{
for (; first != last; ++first)
{
position = insert(position, *first) + 1;
}
}
template <class FwdIterator>
void insert_impl(iterator position,
FwdIterator first, FwdIterator last, std::forward_iterator_tag)
{
typedef yasli_protocols::move_traits<T> mt;
const typename std::iterator_traits<FwdIterator>::difference_type
count = std::distance(first, last);
if (eos_ - end_ > count || reserve_inplace_nstd(size() + count)) // there's enough room
{
if (count > end_ - &*position)
{
// Step 1: fill the hole between end_ and position+count
FwdIterator i1 = first;
std::advance(i1, end_ - &*position);
FwdIterator i2 = i1;
std::advance(i2, &*position + count - end_);//why not i2 = first; advance(i2,count);
T* const oldEnd = end_;
end_ = copy(i1, i2, end_);
assert(end_ == &*position + count);
// Step 2: move existing data to the end
mt::nondestructive_move(
position,
oldEnd,
end_);
end_ = oldEnd + count;
// Step 3: copy in the remaining data
copy(first, i1, position);
}
else // simpler case
{
mt::nondestructive_move(
end_ - count,
end_,
end_);
end_ += count;
mt::nondestructive_assign_move(
position,
end_ - count,
position + count);
copy(first, last, position);
}
}
else
{
vector<T, Allocator> temp(ebo_);
temp.reserve(size() + count);
// The calls below won't cause infinite recursion
// because they will fall on the other branch
// of the if statement
temp.insert(temp.end(), begin(), position);
temp.insert(temp.end(), first, last);
temp.insert(temp.end(), position, end());
assert(temp.size() == size() + count);
temp.swap(*this);
}
}
public:
iterator erase(iterator position)
{
erase(position, position + 1);
return position;
}
iterator erase(iterator first, iterator last)
{
yasli_protocols::move_traits<T>::nondestructive_assign_move(
last, end(), first);
Allocator& a = ebo_;
const size_type destroyed = last - first;
yasli_nstd::destroy(a, end_ - destroyed, destroyed);
end_ -= destroyed;
return first;
}
void swap(vector<T,Allocator>& rhs)//COULD DO THIS WITH LESS TEMPORARIES
{
std::swap(static_cast<Allocator&>(ebo_), static_cast<Allocator&>(rhs.ebo_));
std::swap(ebo_.beg_, rhs.ebo_.beg_);
std::swap(end_, rhs.end_);
std::swap(eos_, rhs.eos_);
}
void clear()
{
Allocator& a = ebo_;
yasli_nstd::destroy(a, ebo_.beg_, size());
end_ = ebo_.beg_;
}
};//vector
template <class T, class Allocator>
bool operator==(const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
template <class T, class Allocator>
bool operator< (const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
template <class T, class Allocator>
bool operator!=(const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
template <class T, class Allocator>
bool operator> (const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
template <class T, class Allocator>
bool operator>=(const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
template <class T, class Allocator>
bool operator<=(const vector<T,Allocator>& x,
const vector<T,Allocator>& y);
// specialized algorithms:
template <class T, class Allocator>
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y);
}//yasli
namespace yasli_protocols
{
template <class T, class A>
struct move_traits< yasli::vector<T, A> >:public
yasli_nstd::type_selector<
sizeof(yasli::vector<T, A>) != (3 * sizeof(T*)),
memmove_traits< std::complex<T> >,
safe_move_traits< std::complex<T> >
>::result
{
};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -