#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