STL原始碼解析之uninitialized_fill_n簡單測試-(用到了迭代器萃取和型別萃取)
阿新 • • 發佈:2019-02-11
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; }