STL source code analysis --- stl_algobase.h Reading Notes

Source: Internet
Author: User
The STL standard does not distinguish between basic algorithms or complex algorithms. SGI defines some common algorithms in <stl_algobase.h>, while other algorithms are defined in <stl_algo.h>.

The algorithm in stl_algobase.h is worth learning about copy (), which improves the efficiency of "having no need to use it. The purpose of copy is to copy an element to a specified range. The assignment operator = is the easiest way to think of a copy operation. However, some assignment operators = are trivial and can be copied directly. For details about whether the value assignment operator = is trivial, refer to the difference between memberwise copy and bitwise copy ".

The following describes the copy call process.


G ++ 2.91.57, Cygnus \ cygwin-b20 \ include \ G ++ \ stl_algobase.h complete list/*** copyright (c) 1994 * Hewlett-Packard Company ** permission to use, copy, modify, distribute and modify this software * and its documentation for any purpose is hereby granted without handle, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * In suppo Rting documentation. hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. it is provided "as is" without express or implied warranty. * ** copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. ** permission to use, copy, modify, distribute and merge this software * and its documentation for any purpose is hereby granted without tables ,* Provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. silicon Graphics makes no * representations about the suitability of this software for any * purpose. it is provided "as is" without express or implied warranty. * // * Note: This is an internal header file, encoded ded by other STL Header S. * You shoshould not attempt to use it directly. */# ifndef _ parameters # DEFINE _ parameters # ifndef _ stl_config_h # include <stl_config.h> # endif # ifndef _ parameters # include <stl_relops.h> # endif # ifndef __ sgi_stl_internal_pair_h # include <stl_pair.h> # endif # ifndef _ type_traits_h _ # include <type_traits.h> # endif # include <string. h> # include <limits. h> # include <s Tdlib. h> # include <stddef. h> # include <New. h> # include <iostream. h> # ifndef _ partition # include <partition> # endif _ partition <class forwarditerator1, Class Partition, class T> inline void _ iter_swap (forwarditerator1 A, forwarditerator2 B, T *) {// T is the iterator, and T * is t TMP = * A; // The type pointed to by the iterator * A = * B; * B = TMP ;} // call the template <class forwarditerator1, class fo Rwarditerator2> inline void iter_swap (forwarditerator1 A, forwarditerator2 B) {// iter_swap () is a good example of "it is necessary to use the value type of the iterator. // Yes, it must know the value type of the iterator to declare an object and use it to temporarily place the object referred to by the iterator. _ Iter_swap (a, B, value_type (a); // pay attention to the third-digit type! /* // The following is defined as <stl_iterator.h> template <class iterator> inline typename iterator_traits <iterator >:: value_type * value_type (const iterator &) {return static_cast <typename iterator_traits <iterator>: value_type *> (0);} * // Hou Jie believes that (and provides evidence) The call does not need to be performed as in the uplink, use the following code: // typename iterator_traits <forwarditerator1>: value_type TMP = * A; // * A = * B; // * B = TMP ;} template <class T> inline void swap (T & A, T & B) {T TMP = A; A = B; B = TMP ;}# ifndef _ BorlandC __# UNDEF min # UNDEF maxtemplate <class T> inline const T & min (const T &, const T & B) {return B <? B: A;} template <class T> inline const T & MAX (const T & A, const T & B) {return a <B? B: A ;}# endif/* _ BorlandC _ */template <class T, class compare> inline const T & min (const T & A, const T & B, compare comp) {return comp (B, )? B: A; // The size comparison standard determined by comp} template <class T, class compare> inline const T & MAX (const T & A, const T & B, compare comp) {return comp (a, B )? B: A; // The size comparison standard determined by comp} template <class inputiterator, class outputiterator> inline outputiterator _ copy (inputiterator first, inputiterator last, outputiterator result, input_iterator_tag) {for (; first! = Last; ++ result, ++ first) * result = * First; return result;} template <class randomaccessiterator, class outputiterator, class distance> inline outputiterator _ copy_d (randomaccessiterator first, randomaccessiterator last, outputiterator result, distance *) {for (distance n = last-first; n> 0; -- N, ++ result, ++ first) * result = * First; // return result;} template <class randomaccessiterator, clas S outputiterator> inline outputiterator _ copy (randomaccessiterator first, last, outputiterator result, second) {return _ copy_d (first, last, result, distance_type (first ));} template <class inputiterator, class outputiterator> struct _ copy_dispatch {outputiterator operator () (inputiterator first, inputiterator last, outputiterator result) {return _ copy (first, Last, result, iterator_category (first) ;};# ifdef _ stl_class_partial_specialization // _ true_type indicates has trivial operator =. You can directly copy the template <class T> inline T * _ copy_t (const T * First, const T * Last, T * result, _ true_type) {memmove (result, first, sizeof (t) * (last-first); return result + (last-first );} // _ false_type means has non-rivial operator = template <class T> inline T * _ copy_t (const T * First, const T * Last, T * result, _ false_type) {return _ copy_d (first, last, result, (ptrdiff_t *) 0);} template <class T> struct __ Copy_dispatch <t *, T *> {T * operator () (T * First, T * Last, T * result) {typedef typename _ type_traits <t> :: has_trivial_assignment_operator t; return _ copy_t (first, last, result, T () ;}; template <class T> struct _ copy_dispatch <const T *, T *> {T * operator () (const T * First, const T * Last, T * result) {// value assignment operator = whether it is trivial's typedef typename _ type_traits <t>: has_trivial_assignment_operator t; return _ Co Py_t (first, last, result, T () ;};# endif/* _ stl_class_partial_specialization * // set [first last) copy the range element to [result + (last-first) // The copy function uses the function overloading, type traits, partial // specialization to improve efficiency. // There is also copy_backward below, which is copied from the back to the front. Avoid overlap between two intervals // [first last) and [result + (last-first. // If values are assigned one by one, they will be overwritten, but memmove will not be used, because it will first copy the // value. Template <Class Identifier, class outputiterator> inline outputiterator copy (inputiterator first, inputiterator last, outputiterator result) {return _ copy_dispatch <inputiterator, outputiterator> () (first, last, result);} inline char * Copy (const char * First, const char * Last, char * result) {memmove (result, first, last-first ); return result + (last-first);} inline wchar_t * Copy (const wchar_t * fir St, const wchar_t * Last, wchar_t * result) {memmove (result, first, sizeof (wchar_t) * (last-first); return result + (last-first );} template <class inline, class bidirectionaliterator2> inline bidirectionaliterator2 _ copy_backward (bidirectionaliterator1 first, bidirectionaliterator1 last, bidirealialiterator2 result) {While (first! = Last) * -- result = * -- last; return result;} template <class member, class bidirectionaliterator2> struct _ copy_backward_dispatch {Operator () (bidirectionaliterator1 first, bidirectionaliterator1 last, bidirectionaliterator2 result) {return _ copy_backward (first, last, result) ;};# ifdef _ stl_class_partial_specialization template <class T> inline T * _ copy_back Ward_t (const T * First, const T * Last, T * result, _ true_type) {const ptrdiff_t n = last-first; memmove (result-N, first, sizeof (t) * n); return result-N;} template <class T> inline T * _ copy_backward_t (const T * First, const T * Last, T * result, _ false_type) {return _ copy_backward (first, last, result);} template <class T> struct _ copy_backward_dispatch <t *, T *> {T * operator () (T * First, T * last, T * result) {typedef typename _ type_traits <t >:: has_trivial_assignment_operator t; return _ copy_backward_t (first, last, result, T ());}}; template <class T> struct _ copy_backward_dispatch <const T *, T *> {T * operator () (const T * First, const T * Last, T * result) {typedef typename _ type_traits <t>: has_trivial_assignment_operator t; return _ copy_backward_t (first, last, result, T () ;};# endif/* _ s Optional */template <Class Identifier, class bidirectionaliterator2> inline bidirectionaliterator2 copy_backward (partition first, last, partition result) {return _ copy_backward_dispatch <partition, bidirectionaliterator2> () (first, last, result);} template <class inputiterator, class size, class outputit Erator> pair <inputiterator, outputiterator> _ copy_n (inputiterator first, size count, outputiterator result, input_iterator_tag) {for (; count> 0; -- count, ++ first, ++ result) * result = * First; return pair <inputiterator, outputiterator> (first, result);} template <class randomaccessiterator, class size, class outputiterator> inline pair <randomaccessiterator, outputiterator >__ copy_n (randomaccessitera Tor first, size count, outputiterator result, operator) {randomaccessiterator last = first + count; return pair <randomaccessiterator, outputiterator> (last, copy (first, last, result ));} // The following is the space exclusive to sgi stl, where the Count elements are copied from first to the result. Template <class inputiterator, class size, class outputiterator> inline pair <inputiterator, outputiterator> copy_n (inputiterator first, size count, outputiterator result) {return _ copy_n (first, count, result, iterator_category (first);} // change all elements in [first last) to the new value valuetemplate <class forwarditerator, class T> void fill (forwarditerator first, forwarditerator last, const T & Value) {for (; first! = Last; ++ first) // The iteration goes through the entire range * First = value;} // Note: N cannot exceed the range length. template <class outputiterator, class size, class T> outputiterator fill_n (outputiterator first, size N, const T & Value) {for (; n> 0; -- N, ++ first) // After n elements * First = value; // note that assignment overwrites rather than inserts return first;} // compares two intervals, specifies the first point of mismatch between the two. Returns an iterator pointing out the unmatched points of the two intervals. If they all match, the return value is the last iterator pointing to two intervals. Template <class inputiterator1, class inputiterator2> pair <strong, inputiterator2> mismatch (interval first1, interval last1, inputiterator2 first2) {// If the sequence is completed, it ends. // If the elements of sequence 1 and Sequence 2 are equal, the end ends. // Obviously, the number of elements in the interval 1 must be greater than the number of elements in the sequence 2; otherwise, the result is unpredictable. While (first1! = Last1 & * first1 = * first2) {++ first1; ++ first2;} return pair <strong, inputiterator2> (first1, first2);} template <class inputiterator1, class Identifier, class binarypredicate> pair <identifier, identifier> mismatch (inputiterator1 first1, inputiterator1 last1, interval first2, binarypredicate binary_pred) {While (first1! = Last1 & binary_pred (* first1, * first2) {++ first1; ++ first2;} return pair <inputiterator1, inputiterator2> (first1, first2 );} // if the two intervals are equal in the [first last) interval, true is returned. If there are many elements in the second interval, extra values are not considered. If there are few elements in the second interval, there will be unpredictable results. Therefore, it is best to determine the interval size before use. Template <class inputiterator1, class inputiterator2> inline bool equal (inputiterator1 first1, inputiterator1 last1, inputiterator2 first2) {// traverse the elements in the interval. // if the number of elements in the interval one is greater than the number of elements in the interval two, it will be terrible. For (; first1! = Last1; ++ first1, ++ first2) if (* first1! = * First2) // return false as long as the corresponding elements are not equal; // The result ends and false is returned. Return true; // At this point, all are equal, and true is returned .} Template <Class Identifier, class inputiterator2, class binarypredicate> inline bool equal (inputiterator1 first1, interval last1, interval first2, binarypredicate binary_pred) {for (; first1! = Last1; ++ first1, ++ first2) if (! Binary_pred (* first1, * first2) return false; return true;} // sort two intervals [first1 last1) and [first2 last2) alphabetically) compare the template <class frequency, class inputiterator2> bool frequency (inputiterator1 first1, interval last1, interval first2, inputiterator2 last2) {// below. When any interval reaches the end, it ends. Otherwise, the two intervals compare the corresponding elements one by one. For (; first1! = Last1 & first2! = Last2; ++ first1, ++ first2) {If (* first1 <* first2) // return true if the element value of the first sequence is less than the element value of the second sequence; if (* first2 <* first1) // If the element value of the second sequence is smaller than the corresponding element value of the first sequence, return false; // if the two conditions are not met, the two values are equal, then compare the values of the corresponding elements in the next group.} // Run here. If the first interval reaches the end and the second interval has a balance, the first interval is smaller than the second interval. Return first1 = last1 & first2! = Last2;} template <class average, class inputiterator2, class compare> bool average (inputiterator1 first1, interval last1, interval first2, interval last2, compare comp) {for (; first1! = Last1 & first2! = Last2; ++ first1, ++ first2) {If (COMP (* first1, * first2) return true; If (COMP (* first2, * first1 )) return false;} return first1 = last1 & first2! = Last2;} inline bool lexicographical_compare (const unsigned char * first1, const unsigned char * last1, const unsigned char * first2, const unsigned char * last2) {const size_t len1 = last1-first1; // the length of the first interval const size_t len2 = last2-first2; // the length of the second interval // compare the length of the second interval first. Memcmp () is extremely fast. Const int result = memcmp (first1, first2, min (len1, len2); // If the length is equal to the upper limit, the length is considered larger. Return result! = 0? Result <0: len1 <len2;} inline bool lexicographical_compare (const char * first1, const char * last1, const char * first2, const char * last2) {# If char_max = schar_max // convert to const signed Char * return lexicographical_compare (const signed Char *) first1, (const signed Char *) last1, (const signed Char *) first2, (const signed Char *) last2); # else // convert to const unsigned char * return lexicographical_compar E (const unsigned char *) first1, (const unsigned char *) last1, (const unsigned char *) first2, (const unsigned char *) last2 ); # endif} template <class inputiterator1, class inputiterator2> int partition (inputiterator1 first1, inputiterator1 last1, interval first2, interval 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 ;}} inline intlexicographical_compare_3way (const unsigned char * first1, const unsigned char * last1, const unsigned char * first2, const unsigned char * last2) {const ptrdiff_t len1 = last1-first1; const ptrdiff_t len2 = last2-first2; const int result = memcmp (first1, first2, min (len1, len2); return result! = 0? Result: (len1 = len2? 0: (len1 <len2? -1: 1);} inline int lexicographical_compare_3way (const char * first1, const char * last1, const char * first2, const char * last2) {# If char_max = schar_max return lexicographical_compare_3way (const signed Char *) first1, (const signed Char *) last1, (const signed Char *) first2, (const signed Char *) last2); # else return lexicographical_compare_3way (const unsigned char *) first1, (const unsigned char *) last1, (const unsigned char *) first2, (const unsigned char *) last2); # endif }__ stl_end_namespace # endif/* _ sgi_stl_internal_algobase_h * // local variables: // mode: C ++ // end:


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.