stl_algobase.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:17k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996-1998
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  */
  26. /* NOTE: This is an internal header file, included by other STL headers.
  27.  *   You should not attempt to use it directly.
  28.  */
  29. #ifndef __SGI_STL_INTERNAL_ALGOBASE_H
  30. #define __SGI_STL_INTERNAL_ALGOBASE_H
  31. #ifndef __STL_CONFIG_H
  32. #include <stl_config.h>
  33. #endif
  34. #ifndef __SGI_STL_INTERNAL_RELOPS
  35. #include <stl_relops.h>
  36. #endif
  37. #ifndef __SGI_STL_INTERNAL_PAIR_H
  38. #include <stl_pair.h>
  39. #endif
  40. #ifndef __TYPE_TRAITS_H_
  41. #include <type_traits.h>
  42. #endif
  43. #include <string.h>
  44. #include <limits.h>
  45. #include <stdlib.h>
  46. #include <stddef.h>
  47. #include <new.h>
  48. #include <iostream.h>
  49. #ifndef __SGI_STL_INTERNAL_ITERATOR_H
  50. #include <stl_iterator.h>
  51. #endif
  52. __STL_BEGIN_NAMESPACE
  53. // swap and iter_swap
  54. template <class _ForwardIter1, class _ForwardIter2, class _T>
  55. inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _T*) {
  56.   _T __tmp = *__a;
  57.   *__a = *__b;
  58.   *__b = __tmp;
  59. }
  60. template <class _ForwardIter1, class _ForwardIter2>
  61. inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
  62.   __iter_swap(__a, __b, __VALUE_TYPE(__a));
  63. }
  64. template <class _T>
  65. inline void swap(_T& __a, _T& __b) {
  66.   _T __tmp = __a;
  67.   __a = __b;
  68.   __b = __tmp;
  69. }
  70. //--------------------------------------------------
  71. // min and max
  72. #ifndef __BORLANDC__
  73. #undef min
  74. #undef max
  75. template <class _T>
  76. inline const _T& min(const _T& __a, const _T& __b) {
  77.   return __b < __a ? __b : __a;
  78. }
  79. template <class _T>
  80. inline const _T& max(const _T& __a, const _T& __b) {
  81.   return  __a < __b ? __b : __a;
  82. }
  83. #endif /* __BORLANDC__ */
  84. template <class _T, class _Compare>
  85. inline const _T& min(const _T& __a, const _T& __b, _Compare __comp) {
  86.   return __comp(__b, __a) ? __b : __a;
  87. }
  88. template <class _T, class _Compare>
  89. inline const _T& max(const _T& __a, const _T& __b, _Compare __comp) {
  90.   return __comp(__a, __b) ? __b : __a;
  91. }
  92. //--------------------------------------------------
  93. // copy
  94. // All of these auxiliary functions serve two purposes.  (1) Replace
  95. // calls to copy with memmove whenever possible.  (Memmove, not memcpy,
  96. // because the input and output ranges are permitted to overlap.)
  97. // (2) If we're using random access iterators, then write the loop as
  98. // a for loop with an explicit count.  The auxiliary class __copy_dispatch
  99. // is a workaround for compilers that don't support partial ordering of
  100. // function templates.
  101. template <class _InputIter, class _OutputIter, class _Distance>
  102. inline _OutputIter __copy(_InputIter __first, _InputIter __last,
  103.                           _OutputIter __result,
  104.                           input_iterator_tag, _Distance*)
  105. {
  106.   for ( ; __first != __last; ++__result, ++__first)
  107.     *__result = *__first;
  108.   return __result;
  109. }
  110. template <class _RandomAccessIter, class _OutputIter, class _Distance>
  111. inline _OutputIter
  112. __copy(_RandomAccessIter __first, _RandomAccessIter __last,
  113.        _OutputIter __result, random_access_iterator_tag, _Distance*)
  114. {
  115.   for (_Distance __n = __last - __first; __n > 0; --__n) {
  116.     *__result = *__first;
  117.     ++__first;
  118.     ++__result;
  119.   }
  120.   return __result;
  121. }
  122. template <class _T>
  123. inline _T* __copy_trivial(const _T* __first, const _T* __last, _T* __result) {
  124.   memmove(__result, __first, sizeof(_T) * (__last - __first));
  125.   return __result + (__last - __first);
  126. }
  127. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
  128. template <class _InputIter, class _OutputIter, class _BoolType>
  129. struct __copy_dispatch {
  130.   static _OutputIter copy(_InputIter __first, _InputIter __last,
  131.                           _OutputIter __result) {
  132.     typedef typename iterator_traits<_InputIter>::iterator_category _Category;
  133.     typedef typename iterator_traits<_InputIter>::difference_type _Distance;
  134.     return __copy(__first, __last, __result, _Category(), (_Distance*) 0);
  135.   }
  136. };
  137. template <class _T>
  138. struct __copy_dispatch<_T*, _T*, __true_type>
  139. {
  140.   static _T* copy(const _T* __first, const _T* __last, _T* __result) {
  141.     return __copy_trivial(__first, __last, __result);
  142.   }
  143. };
  144. template <class _T>
  145. struct __copy_dispatch<const _T*, _T*, __true_type>
  146. {
  147.   static _T* copy(const _T* __first, const _T* __last, _T* __result) {
  148.     return __copy_trivial(__first, __last, __result);
  149.   }
  150. };
  151. template <class _InputIter, class _OutputIter>
  152. inline _OutputIter copy(_InputIter __first, _InputIter __last,
  153.                         _OutputIter __result) {
  154.   typedef typename iterator_traits<_InputIter>::value_type _T;
  155.   typedef typename __type_traits<_T>::has_trivial_assignment_operator
  156.           _Trivial;
  157.   return __copy_dispatch<_InputIter, _OutputIter, _Trivial>
  158.     ::copy(__first, __last, __result);
  159. }
  160. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  161. template <class _InputIter, class _OutputIter>
  162. inline _OutputIter copy(_InputIter __first, _InputIter __last,
  163.                         _OutputIter __result)
  164. {
  165.   return __copy(__first, __last, __result,
  166.                 __ITERATOR_CATEGORY(__first),
  167.                 __DISTANCE_TYPE(__first));
  168. }
  169. inline char* copy(const char* __first, const char* __last, char* __result) {
  170.   memmove(__result, __first, __last - __first);
  171.   return __result + (__last - __first);
  172. }
  173. inline wchar_t* copy(const wchar_t* __first, const wchar_t* __last,
  174.                      wchar_t* __result) {
  175.   memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
  176.   return __result + (__last - __first);
  177. }
  178. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  179. //--------------------------------------------------
  180. // copy_backward
  181. template <class _BidirectionalIter1, class _BidirectionalIter2, 
  182.           class _Distance>
  183. inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, 
  184.                                            _BidirectionalIter1 __last, 
  185.                                            _BidirectionalIter2 __result,
  186.                                            bidirectional_iterator_tag,
  187.                                            _Distance*)
  188. {
  189.   while (__first != __last)
  190.     *--__result = *--__last;
  191.   return __result;
  192. }
  193. template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
  194. inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, 
  195.                                           _RandomAccessIter __last, 
  196.                                           _BidirectionalIter __result,
  197.                                           random_access_iterator_tag,
  198.                                           _Distance*)
  199. {
  200.   for (_Distance __n = __last - __first; __n > 0; --__n)
  201.     *--__result = *--__last;
  202.   return __result;
  203. }
  204. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
  205. // This dispatch class is a workaround for compilers that do not 
  206. // have partial ordering of function templates.  All we're doing is
  207. // creating a specialization so that we can turn a call to copy_backward
  208. // into a memmove whenever possible.
  209. template <class _BidirectionalIter1, class _BidirectionalIter2,
  210.           class _BoolType>
  211. struct __copy_backward_dispatch
  212. {
  213.   typedef typename iterator_traits<_BidirectionalIter1>::iterator_category 
  214.           _Cat;
  215.   typedef typename iterator_traits<_BidirectionalIter1>::difference_type
  216.           _Distance;
  217.   static _BidirectionalIter2 copy(_BidirectionalIter1 __first, 
  218.                                   _BidirectionalIter1 __last, 
  219.                                   _BidirectionalIter2 __result) {
  220.     return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0);
  221.   }
  222. };
  223. template <class _T>
  224. struct __copy_backward_dispatch<_T*, _T*, __true_type>
  225. {
  226.   static _T* copy(const _T* __first, const _T* __last, _T* __result) {
  227.     const ptrdiff_t _Num = __last - __first;
  228.     memmove(__result - _Num, __first, sizeof(_T) * _Num);
  229.     return __result - _Num;
  230.   }
  231. };
  232. template <class _T>
  233. struct __copy_backward_dispatch<const _T*, _T*, __true_type>
  234. {
  235.   static _T* copy(const _T* __first, const _T* __last, _T* __result) {
  236.     return  __copy_backward_dispatch<_T*, _T*, __true_type>
  237.       ::copy(__first, __last, __result);
  238.   }
  239. };
  240. template <class _BI1, class _BI2>
  241. inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
  242.   typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
  243.                         ::has_trivial_assignment_operator
  244.           _Trivial;
  245.   return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
  246.               ::copy(__first, __last, __result);
  247. }
  248. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  249. template <class _BI1, class _BI2>
  250. inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
  251.   return __copy_backward(__first, __last, __result,
  252.                          __ITERATOR_CATEGORY(__first),
  253.                          __DISTANCE_TYPE(__first));
  254. }
  255. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  256. //--------------------------------------------------
  257. // copy_n (not part of the C++ standard)
  258. template <class _InputIter, class _Size, class _OutputIter>
  259. pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count,
  260.                                        _OutputIter __result,
  261.                                        input_iterator_tag) {
  262.   for ( ; __count > 0; --__count, ++__first, ++__result)
  263.     *__result = *__first;
  264.   return pair<_InputIter, _OutputIter>(__first, __result);
  265. }
  266. template <class _RAIter, class _Size, class _OutputIter>
  267. inline pair<_RAIter, _OutputIter>
  268. __copy_n(_RAIter __first, _Size __count,
  269.          _OutputIter __result,
  270.          random_access_iterator_tag) {
  271.   _RAIter __last = __first + __count;
  272.   return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result));
  273. }
  274. template <class _InputIter, class _Size, class _OutputIter>
  275. inline pair<_InputIter, _OutputIter>
  276. __copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
  277.   return __copy_n(__first, __count, __result,
  278.                   __ITERATOR_CATEGORY(__first));
  279. }
  280. template <class _InputIter, class _Size, class _OutputIter>
  281. inline pair<_InputIter, _OutputIter>
  282. copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
  283.   return __copy_n(__first, __count, __result);
  284. }
  285. //--------------------------------------------------
  286. // fill and fill_n
  287. template <class _ForwardIter, class _T>
  288. void fill(_ForwardIter __first, _ForwardIter __last, const _T& __value) {
  289.   for ( ; __first != __last; ++__first)
  290.     *__first = __value;
  291. }
  292. template <class _OutputIter, class _Size, class _T>
  293. _OutputIter fill_n(_OutputIter __first, _Size __n, const _T& __value) {
  294.   for ( ; __n > 0; --__n, ++__first)
  295.     *__first = __value;
  296.   return __first;
  297. }
  298. //--------------------------------------------------
  299. // equal and mismatch
  300. template <class _InputIter1, class _InputIter2>
  301. pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
  302.                                         _InputIter1 __last1,
  303.                                         _InputIter2 __first2) {
  304.   while (__first1 != __last1 && *__first1 == *__first2) {
  305.     ++__first1;
  306.     ++__first2;
  307.   }
  308.   return pair<_InputIter1, _InputIter2>(__first1, __first2);
  309. }
  310. template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
  311. pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
  312.                                         _InputIter1 __last1,
  313.                                         _InputIter2 __first2,
  314.                                         _BinaryPredicate __binary_pred) {
  315.   while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
  316.     ++__first1;
  317.     ++__first2;
  318.   }
  319.   return pair<_InputIter1, _InputIter2>(__first1, __first2);
  320. }
  321. template <class _InputIter1, class _InputIter2>
  322. inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
  323.                   _InputIter2 __first2) {
  324.   for ( ; __first1 != __last1; ++__first1, ++__first2)
  325.     if (*__first1 != *__first2)
  326.       return false;
  327.   return true;
  328. }
  329. template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
  330. inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
  331.                   _InputIter2 __first2, _BinaryPredicate __binary_pred) {
  332.   for ( ; __first1 != __last1; ++__first1, ++__first2)
  333.     if (!__binary_pred(*__first1, *__first2))
  334.       return false;
  335.   return true;
  336. }
  337. //--------------------------------------------------
  338. // lexicographical_compare and lexicographical_compare_3way.
  339. // (the latter is not part of the C++ standard.)
  340. template <class _InputIter1, class _InputIter2>
  341. bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
  342.                              _InputIter2 __first2, _InputIter2 __last2) {
  343.   for ( ; __first1 != __last1 && __first2 != __last2
  344.         ; ++__first1, ++__first2) {
  345.     if (*__first1 < *__first2)
  346.       return true;
  347.     if (*__first2 < *__first1)
  348.       return false;
  349.   }
  350.   return __first1 == __last1 && __first2 != __last2;
  351. }
  352. template <class _InputIter1, class _InputIter2, class _Compare>
  353. bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
  354.                              _InputIter2 __first2, _InputIter2 __last2,
  355.                              _Compare __comp) {
  356.   for ( ; __first1 != __last1 && __first2 != __last2
  357.         ; ++__first1, ++__first2) {
  358.     if (__comp(*__first1, *__first2))
  359.       return true;
  360.     if (__comp(*__first2, *__first1))
  361.       return false;
  362.   }
  363.   return __first1 == __last1 && __first2 != __last2;
  364. }
  365. inline bool 
  366. lexicographical_compare(const unsigned char* __first1,
  367.                         const unsigned char* __last1,
  368.                         const unsigned char* __first2,
  369.                         const unsigned char* __last2)
  370. {
  371.   const size_t __len1 = __last1 - __first1;
  372.   const size_t __len2 = __last2 - __first2;
  373.   const int __result = memcmp(__first1, __first2, min(__len1, __len2));
  374.   return __result != 0 ? __result < 0 : __len1 < __len2;
  375. }
  376. inline bool lexicographical_compare(const char* __first1, const char* __last1,
  377.                                     const char* __first2, const char* __last2)
  378. {
  379. #if CHAR_MAX == SCHAR_MAX
  380.   return lexicographical_compare((const signed char*) __first1,
  381.                                  (const signed char*) __last1,
  382.                                  (const signed char*) __first2,
  383.                                  (const signed char*) __last2);
  384. #else /* CHAR_MAX == SCHAR_MAX */
  385.   return lexicographical_compare((const unsigned char*) __first1,
  386.                                  (const unsigned char*) __last1,
  387.                                  (const unsigned char*) __first2,
  388.                                  (const unsigned char*) __last2);
  389. #endif /* CHAR_MAX == SCHAR_MAX */
  390. }
  391. template <class _InputIter1, class _InputIter2>
  392. int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
  393.                                    _InputIter2 __first2, _InputIter2 __last2)
  394. {
  395.   while (__first1 != __last1 && __first2 != __last2) {
  396.     if (*__first1 < *__first2)
  397.       return -1;
  398.     if (*__first2 < *__first1)
  399.       return 1;
  400.     ++__first1;
  401.     ++__first2;
  402.   }
  403.   if (__first2 == __last2) {
  404.     return !(__first1 == __last1);
  405.   }
  406.   else {
  407.     return -1;
  408.   }
  409. }
  410. inline int
  411. __lexicographical_compare_3way(const unsigned char* __first1,
  412.                                const unsigned char* __last1,
  413.                                const unsigned char* __first2,
  414.                                const unsigned char* __last2)
  415. {
  416.   const ptrdiff_t __len1 = __last1 - __first1;
  417.   const ptrdiff_t __len2 = __last2 - __first2;
  418.   const int __result = memcmp(__first1, __first2, min(__len1, __len2));
  419.   return __result != 0 ? __result 
  420.                        : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
  421. }
  422. inline int 
  423. __lexicographical_compare_3way(const char* __first1, const char* __last1,
  424.                                const char* __first2, const char* __last2)
  425. {
  426. #if CHAR_MAX == SCHAR_MAX
  427.   return __lexicographical_compare_3way(
  428.                                 (const signed char*) __first1,
  429.                                 (const signed char*) __last1,
  430.                                 (const signed char*) __first2,
  431.                                 (const signed char*) __last2);
  432. #else
  433.   return __lexicographical_compare_3way((const unsigned char*) __first1,
  434.                                         (const unsigned char*) __last1,
  435.                                         (const unsigned char*) __first2,
  436.                                         (const unsigned char*) __last2);
  437. #endif
  438. }
  439. template <class _InputIter1, class _InputIter2>
  440. int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
  441.                                  _InputIter2 __first2, _InputIter2 __last2)
  442. {
  443.   return __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
  444. }
  445. __STL_END_NAMESPACE
  446. #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */
  447. // Local Variables:
  448. // mode:C++
  449. // End: