天天看點

C++-----MySTL實作(2)---記憶體基本處理工具

1、相關

        STL定義了五個全局函數,作用域為初始化空間上,這樣的功能對于容器的實作很有幫助,在後面的容器實作代碼中會看到他們的作用,前兩個函數是在上一篇實作的用于構造的construct()和用于析構的destroy()。另外三個在本節實作。其中用到幾個算法比如copy()和fill()等,将在後面算法中實作,這裡知道含義即可。

2、代碼

/*
*STL中有五個全局函數作用于未初始化的空間上,這個檔案實作下面三個
* uninitialized_copy(),uninitialized_fill(),
* uninitialized_fill_n(),以及其他相關函數
*/
#ifndef UNINITIALIZED_H_
#define UNINITIALIZED_H_
#include "construct.h"
#include "algorithm.h"
namespace MySTL {
	/*
	* 以下是uninitialized_copy的實作
	*容器的全區間構造函數會首先配置記憶體區塊,足以包含範圍内所有元素
	**然後會調用uninitialized_copy()在該記憶體區塊上構造元素
	*/
	//如果是POD資料類型,執行下面的函數
	/*POD資料類型是為了解決C++與C之間資料類型的相容性
	*可以簡單地了解為如果對象是采用預設構造函數、
	*預設析構函數、預設拷貝指派函數就認為是POD,否則就不是
	*POD資料類型記憶體中是連續的
	*/
	template<class _InputIterator,class _ForwordIterator>
	_ForwordIterator _uninitialized_copy_aux(_InputIterator first, _InputIterator last,
		_ForwardIterator result, __true_type) {
		//copy函數在algobase.h裡實作
		rerturn copy(first, last, result);
	}
	// 如果是non-POD 型别,執行流程就會轉進到以下函數
	template <class _InputIterator, class _ForwardIterator>
	_ForwardIterator _uninitialized_copy_aux(_InputIterator first, _InputIterator last,
		_ForwardIterator result, __false_type)
	{
		_ForwardIterator cur = result;
		try
		{
			for (; first != last; ++first, ++cur)
				construct(&*cur, *first);	//必須一個一個元素地建構,無法批量進行
			return cur;
		}
		catch (...)
		{
			destroy(result, cur);
			throw;
		}
	}
	//_uninitialized_copy函數,利用萃取技術根據傳入對象調用上面兩個不同函數
	//函數功能:輸入一個疊代器範圍,在以result起始位置上,複制
	//從first到last疊代器指向的對象,然後放在result開始的位置。
	template <class _InputIterator, class _ForwardIterator, class _T>
	inline
		_ForwardIterator _uninitialized_copy(_InputIterator first, _InputIterator last,
			_ForwardIterator result, _T*)
	{
		typedef typename __type_traits<_T>::is_POD_type is_POD;
		//利用 is_POD() 所獲得的結果,讓編譯程式做自變量推導。
		return _uninitialized_copy_aux(first, last, result, is_POD());

	}

	template <class _InputIterator, class _ForwardIterator>
	inline
		_ForwardIterator uninitialized_copy(_InputIterator first, _InputIterator last,
			_ForwardIterator result)
	{
		//利用 value_type() 取出 first 的 value type.
		return _uninitialized_copy(first, last, result, value_type(result));

	}

	// 以下是針對 const char* 的特化版本
	// 采用memmove()函數快速拷貝
	inline
		char* uninitialized_copy(const char* first, const char* last, char* result)
	{
		memmove(result, first, last - first);
		return result + (last - first);
	}

	/* 以下是uninitialized_copy_n的實作:
	*n是要構造的元素的個數
	*
	*/
	
	//疊代器類型是input_iterator_tag
	template <class _InputIterator, class _Size, class _ForwardIterator>
	pair<_InputIterator, _ForwardIterator> _uninitialized_copy_n(_InputIterator first,
		_Size count, _ForwardIterator result, input_iterator_tag)
	{
		_ForwardIterator cur = result;
		try
		{
			for (; count > 0; --count, ++first, ++cur)
				construct(&*cur, *first);
			return pair<_InputIterator, _ForwardIterator>(first, cur);
		}
		catch (...)
		{
			destroy(result, cur);
			throw;
		}
	}
	//疊代器類型是random_access_iterator_tag
	template <class _RandomAccessIterator, class _Size, class _ForwardIterator>
	inline
		pair<_RandomAccessIterator, _ForwardIterator> _uninitialized_copy_n(
			_RandomAccessIterator first, _Size count,
			_ForwardIterator result, random_access_iterator_tag)
	{
		_RandomAccessIterator last = first + count;
		return make_pair(last, uninitialized_copy(first, last, result));
	}

	//根據疊代器類型跳轉到上面兩個函數中一個
	template <class _InputIterator, class _Size, class _ForwardIterator>
	inline
		pair<_InputIterator, _ForwardIterator> uninitialized_copy_n(_InputIterator first,
			_Size count, _ForwardIterator result)
	{
		//根據疊代器型别跳轉執行函數
		return _uninitialized_copy_n(first, count, result, iterator_category(first));
	}

	/* 以下是uninitialized_fill的實作:
	*void uninitialized_fill(_ForwardIterator first, _ForwardIterator last,	const _T& x) 
	*上為函數原型,也能将記憶體配置與對象構造行為分離開,如果在[first,last)上每個
	*疊代器都指向沒有初始化的記憶體,那麼這個函數将在這個範圍内産生x的複制品。
	*
	*/

	// 如果是POD 型别,POD前面說過,會轉進到以下函數
	template <class _ForwardIterator, class _T>
	inline
		void _uninitialized_fill_aux(_ForwardIterator first, _ForwardIterator last,
			const _T& x, __true_type)
	{
		fill(first, last, x);//算法fill()
	}

	// 如果是non-POD 型别,執行流程就會轉進到以下函數
	template <class _ForwardIterator, class _T>
	void _uninitialized_fill_aux(_ForwardIterator first, _ForwardIterator last,
		const _T& x, __false_type)
	{
		_ForwardIterator cur = first;
		try
		{
			for (; cur != last; ++cur)
				construct(&*cur, x);	// 必須一個一個元素地建構,無法批量進行
		}
		catch (...)
		{
			destroy(first, cur);
			throw;
		}
	}
	//根據是否為POD類型調用上面的函數
	template <class _ForwardIterator, class _T, class _T1>
	inline void _uninitialized_fill(_ForwardIterator first, _ForwardIterator last,
		const _T& x, _T1*)
	{
		typedef typename __type_traits<_T1>::is_POD_type is_POD;
		_uninitialized_fill_aux(first, last, x, is_POD());

	}
	//根據疊代器類型
	template <class _ForwardIterator, class _T>
	inline
		void uninitialized_fill(_ForwardIterator first, _ForwardIterator last,
			const _T& x)
	{
		//利用 value_type() 取出 first 的 value type.
		_uninitialized_fill(first, last, x, value_type(first));
	}

	/*以下是uninitialized_fill_n的實作:
	*_ForwardIterator uninitialized_fill_n(_ForwardIterator first, _Size n,const _T& x)
	*在指定範圍内為所有元素設定相同的初值
	*如果在[first,last)上每個
	*疊代器都指向沒有初始化的記憶體,那麼這個函數将在這個範圍内産生x的複制品。
	*/

	// 如果是POD 型别,執行流程就會轉進到以下函數
	template <class _ForwardIterator, class _Size, class _T>
	inline
		_ForwardIterator _uninitialized_fill_n_aux(_ForwardIterator first, _Size n,
			const _T& x, __true_type)
	{
		return MyStl::fill_n(first, n, x); //算法fill_n()
	}

	// 如果是non-POD 型别,執行流程就會轉進到以下函數
	template <class _ForwardIterator, class _Size, class _T>
	_ForwardIterator _uninitialized_fill_n_aux(_ForwardIterator first, _Size n,
		const _T& x, __false_type)
	{
		_ForwardIterator cur = first;
		try
		{
			for (; n > 0; --n, ++cur)
				construct(&*cur, x);
			return cur;
		}
		catch (...)
		{
			destroy(first, cur);
			throw;
		}
	}
	//根據是否為POD轉向上面兩個函數
	template <class _ForwardIterator, class _Size, class _T, class _T1>
	inline _ForwardIterator _uninitialized_fill_n(_ForwardIterator first, _Size n,
		const _T& x, _T1*)
	{
		typedef typename __type_traits<_T1>::is_POD_type is_POD;
		return _uninitialized_fill_n_aux(first, n, x, is_POD());

	}
	//由value_type(first)得到疊代器型别
	template <class _ForwardIterator, class _Size, class _T>
	inline
		_ForwardIterator uninitialized_fill_n(_ForwardIterator first, _Size n,
			const _T& x)
	{
		return _uninitialized_fill_n(first, n, x, value_type(first));
	}

	/*__uninitialized_copy_copy、__uninitialized_fill_copy和__uninitialized_copy_fill函數
  *這幾個函數比較簡單,都是調用上面的函數就可以實作功能
	*/
	  //同時拷貝兩對疊代器内的内容
	 //拷貝[first1, last1)到[result, result + (last1 - first1))
     // 同時拷貝[first2, last2)到
    // [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)]
	template <class _InputIterator1, class _InputIterator2, class _ForwardIterator>
	inline
		_ForwardIterator _uninitialized_copy_copy(_InputIterator1 first1, _InputIterator1 last1,
			_InputIterator2 first2, _InputIterator2 last2, _ForwardIterator result)
	{
		//拷貝第一對疊代器到result,傳回位址是最後的位址
		_ForwardIterator mid = uninitialized_copy(first1, last1, result);
		try
		{
			//拷貝第二對疊代器到result,傳回位址是最後的位址
			return uninitialized_copy(first2, last2, mid);
		}
		catch (...)
		{
			destroy(result, mid);
			throw;
		}
	}

	//用x填充[result,mid),之後将[first,last)疊代器所指的内容
	//拷貝到mid之後
	//
	template <class _ForwardIterator, class _T, class _InputIterator>
	inline
		_ForwardIterator _uninitialized_fill_copy(_ForwardIterator result, _ForwardIterator mid,
			const _T& x, _InputIterator first, _InputIterator last)
	{
		uninitialized_fill(result, mid, x);
		try
		{
			return uninitialized_copy(first, last, mid);
		}
		catch (...)
		{
			destroy(result, mid);
			throw;
		}
	}

	// 和上面函數很像,隻不過調換順序,先拷貝再填充
	template <class _InputIterator, class _ForwardIterator, class _T>
	inline
		void _uninitialized_copy_fill(_InputIterator first1, _InputIterator last1,
			_ForwardIterator first2, _ForwardIterator last2, const _T& x)
	{
		_ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
		try
		{
			uninitialized_fill(mid2, last2, x);
		}
		catch (...)
		{
			destroy(first2, mid2);
			throw;
		}
	}

}//end of MyStl
#endif// end of UNINITIALIZED_H_