【試着本身寫一個STL 】Knife_STL —— algobase.h 2

// We get the last iterator pair if these two is soooo match
template <typename InputIterator_a, typename InputIterator_b>
inline pair<InputIterator_a, InputIterator_b>
mismatch(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b)
{
	while (first_a != last_a && *first_a == *first_b)
	{
		++first_a;
		++first_b;
	}

	return pair<InputIterator_a, InputIterator_b>(first_a, first_b);
}

template <typename InputIterator_a, typename InputIterator_b,
			 typename BinaryPredicate> // BinaryPredicate could be a functor
inline pair<InputIterator_a, InputIterator_b>
mismatch(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	// The binary predicate should handle the content the iterator point to
	// so we should pass content the iterator point to rather than the iterator
	// to the binary predicate to handle
	while (first_a != last_a && binary_predicate(*first_a, *first_b))
	{
		++first_a;
		++first_b;
	}

	return pair<InputIterator_a, InputIterator_b>(first_a, first_b);
}

// 有時候咱們並不須要獲得mismatch的iterator組成的pair
// 這給咱們一種兩層封裝的感受,咱們可能只要mismatch的value組成的pair
// 因此我直接封裝了這樣一個函數,知足需求
// 這個函數也有他的BinaryPredicate版本
template <typename InputIterator_a, typename InputIterator_b>
inline pair<typename iterator_traits<InputIterator_a>::value_type,
			typename iterator_traits<InputIterator_b>::value_type>
mismatch_content(InputIterator_a first_a, InputIterator_a last_a, 
					InputIterator_b first_b)
{
	while (first_a != last_a && *first_a == *first_b)
	{
		++first_a;
		++first_b;
	}

	return pair<typename iterator_traits<InputIterator_a>::value_type,
				typename iterator_traits<InputIterator_b>::value_type>
		   (*first_a, *first_b);
}

template <typename InputIterator_a, typename InputIterator_b, 
			typename BinaryPredicate>
inline pair<typename iterator_traits<InputIterator_a>::value_type,
			typename iterator_traits<InputIterator_b>::value_type>
mismatch_content(InputIterator_a first_a, InputIterator_a last_a, 
					InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (first_a != last_a && binary_predicate(*first_a, *first_b))
	{
		++first_a;
		++first_b;
	}

	return pair<typename iterator_traits<InputIterator_a>::value_type,
				typename iterator_traits<InputIterator_b>::value_type>
		   (*first_a, *first_b);
}

// 遍歷式的實現,當咱們找到不符合的部分時,就直接退出,減小CPU佔用
template <typename InputIterator_a, typename InputIterator_b>
inline bool
equal(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b)
{
	while (first_a != last_a)
	{
		if (*first_a == *first_b)
		{
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}

	return true;
}

template <typename InputIterator_a, typename InputIterator_b, 
			typename BinaryPredicate>
inline bool
equal(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (first_a != last_a)
	{
		if (binary_predicate(*first_a, *first_b))
		{
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

// I added this function for the reason the same as we added the function fill_n
template <typename InputIterator_a, typename _Size, typename InputIterator_b>
inline bool
equal_n(InputIterator_a first_a, _Size size, InputIterator_b first_b)
{
	while (size != _Size(0))
	{
		if (*first_a == *first_b)
		{
			--size;
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

template <typename InputIterator_a, typename _Size, 
			typename InputIterator_b, typename BinaryPredicate>
inline bool
equal(InputIterator_a first_a, _Size size, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (size != _Size(0))
	{
		if (binary_predicate(*first_a, *first_b))
		{
			--size;
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

// 來自有道字典:lexicographic -- 字典式的, 以字典序比較兩個list
// 多用於比較兩個字符串,因此有專門對於字符串的優化
// 在a < b時返回true
template <typename InputIterator_a, typename InputIterator_b>
inline bool
lexicographical_compare(InputIterator_a first_a, InputIterator_a last_a, 
						InputIterator_b first_b, InputIterator_b last_b)
{
	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (*first_b < *first_a) return true;
		if (*first_a < *first_b) return false;
	}

	// Note:: must be && here!!
	return first_a == last_a && first_b != last_b;
}

// STL有一個對於字符串的優化版本,這個版本借用C的函數實現
// 看來C的函數確實在char*處理方面效率很高,多多學習,之後能夠用上
// 可是這裏CHAR_MAX == SCHAR_MAX的部分實在不懂,爲什麼要這樣?
// 因此我這裏只使用了unsigned char*的實現代替了char*的實現
// 好像還挺好用
inline bool
lexicographical_compare(const char* first_a, 
						const char* last_a, 
						const char* first_b, 
						const char* last_b)
{
	const size_t len_a = last_a - first_a;
	const size_t len_b = last_b - first_b;
	const int result = memcmp(first_a, first_b, min(len_a, len_b));
	return result != 0 ? result < 0 : len_a < len_b;
}

// inline bool
// lexicographical_compare(const char* first_a, 
// 						const char* last_a, 
// 						const char* first_b, 
// 						const char* last_b)
// {
// 	const size_t len_a = last_a - first_a;
// 	const size_t len_b = last_b - first_b;
// 	const int result = memcmp(first_a, first_b, min(len_a, len_b));
// 	knife::printf("Result: ", result);
// 	return result != 0 ? result < 0 : len_a < len_b;
// }

// inline bool 
// lexicographical_compare(const char* first1,
// 						const char* last1,
//                         const char* first2, 
//                         const char* last2)
// {
// #if CHAR_MAX == SCHAR_MAX
//   	return lexicographical_compare(	(const signed char*) first1,
//                                  	(const signed char*) last1,
//                                  	(const signed char*) first2,
//                                  	(const signed char*) last2);
// #else
//   	return lexicographical_compare(	(const unsigned char*) first1,
//                                  	(const unsigned char*) last1,
//                                  	(const unsigned char*) first2,
//                                  	(const unsigned char*) last2);
// #endif
// }

template <typename InputIterator_a, typename InputIterator_b, typename Compare>
inline bool
lexicographical_compare(InputIterator_a first_a, InputIterator_a last_a, 
						InputIterator_b first_b, InputIterator_b last_b, 
						Compare comp)
{
	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (comp(*first_a, *first_b)) return true;
		if (comp(*first_a, *first_b)) return false;
	}

	// Note:: must be && here!!
	return first_a == last_a && first_b != last_b;
}

// 我更改了一下實現的方法,我的認爲比原版的好,這裏貼出原版的
// 各位能夠比較一下
template <typename InputIterator_a, typename InputIterator_b>
inline int
lexicographical_compare_3way(InputIterator_a first_a, InputIterator_a last_a, 
							 InputIterator_b first_b, InputIterator_b last_b)
{
	static int more = 1;
	static int less = -1;
	static int equal = 0;

	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (*first_a < *first_b) return less;
		if (*first_b < *first_a) return more;
	}

	return (first_a == last_a) ? ((first_b == last_b) ? equal : less) : more;
}

// 如下都屬於原版
// template <class InputIterator1, class InputIterator2>
// int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
//                                  InputIterator2 first2, InputIterator2 last2)
// {
//     while (first1 != last1 && first2 != last2) {
//         	if (*first1 < *first2) return -1;
//         	if (*first2 < *first1) return 1;
// 			++first1; ++first2;
//     }
//
//     if (first2 == last2) {
// 			return !(first1 == last1);
//     } else {
//         	return -1;
//     }
// }

template <typename InputIterator_a, typename InputIterator_b, typename Compare>
inline int
lexicographical_compare_3way(InputIterator_a first_a, InputIterator_a last_a, 
							 InputIterator_b first_b, InputIterator_b last_b, 
							 Compare comp)
{
	static int more = 1;
	static int less = -1;
	static int equal = 0;

	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (comp(*first_a, *first_b)) return less;
		if (comp(*first_b, *first_a)) return more;
	}

	return (first_a == last_a) ? ((first_b == last_b) ? equal : less) : more;
}

// 這裏有一個例外:如"apple"和"appleapple"比較返回的就是-5
// 這裏有點沒搞懂他設計的想法,難道不是a比b小的時候返回-1嗎?
// 他的想法貌似是對兩個字符串比較時,咱們還須要得出一些額外的值
// 用以告訴user更多信息,但爲何不在template的部分也這麼作呢?
// 恰恰要在特化部分這麼作
inline int 
lexicographical_compare_3way(const char* first_a, const char* last_a,
							 const char* first_b, const char* last_b)
{
	const size_t len_a = last_a - first_a;
	const size_t len_b = last_b - first_b;
	const int result = memcmp(first_a, first_b, min(len_a, len_b));
	knife::printf(len_a, len_b);
	return result == 0 ? len_a - len_b : result;
}
// 後面的問題很lexicographical_compare同樣,就不舉例了

// SGI的做者真是直接額,不知道的就直接叫pointer
// 對於我這種命名強迫症患者真是解脫
template <typename T>
inline void destroy(T* pointer)
{
	pointer->~T();
}

// placement new for initialize A_Type in 
// the place where the A_Type* pointer point
// 這個placement new 很是的暴力,若是你傳個臨時變量
// 的地址過來,他也會執行的,這個函數會在你只重載了
// void* operator new(size_t)的時候報錯,由於沒有
// void* operator new(size_t, B_Type*)的版本
// 看來世上的事不能老是保證正確,雖然咱們已經盡力了
template <typename A_Type, typename B_Type>
inline void construct(A_Type* buffer, const B_Type& value)
{
	new (buffer) A_Type(value);
}

template <typename ForwardIterator>
inline void __destroy_aux_aux(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
{
	for (; first != last; ++first) destroy(&*first);
}

template <typename RandomAccessIterator, typename Distance>
inline void __destroy_aux_aux_d(RandomAccessIterator first, RandomAccessIterator last, Distance*)
{
	for (Distance d = last - first; d != Distance(0); --d, ++first) destroy(&*first);
}

// 相對於原文我又作了一次封裝,相信你們不介意的吧
template <typename RandomAccessIterator>
inline void __destroy_aux_aux(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
	__destroy_aux_aux_d(first, last, distance_type(first));
}

template <typename ForwardIterator>
inline void _destroy_aux(ForwardIterator first, ForwardIterator last, __false_type)
{
	__destroy_aux_aux(first, last, iterator_category(first));
}

// trivial destructor即無用的destructor,因此能夠不調用
template <typename ForwardIterator>
inline void _destroy_aux(ForwardIterator first, ForwardIterator last, __true_type) {}

// 爲啥要叫_destroy_aux?!!!!,aux是輔助的意思
// 爲了獲得iterator所指的類型,咱們不得不作一次這樣的包裝
template <typename ForwardIterator, typename Content>
inline void _destroy(ForwardIterator first, ForwardIterator last, const Content&)
{
	_destroy_aux(first, last, __type_traits<Content>::has_trivial_destructor());
}

template <typename ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
	_destroy(first, last, value_type(first));
}

// char類型固然有trivial_destructor,但你們貌似常常對char*作這樣的操做
// 爲了優化,就直接寫了這樣一個特化版本,這是C++ GP裏面很是重要經常使用的方法
// 學習了!
inline void destroy(char*, char*) {}
inline void destroy(wchar_t*, wchar_t*) {}

_STL_NAMESPACE_END

#endif
相關文章
相關標籤/搜索