1. 程式人生 > >STL原始碼解析之uninitialized_fill_n簡單測試-(用到了迭代器萃取和型別萃取)

STL原始碼解析之uninitialized_fill_n簡單測試-(用到了迭代器萃取和型別萃取)

1. 《STL原始碼解析》P72的uninitialized_fill_n函式;

#include <iostream>
#include <new.h>
//using namespace std; //不要std,因為std名稱空間中也有input_iterator_tag等的定義

struct input_iterator_tag //std名稱空間中也有input_iterator_tag的定義
{
};

struct output_iterator_tag
{
};

struct forward_iterator_tag:public input_iterator_tag
{
};

struct bidirectional_iterator_tag:public forward_iterator_tag
{
};

struct random_access_iterator_tag:public bidirectional_iterator_tag
{
};

struct __true_type{};
struct __false_type{};

template <class T1, class T2>
inline void construct( T1 *p, const T2& value )
{
	new (p) T1(value);
	return;
}


template <class OutputIterator, class Size, class T>
OutputIterator fill_n( OutputIterator first, Size n, const T& value )
{
	for( ; n > 0; --n, ++first )
	{
		*first = value;
	}
	return first;
}

template <class Category, class T, class Distance = ptrdiff_t, class Pointer = T*, class Reference = T&>
struct iterator
{
	typedef Category iterator_category;
	typedef T value_type;
	typedef Distance difference_type;
	typedef Pointer pointer;
	typedef Reference reference;
};

template <class Iterator>
struct iterator_traits  // iterator_traits負責萃取迭代器的特性,例如獲得迭代器指向元素的型別等
{
	typedef typename Iterator::iterator_category iterator_category;
	typedef typename Iterator::value_type value_type;
	typedef typename Iterator::difference_type difference_type;
	typedef typename Iterator::pointer pointer;
	typedef typename Iterator::reference reference;
};

template <class T>
struct iterator_traits<T*>
{
	typedef random_access_iterator_tag iterator_category;
	typedef T value_type;
	typedef ptrdiff_t difference_type;
	typedef T* pointer;
	typedef T& reference;
};

template <class Iterator>
inline typename iterator_traits<Iterator>::value_type* value_type( const Iterator& )
{
	return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}

template <class type>
struct __type_traits
{
	typedef __false_type has_trivial_default_constructor;
	typedef __false_type has_trivial_copy_constructor;
	typedef __false_type has_trivial_assignment_operator;
	typedef __false_type has_trivial_destructor;
	typedef __false_type is_POD_type;
};

template <>
struct __type_traits<int>
{
	typedef __true_type has_trivial_default_constructor;
	typedef __true_type has_trivial_copy_constructor;
	typedef __true_type has_trivial_assignment_operator;
	typedef __true_type has_trivial_destructor;
	typedef __true_type is_POD_type;
};

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) );
}

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() ); 
}

template <class ForwardIterator, class Size, class T>
inline ForwardIterator __uninitialized_fill_n_aux( ForwardIterator first, Size n, const T& x, __true_type )
{
	return fill_n( first, n, x );
}

template <class ForwardIterator, class Size, class T>
ForwardIterator __uninitialized_fill_n_aux( ForwardIterator first, Size n, const T& x, __false_type )
{
	ForwardIterator cur = first;
	for( ; n > 0; --n, ++cur )
	{
		construct( &*cur, x );
	}
	return cur;
}

class Test
{
public:
	Test( int n = 0 )
	{
		std::cout << "Test::Test(" << n << ")被呼叫\n";
		data = n;
	}
	int operator()()
	{
		return data;
	}
	
	operator int()
	{
		return data;
	}
private:
	int data;
};

// iterator_traits負責萃取迭代器的特性,例如獲得迭代器指向元素的型別等
// __type_traits則負責萃取型別的特性,例如該型別是否具備non_trivial copy constructor,non_trivial default destructor等

int main()
{
	int a[] = { 1, 2, 3, 4, 5 };
	int *begin = &a[0];
	uninitialized_fill_n( begin, 5, 1 );
	
	for( int i = 0; i < 5; i++ )
	{
		std::cout << a[i] << ' ';  //輸出5個1
	}

	std::cout << std::endl;
	Test array[5];  //呼叫5次建構函式
	Test *pT = &array[0]; 
	uninitialized_fill_n( pT, 5, 2 ); //呼叫5次建構函式

	std::cout << std::endl;
	for( int i = 0; i < 5; i++ )
	{
		std::cout << array[i] << ' '; //輸出5個2

	}
	std::cout << std::endl;
	system("pause");
	return 0;
}