// 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