(第四步) STL: stl_deque容器的实现

deque 是连续空间(逻辑上是这样的),实际上 deque 是由一段一段的连续空间构成,一旦需要在 deque 的头部和尾部增加存储空间,便配置定量连续的内存空间,串接在整个 deque 的头部或者尾部。

deque 采用映射(map)作为主控,也就是中控器。这里的map是一小块连续空间,其中每个元素都是指针,每个指针都指向一段定量连续空间,也叫作缓冲区,缓冲区才是 deque 的主体。当我们申请对象开辟内存的时候,如果没指定缓冲区大小,默认为512bytes,注意开辟内存存的是指针,缓冲区才是存数据。

 

中控器、迭代器和缓冲区的相互关系:

 

迭代器的设计

迭代器元素:

  • mapIndex:map块连续空间的索引,当前元素指向map的位置

  • cur:当前元素所指缓冲区的位置

  • container:用于访问deque容器的信息

迭代器需要的重载:

  • 指针*、 ->

  • 运算符:++、--、== 、!=

迭代器间的操作:

  • 迭代器 +、- int类型

  • int类型 +、- 迭代器

  • 迭代器 +、- 迭代器

deque 设计

容器元素:

  • EBucksSize { BUCKSIZE = 64 }:定义桶(缓冲区)大小为64

  • start, finish:map首尾

  • mapSize:map可以容纳多少指针

  • map:指向map,map是块连续空间,其中每个元素都是指针指向一块缓冲区

构造函数:

  • 无参构造:deque

  • 有参构造:deque(n, value)

  • 拷贝构造1:deque(old_deque.begin(), old_deque.end())

  • 拷贝构造2:deque(old_deque);

  • 拷贝构造3:deque = old_deque;

元素操作:

  • front()、back()、empty()、 size() 、operator[]、begin() 、 end()

  • push_front()、 push_back()、 pop_front()、 pop_back()

  • clear()、 swap()

函数:

初始化

  • init(); :无参构造时的初始化

  • getANewMap(const size_t size);:根据size得到新的map空间

  • getANewBuck();:得到新的缓冲区空间

  • getNewMapSize(const size_t size);:满时的空间扩容

  • getBuckSize()const;:缓冲区(桶)的扩容

内部辅助函数

  • back_full();:back后元素满,插入back需要扩容

  • front_full();:front前元素满,插入front需要扩容

  • deque_aux(size_t n, const value_type& val, std::true_type);:

  • deque_aux(Iterator first, Iterator last, std::false_type);

  • reallocateAndCopy();:原来空间不足,需要开辟新空间,并copy原空间元素

stl_deque.h

 #ifndef _DEQUE_H_
 #define _DEQUE_H_
 ​
 #include "../Includes/Allocator.h"
 #include "../Includes/ReverseIterator.h"
 #include "../Includes/Utility.h"
 ​
 #include "../Includes/Iterator.h"
 ​
 namespace mySTL {
     template<class T, class alloc = allocator<T>>
     class deque;
     // 定义deque迭代器的类
     namespace detail {
         // 继承五个迭代器必要的型别
         //class of deque iterator
         template<class T>
         class dq_iter : public iterator<bidirectional_iterator_tag, T>
         {
         private:
             template<class T, class alloc>
             friend class ::mySTL::deque;
             
         private:
             // 声明deque指针类型
             typedef const ::mySTL::deque<T>* cntrPtr;
             size_t      mapIndex;           // map块连续空间的索引,当前元素指向map的位置
             T*          cur;                // 当前元素所指缓冲区的位置
             cntrPtr     container;          // 用于访问deque容器的信息
 ​
         public:
             // 构造函数
             dq_iter() :mapIndex(-1), cur(0), container(0) {}
             dq_iter(size_t index, T* ptr, cntrPtr container)
                 :mapIndex(index), cur(ptr), container(container) {}
 ​
             // 拷贝
             dq_iter(const dq_iter& it)
                 :mapIndex(it.mapIndex), cur(it.cur), container(it.container) {}
             dq_iter& operator=(const dq_iter& it);
             void swap(dq_iter& it);
 ​
             // 指针重载定义
             T& operator *() { return *cur; }
             const T& operator *()const { return *cur; }
             T* operator ->() { return &(operator*()); }
             const T* operator ->()const { return &(operator*()); }
 ​
             // 迭代器功能的实现重载
             dq_iter& operator ++();
             dq_iter operator ++(int);
             dq_iter& operator --();
             dq_iter operator --(int);
             bool operator ==(const dq_iter& it)const;
             bool operator !=(const dq_iter& it)const;
 ​
         private:
             T* getBuckTail(size_t mapIndex)const;   // mapIndex对应缓冲区的尾部
             T* getBuckHead(size_t mapIndex)const;   // mapIndex对应缓冲区的头部
             size_t getBuckSize()const;              // 缓冲区的大小
 ​
         public:
             template<class T>
             friend dq_iter<T> operator + (const dq_iter<T>& it, typename dq_iter<T>::difference_type n);
             template<class T>
             friend dq_iter<T> operator + (typename dq_iter<T>::difference_type n, const dq_iter<T>& it);
             template<class T>
             friend dq_iter<T> operator - (const dq_iter<T>& it, typename dq_iter<T>::difference_type n);
             template<class T>
             friend dq_iter<T> operator - (typename dq_iter<T>::difference_type n, const dq_iter<T>& it);
 ​
             template<class T>
             friend typename dq_iter<T>::difference_type operator - (const dq_iter<T>& it1, const dq_iter<T>& it2);
             template<class T>
             friend void swap(dq_iter<T>& lhs, dq_iter<T>& rhs);
         };
     }
 ​
     /********************************结束deque迭代器函数声明*********************************/
 ​
     // deque类的声明
     template<class T, class alloc>
     class deque {
     private:
         template<class T>
         friend class ::mySTL::detail::dq_iter;
     public:
         typedef T                           value_type;
         typedef detail::dq_iter<T>          iterator;
         typedef detail::dq_iter<const T>    const_iterator;
         typedef T&                          reference;
         typedef const reference             const_reference;
         typedef size_t                      size_type;
         typedef ptrdiff_t                   difference_type;
         typedef alloc                       allocator_type;
         typedef T**                         map_pointer;
 ​
     private:
         typedef alloc dataAllocator;
         enum class EBucksSize { BUCKSIZE = 64 };    //定义桶(缓冲区)大小为64
 ​
     private:
         iterator        start, finish;
         size_type       mapSize;            //  map可以容纳多少指针
         map_pointer     map;                // 指向map,map是块连续空间,其中每个元素都是指针
                                             // 指向一块缓冲区
 ​
     public:
         deque();
         explicit deque(size_type n, const value_type& val = value_type());
 ​
         ~deque();
 ​
         template <class InputIterator>
         deque(InputIterator first, InputIterator last);
         deque(const deque& x);
 ​
         deque& operator= (const deque& x);
         deque& operator= (deque&& x);
 ​
         iterator begin() { return start; }
         iterator end() { return finish; }
         iterator begin()const { return start; }
         iterator end()const { return finish; }
 ​
         // 元素操作
     public:
         size_type size()  { return end() - begin(); }
         bool empty()  { return begin() == end(); }
 ​
         reference operator[] (size_type n);
         reference front();
         reference back();
 ​
         const_reference operator[] (size_type n) const { return *(begin() + n); }
         const_reference front() const { return *begin(); }
         const_reference back() const { return *(end() - 1); }
 ​
 ​
         void push_back(const value_type& val);
         void push_front(const value_type& val);
         void pop_back();
         void pop_front();
         void swap(deque& x);
         void clear();
 ​
         
     private:
         // 初始化函数
         void init();
         map_pointer getANewMap(const size_t size);
         T* getANewBuck();
         size_t getNewMapSize(const size_t size);
         size_t getBuckSize()const;
 ​
         // 内部辅助函数
         bool back_full();
         bool front_full();
         void deque_aux(size_t n, const value_type& val, std::true_type);
         template<class Iterator>
         void deque_aux(Iterator first, Iterator last, std::false_type);
         void reallocateAndCopy();
     public:
         template <class T, class alloc>
         friend bool operator== (const deque<T, alloc>& lhs, const  deque<T, alloc>& rhs);
         template <class T, class alloc>
         friend bool operator!= (const deque<T, alloc>& lhs, const deque<T, alloc>& rhs);
         template <class T, class alloc>
         friend void swap(deque<T, alloc>& x, deque<T, alloc>& y);
     };
 }
 ​
 #include "../Detail/stl_deque.impl.h"
 ​
 #endif

stl_deque.impl.h

 //#include "..\p2_STL_Source\stl_deque.h"
 #ifndef _DEQUE_IMPL_H_
 #define _DEQUE_IMPL_H_
 ​
 ​
 namespace mySTL {
     namespace detail {
         // 拷贝
         template<class T>
         dq_iter<T>& dq_iter<T>::operator=(const dq_iter& it)
         {
             if (this != &it) 
             {
                 mapIndex = it.mapIndex;
                 cur = it.cur;
                 container = it.container;
             }
             return *this;
         }
 ​
         template<class T>
         void dq_iter<T>::swap(dq_iter& it) 
         {
             mySTL::swap(mapIndex, it.mapIndex);
             mySTL::swap(cur, it.cur);
             //mySTL::swap(container, it.container);
         }
 ​
         // 迭代器实现,重载运算符
         template<class T>
         dq_iter<T>& dq_iter<T>::operator++() 
         {
             // 判断是否超出缓冲区大小,然后判断是否超出map大小
             if (cur != getBuckTail(mapIndex))//+1后还在同一个桶buf里
                 ++cur;
             else if (mapIndex + 1 < container->mapSize) 
             {
                 //+1后还在同一个map里
                 ++mapIndex;
                 cur = getBuckHead(mapIndex);
             }
             else 
             {
                 //+1后跳出了map
                 mapIndex = container->mapSize;
                 cur = container->map[mapIndex];
             }
             return *this;
         }
 ​
         template<class T>
         inline dq_iter<T> dq_iter<T>::operator++(int)
         {
             auto res = *this;
             ++(*this);
             return res;
         }
 ​
         template<class T>
         inline dq_iter<T>& dq_iter<T>::operator--()
         {
             if (cur != getBuckHead(mapIndex))//当前不指向桶头
                 --cur;
             else if (mapIndex - 1 >= 0) {//-1后还在map里面
                 --mapIndex;
                 cur = getBuckTail(mapIndex);
             }
             else {
                 mapIndex = 0;
                 cur = container->map[mapIndex];//指向map[0]的头
             }
             return *this;
         }
 ​
         template<class T>
         inline dq_iter<T> dq_iter<T>::operator--(int)
         {
             auto res = *this;
             --(*this);
             return res;
         }
 ​
         template<class T>
         inline bool dq_iter<T>::operator==(const dq_iter& it) const
         {
             return ((mapIndex == it.mapIndex) &&
                 (cur == it.cur) && (container == it.container));
         }
 ​
         template<class T>
         inline bool dq_iter<T>::operator!=(const dq_iter& it) const
         {
             return !(*this == it);
         }
 ​
         // 获取缓存区,元素头、尾、大小cur
         template<class T>
         inline T* dq_iter<T>::getBuckTail(size_t mapIndex) const
         {
             return container->map[mapIndex] + (container->getBuckSize() - 1);
         }
 ​
         template<class T>
         inline T* dq_iter<T>::getBuckHead(size_t mapIndex) const
         {
             return container->map[mapIndex];
         }
         template<class T>
 ​
         inline size_t dq_iter<T>::getBuckSize() const
         {
             return container->getBuckSize();
         }
         
 ​
         // friend 类外定义
         // 实现迭代器于 int 类型数字的符号运算
         template<class T>
         dq_iter<T> operator + (const dq_iter<T>& it, typename dq_iter<T>::difference_type n) 
         {
             dq_iter<T> res(it); // 拷贝构造
 ​
             auto m = res.getBuckTail(res.mapIndex) - res.cur;   // 缓冲区的大小
             if (n <= m) 
             {   
                 //前进n步仍在同一个缓冲区中
                 res.cur += n;
             }
             else {
                 n = n - m;  // 跳到当前缓冲区的tail,再开始计算
                 res.mapIndex += (n / it.getBuckSize() + 1); 
                 auto p = res.getBuckHead(res.mapIndex);
                 auto x = n % it.getBuckSize() - 1;
                 res.cur = p + x;
             }
             return res;
         }
 ​
         template<class T>
         dq_iter<T> operator + (typename dq_iter<T>::difference_type n, const dq_iter<T>& it) 
         {
             return (it + n);
         }
 ​
         template<class T>
         dq_iter<T> operator - (const dq_iter<T>& it, typename dq_iter<T>::difference_type n) 
         {
             dq_iter<T> res(it);
             auto m = res.cur - res.getBuckHead(res.mapIndex);
             if (n <= m)//后退n步还在同一个桶中
                 res.cur -= n;
             else {
                 n = n - m;
                 res.mapIndex -= (n / res.getBuckSize() + 1);
                 res.cur = res.getBuckTail(res.mapIndex) - (n % res.getBuckSize() - 1);
             }
             return res;
         }
 ​
         template<class T>
         dq_iter<T> operator - (typename dq_iter<T>::difference_type n, const dq_iter<T>& it) 
         {
             return (it - n);
         }
 ​
         // 迭代器之间的运算
         template<class T>
         typename dq_iter<T>::difference_type operator - (const dq_iter<T>& it1, const dq_iter<T>& it2) 
         {
             if (it1.container == it2.container && it1.container == 0)
                 return 0;
 ​
             // 分3段计算
             // 第一段:it1缓冲区大小 * (map[it1] - map[it2] - 1)
             // 第二段:it1当前缓冲区的位置 - it1缓冲区tail位置
             // 第三段:it2缓冲区tail位置 - it2当前缓冲区的位置
             // 合计:
             return typename dq_iter<T>::difference_type(it1.getBuckSize()) * (it1.mapIndex - it2.mapIndex - 1)
                 + (it1.cur - it1.getBuckHead(it1.mapIndex)) + (it2.getBuckTail(it2.mapIndex) - it2.cur) + 1;
         }
 ​
         template<class T>
         void swap(dq_iter<T>& lhs, dq_iter<T>& rhs) {
             lhs.swap(rhs);
         }
     }
 ​
     // 初始化 init
     template<class T, class alloc>
     inline void deque<T, alloc>::init()
     {
         // 参数初始化
         // 初始化,申请两块内存,初始指针放在第二块的最前端
         mapSize = 2;
         map = getANewMap(mapSize);
         start.container = finish.container = this; 
         start.mapIndex = finish.mapIndex = mapSize - 1;
         start.cur = finish.cur = map[mapSize - 1];
     }
 ​
     template<class T, class alloc>
     typename deque<T, alloc>::map_pointer deque<T, alloc>::getANewMap(const size_t size)
     {
         //
         map_pointer map = new T * [size];
 ​
         for (int i = 0; i != size; ++i)
         {
             map[i] = getANewBuck();//批量获得桶(缓冲区)
         }
 ​
         return map;
     }
 ​
     template<class T, class alloc>
     inline T* deque<T, alloc>::getANewBuck()
     {
         return dataAllocator::allocate(getBuckSize());
     }
 ​
     template<class T, class alloc>
     inline size_t deque<T, alloc>::getNewMapSize(const size_t size)
     {
         return (size == 0 ? 2 : size * 2);
     }
 ​
     template<class T, class alloc>
     inline size_t deque<T, alloc>::getBuckSize() const
     {
         return (size_t)EBucksSize::BUCKSIZE;    // 暂定64
     }
 ​
 ​
 ​
     // 基本功能实现 无参,析构函数
     template<class T, class alloc>
     deque<T, alloc>::deque()
         :mapSize(0), map(0) {}
 ​
     template<class T, class alloc>
     inline deque<T, alloc>::~deque()
     {
         // 先销毁缓冲区,再清除对应缓冲区的map指针,最后在销毁整个map数组
         for (int i = 0; i != mapSize; ++i)
         {
             for(auto j = map[i]+0; !j && j != map[i] + getBuckSize(); ++j)
             {
                 dataAllocator::destroy(j);
             }
             if (!map[i])
                 dataAllocator::deallocate(map[i], getBuckSize());
         }
 ​
         delete[] map;
     }
 ​
     // 元素操作
 ​
     template<class T, class alloc>
     typename deque<T, alloc>::reference deque<T, alloc>::operator[] (size_type n) {
         return *(begin() + n);
     }
     template<class T, class alloc>
     typename deque<T, alloc>::reference deque<T, alloc>::front() {
         return *begin();
     }
     template<class T, class alloc>
     typename deque<T, alloc>::reference deque<T, alloc>::back() {
         return *(end() - 1);
     }
 ​
     // push pop clear swap
     template<class T, class alloc>
     inline void deque<T, alloc>::push_front(const value_type& val)
     {
         if (empty())
         {
             init();
         }
         else if (front_full())
         {
             reallocateAndCopy();
         }
         --start;
 ​
         mySTL::construct(start.cur, val);   // 给予新空间赋值
     }
 ​
     template<class T, class alloc>
     inline void deque<T, alloc>::push_back(const value_type& val)
     {
         if (empty())
         {
             init();
         }
         else if (back_full())
         {
             reallocateAndCopy();
         }
         
         mySTL::construct(finish.cur, val);
         ++finish;
 ​
     }
 ​
     template<class T, class alloc>
     inline void deque<T, alloc>::pop_front()
     {
         dataAllocator::destroy(start.cur);
         ++start;
     }
 ​
     template<class T, class alloc>
     inline void deque<T, alloc>::pop_back()
     {
         --finish;
         dataAllocator::destroy(finish.cur);
     }
 ​
     template<class T, class alloc>
     inline bool deque<T, alloc>::back_full() 
     {
         // map[mapSize - 1]被占用,指针指向end
         // 即,后没有空间可以插入了,需要重新申请
         return map[mapSize - 1] && map[mapSize] == end().cur;
     }
 ​
     template<class T, class alloc>
     inline bool deque<T, alloc>::front_full() 
     {
         // map[0]存在且为当前所指向缓冲区首位
         // 即,前方没有空间可以插入了,需要重新申请
         return map[0] && map[0] == begin().cur; 
     }
 ​
     template<class T, class alloc>
     inline void deque<T, alloc>::reallocateAndCopy()
     {
         auto newMapSize = getNewMapSize(mapSize);   // 扩展两倍
         map_pointer newMap = getANewMap(newMapSize);
 ​
         // 重新申请2倍空间后,将原来数据copy到中间位置,前后空余位置登场,所以/4
         size_t startIndex = newMapSize / 4;         
         // copy
         for (int i = 0; i + start.mapIndex != mapSize; ++i)
         {
             for (int j = 0; j != getBuckSize(); ++j)
             {
                 newMap[startIndex + i][j] = map[start.mapIndex][j];
             }
         }
 ​
         size_t n = start.cur - map[start.mapIndex];
         auto size = this->size();
         // 析构旧地址
         clear();
 ​
         mapSize = newMapSize;
         map = newMap;
         start = iterator(startIndex, newMap[startIndex] + n, this); // iterator构造函数
         finish = start + size;
 ​
     }
 ​
     template<class T, class alloc>
     void deque<T, alloc>::clear() 
     {
         for (auto i = 0; i != mapSize; ++i)
         {
             for (auto j = map[i]+0; !j &&j != map[i] + getBuckSize(); ++j)
             {
                 dataAllocator::destroy(j);
             }
         }
 ​
         mapSize = 0;
         start.mapIndex = finish.mapIndex = mapSize / 2;
         start.cur = finish.cur = map[mapSize / 2];
     }
 ​
 ​
     // deque 有参构造、拷贝
     template<class T, class alloc>
     inline deque<T, alloc>::deque(size_type n, const value_type& val)
     {
         deque();
         deque_aux(n, val, typename std::is_integral<size_type>::type());
     }
 ​
     template<class T, class alloc>
     template<class InputIterator>
     inline deque<T, alloc>::deque(InputIterator first, InputIterator last)
     {
         deque();
         deque_aux(first, last, typename std::is_integral<InputIterator>::type());
 ​
     }
 ​
     template<class T, class alloc>
     inline deque<T, alloc>::deque(const deque& x)
     {
         mapSize = x.mapSize;
         map = getANewMap(mapSize);
 ​
         for (int i = 0; i + x.start.mapIndex != x.mapSize; i++)
         {
             for (int j = 0; j != getBuckSize(); ++j)
             {
                 map[x.start.mapIndex + i][j] = x.map[x.start.mapIndex + i][j];
             }
         }
 ​
         start.mapIndex = x.start.mapIndex;
         finish.mapIndex = x.finish.mapIndex;
         start.cur = map[start.mapIndex] + (x.start.cur - x.map[x.start.mapIndex]);
         finish.cur = map[finish.mapIndex] + (x.finish.cur - x.map[x.finish.mapIndex]);
         start.container = finish.container = this;
     }
 ​
     template<class T, class alloc>
     typename deque<T, alloc>::deque& deque<T, alloc>::operator= (const deque& x)
     {
         mapSize = x.mapSize;
         map = getANewMap(mapSize);
 ​
         for (int i = 0; i + x.start.mapIndex != x.mapSize; i++)
         {
             for (int j = 0; j != getBuckSize(); ++j)
             {
                 map[x.start.mapIndex + i][j] = x.map[x.start.mapIndex + i][j];
             }
         }
 ​
         start.mapIndex = x.start.mapIndex;
         finish.mapIndex = x.finish.mapIndex;
         start.cur = map[start.mapIndex] + (x.start.cur - x.map[x.start.mapIndex]);
         finish.cur = map[finish.mapIndex] + (x.finish.cur - x.map[x.finish.mapIndex]);
         start.container = finish.container = this;
         return *this;
     }
 ​
     template<class T, class alloc>
     inline void deque<T, alloc>::deque_aux(size_t n, const value_type& val, std::true_type)
     {
         int i = 0;
         for (; i != n / 2; ++i)
             (*this).push_front(val);
         for (; i != n; ++i)
             (*this).push_back(val);
     }
 ​
     
 ​
     template<class T, class alloc>
     template<class Iterator>
     inline void deque<T, alloc>::deque_aux(Iterator first, Iterator last, std::false_type)
     {
         difference_type mid = (last - first) / 2;
         for (auto it = first + mid; it != first - 1; --it)
             (*this).push_front(*it);
         for (auto it = first + mid + 1; it != last; ++it)
             (*this).push_back(*it);
     }
 ​
     template<class T, class alloc>
     void deque<T, alloc>::swap(deque<T, alloc>& x) {
         mySTL::swap(mapSize, x.mapSize);
         mySTL::swap(map, x.map);
         start.swap(x.start);
         finish.swap(x.finish);
     }
 ​
     // 友元函数
     template<class T, class alloc>
     bool operator==(const deque<T, alloc>& lhs, const deque<T, alloc>& rhs)
     {
         auto beg1 = lhs.begin(), beg2 = rhs.begin();
 ​
         for (; beg1 != lhs.end() && beg2 != rhs.end(); ++beg1, ++beg2)
         {
             if (*beg1 != *beg2)
                 return false;
         }
         if (beg1 == lhs.end() && beg2 == rhs.end())
             return true;
 ​
         return false;
     }
 ​
     template<class T, class alloc>
     bool operator!=(const deque<T, alloc>& lhs, const deque<T, alloc>& rhs)
     {
         return !(lhs == rhs);
     }
 ​
     template<class T, class alloc>
     void swap(deque<T, alloc>& x, deque<T, alloc>& y)
     {
         x.swap(y);
     }
 ​
     
 }
 ​
 #endif
 ​

stl_deque_test.h

 #ifndef _DEQUE_TEST_H_
 #define _DEQUE_TEST_H_
 ​
 ​
 ​
 #include "../p2_STL_Source/stl_deque.h"
 #include <deque>
 ​
 #include <cassert>
 #include <string>
 ​
 namespace mySTL {
     namespace dequeTest {
         template<class T>
         using stdDQ = std::deque < T >;
         template<class T>
         using myDQ = mySTL::deque < T >;
 ​
         template<class T>
         void stdPrint(std::deque<T>& dq);
         template<class T>
         void myPrint(mySTL::deque<T>& dq);
 ​
         void test01();  // 有参构造、拷贝构造测试
         void test02();  // 无参构造、push、pop测试
         void test03();  // string类型、重载[]、front、back测试
         void test04();  // swap 测试
         void test05();
         void test06();
 ​
         
 ​
     }
 }
 ​
 #endif

stl_deque_test.cpp

 #include "stl_deque_test.h"
 ​
 #include <iostream>
 using namespace std;
 ​
 namespace mySTL {
     namespace dequeTest {
         template<class T>
         void stdPrint(std::deque<T>& dq)
         {
             cout << "stdSTL: ";
             for (auto i = dq.begin(); i != dq.end(); i++)
             {
 ​
                 cout << *i << "  ";
             }
             cout << endl;
         }
 ​
         template<class T>
         void myPrint(mySTL::deque<T>& dq)
         {
             cout << "mySTL: ";
             for (auto i = dq.begin(); i != dq.end(); i++)
             {
 ​
                 cout << *i << "  ";
             }
             cout << endl;
         }
 ​
         void test01()
         {
             stdDQ<int> dq1(10, 6);
             myDQ<int> dq2(10, 6);
             cout << "-------------有参构造0 deque(size,val) test----------" << endl;
             stdPrint(dq1);
             myPrint(dq2);
             int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
             stdDQ<int> dq3(std::begin(arr), std::end(arr));
             myDQ<int> dq4(std::begin(arr), std::end(arr));
             cout << "------------- 有参构造1 deque(begin(), end()) test----------" << endl;
             stdPrint(dq3);
             myPrint(dq4);
 ​
             auto dq5(dq3);
             auto dq6(dq4);
             cout << "------------- 有参构造2 deque(deque) test----------" << endl;
             stdPrint(dq5);
             myPrint(dq6);
 ​
             auto dq7 = dq3;
             auto dq8 = dq4;
             cout << "------------- 有参构造3  = test----------" << endl;
             stdPrint(dq7);
             myPrint(dq8);
 ​
             auto dq9 = std::move(dq7);
             auto dq10 = std::move(dq8);
             cout << "------------- 有参构造4  = test----------" << endl;
             stdPrint(dq9);
             myPrint(dq10);
         }
 ​
         void test02()
         {
             myDQ<int> dq1;
             cout << "-------------无参构造 test----------" << endl;
             cout << "is empty: " << boolalpha << dq1.empty() << endl;
             cout << "size : " << dq1.size() << endl;
         
 ​
             cout << "-------------push  test----------" << endl;
             for (auto i = 10; i < 20; ++i) {
                 dq1.push_front(i);
             }
 ​
             for (auto i = 0; i < 10; ++i) {
                 dq1.push_back(i);
             }
             myPrint(dq1);
             cout << "size : " << dq1.size() << endl;
 ​
             cout << "-------------pop  test----------" << endl;
             for (auto i = 0; i != 5; ++i) {
                 dq1.pop_back();
             }
             for (auto i = 0; i != 5; ++i) {
                 dq1.pop_front();
             }
             myPrint(dq1);
             cout << "size : " << dq1.size() << endl;
         }
 ​
         void test03()
         {
             cout << "------------- 有参构造 string  test----------" << endl;
             stdDQ<std::string> dq1(10, "10");
             myDQ<std::string> dq2(10, "10");
             stdPrint(dq1);
             myPrint(dq2);
 ​
             cout << "------------- 重载[]  test----------" << endl;
             dq1[0] = "0aa";
             dq1[9] = "9aa";
             dq2[0] = "0aa";
             dq2[9] = "9aa";
             dq1.front() = "dd";
             dq2.front() = "dd";
             stdPrint(dq1);
             myPrint(dq2);
 ​
             cout << "------------- front back  test----------" << endl;
             cout << "std: front val: " << dq1.front() << "\tback val: " << dq1.back() << endl;
             cout << "my : front val: " << dq2.front() << "\tback val: " << dq2.back() << endl;
 ​
         }
 ​
         void test04()
         {
             int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
             cout << "------------- raw  data----------" << endl;
             myDQ<int> foo(arr, arr + 3), bar(arr + 3, arr + 10);
             myPrint(foo);
             myPrint(bar);
             cout << "------------- swap1 test----------" << endl;
             foo.swap(bar);
             myPrint(foo);
             myPrint(bar);
             cout << "------------- swap2 test----------" << endl;
             mySTL::swap(foo, bar);
             myPrint(foo);
             myPrint(bar);
 ​
             cout << "------------- != test----------" << endl;
             cout << boolalpha << (foo != bar) << endl;
             
             cout << "------------- = 复值 test----------" << endl;
             foo = bar;
             myPrint(foo);
             myPrint(bar);           
             
             cout << "------------- == test----------" << endl;
             myDQ<int> copy(foo);
             cout << boolalpha << (foo == copy) << endl;
 ​
         }
 ​
         void test05()
         {
         }
 ​
         void test06()
         {
         }
     }
 }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值