主要用于记录一下(代码量太少,没有使用git,又担心代码丢失了),代码未必正确,请勿参考!
#ifndef MYDEQUEITERATOR_HPP_INCLUDED
#define MYDEQUEITERATOR_HPP_INCLUDED
#include<iostream>
using namespace std;
namespace com
{
namespace example
{
namespace stl
{
template<typename T>
class MyDequeIterator
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef pointer* map_pointer;
typedef MyDequeIterator self;
#define BUFSIZE 32
public:
/**
* 获取缓冲区的元素个数
* 当元素大小大于缓冲区时,该怎么处理,
* 还是有问题的
*/
size_type get_element_count(){
size_type ele_size = sizeof(T);
if(ele_size < BUFSIZE){
return BUFSIZE / ele_size;
}else{
return 1;
}
}
/**
* 跳转到控制中心的下一个node
*/
void goToNextNode(){
this->node += 1;
this->start = *(this->node);
this->end = this->start + get_element_count();
this->cur = this->start;
}
/**
* 跳转到控制中心的前一个node
*/
void goToPreviousNode(){
this->node -= 1;
this->start = *(this->node);
this->end = this->start + get_element_count();
this->cur = this->end - 1;
}
public:
/**
* 设置控制中心的node
*/
void setNode(map_pointer node){
this->node = node;
this->start = *(this->node);
this->end = this->start + get_element_count();
}
public:
/**
* 前置++
*/
self& operator++(){
if(this->cur >= this->end - 1){
goToNextNode();
}else{
this->cur++;
}
return *this;
}
/**
* 后置++
*/
self operator++(int){
self tmp = *this;
++(*this);
return tmp;
}
/**
* 前置--
*/
self& operator--(){
if(this->cur <= this->start){
goToPreviousNode();
}else{
this->cur--;
}
return *this;
}
/**
* 后置--
*/
self operator--(int){
self tmp = *this;
--(*this);
return tmp;
}
reference operator*(){
return *(this->cur);
}
bool operator==(self& other){
return this->node == other.node && this->cur == other.cur;
}
bool operator!=(self& other){
return this->node != other.node || this->cur != other.cur;
}
/**
* 最关键的一个方法,实现随机访问的功能
*/
self& operator+=(difference_type diff){
size_type ele_count = get_element_count();//每个缓冲区的元素个数
difference_type offset = this->cur - this->start + diff;//相对某个特定缓冲区头部的偏移
if(offset >= 0){
if(offset < ele_count){
this->cur += diff;
}else{
size_type node_offset = offset / ele_count + 1;
size_type end_offset = offset % ele_count;
this->node += node_offset;
setNode(this->node);
this->cur = this->start + end_offset - 1;//设置指向缓冲区的当前位置
}
}else{
size_type node_offset = -offset / ele_count + 1;
size_type end_offset = -offset % ele_count;
this->node -= node_offset;
setNode(this->node);
this->cur = this->end - end_offset;//设置指向缓冲区的当前位置
}
return *this;
}
self operator+(difference_type diff){
self tmp = *this;
tmp += diff;
return tmp;
}
self& operator-=(difference_type diff){
return (*this) += (-diff);
}
self operator-(difference_type diff){
self tmp = *this;
tmp -= diff;
return tmp;
}
self& operator[](size_type index){
return *this += index;
}
public:
map_pointer node;//指向控制中心的指针
pointer start;//指向某个缓冲区的开始
pointer end;//指向某个缓冲区的尾部 + 1
pointer cur;//指向某个缓冲区的当前位置
};//end MyDequeIterator
}//end namespace stl
}//end namespace example
}//end namespace com
#endif // MYDEQUEITERATOR_HPP_INCLUDED
#ifndef MYDEQUE_HPP_INCLUDED
#define MYDEQUE_HPP_INCLUDED
#include "com/example/stl/MyDequeIterator.hpp"
#include <cstdlib>
#include <new>
namespace com
{
namespace example
{
namespace stl
{
template<typename T, typename Alloc = std::allocator<T>>
class MyDeque{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef pointer* map_pointer;
typedef MyDequeIterator<T> iterator;
typedef std::allocator<T> data_allocator_type;
typedef std::allocator<pointer> control_allocator_type;
#define BUFSIZE 32
private:
/**
* len指的是元素个数,BUFSIZE指的是缓冲区大小
*/
MyDeque(size_type len){
this->len = len;
size_type node_count = this->len * sizeof(value_type) / BUFSIZE + 1;
this->control_len = 2 * node_count;//控制中心的大小是所需要的大小的2倍
//为控制中心分配空间
pcontrol = control_allocator.allocate(this->control_len * sizeof(pointer));
//给start迭代器和end迭代器设置初值
start.node = pcontrol + this->control_len / 4;
end_1.node = start.node + node_count - 1;
//start迭代器和end迭代器之间的缓冲区分配空间(注意这一块逻辑的位置)
size_type ele_count = start.get_element_count();
for(map_pointer p = start.node; p <= end_1.node; p++){
*p = data_allocator.allocate(sizeof(value_type) * ele_count);
}
//给start迭代器和end迭代器设置初值
start.setNode(start.node);
end_1.setNode(end_1.node);
start.cur = start.end;
end_1.cur = end_1.start - 1;//注意这个地方的设置
}
public:
MyDeque(){
//MyDeque(0);//错误的,构造函数不能这样调用
new(this) MyDeque(4);
}
private:
/**
* end迭代器是否到了控制中心的边界了
*/
bool is_end_boundary_control(){
return (end_1.node == (pcontrol + control_len - 1)) && (end_1.cur == (end_1.end - 1));
}
/**
* start迭代器是否到了控制中心的边界了
*/
bool is_start_boundary_control(){
return (start.node == pcontrol) && (start.cur == start.start);
}
/**
* 给控制中心扩容
*/
void expan_control(){
size_type tmp_len = this->control_len;//老的长度
map_pointer old_start_node = start.node;//老的start
map_pointer old_end_node = end_1.node;//老的end
map_pointer delete_point = this->pcontrol;//专门用于删除的
size_type start_end_offset = end_1.node - start.node;//开始和结尾之间的偏移
this->control_len = this->control_len * 2;
this->pcontrol = control_allocator.allocate(sizeof(pointer) * this->control_len);
//将老的复制到新的里面
size_type base_index = this->control_len / 4;
map_pointer tmp_after_pointer = this->pcontrol + base_index;
while(old_start_node <= old_end_node){
*tmp_after_pointer = *old_start_node;
++tmp_after_pointer;
++old_start_node;
}
//给迭代器重新赋值
start.node = this->pcontrol + base_index;//注意这个地方的计算
end_1.node = start.node + start_end_offset;
//释放老的控制中心所占的空间
control_allocator.deallocate(delete_point, sizeof(pointer) * tmp_len);
}
/**
* 在最后一位重新分配空间,然后插入元素
*/
void allocate_and_insert_last(reference obj){
size_type ele_count = end_1.get_element_count();
*(++end_1.node) = data_allocator.allocate(sizeof(value_type) * ele_count);
end_1.start = *(end_1.node);
end_1.end = end_1.start + ele_count;
end_1.cur = end_1.start;
new(end_1.cur) value_type(obj);//调用copy构造函数
}
/**
* 在开始一位重新分配空间,然后插入元素
*/
void allocate_and_insert_start(reference obj){
size_type ele_count = start.get_element_count();
*(--start.node) = data_allocator.allocate(sizeof(value_type) * ele_count);
start.start = *(start.node);
start.end = start.start + ele_count;
start.cur = start.end - 1;
new(start.cur) value_type(obj);
}
public:
/**
* 从后面插入一个元素
*/
void push_back(reference obj){
if(is_end_boundary_control()){
//需要对控制中心扩容
expan_control();
allocate_and_insert_last(obj);
}else{
++(end_1.cur);
if(end_1.cur < end_1.end){
new(end_1.cur) value_type(obj);//调用copy构造函数
}else{
allocate_and_insert_last(obj);
}
}
this->len++;//长度增加
}
/**
* 弹出最后一个元素
*/
value_type pop_back(){
value_type tmp = *(end_1.cur);
--end_1;
this->len--;
return tmp;
}
/**
* 返回最后一个元素,不弹出
*/
reference back(){
return *(end_1.cur);
}
/**
* 从容器的前面插入元素
*/
void push_front(reference obj){
if(is_start_boundary_control()){
//需要扩容
expan_control();
allocate_and_insert_start(obj);
}else{
--start.cur;
if(start.cur < start.start){
allocate_and_insert_start(obj);
}else{
new(start.cur) value_type(obj);//调用copy构造函数
}
}
this->len++;
}
/**
* 从容器的前面弹出元素
*/
value_type pop_front(){
value_type tmp = *(start.cur);
++start;
this->len--;
return tmp;
}
/**
* 返回最前面的元素
*/
reference front(){
return *(start.cur);
}
/**
* 清空容器
*/
void clear(){
map_pointer start_node = start.node;
map_pointer end_node = end_1.node;
size_type arr_len = end_node - start_node + 1;
map_pointer* arr = new map_pointer[arr_len];
size_type ele_count = start.get_element_count();
//销毁容器里面的对象
for(int i = 0; i < arr_len; i++){
arr[i] = start_node + i;
}
for(int i = 0; i < arr_len; i++){
for(int j = 0; j < ele_count; j++){
data_allocator.destroy(*arr[i] + j);
}
data_allocator.deallocate(*arr[i], ele_count * sizeof(value_type));
}
//销毁控制中心
control_allocator.deallocate(this->pcontrol, sizeof(pointer) * this->control_len);
delete[] arr;
this->len = 0;
new(this) MyDeque(0);
}
public:
iterator begin(){
return this->start;
}
iterator end_my(){
return this->end_1;
}
size_type size(){
return this->len;
}
bool empty(){
return this->len == 0;
}
private:
iterator start;
iterator end_1;
//指向控制中心的开始
//pcontrol + control_len就是控制中心的尾部
map_pointer pcontrol;
size_type control_len;//控制中心的大小
size_type len;
data_allocator_type data_allocator;
control_allocator_type control_allocator;
};//end MyDeque
}//end namespace stl
}//end namespace example
}//end namespace com
#endif // MYDEQUE_HPP_INCLUDED
// TestSTL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "com/example/stl/MyDeque.hpp"
#include<iostream>
using namespace com::example::stl;
using namespace std;
class Object{
public:
Object(int x, float y){
this->x = x;
this->y = y;
}
Object(){
}
~Object(){
//cout << "~Object 析构..." << endl;
}
public:
int x;
float y;
public:
void toString(){
cout << "x = " << x << ", " << "y = " << y << endl;
}
};
void test1(){
MyDeque<Object> dq;
int len = 25;
for(int i = 0; i < len; i++){
Object obj(i, i);
dq.push_back(obj);
}
cout << "插入完成..........................." << endl;
cout << endl;
cout << "开始调用pop_back()..........................." << endl;
//测试pop_back()
for(int i = 0; i < len; i++){
dq.pop_back().toString();
}
cout << "开始调用clear()..........................." << endl;
dq.clear();
}
void test2(){
MyDeque<Object> dq;
int len = 25;
for(int i = 0; i < len; i++){
Object obj(i, i);
dq.push_front(obj);
}
//测试pop_front()
for(int i = 0; i < len; i++){
dq.pop_front().toString();
}
cout << "开始调用clear()..........................." << endl;
dq.clear();
}
void test3(){
MyDeque<int> dq;
int len = 25;
int tmp;
for(int i = 0; i < len; i++){
tmp = i;
dq.push_front(tmp);
}
//测试pop_front()
for(int i = 0; i < len; i++){
cout << dq.pop_front() << endl;
}
dq.clear();
}
void test4(){
MyDeque<float> dq;
int len = 700;
float tmp;
for(int i = 0; i < len; i++){
tmp = i * 0.1f;
dq.push_front(tmp);
}
//测试pop_front()
for(int i = 0; i < len; i++){
cout << dq.pop_front() << endl;
}
}
void test5(){
typedef MyDeque<Object>::iterator iterator_;
MyDeque<Object> dq;
int len = 800;
for(int i = 0; i < len; i++){
Object obj(i, i);
dq.push_back(obj);
dq.push_front(obj);
}
//相等的时候也要打印出来
iterator_ it = dq.begin();
for(; it != dq.end_my(); ++it){
(*it).toString();
}
(*it).toString();
}
int main(int argc, _TCHAR* argv[])
{
test5();
system("pause");
return 0;
}