?? stl_deque.c
字號:
/*
*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Copyright (c) 1997
* Moscow Center for SPARC Technology
*
* Copyright (c) 1999
* Boris Fomitchev
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#ifndef __STL_DEQUE_C
#define __STL_DEQUE_C
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#pragma set woff 1375
#endif
# undef deque
# if defined ( __STL_NO_DEFAULT_NON_TYPE_PARAM )
# define deque __deque
# else
# define deque __WORKAROUND_RENAME(deque)
# endif
__STL_BEGIN_NAMESPACE
# ifdef __STL_DEBUG
// this hack is horrible, but, given no Alloc parameter
// for _Deque_iterator, we are not able to restore full deque structure anyways
template <class _Tp>
struct _Deq_iter_guts : public __owned_link {
_Tp* _M_cur;
_Tp* _M_first;
_Tp* _M_last;
_Tp** _M_node;
bool _M_unsafe;
};
// We do not send __ptr as _Tp*, as only void* is guaranteed to hold any pointer
template <class _Tp>
bool __Deq_dereferenceable(const void* __ptr, _Tp*) {
typedef _Deq_iter_guts<_Tp> _Guts;
const _Guts * __guts = (const _Guts*)(void*)__ptr;
__stl_verbose_return(__guts->_Valid(), _StlMsg_INVALID_ITERATOR);
if (__guts->_M_unsafe) return true;
const _Guts* __start = (const _Guts*)(__guts->_Owner()->_Owner());
const _Guts* __finish = __start+1;
__stl_verbose_return(
((__guts->_M_node == __finish->_M_node) ? /* *__guts < *__finish */
(__guts->_M_cur < __finish->_M_cur) : (__guts->_M_node < __finish->_M_node)) &&
!((__guts->_M_node == __start->_M_node) ? /* ! (*__guts < *__start) */
(__guts->_M_cur < __start->_M_cur) : (__guts->_M_node < __start->_M_node)),
_StlMsg_NOT_DEREFERENCEABLE);
return true;
}
template <class _Tp>
bool __Deq_nonsingular(const void* __ptr, _Tp*) {
typedef _Deq_iter_guts<_Tp> _Guts;
const _Guts * __guts = (const _Guts*)(void*)__ptr;
__stl_verbose_return(__guts->_Valid(), _StlMsg_INVALID_ITERATOR);
if (__guts->_M_unsafe) return true;
const _Guts* __start = (const _Guts*)(__guts->_Owner()->_Owner());
const _Guts* __finish = __start+1;
__stl_verbose_return(
!(((__guts->_M_node == __finish->_M_node) ? /* *__guts > *__finish */
(__guts->_M_cur > __finish->_M_cur) : (__guts->_M_node > __finish->_M_node)) ||
((__guts->_M_node == __start->_M_node) ? /* (*__guts < *__start) */
(__guts->_M_cur < __start->_M_cur) : (__guts->_M_node < __start->_M_node))),
_StlMsg_SINGULAR_ITERATOR);
return true;
}
# endif
// Non-inline member functions from _Deque_base.
template <class _Tp, class _Alloc, size_t __bufsiz>
_Deque_base<_Tp,_Alloc,__bufsiz>::~_Deque_base() {
if (_M_map._M_data) {
_M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
_M_map.deallocate(_M_map._M_data, _M_map_size._M_data);
}
// should be done here instead of ~deque to ensure
// no detach is ever possible
__stl_debug_do(_M_start._Invalidate());
__stl_debug_do(_M_finish._Invalidate());
}
template <class _Tp, class _Alloc, size_t __bufsiz>
void
_Deque_base<_Tp,_Alloc,__bufsiz>::_M_initialize_map(size_t __num_elements)
{
size_t __num_nodes =
__num_elements / __deque_buf_size(__bufsiz, sizeof(_Tp)) + 1;
_M_map_size._M_data = max((size_t) _S_initial_map_size, __num_nodes + 2);
_M_map._M_data = _M_map.allocate(_M_map_size._M_data);
_Tp** __nstart = _M_map._M_data + (_M_map_size._M_data - __num_nodes) / 2;
_Tp** __nfinish = __nstart + __num_nodes;
__STL_TRY {
_M_create_nodes(__nstart, __nfinish);
}
__STL_UNWIND((_M_map.deallocate(_M_map._M_data, _M_map_size._M_data),
_M_map._M_data = 0, _M_map_size._M_data = 0));
_M_start._M_set_node(__nstart);
_M_finish._M_set_node(__nfinish - 1);
_M_start._M_cur = _M_start._M_first;
_M_finish._M_cur = _M_finish._M_first +
__num_elements % __deque_buf_size(__bufsiz, sizeof(_Tp));
}
template <class _Tp, class _Alloc, size_t __bufsiz>
void
_Deque_base<_Tp,_Alloc,__bufsiz>::_M_create_nodes(_Tp** __nstart,
_Tp** __nfinish)
{
_Tp** __cur;
__STL_TRY {
for (__cur = __nstart; __cur < __nfinish; ++__cur)
*__cur = _M_map_size.allocate(__buf_traits::_buf_size);
}
__STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
}
template <class _Tp, class _Alloc, size_t __bufsiz>
void
_Deque_base<_Tp,_Alloc,__bufsiz>::_M_destroy_nodes(_Tp** __nstart,
_Tp** __nfinish)
{
for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
_M_map_size.deallocate(*__n, __buf_traits::_buf_size);
}
// Non-inline member functions
# if defined ( __STL_NESTED_TYPE_PARAM_BUG )
// qualified references
# define __iterator__ _Deque_iterator<_Tp, _Nonconst_traits<_Tp>, _Buf_size_traits<_Tp, __bufsiz> >
# define const_iterator _Deque_iterator<_Tp, _Const_traits<_Tp>, _Buf_size_traits<_Tp, __bufsiz> >
# define iterator __iterator__
# define size_type size_t
# define value_type _Tp
# else
# define __iterator__ __STL_TYPENAME_ON_RETURN_TYPE deque<_Tp, _Alloc, __bufsiz>::iterator
# endif
template <class _Tp, class _Alloc, size_t __bufsiz>
deque<_Tp, _Alloc, __bufsiz>&
deque<_Tp, _Alloc, __bufsiz>::operator= (const deque<_Tp, _Alloc, __bufsiz>& __x) {
const size_type __len = size();
if (&__x != this) {
if (__len >= __x.size())
erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
else {
const_iterator __mid = __x.begin() + difference_type(__len);
copy(__x.begin(), __mid, _M_start);
insert(_M_finish, __mid, __x.end());
}
}
__stl_debug_do(_Invalidate_all());
return *this;
}
template <class _Tp, class _Alloc, size_t __bufsiz>
void
deque<_Tp, _Alloc, __bufsiz>::_M_fill_insert(iterator __pos,
size_type __n, const value_type& __x)
{
__stl_debug_check(__check_if_owner(&_M_iter_list, __pos));
if (__pos._M_cur == _M_start._M_cur) {
iterator __new_start = _M_reserve_elements_at_front(__n);
__STL_TRY {
uninitialized_fill(__new_start, _M_start, __x);
}
__STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
_M_start = __new_start;
__stl_debug_do(_M_orphan_start());
}
else if (__pos._M_cur == _M_finish._M_cur) {
iterator __new_finish = _M_reserve_elements_at_back(__n);
__STL_TRY {
uninitialized_fill(_M_finish, __new_finish, __x);
}
__STL_UNWIND(_M_destroy_nodes(_M_finish._M_node+1, __new_finish._M_node+1));
_M_finish = __new_finish;
__stl_debug_do(_M_orphan_finish());
}
else
_M_insert_aux(__pos, __n, __x);
}
#ifndef __STL_MEMBER_TEMPLATES
template <class _Tp, class _Alloc, size_t __bufsiz>
void deque<_Tp, _Alloc, __bufsiz>::insert(iterator __pos,
const value_type* __first,
const value_type* __last) {
__stl_debug_check(__check_if_owner(&_M_iter_list, __pos));
size_type __n = __last - __first;
if (__pos._M_cur == _M_start._M_cur) {
iterator __new_start = _M_reserve_elements_at_front(__n);
__STL_TRY {
uninitialized_copy(__first, __last, __new_start);
}
__STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
_M_start = __new_start;
__stl_debug_do(_M_orphan_start());
}
else if (__pos._M_cur == _M_finish._M_cur) {
iterator __new_finish = _M_reserve_elements_at_back(__n);
__STL_TRY {
uninitialized_copy(__first, __last, _M_finish);
}
__STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
__new_finish._M_node + 1));
_M_finish = __new_finish;
__stl_debug_do(_M_orphan_finish());
}
else
_M_insert_aux(__pos, __first, __last, __n);
}
template <class _Tp, class _Alloc, size_t __bufsiz>
void deque<_Tp,_Alloc,__bufsiz>::insert(iterator __pos,
const_iterator __first,
const_iterator __last)
{
__stl_debug_check(__check_if_owner(&_M_iter_list, __pos));
size_type __n = __last - __first;
if (__pos._M_cur == _M_start._M_cur) {
iterator __new_start = _M_reserve_elements_at_front(__n);
__STL_TRY {
uninitialized_copy(__first, __last, __new_start);
}
__STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
_M_start = __new_start;
__stl_debug_do(_M_orphan_start());
}
else if (__pos._M_cur == _M_finish._M_cur) {
iterator __new_finish = _M_reserve_elements_at_back(__n);
__STL_TRY {
uninitialized_copy(__first, __last, _M_finish);
}
__STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,__new_finish._M_node + 1));
_M_finish = __new_finish;
__stl_debug_do(_M_orphan_finish());
}
else
_M_insert_aux(__pos, __first, __last, __n);
}
#endif /* __STL_MEMBER_TEMPLATES */
template <class _Tp, class _Alloc, size_t __bufsiz>
__iterator__
deque<_Tp,_Alloc,__bufsiz>::erase(iterator __first, iterator __last)
{
__stl_debug_check(__check_if_owner(&_M_iter_list, __first) && __check_range(__first,__last));
if (__first == _M_start && __last == _M_finish) {
clear();
return _M_finish;
}
else {
difference_type __n = __last - __first;
difference_type __elems_before = __first - _M_start;
if (__elems_before < difference_type(size() - __n) / 2) {
copy_backward(_M_start, __first, __last);
iterator __new_start = _M_start + __n;
destroy(_M_start, __new_start);
_M_destroy_nodes(__new_start._M_node, _M_start._M_node);
_M_start = __new_start;
__stl_debug_do(_M_orphan_start());
}
else {
copy(__last, _M_finish, __first);
iterator __new_finish = _M_finish - __n;
destroy(__new_finish, _M_finish);
_M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
_M_finish = __new_finish;
__stl_debug_do(_M_orphan_finish());
}
return _M_start + __elems_before;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -