#ifndef M_DEQUE_H #define M_DEQUE_H /*************************************** * Description:deque实现,使用场景,类似排队系统,队首和队尾不要频繁的删除和天剑 * Create:2019/12/7 * Author:zhangfeng * History: * 2019-12-7 搭建初步框架和基本接口 * * * *************************************/ #include <memory> #include <iostream> #include <algorithm> #include <cstddef> // Note: this function is simply a kludge to work around several compilers' // bugs in handling constant expressions. inline size_t deque_buf_size(size_t __size) { return __size < 512 ? size_t(512 / __size) : size_t(1); } //迭代器 template <class T, class Ref, class Ptr> struct Deque_iterator { typedef Deque_iterator<T, T&, T*> iterator; typedef Deque_iterator<T, const T&, const T*> const_iterator; static size_t _S_buffer_size() { return deque_buf_size(sizeof(T)); } typedef Deque_iterator _Self; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T** _Map_pointer; T* _cur; //缓冲区的现行 T* _first; //缓冲区的头 T* _last; //缓冲区的尾 _Map_pointer _node; //指向管控中心 Deque_iterator() : _cur(0), _first(0), _last(0), _node(0) {} reference operator*() const { return *_cur; } reference operator->() const { return *_cur; } difference_type operator-(const _Self& _x) const { return difference_type(_S_buffer_size()) * (_node - _x._node -1) + (_cur - _first) + (_last - _cur); } _Self& operator++() { ++_cur; if(_cur == _last) { set_node(_node + 1); _cur = _first; } return *this; } _Self operator++(int) { _Self _tmp = *this; ++*this; return _tmp; } _Self& operator--() { if(_cur == _first) { set_node(_node - 1); _cur = _last; } --_cur; return *this; } _Self operator--(int) { _Self _tmp = *this; --*this; return _tmp; } _Self& operator+=(difference_type _n) { difference_type _offset = _n + (_cur - _first); if(_offset >= 0 && _offset < difference_type(_S_buffer_size())) { _cur += _n; } else { difference_type _node_offset = _offset > 0 ? _offset / difference_type(_S_buffer_size()) : -difference_type((-_offset - 1) / _S_buffer_size()) - 1; set_node(_node + _node_offset); _cur = _first + (_offset - _node_offset * difference_type(_S_buffer_size())); } return *this; } _Self operator+(difference_type _n) const { _Self _tmp = *this; return _tmp += _n; } _Self& operator-=(difference_type _n) { return *this += -_n; } reference operator[](difference_type _n) { return *(*this + _n); } bool operator==(const _Self& _x) const { return this->_cur == _x._cur; } bool operator!=(const _Self& _x) const { return !(*this == _x); } void set_node(_Map_pointer _new_node) { _node = _new_node; _first = *_new_node; _last = _first + difference_type(_S_buffer_size()); } }; template <class T> class mDeque_base { public: typedef Deque_iterator<T, T&, T*> iterator; typedef Deque_iterator<T, const T&, const T*> const_iterator; typedef T** _Map_pointer; mDeque_base() : _map(0), _map_size(0), _start(), _finish() {} mDeque_base(size_t _num) : _map(0), _map_size(0), _start(), _finish() { init_map(_num); } ~mDeque_base() { if(_map) { destroy_node(_start._node, _finish._node + 2); deallocate_map(_map, _map_size); } } protected: void init_map(size_t); void create_node(_Map_pointer _nstart, _Map_pointer _nfinish); void destroy_node(_Map_pointer _nstart, _Map_pointer _nfinish); T* allocate_node() { return _Node_alloc.allocate(deque_buf_size(sizeof(T))); } void deallocate_node(T* _p) { _Node_alloc.deallocate(_p, deque_buf_size(sizeof(T)));} T** allocate_map(size_t _n) { return _Map_alloc.allocate(_n); } void deallocate_map(T** _p, size_t _n) { return _Map_alloc.deallocate(_p, _n); } enum { _S_initial_map_size = 8 }; protected: T** _map; size_t _map_size; iterator _start; iterator _finish; std::allocator<T> _Node_alloc; std::allocator<T*> _Map_alloc; }; template <class T> void mDeque_base<T>::init_map(size_t _num_elements) { size_t _num_node = _num_elements / deque_buf_size(sizeof(T)) + 1; _map_size = std::max((size_t)_S_initial_map_size, _num_node + 2); _map = _Map_alloc.allocate(_map_size); _Map_pointer _nstart = _map + (_map_size - _num_node) / 2; _Map_pointer _nfinish = _nstart + _num_node; try { create_node(_nstart, _nfinish); } catch(...) { _Map_alloc.deallocate(_map, _map_size); _map = 0; _map_size = 0; } _start.set_node(_nstart); _finish.set_node(_nfinish); _start._cur = _start._first; _finish._cur = _start._first + _num_elements % deque_buf_size(sizeof(T)); } template <class T> void mDeque_base<T>::create_node(_Map_pointer _nstart, _Map_pointer _nfinish) { _Map_pointer _cur; try { for(_cur=_nstart; _cur != _nfinish; ++_cur) { *_cur = allocate_node(); } } catch(...) { destroy_node(_nstart, _nfinish); } } template <class T> void mDeque_base<T>::destroy_node(_Map_pointer _nstart, _Map_pointer _nfinish) { for(_Map_pointer _cur=_nstart; _cur != _nfinish; ++_cur) { deallocate_node(*_cur); } } template <class T> class mDeque : protected mDeque_base<T> { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T** _Map_pointer; typedef mDeque_base<T> _Base; public: typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; protected: using _Base::_map; using _Base::_map_size; using _Base::_start; using _Base::_finish; using _Base::_Node_alloc; using _Base::_Map_alloc; using _Base::allocate_node; using _Base::deallocate_node; public: mDeque() : _Base(0) {} ~mDeque() { destroy(_start, _finish); } void push_back(const value_type& _t); //元素访问 reference operator[](size_t _n) { return _start[difference_type(_n)]; } protected: void push_back_aux(const value_type&); void reserve_map_at_back(size_type _nodes_to_add = 1) { if(_nodes_to_add + 1 > _map_size - (_finish._node - _map)) { reallocate_map(_nodes_to_add, false); } } void reallocate_map(size_type _nodes_to_add, bool __add_at_front); void destroy(iterator start, iterator finist) { for(; start != finist; start++){ _Map_alloc.destroy(&(*start)); } } }; template <class T> void mDeque<T>::push_back(const value_type& _t) { if(_finish._cur != _finish._last - 1) { _Node_alloc.construct(_finish._cur, _t); ++_finish._cur; } else { push_back_aux(_t); } } template <class T> void mDeque<T>::push_back_aux(const value_type& _t) { value_type _t_copy = _t; reserve_map_at_back(); *(_finish._node + 1) = allocate_node(); try { _Node_alloc.construct(_finish._cur, _t_copy); _finish.set_node(_finish._node + 1); _finish._cur = _finish._first; } catch(...) { deallocate_node(*(_finish._node + 1)); } } template <class T> void mDeque<T>::reallocate_map(size_type _nodes_to_add, bool _add_at_front) { size_type _old_num_nodes = _finish._node - _start._node + 1; size_type _new_num_nodes = _old_num_nodes + _nodes_to_add; _Map_pointer _new_nstart; if (_map_size > 2 * _new_num_nodes) { _new_nstart = _map + (_map_size - _new_num_nodes)/2 + (_add_at_front ? _nodes_to_add : 0); if(_new_nstart < _start._node) { std::copy(_start._node, _finish._node + 1, _new_nstart); } else { std::copy_backward(_start._node, _finish._node + 1, _new_nstart + _old_num_nodes); } } else { size_type _new_map_size = _map_size + std::max(_map_size, _nodes_to_add) + 2; _Map_pointer _new_map = _Map_alloc.allocate(_new_map_size); _new_nstart = _new_map + (_new_map_size - _new_num_nodes)/2 + (_add_at_front ? _nodes_to_add : 0); std::copy(_start._node, _finish._node + 1, _new_nstart); _Map_alloc.deallocate(_map, _map_size); _map = _new_map; _map_size = _new_map_size; } _start.set_node(_new_nstart); _finish.set_node(_new_nstart + _old_num_nodes - 1); } #endif