C++ STL源码剖析
来源:互联网 发布:周生生淘宝 编辑:程序博客网 时间:2024/06/16 17:51
C++ STL源码剖析
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 1. // Filename: stl_config.h 2 2. 3 3. // Comment By: 凝霜 4 4. // E-mail: mdl2009@vip.qq.com 5 5. // Blog: http://blog.csdn.net/mdl13412 6 6. 7 7. /* 8 8. * Copyright (c) 1996-1997 9 9. * Silicon Graphics Computer Systems, Inc. 10 10. * 11 11. * Permission to use, copy, modify, distribute and sell this software 12 12. * and its documentation for any purpose is hereby granted without fee, 13 13. * provided that the above copyright notice appear in all copies and 14 14. * that both that copyright notice and this permission notice appear 15 15. * in supporting documentation. Silicon Graphics makes no 16 16. * representations about the suitability of this software for any 17 17. * purpose. It is provided "as is" without express or implied warranty. 18 18. */ 19 19. 20 20. /* NOTE: This is an internal header file, included by other STL headers. 21 21. * You should not attempt to use it directly. 22 22. */ 23 23. 24 24. #ifndef __STL_CONFIG_H 25 25. #define __STL_CONFIG_H 26 26. 27 27. // 本配置文件功能表: 28 28. // (1) 如果不编译器没有定义bool, true, false则定义 29 29. // (2) 如果编译器不支持drand48()函数则定义__STL_NO_DRAND48 30 30. // 注: drand48产生双精度的伪随机数, 因为采用了48bit计算, 故名drand48 31 31. // (3) 如果编译器不支持static members of template classes(模板类静态成员), 32 32. // 则定义__STL_STATIC_TEMPLATE_MEMBER_BUG 33 33. // (4) 如果编译器不支持'typename'关键字, 则将'typename'定义为空(null macro) 34 34. // (5) 如果编译器支持partial specialization of class templates(模板类偏特化), 35 35. // 则定义__STL_CLASS_PARTIAL_SPECIALIZATION 36 36. // 参考文献: http://msdn.microsoft.com/en-us/library/9w7t3kf1(v=VS.71).aspx 37 37. // (6) 如果编译器支持partial ordering of function templates(模板函数特化优先级), 38 38. // 则定义__STL_FUNCTION_TMPL_PARTIAL_ORDER 39 39. // 参考资料: http://msdn.microsoft.com/zh-cn/library/zaycz069.aspx 40 40. // (7) 如果编译器支持calling a function template by providing its template 41 41. // arguments explicitly(显式指定调用模板函数的模板参数) 42 42. // 则定义__STL_EXPLICIT_FUNCTION_TMPL_ARGS 43 43. // (8) 如果编译器支持template members of classes(类模板成员), 44 44. // 则定义__STL_MEMBER_TEMPLATES 45 45. // (9) 如果编译器不支持'explicit'关键字, 则将'explicit'定义为空(null macro) 46 46. // (10) 如果编译器不能根据前一个模板参数设定后面的默认模板参数, 47 47. // 则定义__STL_LIMITED_DEFAULT_TEMPLATES 48 48. // (11) 如果编译器处理模板函数的non-type模板参数类型推断有困难, 49 49. // 则定义__STL_NON_TYPE_TMPL_PARAM_BUG 50 50. // (12) 如果编译器不支持迭代器使用'->'操作符, 51 51. // 则定义__SGI_STL_NO_ARROW_OPERATOR 52 52. // (13) 如果编译器(在当前编译模式下)支持异常, 53 53. // 则定义__STL_USE_EXCEPTIONS 54 54. // (14) 如果我们将STL放进命名空间中, 55 55. // 则定义__STL_USE_NAMESPACES 56 56. // (15) 如果本STL在SGI的编译器上编译, 并且用户没有选择pthreads或者no threads, 57 57. // 则默认使用__STL_SGI_THREADS 58 58. // 注: POSIX thread 简称为pthread, Posix线程是一个POSIX标准线程. 59 59. // (16) 如果本STL在Win32平台的编译器上使用多线程模式编译, 60 60. // 则定义__STL_WIN32THREADS 61 61. // (17) 适当的定义命名空间相关的宏(__STD, __STL_BEGIN_NAMESPACE, 等) 62 62. // (18) 适当的定义异常相关的宏(__STL_TRY, __STL_UNWIND, 等) 63 63. // (19) 根据是否定义__STL_ASSERTIONS, 将__stl_assert定义为断言或者空(null macro) 64 64. 65 65. #ifdef _PTHREADS 66 66. # define __STL_PTHREADS 67 67. #endif 68 68. 69 69. // 如果编译器不提供本STL需要的一些功能,则定义__STL_NEED_XXX 70 70. # if defined(__sgi) && !defined(__GNUC__) 71 71. # if !defined(_BOOL) 72 72. # define __STL_NEED_BOOL 73 73. # endif 74 74. # if !defined(_TYPENAME_IS_KEYWORD) 75 75. # define __STL_NEED_TYPENAME 76 76. # endif 77 77. # ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES 78 78. # define __STL_CLASS_PARTIAL_SPECIALIZATION 79 79. # endif 80 80. # ifdef _MEMBER_TEMPLATES 81 81. # define __STL_MEMBER_TEMPLATES 82 82. # endif 83 83. # if !defined(_EXPLICIT_IS_KEYWORD) 84 84. # define __STL_NEED_EXPLICIT 85 85. # endif 86 86. # ifdef __EXCEPTIONS 87 87. # define __STL_USE_EXCEPTIONS 88 88. # endif 89 89. # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) 90 90. # define __STL_USE_NAMESPACES 91 91. # endif 92 92. # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) 93 93. # define __STL_SGI_THREADS 94 94. # endif 95 95. # endif 96 96. 97 97. # ifdef __GNUC__ 98 98. # include <_G_config.h> 99 99. # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) 100 100. # define __STL_STATIC_TEMPLATE_MEMBER_BUG 101 101. # define __STL_NEED_TYPENAME 102 102. # define __STL_NEED_EXPLICIT 103 103. # else 104 104. # define __STL_CLASS_PARTIAL_SPECIALIZATION 105 105. # define __STL_FUNCTION_TMPL_PARTIAL_ORDER 106 106. # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS 107 107. # define __STL_MEMBER_TEMPLATES 108 108. # endif 109 109. /* glibc pre 2.0 is very buggy. We have to disable thread for it. 110 110. It should be upgraded to glibc 2.0 or later. */ 111 111. # if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) 112 112. # define __STL_PTHREADS 113 113. # endif 114 114. # ifdef __EXCEPTIONS 115 115. # define __STL_USE_EXCEPTIONS 116 116. # endif 117 117. # endif 118 118. 119 119. // Sun C++ compiler 120 120. # if defined(__SUNPRO_CC) 121 121. # define __STL_NEED_BOOL 122 122. # define __STL_NEED_TYPENAME 123 123. # define __STL_NEED_EXPLICIT 124 124. # define __STL_USE_EXCEPTIONS 125 125. # endif 126 126. 127 127. // TODO: 这个我没找到资料, 如果你知道或者有相关资料请联系我, Thank U 128 128. # if defined(__COMO__) 129 129. # define __STL_MEMBER_TEMPLATES 130 130. # define __STL_CLASS_PARTIAL_SPECIALIZATION 131 131. # define __STL_USE_EXCEPTIONS 132 132. # define __STL_USE_NAMESPACES 133 133. # endif 134 134. 135 135. // _MSC_VER 定义微软编译器的版本 136 136. // MS VC++ 10.0 _MSC_VER = 1600 137 137. // MS VC++ 9.0 _MSC_VER = 1500 138 138. // MS VC++ 8.0 _MSC_VER = 1400 139 139. // MS VC++ 7.1 _MSC_VER = 1310 140 140. // MS VC++ 7.0 _MSC_VER = 1300 141 141. // MS VC++ 6.0 _MSC_VER = 1200 142 142. // MS VC++ 5.0 _MSC_VER = 1100 143 143. # if defined(_MSC_VER) 144 144. # if _MSC_VER > 1000 145 145. # include <yvals.h> 146 146. # else 147 147. # define __STL_NEED_BOOL 148 148. # endif 149 149. # define __STL_NO_DRAND48 150 150. # define __STL_NEED_TYPENAME 151 151. # if _MSC_VER < 1100 152 152. # define __STL_NEED_EXPLICIT 153 153. # endif 154 154. # define __STL_NON_TYPE_TMPL_PARAM_BUG 155 155. # define __SGI_STL_NO_ARROW_OPERATOR 156 156. # ifdef _CPPUNWIND 157 157. # define __STL_USE_EXCEPTIONS 158 158. # endif 159 159. # ifdef _MT 160 160. # define __STL_WIN32THREADS 161 161. # endif 162 162. # endif 163 163. 164 164. # if defined(__BORLANDC__) 165 165. # define __STL_NO_DRAND48 166 166. # define __STL_NEED_TYPENAME 167 167. # define __STL_LIMITED_DEFAULT_TEMPLATES 168 168. # define __SGI_STL_NO_ARROW_OPERATOR 169 169. # define __STL_NON_TYPE_TMPL_PARAM_BUG 170 170. # ifdef _CPPUNWIND 171 171. # define __STL_USE_EXCEPTIONS 172 172. # endif 173 173. # ifdef __MT__ 174 174. # define __STL_WIN32THREADS 175 175. # endif 176 176. # endif 177 177. 178 178. 179 179. # if defined(__STL_NEED_BOOL) 180 180. typedef int bool; 181 181. # define true 1 182 182. # define false 0 183 183. # endif 184 184. 185 185. # ifdef __STL_NEED_TYPENAME 186 186. # define typename 187 187. # endif 188 188. 189 189. # ifdef __STL_NEED_EXPLICIT 190 190. # define explicit 191 191. # endif 192 192. 193 193. # ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS 194 194. # define __STL_NULL_TMPL_ARGS <> 195 195. # else 196 196. # define __STL_NULL_TMPL_ARGS 197 197. # endif 198 198. 199 199. # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 200 200. # define __STL_TEMPLATE_NULL template<> 201 201. # else 202 202. # define __STL_TEMPLATE_NULL 203 203. # endif 204 204. 205 205. // __STL_NO_NAMESPACES is a hook so that users can disable namespaces 206 206. // without having to edit library headers. 207 207. # if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES) 208 208. # define __STD std 209 209. # define __STL_BEGIN_NAMESPACE namespace std { 210 210. # define __STL_END_NAMESPACE } 211 211. # define __STL_USE_NAMESPACE_FOR_RELOPS 212 212. # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { 213 213. # define __STL_END_RELOPS_NAMESPACE } 214 214. # define __STD_RELOPS std 215 215. # else 216 216. # define __STD 217 217. # define __STL_BEGIN_NAMESPACE 218 218. # define __STL_END_NAMESPACE 219 219. # undef __STL_USE_NAMESPACE_FOR_RELOPS 220 220. # define __STL_BEGIN_RELOPS_NAMESPACE 221 221. # define __STL_END_RELOPS_NAMESPACE 222 222. # define __STD_RELOPS 223 223. # endif 224 224. 225 225. # ifdef __STL_USE_EXCEPTIONS 226 226. # define __STL_TRY try 227 227. # define __STL_CATCH_ALL catch(...) 228 228. # define __STL_RETHROW throw 229 229. # define __STL_NOTHROW throw() 230 230. # define __STL_UNWIND(action) catch(...) { action; throw; } 231 231. # else 232 232. # define __STL_TRY 233 233. # define __STL_CATCH_ALL if (false) 234 234. # define __STL_RETHROW 235 235. # define __STL_NOTHROW 236 236. # define __STL_UNWIND(action) 237 237. # endif 238 238. 239 239. #ifdef __STL_ASSERTIONS 240 240. # include <stdio.h> 241 241. # define __stl_assert(expr) \ 242 242. if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ 243 243. __FILE__, __LINE__, # expr); abort(); } 244 244. #else 245 245. # define __stl_assert(expr) 246 246. #endif 247 247. 248 248. #endif /* __STL_CONFIG_H */ 249 249. 250 250. // Local Variables: 251 251. // mode:C++ 252 252. // End:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 // Filename: stl_slist.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * Copyright (c) 1997 9 * Silicon Graphics Computer Systems, Inc. 10 * 11 * Permission to use, copy, modify, distribute and sell this software 12 * and its documentation for any purpose is hereby granted without fee, 13 * provided that the above copyright notice appear in all copies and 14 * that both that copyright notice and this permission notice appear 15 * in supporting documentation. Silicon Graphics makes no 16 * representations about the suitability of this software for any 17 * purpose. It is provided "as is" without express or implied warranty. 18 * 19 */ 20 21 /* NOTE: This is an internal header file, included by other STL headers. 22 * You should not attempt to use it directly. 23 */ 24 25 #ifndef __SGI_STL_INTERNAL_SLIST_H 26 #define __SGI_STL_INTERNAL_SLIST_H 27 28 29 __STL_BEGIN_NAMESPACE 30 31 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 32 #pragma set woff 1174 33 #endif 34 35 // 这个是链表结点的指针域 36 struct __slist_node_base 37 { 38 __slist_node_base* next; 39 }; 40 41 //////////////////////////////////////////////////////////////////////////////// 42 // 将new_node插入到prev_node后面 43 //////////////////////////////////////////////////////////////////////////////// 44 // 插入前 45 // 这个是prev_node 这个是new_node 46 // ↓ ↓ 47 // -------- -------- -------- -------- 48 // ... | next |--->| next |-------->| next | ... | next | 49 // -------- -------- -------- -------- 50 // 插入后 51 // 这个是prev_node 这个是new_node 52 // ↓ --------------------------------- ↓ 53 // -------- -------- | -------- | -------- 54 // ... | next |--->| next |--- -->| next | ... --->| next |--- 55 // -------- -------- | -------- -------- | 56 // ------------------------------------------- 57 //////////////////////////////////////////////////////////////////////////////// 58 59 inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node, 60 __slist_node_base* new_node) 61 { 62 new_node->next = prev_node->next; 63 prev_node->next = new_node; 64 return new_node; 65 } 66 67 // 获取指定结点的前一个结点 68 inline __slist_node_base* __slist_previous(__slist_node_base* head, 69 const __slist_node_base* node) 70 { 71 while (head && head->next != node) 72 head = head->next; 73 return head; 74 } 75 76 inline const __slist_node_base* __slist_previous(const __slist_node_base* head, 77 const __slist_node_base* node) 78 { 79 while (head && head->next != node) 80 head = head->next; 81 return head; 82 } 83 84 //////////////////////////////////////////////////////////////////////////////// 85 // 将(first, last]链接到pos后面 86 //////////////////////////////////////////////////////////////////////////////// 87 // 下面的例子是在同一链表进行操作的情况 88 // 操作前 89 // pos after before_first first before_last 90 // ↓ ↓ ↓ ↓ ↓ 91 // -------- -------- -------- -------- -------- -------- -------- 92 // ... | next |--->| next |--->| next |--->| next |--->| next |--->| next |--->| next | ... 93 // -------- -------- -------- -------- -------- -------- -------- 94 // 操作后 95 // pos after before_first first before_last 96 // ↓ ↓ ↓ ↓ ↓ 97 // -------- -------- -------- -------- -------- -------- -------- 98 // ... | next | ->| next |--->| next |-- | next |--->| next |--->| next | ->| next | ... 99 // -------- | -------- -------- | -------- -------- -------- | --------100 // | | | ↑ | |101 // ------|----------------------|------- | |102 // -----------------------|------------------------------- |103 // --------------------------------------104 ////////////////////////////////////////////////////////////////////////////////105 inline void __slist_splice_after(__slist_node_base* pos,106 __slist_node_base* before_first,107 __slist_node_base* before_last)108 {109 if (pos != before_first && pos != before_last) {110 __slist_node_base* first = before_first->next;111 __slist_node_base* after = pos->next;112 before_first->next = before_last->next;113 pos->next = first;114 before_last->next = after;115 }116 }117 118 // 链表转置119 inline __slist_node_base* __slist_reverse(__slist_node_base* node)120 {121 __slist_node_base* result = node;122 node = node->next;123 result->next = 0;124 while(node) {125 __slist_node_base* next = node->next;126 node->next = result;127 result = node;128 node = next;129 }130 return result;131 }132 133 // 这个是真正的链表结点134 template <class T>135 struct __slist_node : public __slist_node_base136 {137 T data;138 };139 140 struct __slist_iterator_base141 {142 typedef size_t size_type;143 typedef ptrdiff_t difference_type;144 typedef forward_iterator_tag iterator_category;145 146 __slist_node_base* node;147 148 __slist_iterator_base(__slist_node_base* x) : node(x) {}149 void incr() { node = node->next; }150 151 bool operator==(const __slist_iterator_base& x) const152 {153 return node == x.node;154 }155 bool operator!=(const __slist_iterator_base& x) const156 {157 return node != x.node;158 }159 };160 161 // 链表迭代器, 关于迭代器参考<stl_iterator.h>162 // 由于是单向链表, 所以不能提供operator --(效率太低)163 // 同样也不能提供随机访问能力164 template <class T, class Ref, class Ptr>165 struct __slist_iterator : public __slist_iterator_base166 {167 typedef __slist_iterator<T, T&, T*> iterator;168 typedef __slist_iterator<T, const T&, const T*> const_iterator;169 typedef __slist_iterator<T, Ref, Ptr> self;170 171 typedef T value_type;172 typedef Ptr pointer;173 typedef Ref reference;174 typedef __slist_node<T> list_node;175 176 __slist_iterator(list_node* x) : __slist_iterator_base(x) {}177 __slist_iterator() : __slist_iterator_base(0) {}178 __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}179 180 reference operator*() const { return ((list_node*) node)->data; }181 #ifndef __SGI_STL_NO_ARROW_OPERATOR182 // 如果编译器支持'->'则重载, 详细见我在<stl_list.h>中的剖析183 pointer operator->() const { return &(operator*()); }184 #endif /* __SGI_STL_NO_ARROW_OPERATOR */185 186 self& operator++()187 {188 incr();189 return *this;190 }191 self operator++(int)192 {193 self tmp = *this;194 incr();195 return tmp;196 }197 };198 199 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION200 201 inline ptrdiff_t*202 distance_type(const __slist_iterator_base&)203 {204 return 0;205 }206 207 inline forward_iterator_tag208 iterator_category(const __slist_iterator_base&)209 {210 return forward_iterator_tag();211 }212 213 template <class T, class Ref, class Ptr>214 inline T*215 value_type(const __slist_iterator<T, Ref, Ptr>&) {216 return 0;217 }218 219 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */220 221 // 计算链表长度, 时间复杂度O(n)222 inline size_t __slist_size(__slist_node_base* node)223 {224 size_t result = 0;225 for ( ; node != 0; node = node->next)226 ++result;227 return result;228 }229 230 template <class T, class Alloc = alloc>231 class slist232 {233 public:234 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持235 typedef T value_type; // STL标准强制要求236 typedef value_type* pointer; // STL标准强制要求237 typedef const value_type* const_pointer;238 typedef value_type& reference; // STL标准强制要求239 typedef const value_type& const_reference;240 typedef size_t size_type;241 typedef ptrdiff_t difference_type; // STL标准强制要求242 243 typedef __slist_iterator<T, T&, T*> iterator; // STL标准强制要求244 typedef __slist_iterator<T, const T&, const T*> const_iterator;245 246 private:247 typedef __slist_node<T> list_node;248 typedef __slist_node_base list_node_base;249 typedef __slist_iterator_base iterator_base;250 251 // 这个提供STL标准的allocator接口252 typedef simple_alloc<list_node, Alloc> list_node_allocator;253 254 // 创建一个值为x的结点, 其没有后继结点255 static list_node* create_node(const value_type& x)256 {257 list_node* node = list_node_allocator::allocate();258 __STL_TRY {259 construct(&node->data, x);260 node->next = 0;261 }262 __STL_UNWIND(list_node_allocator::deallocate(node));263 return node;264 }265 266 // 析构一个结点的数据, 不释放内存267 static void destroy_node(list_node* node)268 {269 destroy(&node->data);270 list_node_allocator::deallocate(node);271 }272 273 ////////////////////////////////////////////////////////////////////////////////274 // 在头结点插入n个值为x的结点275 ////////////////////////////////////////////////////////////////////////////////276 // fill_initialize(size_type n, const value_type& x)277 // ↓278 // _insert_after_fill(&head, n, x);279 // ↓280 // for (size_type i = 0; i < n; ++i)281 // pos = __slist_make_link(pos, create_node(x));282 // |283 // |284 // ↓285 // create_node(const value_type& x)286 // list_node_allocator::allocate();287 // construct(&node->data, x);288 ////////////////////////////////////////////////////////////////////////////////289 void fill_initialize(size_type n, const value_type& x)290 {291 head.next = 0;292 __STL_TRY {293 _insert_after_fill(&head, n, x);294 }295 __STL_UNWIND(clear());296 }297 298 // 在头结点后面插入[first, last)区间内的结点, 注意是新建立结点299 #ifdef __STL_MEMBER_TEMPLATES300 template <class InputIterator>301 void range_initialize(InputIterator first, InputIterator last)302 {303 head.next = 0;304 __STL_TRY {305 _insert_after_range(&head, first, last);306 }307 __STL_UNWIND(clear());308 }309 #else /* __STL_MEMBER_TEMPLATES */310 void range_initialize(const value_type* first, const value_type* last) {311 head.next = 0;312 __STL_TRY {313 _insert_after_range(&head, first, last);314 }315 __STL_UNWIND(clear());316 }317 void range_initialize(const_iterator first, const_iterator last) {318 head.next = 0;319 __STL_TRY {320 _insert_after_range(&head, first, last);321 }322 __STL_UNWIND(clear());323 }324 #endif /* __STL_MEMBER_TEMPLATES */325 326 private:327 list_node_base head; // 这是链表头328 329 public:330 slist() { head.next = 0; }331 332 slist(size_type n, const value_type& x) { fill_initialize(n, x); }333 slist(int n, const value_type& x) { fill_initialize(n, x); }334 slist(long n, const value_type& x) { fill_initialize(n, x); }335 explicit slist(size_type n) { fill_initialize(n, value_type()); }336 337 #ifdef __STL_MEMBER_TEMPLATES338 template <class InputIterator>339 slist(InputIterator first, InputIterator last)340 {341 range_initialize(first, last);342 }343 344 #else /* __STL_MEMBER_TEMPLATES */345 slist(const_iterator first, const_iterator last) {346 range_initialize(first, last);347 }348 slist(const value_type* first, const value_type* last) {349 range_initialize(first, last);350 }351 #endif /* __STL_MEMBER_TEMPLATES */352 353 slist(const slist& L) { range_initialize(L.begin(), L.end()); }354 355 slist& operator= (const slist& L);356 357 // 析构所有元素, 并释放内存358 ~slist() { clear(); }359 360 public:361 362 iterator begin() { return iterator((list_node*)head.next); }363 const_iterator begin() const { return const_iterator((list_node*)head.next);}364 365 iterator end() { return iterator(0); }366 const_iterator end() const { return const_iterator(0); }367 368 size_type size() const { return __slist_size(head.next); }369 370 size_type max_size() const { return size_type(-1); }371 372 bool empty() const { return head.next == 0; }373 374 // 只需交换链表头数据就能实现交换^_^375 void swap(slist& L)376 {377 list_node_base* tmp = head.next;378 head.next = L.head.next;379 L.head.next = tmp;380 }381 382 public:383 friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1,384 const slist<T, Alloc>& L2);385 386 public:387 388 // OK. 下面四个函数时间复杂度为O(1)389 // 对于插入操作只推荐push_front()其余操作个人感觉很慢390 reference front() { return ((list_node*) head.next)->data; }391 const_reference front() const { return ((list_node*) head.next)->data; }392 void push_front(const value_type& x)393 {394 __slist_make_link(&head, create_node(x));395 }396 void pop_front()397 {398 list_node* node = (list_node*) head.next;399 head.next = node->next;400 destroy_node(node);401 }402 403 // 获取指定结点的前驱结点404 iterator previous(const_iterator pos)405 {406 return iterator((list_node*) __slist_previous(&head, pos.node));407 }408 const_iterator previous(const_iterator pos) const409 {410 return const_iterator((list_node*) __slist_previous(&head, pos.node));411 }412 413 private:414 // 在指定结点后插入值为x的元素, 分配内存415 list_node* _insert_after(list_node_base* pos, const value_type& x)416 {417 return (list_node*) (__slist_make_link(pos, create_node(x)));418 }419 420 // 在指定结点后面插入n个值为x的元素421 void _insert_after_fill(list_node_base* pos,422 size_type n, const value_type& x)423 {424 for (size_type i = 0; i < n; ++i)425 pos = __slist_make_link(pos, create_node(x));426 }427 428 // TODO: 待分析429 // 在pos后面插入[first, last)区间内的元素430 #ifdef __STL_MEMBER_TEMPLATES431 template <class InIter>432 void _insert_after_range(list_node_base* pos, InIter first, InIter last)433 {434 while (first != last) {435 pos = __slist_make_link(pos, create_node(*first));436 ++first;437 }438 }439 #else /* __STL_MEMBER_TEMPLATES */440 void _insert_after_range(list_node_base* pos,441 const_iterator first, const_iterator last) {442 while (first != last) {443 pos = __slist_make_link(pos, create_node(*first));444 ++first;445 }446 }447 void _insert_after_range(list_node_base* pos,448 const value_type* first, const value_type* last) {449 while (first != last) {450 pos = __slist_make_link(pos, create_node(*first));451 ++first;452 }453 }454 #endif /* __STL_MEMBER_TEMPLATES */455 456 // 擦除pos后面的结点457 list_node_base* erase_after(list_node_base* pos)458 {459 list_node* next = (list_node*) (pos->next);460 list_node_base* next_next = next->next;461 pos->next = next_next;462 destroy_node(next);463 return next_next;464 }465 466 // 擦除(before_first, last_node)区间的结点467 list_node_base* erase_after(list_node_base* before_first,468 list_node_base* last_node)469 {470 list_node* cur = (list_node*) (before_first->next);471 while (cur != last_node) {472 list_node* tmp = cur;473 cur = (list_node*) cur->next;474 destroy_node(tmp);475 }476 before_first->next = last_node;477 return last_node;478 }479 480 public:481 // 在pos后面插入值为x的结点482 iterator insert_after(iterator pos, const value_type& x)483 {484 return iterator(_insert_after(pos.node, x));485 }486 487 iterator insert_after(iterator pos)488 {489 return insert_after(pos, value_type());490 }491 492 void insert_after(iterator pos, size_type n, const value_type& x)493 {494 _insert_after_fill(pos.node, n, x);495 }496 void insert_after(iterator pos, int n, const value_type& x)497 {498 _insert_after_fill(pos.node, (size_type) n, x);499 }500 void insert_after(iterator pos, long n, const value_type& x)501 {502 _insert_after_fill(pos.node, (size_type) n, x);503 }504 505 #ifdef __STL_MEMBER_TEMPLATES506 template <class InIter>507 void insert_after(iterator pos, InIter first, InIter last) {508 _insert_after_range(pos.node, first, last);509 }510 #else /* __STL_MEMBER_TEMPLATES */511 void insert_after(iterator pos, const_iterator first, const_iterator last) {512 _insert_after_range(pos.node, first, last);513 }514 void insert_after(iterator pos,515 const value_type* first, const value_type* last) {516 _insert_after_range(pos.node, first, last);517 }518 #endif /* __STL_MEMBER_TEMPLATES */519 520 // 在pos后面插入值为x的结点521 iterator insert(iterator pos, const value_type& x)522 {523 return iterator(_insert_after(__slist_previous(&head, pos.node), x));524 }525 526 iterator insert(iterator pos)527 {528 return iterator(_insert_after(__slist_previous(&head, pos.node),529 value_type()));530 }531 532 // 在pos前插入m个值为x的结点533 void insert(iterator pos, size_type n, const value_type& x)534 {535 _insert_after_fill(__slist_previous(&head, pos.node), n, x);536 }537 void insert(iterator pos, int n, const value_type& x)538 {539 _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);540 }541 void insert(iterator pos, long n, const value_type& x)542 {543 _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);544 }545 546 #ifdef __STL_MEMBER_TEMPLATES547 template <class InIter>548 void insert(iterator pos, InIter first, InIter last) {549 _insert_after_range(__slist_previous(&head, pos.node), first, last);550 }551 #else /* __STL_MEMBER_TEMPLATES */552 void insert(iterator pos, const_iterator first, const_iterator last) {553 _insert_after_range(__slist_previous(&head, pos.node), first, last);554 }555 void insert(iterator pos, const value_type* first, const value_type* last) {556 _insert_after_range(__slist_previous(&head, pos.node), first, last);557 }558 #endif /* __STL_MEMBER_TEMPLATES */559 560 public:561 iterator erase_after(iterator pos)562 {563 return iterator((list_node*)erase_after(pos.node));564 }565 iterator erase_after(iterator before_first, iterator last)566 {567 return iterator((list_node*)erase_after(before_first.node, last.node));568 }569 570 iterator erase(iterator pos)571 {572 return (list_node*) erase_after(__slist_previous(&head, pos.node));573 }574 iterator erase(iterator first, iterator last)575 {576 return (list_node*) erase_after(__slist_previous(&head, first.node),577 last.node);578 }579 580 // 详细剖析见后面实现部分581 void resize(size_type new_size, const T& x);582 void resize(size_type new_size) { resize(new_size, T()); }583 void clear() { erase_after(&head, 0); }584 585 public:586 // splic操作可以参考<stl_list.h>的说明587 588 // Moves the range [before_first + 1, before_last + 1) to *this,589 // inserting it immediately after pos. This is constant time.590 void splice_after(iterator pos,591 iterator before_first, iterator before_last)592 {593 if (before_first != before_last)594 __slist_splice_after(pos.node, before_first.node, before_last.node);595 }596 597 // Moves the element that follows prev to *this, inserting it immediately598 // after pos. This is constant time.599 600 void splice_after(iterator pos, iterator prev)601 {602 __slist_splice_after(pos.node, prev.node, prev.node->next);603 }604 605 // Linear in distance(begin(), pos), and linear in L.size().606 void splice(iterator pos, slist& L)607 {608 if (L.head.next)609 __slist_splice_after(__slist_previous(&head, pos.node),610 &L.head,611 __slist_previous(&L.head, 0));612 }613 614 // Linear in distance(begin(), pos), and in distance(L.begin(), i).615 void splice(iterator pos, slist& L, iterator i)616 {617 __slist_splice_after(__slist_previous(&head, pos.node),618 __slist_previous(&L.head, i.node),619 i.node);620 }621 622 // Linear in distance(begin(), pos), in distance(L.begin(), first),623 // and in distance(first, last).624 void splice(iterator pos, slist& L, iterator first, iterator last)625 {626 if (first != last)627 __slist_splice_after(__slist_previous(&head, pos.node),628 __slist_previous(&L.head, first.node),629 __slist_previous(first.node, last.node));630 }631 632 public:633 // 这些接口可以参考<stl_list.h>634 void reverse() { if (head.next) head.next = __slist_reverse(head.next); }635 636 void remove(const T& val);637 void unique();638 void merge(slist& L);639 void sort();640 641 #ifdef __STL_MEMBER_TEMPLATES642 template <class Predicate> void remove_if(Predicate pred);643 template <class BinaryPredicate> void unique(BinaryPredicate pred);644 template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering);645 template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp);646 #endif /* __STL_MEMBER_TEMPLATES */647 };648 649 // 实现整个链表的赋值, 会析构原有的元素650 template <class T, class Alloc>651 slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)652 {653 if (&L != this) {654 list_node_base* p1 = &head;655 list_node* n1 = (list_node*) head.next;656 const list_node* n2 = (const list_node*) L.head.next;657 while (n1 && n2) {658 n1->data = n2->data;659 p1 = n1;660 n1 = (list_node*) n1->next;661 n2 = (const list_node*) n2->next;662 }663 if (n2 == 0)664 erase_after(p1, 0);665 else666 _insert_after_range(p1,667 const_iterator((list_node*)n2), const_iterator(0));668 }669 return *this;670 }671 672 // 只有两个链表所有内容都相等才判定其等价673 // 不过个人觉得只需要判断头结点指向的第一个结点就可以674 // 大家可以讨论一下675 template <class T, class Alloc>676 bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)677 {678 typedef typename slist<T,Alloc>::list_node list_node;679 list_node* n1 = (list_node*) L1.head.next;680 list_node* n2 = (list_node*) L2.head.next;681 while (n1 && n2 && n1->data == n2->data) {682 n1 = (list_node*) n1->next;683 n2 = (list_node*) n2->next;684 }685 return n1 == 0 && n2 == 0;686 }687 688 // 字典序比较689 template <class T, class Alloc>690 inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)691 {692 return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());693 }694 695 // 如果编译器支持模板函数特化优先级696 // 那么将全局的swap实现为使用slist私有的swap以提高效率697 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER698 699 template <class T, class Alloc>700 inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) {701 x.swap(y);702 }703 704 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */705 706 ////////////////////////////////////////////////////////////////////////////////707 // 下面这些接口和list的行为一致, 只是算法有些不同, 请参考<stl_list.h>708 ////////////////////////////////////////////////////////////////////////////////709 710 template <class T, class Alloc>711 void slist<T, Alloc>::resize(size_type len, const T& x)712 {713 list_node_base* cur = &head;714 while (cur->next != 0 && len > 0) {715 --len;716 cur = cur->next;717 }718 if (cur->next)719 erase_after(cur, 0);720 else721 _insert_after_fill(cur, len, x);722 }723 724 template <class T, class Alloc>725 void slist<T,Alloc>::remove(const T& val)726 {727 list_node_base* cur = &head;728 while (cur && cur->next) {729 if (((list_node*) cur->next)->data == val)730 erase_after(cur);731 else732 cur = cur->next;733 }734 }735 736 template <class T, class Alloc>737 void slist<T,Alloc>::unique()738 {739 list_node_base* cur = head.next;740 if (cur) {741 while (cur->next) {742 if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)743 erase_after(cur);744 else745 cur = cur->next;746 }747 }748 }749 750 template <class T, class Alloc>751 void slist<T,Alloc>::merge(slist<T,Alloc>& L)752 {753 list_node_base* n1 = &head;754 while (n1->next && L.head.next) {755 if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data)756 __slist_splice_after(n1, &L.head, L.head.next);757 n1 = n1->next;758 }759 if (L.head.next) {760 n1->next = L.head.next;761 L.head.next = 0;762 }763 }764 765 template <class T, class Alloc>766 void slist<T,Alloc>::sort()767 {768 if (head.next && head.next->next) {769 slist carry;770 slist counter[64];771 int fill = 0;772 while (!empty()) {773 __slist_splice_after(&carry.head, &head, head.next);774 int i = 0;775 while (i < fill && !counter[i].empty()) {776 counter[i].merge(carry);777 carry.swap(counter[i]);778 ++i;779 }780 carry.swap(counter[i]);781 if (i == fill)782 ++fill;783 }784 785 for (int i = 1; i < fill; ++i)786 counter[i].merge(counter[i-1]);787 this->swap(counter[fill-1]);788 }789 }790 791 #ifdef __STL_MEMBER_TEMPLATES792 793 template <class T, class Alloc>794 template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)795 {796 list_node_base* cur = &head;797 while (cur->next) {798 if (pred(((list_node*) cur->next)->data))799 erase_after(cur);800 else801 cur = cur->next;802 }803 }804 805 template <class T, class Alloc> template <class BinaryPredicate>806 void slist<T,Alloc>::unique(BinaryPredicate pred)807 {808 list_node* cur = (list_node*) head.next;809 if (cur) {810 while (cur->next) {811 if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))812 erase_after(cur);813 else814 cur = (list_node*) cur->next;815 }816 }817 }818 819 template <class T, class Alloc> template <class StrictWeakOrdering>820 void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)821 {822 list_node_base* n1 = &head;823 while (n1->next && L.head.next) {824 if (comp(((list_node*) L.head.next)->data,825 ((list_node*) n1->next)->data))826 __slist_splice_after(n1, &L.head, L.head.next);827 n1 = n1->next;828 }829 if (L.head.next) {830 n1->next = L.head.next;831 L.head.next = 0;832 }833 }834 835 template <class T, class Alloc> template <class StrictWeakOrdering>836 void slist<T,Alloc>::sort(StrictWeakOrdering comp)837 {838 if (head.next && head.next->next) {839 slist carry;840 slist counter[64];841 int fill = 0;842 while (!empty()) {843 __slist_splice_after(&carry.head, &head, head.next);844 int i = 0;845 while (i < fill && !counter[i].empty()) {846 counter[i].merge(carry, comp);847 carry.swap(counter[i]);848 ++i;849 }850 carry.swap(counter[i]);851 if (i == fill)852 ++fill;853 }854 855 for (int i = 1; i < fill; ++i)856 counter[i].merge(counter[i-1], comp);857 this->swap(counter[fill-1]);858 }859 }860 861 #endif /* __STL_MEMBER_TEMPLATES */862 863 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)864 #pragma reset woff 1174865 #endif866 867 __STL_END_NAMESPACE868 869 #endif /* __SGI_STL_INTERNAL_SLIST_H */870 871 // Local Variables:872 // mode:C++873 // End:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 // Filename: <stl_algo.h> 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // 这个文件中定义了一些STL关键的算法, 我仅仅给出一个思路, 8 // 不进行详尽讲解, 具体算法请参考算法书籍, 推荐《算法导论》 9 // 另外, 对于基础薄弱的, 推荐《大话数据结构》, 此书我读了一下 10 // 试读章节, 适合初学者学习 11 12 /* 13 * 14 * Copyright (c) 1994 15 * Hewlett-Packard Company 16 * 17 * Permission to use, copy, modify, distribute and sell this software 18 * and its documentation for any purpose is hereby granted without fee, 19 * provided that the above copyright notice appear in all copies and 20 * that both that copyright notice and this permission notice appear 21 * in supporting documentation. Hewlett-Packard Company makes no 22 * representations about the suitability of this software for any 23 * purpose. It is provided "as is" without express or implied warranty. 24 * 25 * 26 * Copyright (c) 1996 27 * Silicon Graphics Computer Systems, Inc. 28 * 29 * Permission to use, copy, modify, distribute and sell this software 30 * and its documentation for any purpose is hereby granted without fee, 31 * provided that the above copyright notice appear in all copies and 32 * that both that copyright notice and this permission notice appear 33 * in supporting documentation. Silicon Graphics makes no 34 * representations about the suitability of this software for any 35 * purpose. It is provided "as is" without express or implied warranty. 36 */ 37 38 /* NOTE: This is an internal header file, included by other STL headers. 39 * You should not attempt to use it directly. 40 */ 41 42 #ifndef __SGI_STL_INTERNAL_ALGO_H 43 #define __SGI_STL_INTERNAL_ALGO_H 44 45 #include <stl_heap.h> 46 47 __STL_BEGIN_NAMESPACE 48 49 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 50 #pragma set woff 1209 51 #endif 52 53 // 选取a, b, c三个数中间的那个 54 template <class T> 55 inline const T& __median(const T& a, const T& b, const T& c) { 56 if (a < b) 57 if (b < c) 58 return b; 59 else if (a < c) 60 return c; 61 else 62 return a; 63 else if (a < c) 64 return a; 65 else if (b < c) 66 return c; 67 else 68 return b; 69 } 70 71 template <class T, class Compare> 72 inline const T& __median(const T& a, const T& b, const T& c, Compare comp) { 73 if (comp(a, b)) 74 if (comp(b, c)) 75 return b; 76 else if (comp(a, c)) 77 return c; 78 else 79 return a; 80 else if (comp(a, c)) 81 return a; 82 else if (comp(b, c)) 83 return c; 84 else 85 return b; 86 } 87 88 // 对于[first, last)区间内的元素调用判别式 89 // 个人非常喜欢这个函数, 在C#中这个是语言层面就支持的 90 template <class InputIterator, class Function> 91 Function for_each(InputIterator first, InputIterator last, Function f) { 92 for ( ; first != last; ++first) 93 f(*first); 94 return f; 95 } 96 97 // 查找指定区间内第一个值为value的元素 98 template <class InputIterator, class T> 99 InputIterator find(InputIterator first, InputIterator last, const T& value) 100 { 101 while (first != last && *first != value) ++first; 102 return first; 103 } 104 105 // 查找指定区间内第一个满足判别式额元素 106 template <class InputIterator, class Predicate> 107 InputIterator find_if(InputIterator first, InputIterator last, 108 Predicate pred) 109 { 110 while (first != last && !pred(*first)) ++first; 111 return first; 112 } 113 114 // 找出第一组满足条件的相邻元素 115 template <class ForwardIterator> 116 ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) 117 { 118 if (first == last) return last; 119 ForwardIterator next = first; 120 while(++next != last) { 121 // 判断是否满足条件, 满足就返回 122 if (*first == *next) return first; 123 first = next; 124 } 125 return last; 126 } 127 128 // 使用用户指定的二元比较判别式, 其余同上面 129 template <class ForwardIterator, class BinaryPredicate> 130 ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, 131 BinaryPredicate binary_pred) 132 { 133 if (first == last) return last; 134 ForwardIterator next = first; 135 while(++next != last) { 136 if (binary_pred(*first, *next)) return first; 137 first = next; 138 } 139 return last; 140 } 141 142 // 统计指定元素在指定区间内出现的次数 143 template <class InputIterator, class T, class Size> 144 void count(InputIterator first, InputIterator last, const T& value, 145 Size& n) 146 { 147 // 统计操作要历遍整个区间 148 for ( ; first != last; ++first) 149 if (*first == value) 150 ++n; 151 } 152 153 // 统计满足指定判别式的元素的个数 154 template <class InputIterator, class Predicate, class Size> 155 void count_if(InputIterator first, InputIterator last, Predicate pred, 156 Size& n) { 157 for ( ; first != last; ++first) 158 if (pred(*first)) 159 ++n; 160 } 161 162 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 163 164 template <class InputIterator, class T> 165 typename iterator_traits<InputIterator>::difference_type 166 count(InputIterator first, InputIterator last, const T& value) 167 { 168 typename iterator_traits<InputIterator>::difference_type n = 0; 169 for ( ; first != last; ++first) 170 if (*first == value) 171 ++n; 172 return n; 173 } 174 175 template <class InputIterator, class Predicate> 176 typename iterator_traits<InputIterator>::difference_type 177 count_if(InputIterator first, InputIterator last, Predicate pred) { 178 typename iterator_traits<InputIterator>::difference_type n = 0; 179 for ( ; first != last; ++first) 180 if (pred(*first)) 181 ++n; 182 return n; 183 } 184 185 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 186 187 template <class ForwardIterator1, class ForwardIterator2, class Distance1, 188 class Distance2> 189 ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, 190 ForwardIterator2 first2, ForwardIterator2 last2, 191 Distance1*, Distance2*) { 192 Distance1 d1 = 0; 193 distance(first1, last1, d1); 194 Distance2 d2 = 0; 195 distance(first2, last2, d2); 196 197 if (d1 < d2) return last1; 198 199 ForwardIterator1 current1 = first1; 200 ForwardIterator2 current2 = first2; 201 202 while (current2 != last2) 203 if (*current1 == *current2) { 204 ++current1; 205 ++current2; 206 } 207 else { 208 if (d1 == d2) 209 return last1; 210 else { 211 current1 = ++first1; 212 current2 = first2; 213 --d1; 214 } 215 } 216 return first1; 217 } 218 219 // 在[first1, last1)区间内, 查找[first2, last2)区间 220 // 为了效率, 进行函数派发 221 template <class ForwardIterator1, class ForwardIterator2> 222 inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, 223 ForwardIterator2 first2, ForwardIterator2 last2) 224 { 225 return __search(first1, last1, first2, last2, distance_type(first1), 226 distance_type(first2)); 227 } 228 229 template <class ForwardIterator1, class ForwardIterator2, 230 class BinaryPredicate, class Distance1, class Distance2> 231 ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, 232 ForwardIterator2 first2, ForwardIterator2 last2, 233 BinaryPredicate binary_pred, Distance1*, Distance2*) { 234 Distance1 d1 = 0; 235 distance(first1, last1, d1); 236 Distance2 d2 = 0; 237 distance(first2, last2, d2); 238 239 if (d1 < d2) return last1; 240 241 ForwardIterator1 current1 = first1; 242 ForwardIterator2 current2 = first2; 243 244 while (current2 != last2) 245 if (binary_pred(*current1, *current2)) { 246 ++current1; 247 ++current2; 248 } 249 else { 250 if (d1 == d2) 251 return last1; 252 else { 253 current1 = ++first1; 254 current2 = first2; 255 --d1; 256 } 257 } 258 return first1; 259 } 260 261 template <class ForwardIterator1, class ForwardIterator2, 262 class BinaryPredicate> 263 inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, 264 ForwardIterator2 first2, ForwardIterator2 last2, 265 BinaryPredicate binary_pred) { 266 return __search(first1, last1, first2, last2, binary_pred, 267 distance_type(first1), distance_type(first2)); 268 } 269 270 // 在[first, last)内查找第一个满足连续count个value的位置 271 template <class ForwardIterator, class Integer, class T> 272 ForwardIterator search_n(ForwardIterator first, ForwardIterator last, 273 Integer count, const T& value) 274 { 275 if (count <= 0) 276 return first; 277 else { 278 first = find(first, last, value); 279 while (first != last) { 280 Integer n = count - 1; 281 ForwardIterator i = first; 282 ++i; 283 while (i != last && n != 0 && *i == value) { 284 ++i; 285 --n; 286 } 287 if (n == 0) 288 return first; 289 else 290 first = find(i, last, value); 291 } 292 return last; 293 } 294 } 295 296 // 好吧, 二元判别式自己指定的 297 template <class ForwardIterator, class Integer, class T, class BinaryPredicate> 298 ForwardIterator search_n(ForwardIterator first, ForwardIterator last, 299 Integer count, const T& value, 300 BinaryPredicate binary_pred) { 301 if (count <= 0) 302 return first; 303 else { 304 while (first != last) { 305 if (binary_pred(*first, value)) break; 306 ++first; 307 } 308 while (first != last) { 309 Integer n = count - 1; 310 ForwardIterator i = first; 311 ++i; 312 while (i != last && n != 0 && binary_pred(*i, value)) { 313 ++i; 314 --n; 315 } 316 if (n == 0) 317 return first; 318 else { 319 while (i != last) { 320 if (binary_pred(*i, value)) break; 321 ++i; 322 } 323 first = i; 324 } 325 } 326 return last; 327 } 328 } 329 330 // 交换两个区间内的元素, 要求长度相同 331 template <class ForwardIterator1, class ForwardIterator2> 332 ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, 333 ForwardIterator2 first2) 334 { 335 for ( ; first1 != last1; ++first1, ++first2) 336 iter_swap(first1, first2); 337 return first2; 338 } 339 340 // 将[first, last)经判别式转换到result处 341 template <class InputIterator, class OutputIterator, class UnaryOperation> 342 OutputIterator transform(InputIterator first, InputIterator last, 343 OutputIterator result, UnaryOperation op) 344 { 345 for ( ; first != last; ++first, ++result) 346 *result = op(*first); 347 return result; 348 } 349 350 // 这个多了一个区间 351 template <class InputIterator1, class InputIterator2, class OutputIterator, 352 class BinaryOperation> 353 OutputIterator transform(InputIterator1 first1, InputIterator1 last1, 354 InputIterator2 first2, OutputIterator result, 355 BinaryOperation binary_op) 356 { 357 for ( ; first1 != last1; ++first1, ++first2, ++result) 358 *result = binary_op(*first1, *first2); 359 return result; 360 } 361 362 // 将[first, last)内的old_value都以new_value替代 363 template <class ForwardIterator, class T> 364 void replace(ForwardIterator first, ForwardIterator last, const T& old_value, 365 const T& new_value) 366 { 367 for ( ; first != last; ++first) 368 if (*first == old_value) *first = new_value; 369 } 370 371 // 将[first, last)内的满足判别式的元素都以new_value代替 372 template <class ForwardIterator, class Predicate, class T> 373 void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, 374 const T& new_value) 375 { 376 for ( ; first != last; ++first) 377 if (pred(*first)) *first = new_value; 378 } 379 380 // 与replace唯一不同的是会将元素复制到新的位置 381 template <class InputIterator, class OutputIterator, class T> 382 OutputIterator replace_copy(InputIterator first, InputIterator last, 383 OutputIterator result, const T& old_value, 384 const T& new_value) 385 { 386 for ( ; first != last; ++first, ++result) 387 *result = *first == old_value ? new_value : *first; 388 return result; 389 } 390 391 // 同上 392 template <class Iterator, class OutputIterator, class Predicate, class T> 393 OutputIterator replace_copy_if(Iterator first, Iterator last, 394 OutputIterator result, Predicate pred, 395 const T& new_value) 396 { 397 for ( ; first != last; ++first, ++result) 398 *result = pred(*first) ? new_value : *first; 399 return result; 400 } 401 402 // 将仿函数的处理结果填充在[first, last)区间内 403 // 对于用户自定义类型要提供operator =() 404 template <class ForwardIterator, class Generator> 405 void generate(ForwardIterator first, ForwardIterator last, Generator gen) 406 { 407 for ( ; first != last; ++first) 408 *first = gen(); 409 } 410 411 // 和generate()差不多, 只是给定的是起点和个数 412 template <class OutputIterator, class Size, class Generator> 413 OutputIterator generate_n(OutputIterator first, Size n, Generator gen) 414 { 415 for ( ; n > 0; --n, ++first) 416 *first = gen(); 417 return first; 418 } 419 420 // 将[first, last)中除了value的元素拷贝到result处 421 // 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构 422 template <class InputIterator, class OutputIterator, class T> 423 OutputIterator remove_copy(InputIterator first, InputIterator last, 424 OutputIterator result, const T& value) 425 { 426 for ( ; first != last; ++first) 427 if (*first != value) { 428 *result = *first; 429 ++result; 430 } 431 return result; 432 } 433 434 // 将[first, last)中除了满足判别式的元素拷贝到result处 435 // 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构 436 template <class InputIterator, class OutputIterator, class Predicate> 437 OutputIterator remove_copy_if(InputIterator first, InputIterator last, 438 OutputIterator result, Predicate pred) 439 { 440 for ( ; first != last; ++first) 441 if (!pred(*first)) { 442 *result = *first; 443 ++result; 444 } 445 return result; 446 } 447 448 // 移除指定值的元素, 但是并不删除 449 template <class ForwardIterator, class T> 450 ForwardIterator remove(ForwardIterator first, ForwardIterator last, 451 const T& value) 452 { 453 first = find(first, last, value); 454 ForwardIterator next = first; 455 return first == last ? first : remove_copy(++next, last, first, value); 456 } 457 458 // 移除满足判别式的元素, 但是并不删除 459 template <class ForwardIterator, class Predicate> 460 ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, 461 Predicate pred) 462 { 463 first = find_if(first, last, pred); 464 ForwardIterator next = first; 465 return first == last ? first : remove_copy_if(++next, last, first, pred); 466 } 467 468 template <class InputIterator, class ForwardIterator> 469 ForwardIterator __unique_copy(InputIterator first, InputIterator last, 470 ForwardIterator result, forward_iterator_tag) { 471 *result = *first; 472 while (++first != last) 473 if (*result != *first) *++result = *first; 474 return ++result; 475 } 476 477 478 template <class InputIterator, class OutputIterator, class T> 479 OutputIterator __unique_copy(InputIterator first, InputIterator last, 480 OutputIterator result, T*) { 481 T value = *first; 482 *result = value; 483 while (++first != last) 484 if (value != *first) { 485 value = *first; 486 *++result = value; 487 } 488 return ++result; 489 } 490 491 template <class InputIterator, class OutputIterator> 492 inline OutputIterator __unique_copy(InputIterator first, InputIterator last, 493 OutputIterator result, 494 output_iterator_tag) { 495 return __unique_copy(first, last, result, value_type(first)); 496 } 497 498 template <class InputIterator, class OutputIterator> 499 inline OutputIterator unique_copy(InputIterator first, InputIterator last, 500 OutputIterator result) { 501 if (first == last) return result; 502 return __unique_copy(first, last, result, iterator_category(result)); 503 } 504 template <class InputIterator, class ForwardIterator, class BinaryPredicate> 505 ForwardIterator __unique_copy(InputIterator first, InputIterator last, 506 ForwardIterator result, 507 BinaryPredicate binary_pred, 508 forward_iterator_tag) { 509 *result = *first; 510 while (++first != last) 511 if (!binary_pred(*result, *first)) *++result = *first; 512 return ++result; 513 } 514 515 template <class InputIterator, class OutputIterator, class BinaryPredicate, 516 class T> 517 OutputIterator __unique_copy(InputIterator first, InputIterator last, 518 OutputIterator result, 519 BinaryPredicate binary_pred, T*) { 520 T value = *first; 521 *result = value; 522 while (++first != last) 523 if (!binary_pred(value, *first)) { 524 value = *first; 525 *++result = value; 526 } 527 return ++result; 528 } 529 530 template <class InputIterator, class OutputIterator, class BinaryPredicate> 531 inline OutputIterator __unique_copy(InputIterator first, InputIterator last, 532 OutputIterator result, 533 BinaryPredicate binary_pred, 534 output_iterator_tag) { 535 return __unique_copy(first, last, result, binary_pred, value_type(first)); 536 } 537 538 template <class InputIterator, class OutputIterator, class BinaryPredicate> 539 inline OutputIterator unique_copy(InputIterator first, InputIterator last, 540 OutputIterator result, 541 BinaryPredicate binary_pred) { 542 if (first == last) return result; 543 return __unique_copy(first, last, result, binary_pred, 544 iterator_category(result)); 545 } 546 547 // 删除所有相邻重复元素 548 template <class ForwardIterator> 549 ForwardIterator unique(ForwardIterator first, ForwardIterator last) 550 { 551 first = adjacent_find(first, last); 552 return unique_copy(first, last, first); 553 } 554 555 // 好吧, 删除所有相邻重复元素, 并拷贝到指定位置 556 template <class ForwardIterator, class BinaryPredicate> 557 ForwardIterator unique(ForwardIterator first, ForwardIterator last, 558 BinaryPredicate binary_pred) 559 { 560 first = adjacent_find(first, last, binary_pred); 561 return unique_copy(first, last, first, binary_pred); 562 } 563 564 template <class BidirectionalIterator> 565 void __reverse(BidirectionalIterator first, BidirectionalIterator last, 566 bidirectional_iterator_tag) 567 { 568 while (true) 569 if (first == last || first == --last) 570 return; 571 else 572 iter_swap(first++, last); 573 } 574 575 template <class RandomAccessIterator> 576 void __reverse(RandomAccessIterator first, RandomAccessIterator last, 577 random_access_iterator_tag) 578 { 579 while (first < last) iter_swap(first++, --last); 580 } 581 582 // 将[first, last)内的元素倒置 583 // 还是为了效率进行函数派发, 不做解释了 584 template <class BidirectionalIterator> 585 inline void reverse(BidirectionalIterator first, BidirectionalIterator last) 586 { 587 __reverse(first, last, iterator_category(first)); 588 } 589 590 // 好吧, 和reverse的区别是会把处理后的元素拷贝到新区间 591 template <class BidirectionalIterator, class OutputIterator> 592 OutputIterator reverse_copy(BidirectionalIterator first, 593 BidirectionalIterator last, 594 OutputIterator result) 595 { 596 while (first != last) { 597 --last; 598 *result = *last; 599 ++result; 600 } 601 return result; 602 } 603 604 template <class ForwardIterator, class Distance> 605 void __rotate(ForwardIterator first, ForwardIterator middle, 606 ForwardIterator last, Distance*, forward_iterator_tag) { 607 for (ForwardIterator i = middle; ;) { 608 iter_swap(first, i); 609 ++first; 610 ++i; 611 if (first == middle) { 612 if (i == last) return; 613 middle = i; 614 } 615 else if (i == last) 616 i = middle; 617 } 618 } 619 620 template <class BidirectionalIterator, class Distance> 621 void __rotate(BidirectionalIterator first, BidirectionalIterator middle, 622 BidirectionalIterator last, Distance*, 623 bidirectional_iterator_tag) { 624 reverse(first, middle); 625 reverse(middle, last); 626 reverse(first, last); 627 } 628 629 // 这个你要是都不知道那就马上去学习数据结构的知识吧 630 template <class EuclideanRingElement> 631 EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n) 632 { 633 while (n != 0) { 634 EuclideanRingElement t = m % n; 635 m = n; 636 n = t; 637 } 638 return m; 639 } 640 641 template <class RandomAccessIterator, class Distance, class T> 642 void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last, 643 RandomAccessIterator initial, Distance shift, T*) { 644 T value = *initial; 645 RandomAccessIterator ptr1 = initial; 646 RandomAccessIterator ptr2 = ptr1 + shift; 647 while (ptr2 != initial) { 648 *ptr1 = *ptr2; 649 ptr1 = ptr2; 650 if (last - ptr2 > shift) 651 ptr2 += shift; 652 else 653 ptr2 = first + (shift - (last - ptr2)); 654 } 655 *ptr1 = value; 656 } 657 658 template <class RandomAccessIterator, class Distance> 659 void __rotate(RandomAccessIterator first, RandomAccessIterator middle, 660 RandomAccessIterator last, Distance*, 661 random_access_iterator_tag) { 662 Distance n = __gcd(last - first, middle - first); 663 while (n--) 664 __rotate_cycle(first, last, first + n, middle - first, 665 value_type(first)); 666 } 667 668 // 将[first, middle)和[middle, last)内元素互换 669 // 还是为了效率, 进行函数派发, 不解释了 670 template <class ForwardIterator> 671 inline void rotate(ForwardIterator first, ForwardIterator middle, 672 ForwardIterator last) { 673 if (first == middle || middle == last) return; 674 __rotate(first, middle, last, distance_type(first), 675 iterator_category(first)); 676 } 677 678 // 和rotate唯一的区别就是将旋转后的元素拷贝到新位置 679 template <class ForwardIterator, class OutputIterator> 680 OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, 681 ForwardIterator last, OutputIterator result) { 682 return copy(first, middle, copy(middle, last, result)); 683 } 684 685 template <class RandomAccessIterator, class Distance> 686 void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last, 687 Distance*) { 688 if (first == last) return; 689 for (RandomAccessIterator i = first + 1; i != last; ++i) 690 #ifdef __STL_NO_DRAND48 691 iter_swap(i, first + Distance(rand() % ((i - first) + 1))); 692 #else 693 iter_swap(i, first + Distance(lrand48() % ((i - first) + 1))); 694 #endif 695 } 696 697 template <class RandomAccessIterator> 698 inline void random_shuffle(RandomAccessIterator first, 699 RandomAccessIterator last) { 700 __random_shuffle(first, last, distance_type(first)); 701 } 702 703 // 产生随机的排列 704 template <class RandomAccessIterator, class RandomNumberGenerator> 705 void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, 706 RandomNumberGenerator& rand) 707 { 708 if (first == last) return; 709 for (RandomAccessIterator i = first + 1; i != last; ++i) 710 iter_swap(i, first + rand((i - first) + 1)); 711 } 712 713 template <class ForwardIterator, class OutputIterator, class Distance> 714 OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, 715 OutputIterator out, const Distance n) 716 { 717 Distance remaining = 0; 718 distance(first, last, remaining); 719 Distance m = min(n, remaining); 720 721 while (m > 0) { 722 #ifdef __STL_NO_DRAND48 723 if (rand() % remaining < m) { 724 #else 725 if (lrand48() % remaining < m) { 726 #endif 727 *out = *first; 728 ++out; 729 --m; 730 } 731 732 --remaining; 733 ++first; 734 } 735 return out; 736 } 737 738 template <class ForwardIterator, class OutputIterator, class Distance, 739 class RandomNumberGenerator> 740 OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, 741 OutputIterator out, const Distance n, 742 RandomNumberGenerator& rand) 743 { 744 Distance remaining = 0; 745 distance(first, last, remaining); 746 Distance m = min(n, remaining); 747 748 while (m > 0) { 749 if (rand(remaining) < m) { 750 *out = *first; 751 ++out; 752 --m; 753 } 754 755 --remaining; 756 ++first; 757 } 758 return out; 759 } 760 761 template <class InputIterator, class RandomAccessIterator, class Distance> 762 RandomAccessIterator __random_sample(InputIterator first, InputIterator last, 763 RandomAccessIterator out, 764 const Distance n) 765 { 766 Distance m = 0; 767 Distance t = n; 768 for ( ; first != last && m < n; ++m, ++first) 769 out[m] = *first; 770 771 while (first != last) { 772 ++t; 773 #ifdef __STL_NO_DRAND48 774 Distance M = rand() % t; 775 #else 776 Distance M = lrand48() % t; 777 #endif 778 if (M < n) 779 out[M] = *first; 780 ++first; 781 } 782 783 return out + m; 784 } 785 786 template <class InputIterator, class RandomAccessIterator, 787 class RandomNumberGenerator, class Distance> 788 RandomAccessIterator __random_sample(InputIterator first, InputIterator last, 789 RandomAccessIterator out, 790 RandomNumberGenerator& rand, 791 const Distance n) 792 { 793 Distance m = 0; 794 Distance t = n; 795 for ( ; first != last && m < n; ++m, ++first) 796 out[m] = *first; 797 798 while (first != last) { 799 ++t; 800 Distance M = rand(t); 801 if (M < n) 802 out[M] = *first; 803 ++first; 804 } 805 806 return out + m; 807 } 808 809 template <class InputIterator, class RandomAccessIterator> 810 inline RandomAccessIterator 811 random_sample(InputIterator first, InputIterator last, 812 RandomAccessIterator out_first, RandomAccessIterator out_last) 813 { 814 return __random_sample(first, last, out_first, out_last - out_first); 815 } 816 817 template <class InputIterator, class RandomAccessIterator, 818 class RandomNumberGenerator> 819 inline RandomAccessIterator 820 random_sample(InputIterator first, InputIterator last, 821 RandomAccessIterator out_first, RandomAccessIterator out_last, 822 RandomNumberGenerator& rand) 823 { 824 return __random_sample(first, last, out_first, rand, out_last - out_first); 825 } 826 827 828 // 将[first, last)区间内元素重新排序, 所有满足判别式的元素都被放在前面 829 template <class BidirectionalIterator, class Predicate> 830 BidirectionalIterator partition(BidirectionalIterator first, 831 BidirectionalIterator last, Predicate pred) 832 { 833 while (true) { 834 while (true) 835 if (first == last) 836 return first; 837 else if (pred(*first)) 838 ++first; 839 else 840 break; 841 --last; 842 while (true) 843 if (first == last) 844 return first; 845 else if (!pred(*last)) 846 --last; 847 else 848 break; 849 iter_swap(first, last); 850 ++first; 851 } 852 } 853 854 template <class ForwardIterator, class Predicate, class Distance> 855 ForwardIterator __inplace_stable_partition(ForwardIterator first, 856 ForwardIterator last, 857 Predicate pred, Distance len) { 858 if (len == 1) return pred(*first) ? last : first; 859 ForwardIterator middle = first; 860 advance(middle, len / 2); 861 ForwardIterator 862 first_cut = __inplace_stable_partition(first, middle, pred, len / 2); 863 ForwardIterator 864 second_cut = __inplace_stable_partition(middle, last, pred, 865 len - len / 2); 866 rotate(first_cut, middle, second_cut); 867 len = 0; 868 distance(middle, second_cut, len); 869 advance(first_cut, len); 870 return first_cut; 871 } 872 873 template <class ForwardIterator, class Pointer, class Predicate, 874 class Distance> 875 ForwardIterator __stable_partition_adaptive(ForwardIterator first, 876 ForwardIterator last, 877 Predicate pred, Distance len, 878 Pointer buffer, 879 Distance buffer_size) { 880 if (len <= buffer_size) { 881 ForwardIterator result1 = first; 882 Pointer result2 = buffer; 883 for ( ; first != last ; ++first) 884 if (pred(*first)) { 885 *result1 = *first; 886 ++result1; 887 } 888 else { 889 *result2 = *first; 890 ++result2; 891 } 892 copy(buffer, result2, result1); 893 return result1; 894 } 895 else { 896 ForwardIterator middle = first; 897 advance(middle, len / 2); 898 ForwardIterator first_cut = 899 __stable_partition_adaptive(first, middle, pred, len / 2, 900 buffer, buffer_size); 901 ForwardIterator second_cut = 902 __stable_partition_adaptive(middle, last, pred, len - len / 2, 903 buffer, buffer_size); 904 905 rotate(first_cut, middle, second_cut); 906 len = 0; 907 distance(middle, second_cut, len); 908 advance(first_cut, len); 909 return first_cut; 910 } 911 } 912 913 template <class ForwardIterator, class Predicate, class T, class Distance> 914 inline ForwardIterator __stable_partition_aux(ForwardIterator first, 915 ForwardIterator last, 916 Predicate pred, T*, Distance*) { 917 temporary_buffer<ForwardIterator, T> buf(first, last); 918 if (buf.size() > 0) 919 return __stable_partition_adaptive(first, last, pred, 920 Distance(buf.requested_size()), 921 buf.begin(), buf.size()); 922 else 923 return __inplace_stable_partition(first, last, pred, 924 Distance(buf.requested_size())); 925 } 926 927 template <class ForwardIterator, class Predicate> 928 inline ForwardIterator stable_partition(ForwardIterator first, 929 ForwardIterator last, 930 Predicate pred) { 931 if (first == last) 932 return first; 933 else 934 return __stable_partition_aux(first, last, pred, 935 value_type(first), distance_type(first)); 936 } 937 938 template <class RandomAccessIterator, class T> 939 RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 940 RandomAccessIterator last, 941 T pivot) { 942 while (true) { 943 while (*first < pivot) ++first; 944 --last; 945 while (pivot < *last) --last; 946 if (!(first < last)) return first; 947 iter_swap(first, last); 948 ++first; 949 } 950 } 951 952 template <class RandomAccessIterator, class T, class Compare> 953 RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 954 RandomAccessIterator last, 955 T pivot, Compare comp) { 956 while (1) { 957 while (comp(*first, pivot)) ++first; 958 --last; 959 while (comp(pivot, *last)) --last; 960 if (!(first < last)) return first; 961 iter_swap(first, last); 962 ++first; 963 } 964 } 965 966 const int __stl_threshold = 16; 967 968 969 template <class RandomAccessIterator, class T> 970 void __unguarded_linear_insert(RandomAccessIterator last, T value) { 971 RandomAccessIterator next = last; 972 --next; 973 while (value < *next) { 974 *last = *next; 975 last = next; 976 --next; 977 } 978 *last = value; 979 } 980 981 template <class RandomAccessIterator, class T, class Compare> 982 void __unguarded_linear_insert(RandomAccessIterator last, T value, 983 Compare comp) { 984 RandomAccessIterator next = last; 985 --next; 986 while (comp(value , *next)) { 987 *last = *next; 988 last = next; 989 --next; 990 } 991 *last = value; 992 } 993 994 template <class RandomAccessIterator, class T> 995 inline void __linear_insert(RandomAccessIterator first, 996 RandomAccessIterator last, T*) { 997 T value = *last; 998 if (value < *first) { 999 copy_backward(first, last, last + 1);1000 *first = value;1001 }1002 else1003 __unguarded_linear_insert(last, value);1004 }1005 1006 template <class RandomAccessIterator, class T, class Compare>1007 inline void __linear_insert(RandomAccessIterator first,1008 RandomAccessIterator last, T*, Compare comp) {1009 T value = *last;1010 if (comp(value, *first)) {1011 copy_backward(first, last, last + 1);1012 *first = value;1013 }1014 else1015 __unguarded_linear_insert(last, value, comp);1016 }1017 1018 template <class RandomAccessIterator>1019 void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {1020 if (first == last) return;1021 for (RandomAccessIterator i = first + 1; i != last; ++i)1022 __linear_insert(first, i, value_type(first));1023 }1024 1025 template <class RandomAccessIterator, class Compare>1026 void __insertion_sort(RandomAccessIterator first,1027 RandomAccessIterator last, Compare comp) {1028 if (first == last) return;1029 for (RandomAccessIterator i = first + 1; i != last; ++i)1030 __linear_insert(first, i, value_type(first), comp);1031 }1032 1033 template <class RandomAccessIterator, class T>1034 void __unguarded_insertion_sort_aux(RandomAccessIterator first,1035 RandomAccessIterator last, T*) {1036 for (RandomAccessIterator i = first; i != last; ++i)1037 __unguarded_linear_insert(i, T(*i));1038 }1039 1040 template <class RandomAccessIterator>1041 inline void __unguarded_insertion_sort(RandomAccessIterator first,1042 RandomAccessIterator last) {1043 __unguarded_insertion_sort_aux(first, last, value_type(first));1044 }1045 1046 template <class RandomAccessIterator, class T, class Compare>1047 void __unguarded_insertion_sort_aux(RandomAccessIterator first,1048 RandomAccessIterator last,1049 T*, Compare comp) {1050 for (RandomAccessIterator i = first; i != last; ++i)1051 __unguarded_linear_insert(i, T(*i), comp);1052 }1053 1054 template <class RandomAccessIterator, class Compare>1055 inline void __unguarded_insertion_sort(RandomAccessIterator first,1056 RandomAccessIterator last,1057 Compare comp) {1058 __unguarded_insertion_sort_aux(first, last, value_type(first), comp);1059 }1060 1061 template <class RandomAccessIterator>1062 void __final_insertion_sort(RandomAccessIterator first,1063 RandomAccessIterator last) {1064 if (last - first > __stl_threshold) {1065 __insertion_sort(first, first + __stl_threshold);1066 __unguarded_insertion_sort(first + __stl_threshold, last);1067 }1068 else1069 __insertion_sort(first, last);1070 }1071 1072 template <class RandomAccessIterator, class Compare>1073 void __final_insertion_sort(RandomAccessIterator first,1074 RandomAccessIterator last, Compare comp) {1075 if (last - first > __stl_threshold) {1076 __insertion_sort(first, first + __stl_threshold, comp);1077 __unguarded_insertion_sort(first + __stl_threshold, last, comp);1078 }1079 else1080 __insertion_sort(first, last, comp);1081 }1082 1083 template <class Size>1084 inline Size __lg(Size n) {1085 Size k;1086 for (k = 0; n > 1; n >>= 1) ++k;1087 return k;1088 }1089 1090 template <class RandomAccessIterator, class T, class Size>1091 void __introsort_loop(RandomAccessIterator first,1092 RandomAccessIterator last, T*,1093 Size depth_limit) {1094 while (last - first > __stl_threshold) {1095 if (depth_limit == 0) {1096 partial_sort(first, last, last);1097 return;1098 }1099 --depth_limit;1100 RandomAccessIterator cut = __unguarded_partition1101 (first, last, T(__median(*first, *(first + (last - first)/2),1102 *(last - 1))));1103 __introsort_loop(cut, last, value_type(first), depth_limit);1104 last = cut;1105 }1106 }1107 1108 template <class RandomAccessIterator, class T, class Size, class Compare>1109 void __introsort_loop(RandomAccessIterator first,1110 RandomAccessIterator last, T*,1111 Size depth_limit, Compare comp) {1112 while (last - first > __stl_threshold) {1113 if (depth_limit == 0) {1114 partial_sort(first, last, last, comp);1115 return;1116 }1117 --depth_limit;1118 RandomAccessIterator cut = __unguarded_partition1119 (first, last, T(__median(*first, *(first + (last - first)/2),1120 *(last - 1), comp)), comp);1121 __introsort_loop(cut, last, value_type(first), depth_limit, comp);1122 last = cut;1123 }1124 }1125 1126 // 必须为随RandomAccessIterator, 排序算法要根据情况进行派发1127 template <class RandomAccessIterator>1128 inline void sort(RandomAccessIterator first, RandomAccessIterator last)1129 {1130 if (first != last) {1131 __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);1132 __final_insertion_sort(first, last);1133 }1134 }1135 1136 template <class RandomAccessIterator, class Compare>1137 inline void sort(RandomAccessIterator first, RandomAccessIterator last,1138 Compare comp) {1139 if (first != last) {1140 __introsort_loop(first, last, value_type(first), __lg(last - first) * 2,1141 comp);1142 __final_insertion_sort(first, last, comp);1143 }1144 }1145 1146 1147 template <class RandomAccessIterator>1148 void __inplace_stable_sort(RandomAccessIterator first,1149 RandomAccessIterator last) {1150 if (last - first < 15) {1151 __insertion_sort(first, last);1152 return;1153 }1154 RandomAccessIterator middle = first + (last - first) / 2;1155 __inplace_stable_sort(first, middle);1156 __inplace_stable_sort(middle, last);1157 __merge_without_buffer(first, middle, last, middle - first, last - middle);1158 }1159 1160 template <class RandomAccessIterator, class Compare>1161 void __inplace_stable_sort(RandomAccessIterator first,1162 RandomAccessIterator last, Compare comp) {1163 if (last - first < 15) {1164 __insertion_sort(first, last, comp);1165 return;1166 }1167 RandomAccessIterator middle = first + (last - first) / 2;1168 __inplace_stable_sort(first, middle, comp);1169 __inplace_stable_sort(middle, last, comp);1170 __merge_without_buffer(first, middle, last, middle - first,1171 last - middle, comp);1172 }1173 1174 template <class RandomAccessIterator1, class RandomAccessIterator2,1175 class Distance>1176 void __merge_sort_loop(RandomAccessIterator1 first,1177 RandomAccessIterator1 last,1178 RandomAccessIterator2 result, Distance step_size) {1179 Distance two_step = 2 * step_size;1180 1181 while (last - first >= two_step) {1182 result = merge(first, first + step_size,1183 first + step_size, first + two_step, result);1184 first += two_step;1185 }1186 1187 step_size = min(Distance(last - first), step_size);1188 merge(first, first + step_size, first + step_size, last, result);1189 }1190 1191 template <class RandomAccessIterator1, class RandomAccessIterator2,1192 class Distance, class Compare>1193 void __merge_sort_loop(RandomAccessIterator1 first,1194 RandomAccessIterator1 last,1195 RandomAccessIterator2 result, Distance step_size,1196 Compare comp) {1197 Distance two_step = 2 * step_size;1198 1199 while (last - first >= two_step) {1200 result = merge(first, first + step_size,1201 first + step_size, first + two_step, result, comp);1202 first += two_step;1203 }1204 step_size = min(Distance(last - first), step_size);1205 1206 merge(first, first + step_size, first + step_size, last, result, comp);1207 }1208 1209 const int __stl_chunk_size = 7;1210 1211 template <class RandomAccessIterator, class Distance>1212 void __chunk_insertion_sort(RandomAccessIterator first,1213 RandomAccessIterator last, Distance chunk_size) {1214 while (last - first >= chunk_size) {1215 __insertion_sort(first, first + chunk_size);1216 first += chunk_size;1217 }1218 __insertion_sort(first, last);1219 }1220 1221 template <class RandomAccessIterator, class Distance, class Compare>1222 void __chunk_insertion_sort(RandomAccessIterator first,1223 RandomAccessIterator last,1224 Distance chunk_size, Compare comp) {1225 while (last - first >= chunk_size) {1226 __insertion_sort(first, first + chunk_size, comp);1227 first += chunk_size;1228 }1229 __insertion_sort(first, last, comp);1230 }1231 1232 template <class RandomAccessIterator, class Pointer, class Distance>1233 void __merge_sort_with_buffer(RandomAccessIterator first,1234 RandomAccessIterator last,1235 Pointer buffer, Distance*) {1236 Distance len = last - first;1237 Pointer buffer_last = buffer + len;1238 1239 Distance step_size = __stl_chunk_size;1240 __chunk_insertion_sort(first, last, step_size);1241 1242 while (step_size < len) {1243 __merge_sort_loop(first, last, buffer, step_size);1244 step_size *= 2;1245 __merge_sort_loop(buffer, buffer_last, first, step_size);1246 step_size *= 2;1247 }1248 }1249 1250 template <class RandomAccessIterator, class Pointer, class Distance,1251 class Compare>1252 void __merge_sort_with_buffer(RandomAccessIterator first,1253 RandomAccessIterator last, Pointer buffer,1254 Distance*, Compare comp) {1255 Distance len = last - first;1256 Pointer buffer_last = buffer + len;1257 1258 Distance step_size = __stl_chunk_size;1259 __chunk_insertion_sort(first, last, step_size, comp);1260 1261 while (step_size < len) {1262 __merge_sort_loop(first, last, buffer, step_size, comp);1263 step_size *= 2;1264 __merge_sort_loop(buffer, buffer_last, first, step_size, comp);1265 step_size *= 2;1266 }1267 }1268 1269 template <class RandomAccessIterator, class Pointer, class Distance>1270 void __stable_sort_adaptive(RandomAccessIterator first,1271 RandomAccessIterator last, Pointer buffer,1272 Distance buffer_size) {1273 Distance len = (last - first + 1) / 2;1274 RandomAccessIterator middle = first + len;1275 if (len > buffer_size) {1276 __stable_sort_adaptive(first, middle, buffer, buffer_size);1277 __stable_sort_adaptive(middle, last, buffer, buffer_size);1278 } else {1279 __merge_sort_with_buffer(first, middle, buffer, (Distance*)0);1280 __merge_sort_with_buffer(middle, last, buffer, (Distance*)0);1281 }1282 __merge_adaptive(first, middle, last, Distance(middle - first),1283 Distance(last - middle), buffer, buffer_size);1284 }1285 1286 template <class RandomAccessIterator, class Pointer, class Distance,1287 class Compare>1288 void __stable_sort_adaptive(RandomAccessIterator first,1289 RandomAccessIterator last, Pointer buffer,1290 Distance buffer_size, Compare comp) {1291 Distance len = (last - first + 1) / 2;1292 RandomAccessIterator middle = first + len;1293 if (len > buffer_size) {1294 __stable_sort_adaptive(first, middle, buffer, buffer_size,1295 comp);1296 __stable_sort_adaptive(middle, last, buffer, buffer_size,1297 comp);1298 } else {1299 __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp);1300 __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp);1301 }1302 __merge_adaptive(first, middle, last, Distance(middle - first),1303 Distance(last - middle), buffer, buffer_size,1304 comp);1305 }1306 1307 template <class RandomAccessIterator, class T, class Distance>1308 inline void __stable_sort_aux(RandomAccessIterator first,1309 RandomAccessIterator last, T*, Distance*) {1310 temporary_buffer<RandomAccessIterator, T> buf(first, last);1311 if (buf.begin() == 0)1312 __inplace_stable_sort(first, last);1313 else1314 __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));1315 }1316 1317 template <class RandomAccessIterator, class T, class Distance, class Compare>1318 inline void __stable_sort_aux(RandomAccessIterator first,1319 RandomAccessIterator last, T*, Distance*,1320 Compare comp) {1321 temporary_buffer<RandomAccessIterator, T> buf(first, last);1322 if (buf.begin() == 0)1323 __inplace_stable_sort(first, last, comp);1324 else1325 __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),1326 comp);1327 }1328 1329 template <class RandomAccessIterator>1330 inline void stable_sort(RandomAccessIterator first,1331 RandomAccessIterator last) {1332 __stable_sort_aux(first, last, value_type(first), distance_type(first));1333 }1334 1335 template <class RandomAccessIterator, class Compare>1336 inline void stable_sort(RandomAccessIterator first,1337 RandomAccessIterator last, Compare comp) {1338 __stable_sort_aux(first, last, value_type(first), distance_type(first),1339 comp);1340 }1341 1342 template <class RandomAccessIterator, class T>1343 void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,1344 RandomAccessIterator last, T*) {1345 make_heap(first, middle);1346 for (RandomAccessIterator i = middle; i < last; ++i)1347 if (*i < *first)1348 __pop_heap(first, middle, i, T(*i), distance_type(first));1349 sort_heap(first, middle);1350 }1351 1352 // 只保证[first, middle)有序, 效率至上时使用1353 template <class RandomAccessIterator>1354 inline void partial_sort(RandomAccessIterator first,1355 RandomAccessIterator middle,1356 RandomAccessIterator last)1357 {1358 __partial_sort(first, middle, last, value_type(first));1359 }1360 1361 template <class RandomAccessIterator, class T, class Compare>1362 void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,1363 RandomAccessIterator last, T*, Compare comp) {1364 make_heap(first, middle, comp);1365 for (RandomAccessIterator i = middle; i < last; ++i)1366 if (comp(*i, *first))1367 __pop_heap(first, middle, i, T(*i), comp, distance_type(first));1368 sort_heap(first, middle, comp);1369 }1370 1371 template <class RandomAccessIterator, class Compare>1372 inline void partial_sort(RandomAccessIterator first,1373 RandomAccessIterator middle,1374 RandomAccessIterator last, Compare comp) {1375 __partial_sort(first, middle, last, value_type(first), comp);1376 }1377 1378 template <class InputIterator, class RandomAccessIterator, class Distance,1379 class T>1380 RandomAccessIterator __partial_sort_copy(InputIterator first,1381 InputIterator last,1382 RandomAccessIterator result_first,1383 RandomAccessIterator result_last,1384 Distance*, T*) {1385 if (result_first == result_last) return result_last;1386 RandomAccessIterator result_real_last = result_first;1387 while(first != last && result_real_last != result_last) {1388 *result_real_last = *first;1389 ++result_real_last;1390 ++first;1391 }1392 make_heap(result_first, result_real_last);1393 while (first != last) {1394 if (*first < *result_first)1395 __adjust_heap(result_first, Distance(0),1396 Distance(result_real_last - result_first), T(*first));1397 ++first;1398 }1399 sort_heap(result_first, result_real_last);1400 return result_real_last;1401 }1402 1403 template <class InputIterator, class RandomAccessIterator>1404 inline RandomAccessIterator1405 partial_sort_copy(InputIterator first, InputIterator last,1406 RandomAccessIterator result_first,1407 RandomAccessIterator result_last) {1408 return __partial_sort_copy(first, last, result_first, result_last,1409 distance_type(result_first), value_type(first));1410 }1411 1412 template <class InputIterator, class RandomAccessIterator, class Compare,1413 class Distance, class T>1414 RandomAccessIterator __partial_sort_copy(InputIterator first,1415 InputIterator last,1416 RandomAccessIterator result_first,1417 RandomAccessIterator result_last,1418 Compare comp, Distance*, T*) {1419 if (result_first == result_last) return result_last;1420 RandomAccessIterator result_real_last = result_first;1421 while(first != last && result_real_last != result_last) {1422 *result_real_last = *first;1423 ++result_real_last;1424 ++first;1425 }1426 make_heap(result_first, result_real_last, comp);1427 while (first != last) {1428 if (comp(*first, *result_first))1429 __adjust_heap(result_first, Distance(0),1430 Distance(result_real_last - result_first), T(*first),1431 comp);1432 ++first;1433 }1434 sort_heap(result_first, result_real_last, comp);1435 return result_real_last;1436 }1437 1438 template <class InputIterator, class RandomAccessIterator, class Compare>1439 inline RandomAccessIterator1440 partial_sort_copy(InputIterator first, InputIterator last,1441 RandomAccessIterator result_first,1442 RandomAccessIterator result_last, Compare comp) {1443 return __partial_sort_copy(first, last, result_first, result_last, comp,1444 distance_type(result_first), value_type(first));1445 }1446 1447 template <class RandomAccessIterator, class T>1448 void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,1449 RandomAccessIterator last, T*) {1450 while (last - first > 3) {1451 RandomAccessIterator cut = __unguarded_partition1452 (first, last, T(__median(*first, *(first + (last - first)/2),1453 *(last - 1))));1454 if (cut <= nth)1455 first = cut;1456 else1457 last = cut;1458 }1459 __insertion_sort(first, last);1460 }1461 1462 template <class RandomAccessIterator>1463 inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,1464 RandomAccessIterator last) {1465 __nth_element(first, nth, last, value_type(first));1466 }1467 1468 template <class RandomAccessIterator, class T, class Compare>1469 void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,1470 RandomAccessIterator last, T*, Compare comp) {1471 while (last - first > 3) {1472 RandomAccessIterator cut = __unguarded_partition1473 (first, last, T(__median(*first, *(first + (last - first)/2),1474 *(last - 1), comp)), comp);1475 if (cut <= nth)1476 first = cut;1477 else1478 last = cut;1479 }1480 __insertion_sort(first, last, comp);1481 }1482 1483 template <class RandomAccessIterator, class Compare>1484 inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,1485 RandomAccessIterator last, Compare comp) {1486 __nth_element(first, nth, last, value_type(first), comp);1487 }1488 1489 template <class ForwardIterator, class T, class Distance>1490 ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,1491 const T& value, Distance*,1492 forward_iterator_tag) {1493 Distance len = 0;1494 distance(first, last, len);1495 Distance half;1496 ForwardIterator middle;1497 1498 while (len > 0) {1499 half = len >> 1;1500 middle = first;1501 advance(middle, half);1502 if (*middle < value) {1503 first = middle;1504 ++first;1505 len = len - half - 1;1506 }1507 else1508 len = half;1509 }1510 return first;1511 }1512 1513 template <class RandomAccessIterator, class T, class Distance>1514 RandomAccessIterator __lower_bound(RandomAccessIterator first,1515 RandomAccessIterator last, const T& value,1516 Distance*, random_access_iterator_tag) {1517 Distance len = last - first;1518 Distance half;1519 RandomAccessIterator middle;1520 1521 while (len > 0) {1522 half = len >> 1;1523 middle = first + half;1524 if (*middle < value) {1525 first = middle + 1;1526 len = len - half - 1;1527 }1528 else1529 len = half;1530 }1531 return first;1532 }1533 1534 // 用于有序区间, 返回第一个大于value的位置1535 // 同样为了效率, 要进行函数派发1536 template <class ForwardIterator, class T>1537 inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,1538 const T& value)1539 {1540 return __lower_bound(first, last, value, distance_type(first),1541 iterator_category(first));1542 }1543 1544 template <class ForwardIterator, class T, class Compare, class Distance>1545 ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,1546 const T& value, Compare comp, Distance*,1547 forward_iterator_tag) {1548 Distance len = 0;1549 distance(first, last, len);1550 Distance half;1551 ForwardIterator middle;1552 1553 while (len > 0) {1554 half = len >> 1;1555 middle = first;1556 advance(middle, half);1557 if (comp(*middle, value)) {1558 first = middle;1559 ++first;1560 len = len - half - 1;1561 }1562 else1563 len = half;1564 }1565 return first;1566 }1567 1568 template <class RandomAccessIterator, class T, class Compare, class Distance>1569 RandomAccessIterator __lower_bound(RandomAccessIterator first,1570 RandomAccessIterator last,1571 const T& value, Compare comp, Distance*,1572 random_access_iterator_tag) {1573 Distance len = last - first;1574 Distance half;1575 RandomAccessIterator middle;1576 1577 while (len > 0) {1578 half = len >> 1;1579 middle = first + half;1580 if (comp(*middle, value)) {1581 first = middle + 1;1582 len = len - half - 1;1583 }1584 else1585 len = half;1586 }1587 return first;1588 }1589 1590 template <class ForwardIterator, class T, class Compare>1591 inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,1592 const T& value, Compare comp) {1593 return __lower_bound(first, last, value, comp, distance_type(first),1594 iterator_category(first));1595 }1596 1597 template <class ForwardIterator, class T, class Distance>1598 ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,1599 const T& value, Distance*,1600 forward_iterator_tag) {1601 Distance len = 0;1602 distance(first, last, len);1603 Distance half;1604 ForwardIterator middle;1605 1606 while (len > 0) {1607 half = len >> 1;1608 middle = first;1609 advance(middle, half);1610 if (value < *middle)1611 len = half;1612 else {1613 first = middle;1614 ++first;1615 len = len - half - 1;1616 }1617 }1618 return first;1619 }1620 1621 template <class RandomAccessIterator, class T, class Distance>1622 RandomAccessIterator __upper_bound(RandomAccessIterator first,1623 RandomAccessIterator last, const T& value,1624 Distance*, random_access_iterator_tag) {1625 Distance len = last - first;1626 Distance half;1627 RandomAccessIterator middle;1628 1629 while (len > 0) {1630 half = len >> 1;1631 middle = first + half;1632 if (value < *middle)1633 len = half;1634 else {1635 first = middle + 1;1636 len = len - half - 1;1637 }1638 }1639 return first;1640 }1641 1642 template <class ForwardIterator, class T>1643 inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,1644 const T& value) {1645 return __upper_bound(first, last, value, distance_type(first),1646 iterator_category(first));1647 }1648 1649 template <class ForwardIterator, class T, class Compare, class Distance>1650 ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,1651 const T& value, Compare comp, Distance*,1652 forward_iterator_tag) {1653 Distance len = 0;1654 distance(first, last, len);1655 Distance half;1656 ForwardIterator middle;1657 1658 while (len > 0) {1659 half = len >> 1;1660 middle = first;1661 advance(middle, half);1662 if (comp(value, *middle))1663 len = half;1664 else {1665 first = middle;1666 ++first;1667 len = len - half - 1;1668 }1669 }1670 return first;1671 }1672 1673 template <class RandomAccessIterator, class T, class Compare, class Distance>1674 RandomAccessIterator __upper_bound(RandomAccessIterator first,1675 RandomAccessIterator last,1676 const T& value, Compare comp, Distance*,1677 random_access_iterator_tag) {1678 Distance len = last - first;1679 Distance half;1680 RandomAccessIterator middle;1681 1682 while (len > 0) {1683 half = len >> 1;1684 middle = first + half;1685 if (comp(value, *middle))1686 len = half;1687 else {1688 first = middle + 1;1689 len = len - half - 1;1690 }1691 }1692 return first;1693 }1694 1695 template <class ForwardIterator, class T, class Compare>1696 inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,1697 const T& value, Compare comp) {1698 return __upper_bound(first, last, value, comp, distance_type(first),1699 iterator_category(first));1700 }1701 1702 template <class ForwardIterator, class T, class Distance>1703 pair<ForwardIterator, ForwardIterator>1704 __equal_range(ForwardIterator first, ForwardIterator last, const T& value,1705 Distance*, forward_iterator_tag) {1706 Distance len = 0;1707 distance(first, last, len);1708 Distance half;1709 ForwardIterator middle, left, right;1710 1711 while (len > 0) {1712 half = len >> 1;1713 middle = first;1714 advance(middle, half);1715 if (*middle < value) {1716 first = middle;1717 ++first;1718 len = len - half - 1;1719 }1720 else if (value < *middle)1721 len = half;1722 else {1723 left = lower_bound(first, middle, value);1724 advance(first, len);1725 right = upper_bound(++middle, first, value);1726 return pair<ForwardIterator, ForwardIterator>(left, right);1727 }1728 }1729 return pair<ForwardIterator, ForwardIterator>(first, first);1730 }1731 1732 template <class RandomAccessIterator, class T, class Distance>1733 pair<RandomAccessIterator, RandomAccessIterator>1734 __equal_range(RandomAccessIterator first, RandomAccessIterator last,1735 const T& value, Distance*, random_access_iterator_tag) {1736 Distance len = last - first;1737 Distance half;1738 RandomAccessIterator middle, left, right;1739 1740 while (len > 0) {1741 half = len >> 1;1742 middle = first + half;1743 if (*middle < value) {1744 first = middle + 1;1745 len = len - half - 1;1746 }1747 else if (value < *middle)1748 len = half;1749 else {1750 left = lower_bound(first, middle, value);1751 right = upper_bound(++middle, first + len, value);1752 return pair<RandomAccessIterator, RandomAccessIterator>(left,1753 right);1754 }1755 }1756 return pair<RandomAccessIterator, RandomAccessIterator>(first, first);1757 }1758 1759 template <class ForwardIterator, class T>1760 inline pair<ForwardIterator, ForwardIterator>1761 equal_range(ForwardIterator first, ForwardIterator last, const T& value) {1762 return __equal_range(first, last, value, distance_type(first),1763 iterator_category(first));1764 }1765 1766 template <class ForwardIterator, class T, class Compare, class Distance>1767 pair<ForwardIterator, ForwardIterator>1768 __equal_range(ForwardIterator first, ForwardIterator last, const T& value,1769 Compare comp, Distance*, forward_iterator_tag) {1770 Distance len = 0;1771 distance(first, last, len);1772 Distance half;1773 ForwardIterator middle, left, right;1774 1775 while (len > 0) {1776 half = len >> 1;1777 middle = first;1778 advance(middle, half);1779 if (comp(*middle, value)) {1780 first = middle;1781 ++first;1782 len = len - half - 1;1783 }1784 else if (comp(value, *middle))1785 len = half;1786 else {1787 left = lower_bound(first, middle, value, comp);1788 advance(first, len);1789 right = upper_bound(++middle, first, value, comp);1790 return pair<ForwardIterator, ForwardIterator>(left, right);1791 }1792 }1793 return pair<ForwardIterator, ForwardIterator>(first, first);1794 }1795 1796 template <class RandomAccessIterator, class T, class Compare, class Distance>1797 pair<RandomAccessIterator, RandomAccessIterator>1798 __equal_range(RandomAccessIterator first, RandomAccessIterator last,1799 const T& value, Compare comp, Distance*,1800 random_access_iterator_tag) {1801 Distance len = last - first;1802 Distance half;1803 RandomAccessIterator middle, left, right;1804 1805 while (len > 0) {1806 half = len >> 1;1807 middle = first + half;1808 if (comp(*middle, value)) {1809 first = middle + 1;1810 len = len - half - 1;1811 }1812 else if (comp(value, *middle))1813 len = half;1814 else {1815 left = lower_bound(first, middle, value, comp);1816 right = upper_bound(++middle, first + len, value, comp);1817 return pair<RandomAccessIterator, RandomAccessIterator>(left,1818 right);1819 }1820 }1821 return pair<RandomAccessIterator, RandomAccessIterator>(first, first);1822 }1823 1824 template <class ForwardIterator, class T, class Compare>1825 inline pair<ForwardIterator, ForwardIterator>1826 equal_range(ForwardIterator first, ForwardIterator last, const T& value,1827 Compare comp) {1828 return __equal_range(first, last, value, comp, distance_type(first),1829 iterator_category(first));1830 }1831 1832 // 用于有序区间的二分查找, 不知道的赶快去学数据结构1833 template <class ForwardIterator, class T>1834 bool binary_search(ForwardIterator first, ForwardIterator last,1835 const T& value) {1836 ForwardIterator i = lower_bound(first, last, value);1837 return i != last && !(value < *i);1838 }1839 1840 template <class ForwardIterator, class T, class Compare>1841 bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,1842 Compare comp) {1843 ForwardIterator i = lower_bound(first, last, value, comp);1844 return i != last && !comp(value, *i);1845 }1846 1847 // 将两个有序区间合并起来, 并保证其也有序1848 template <class InputIterator1, class InputIterator2, class OutputIterator>1849 OutputIterator merge(InputIterator1 first1, InputIterator1 last1,1850 InputIterator2 first2, InputIterator2 last2,1851 OutputIterator result)1852 {1853 while (first1 != last1 && first2 != last2) {1854 if (*first2 < *first1) {1855 *result = *first2;1856 ++first2;1857 }1858 else {1859 *result = *first1;1860 ++first1;1861 }1862 ++result;1863 }1864 return copy(first2, last2, copy(first1, last1, result));1865 }1866 1867 template <class InputIterator1, class InputIterator2, class OutputIterator,1868 class Compare>1869 OutputIterator merge(InputIterator1 first1, InputIterator1 last1,1870 InputIterator2 first2, InputIterator2 last2,1871 OutputIterator result, Compare comp)1872 {1873 while (first1 != last1 && first2 != last2) {1874 if (comp(*first2, *first1)) {1875 *result = *first2;1876 ++first2;1877 }1878 else {1879 *result = *first1;1880 ++first1;1881 }1882 ++result;1883 }1884 return copy(first2, last2, copy(first1, last1, result));1885 }1886 1887 template <class BidirectionalIterator, class Distance>1888 void __merge_without_buffer(BidirectionalIterator first,1889 BidirectionalIterator middle,1890 BidirectionalIterator last,1891 Distance len1, Distance len2) {1892 if (len1 == 0 || len2 == 0) return;1893 if (len1 + len2 == 2) {1894 if (*middle < *first) iter_swap(first, middle);1895 return;1896 }1897 BidirectionalIterator first_cut = first;1898 BidirectionalIterator second_cut = middle;1899 Distance len11 = 0;1900 Distance len22 = 0;1901 if (len1 > len2) {1902 len11 = len1 / 2;1903 advance(first_cut, len11);1904 second_cut = lower_bound(middle, last, *first_cut);1905 distance(middle, second_cut, len22);1906 }1907 else {1908 len22 = len2 / 2;1909 advance(second_cut, len22);1910 first_cut = upper_bound(first, middle, *second_cut);1911 distance(first, first_cut, len11);1912 }1913 rotate(first_cut, middle, second_cut);1914 BidirectionalIterator new_middle = first_cut;1915 advance(new_middle, len22);1916 __merge_without_buffer(first, first_cut, new_middle, len11, len22);1917 __merge_without_buffer(new_middle, second_cut, last, len1 - len11,1918 len2 - len22);1919 }1920 1921 template <class BidirectionalIterator, class Distance, class Compare>1922 void __merge_without_buffer(BidirectionalIterator first,1923 BidirectionalIterator middle,1924 BidirectionalIterator last,1925 Distance len1, Distance len2, Compare comp) {1926 if (len1 == 0 || len2 == 0) return;1927 if (len1 + len2 == 2) {1928 if (comp(*middle, *first)) iter_swap(first, middle);1929 return;1930 }1931 BidirectionalIterator first_cut = first;1932 BidirectionalIterator second_cut = middle;1933 Distance len11 = 0;1934 Distance len22 = 0;1935 if (len1 > len2) {1936 len11 = len1 / 2;1937 advance(first_cut, len11);1938 second_cut = lower_bound(middle, last, *first_cut, comp);1939 distance(middle, second_cut, len22);1940 }1941 else {1942 len22 = len2 / 2;1943 advance(second_cut, len22);1944 first_cut = upper_bound(first, middle, *second_cut, comp);1945 distance(first, first_cut, len11);1946 }1947 rotate(first_cut, middle, second_cut);1948 BidirectionalIterator new_middle = first_cut;1949 advance(new_middle, len22);1950 __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);1951 __merge_without_buffer(new_middle, second_cut, last, len1 - len11,1952 len2 - len22, comp);1953 }1954 1955 template <class BidirectionalIterator1, class BidirectionalIterator2,1956 class Distance>1957 BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,1958 BidirectionalIterator1 middle,1959 BidirectionalIterator1 last,1960 Distance len1, Distance len2,1961 BidirectionalIterator2 buffer,1962 Distance buffer_size) {1963 BidirectionalIterator2 buffer_end;1964 if (len1 > len2 && len2 <= buffer_size) {1965 buffer_end = copy(middle, last, buffer);1966 copy_backward(first, middle, last);1967 return copy(buffer, buffer_end, first);1968 } else if (len1 <= buffer_size) {1969 buffer_end = copy(first, middle, buffer);1970 copy(middle, last, first);1971 return copy_backward(buffer, buffer_end, last);1972 } else {1973 rotate(first, middle, last);1974 advance(first, len2);1975 return first;1976 }1977 }1978 1979 template <class BidirectionalIterator1, class BidirectionalIterator2,1980 class BidirectionalIterator3>1981 BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,1982 BidirectionalIterator1 last1,1983 BidirectionalIterator2 first2,1984 BidirectionalIterator2 last2,1985 BidirectionalIterator3 result) {1986 if (first1 == last1) return copy_backward(first2, last2, result);1987 if (first2 == last2) return copy_backward(first1, last1, result);1988 --last1;1989 --last2;1990 while (true) {1991 if (*last2 < *last1) {1992 *--result = *last1;1993 if (first1 == last1) return copy_backward(first2, ++last2, result);1994 --last1;1995 }1996 else {1997 *--result = *last2;1998 if (first2 == last2) return copy_backward(first1, ++last1, result);1999 --last2;2000 }2001 }2002 }2003 2004 template <class BidirectionalIterator1, class BidirectionalIterator2,2005 class BidirectionalIterator3, class Compare>2006 BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,2007 BidirectionalIterator1 last1,2008 BidirectionalIterator2 first2,2009 BidirectionalIterator2 last2,2010 BidirectionalIterator3 result,2011 Compare comp) {2012 if (first1 == last1) return copy_backward(first2, last2, result);2013 if (first2 == last2) return copy_backward(first1, last1, result);2014 --last1;2015 --last2;2016 while (true) {2017 if (comp(*last2, *last1)) {2018 *--result = *last1;2019 if (first1 == last1) return copy_backward(first2, ++last2, result);2020 --last1;2021 }2022 else {2023 *--result = *last2;2024 if (first2 == last2) return copy_backward(first1, ++last1, result);2025 --last2;2026 }2027 }2028 }2029 2030 template <class BidirectionalIterator, class Distance, class Pointer>2031 void __merge_adaptive(BidirectionalIterator first,2032 BidirectionalIterator middle,2033 BidirectionalIterator last, Distance len1, Distance len2,2034 Pointer buffer, Distance buffer_size) {2035 if (len1 <= len2 && len1 <= buffer_size) {2036 Pointer end_buffer = copy(first, middle, buffer);2037 merge(buffer, end_buffer, middle, last, first);2038 }2039 else if (len2 <= buffer_size) {2040 Pointer end_buffer = copy(middle, last, buffer);2041 __merge_backward(first, middle, buffer, end_buffer, last);2042 }2043 else {2044 BidirectionalIterator first_cut = first;2045 BidirectionalIterator second_cut = middle;2046 Distance len11 = 0;2047 Distance len22 = 0;2048 if (len1 > len2) {2049 len11 = len1 / 2;2050 advance(first_cut, len11);2051 second_cut = lower_bound(middle, last, *first_cut);2052 distance(middle, second_cut, len22);2053 }2054 else {2055 len22 = len2 / 2;2056 advance(second_cut, len22);2057 first_cut = upper_bound(first, middle, *second_cut);2058 distance(first, first_cut, len11);2059 }2060 BidirectionalIterator new_middle =2061 __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,2062 len22, buffer, buffer_size);2063 __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,2064 buffer_size);2065 __merge_adaptive(new_middle, second_cut, last, len1 - len11,2066 len2 - len22, buffer, buffer_size);2067 }2068 }2069 2070 template <class BidirectionalIterator, class Distance, class Pointer,2071 class Compare>2072 void __merge_adaptive(BidirectionalIterator first,2073 BidirectionalIterator middle,2074 BidirectionalIterator last, Distance len1, Distance len2,2075 Pointer buffer, Distance buffer_size, Compare comp) {2076 if (len1 <= len2 && len1 <= buffer_size) {2077 Pointer end_buffer = copy(first, middle, buffer);2078 merge(buffer, end_buffer, middle, last, first, comp);2079 }2080 else if (len2 <= buffer_size) {2081 Pointer end_buffer = copy(middle, last, buffer);2082 __merge_backward(first, middle, buffer, end_buffer, last, comp);2083 }2084 else {2085 BidirectionalIterator first_cut = first;2086 BidirectionalIterator second_cut = middle;2087 Distance len11 = 0;2088 Distance len22 = 0;2089 if (len1 > len2) {2090 len11 = len1 / 2;2091 advance(first_cut, len11);2092 second_cut = lower_bound(middle, last, *first_cut, comp);2093 distance(middle, second_cut, len22);2094 }2095 else {2096 len22 = len2 / 2;2097 advance(second_cut, len22);2098 first_cut = upper_bound(first, middle, *second_cut, comp);2099 distance(first, first_cut, len11);2100 }2101 BidirectionalIterator new_middle =2102 __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,2103 len22, buffer, buffer_size);2104 __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,2105 buffer_size, comp);2106 __merge_adaptive(new_middle, second_cut, last, len1 - len11,2107 len2 - len22, buffer, buffer_size, comp);2108 }2109 }2110 2111 template <class BidirectionalIterator, class T, class Distance>2112 inline void __inplace_merge_aux(BidirectionalIterator first,2113 BidirectionalIterator middle,2114 BidirectionalIterator last, T*, Distance*) {2115 Distance len1 = 0;2116 distance(first, middle, len1);2117 Distance len2 = 0;2118 distance(middle, last, len2);2119 2120 temporary_buffer<BidirectionalIterator, T> buf(first, last);2121 if (buf.begin() == 0)2122 __merge_without_buffer(first, middle, last, len1, len2);2123 else2124 __merge_adaptive(first, middle, last, len1, len2,2125 buf.begin(), Distance(buf.size()));2126 }2127 2128 template <class BidirectionalIterator, class T, class Distance, class Compare>2129 inline void __inplace_merge_aux(BidirectionalIterator first,2130 BidirectionalIterator middle,2131 BidirectionalIterator last, T*, Distance*,2132 Compare comp) {2133 Distance len1 = 0;2134 distance(first, middle, len1);2135 Distance len2 = 0;2136 distance(middle, last, len2);2137 2138 temporary_buffer<BidirectionalIterator, T> buf(first, last);2139 if (buf.begin() == 0)2140 __merge_without_buffer(first, middle, last, len1, len2, comp);2141 else2142 __merge_adaptive(first, middle, last, len1, len2,2143 buf.begin(), Distance(buf.size()),2144 comp);2145 }2146 2147 template <class BidirectionalIterator>2148 inline void inplace_merge(BidirectionalIterator first,2149 BidirectionalIterator middle,2150 BidirectionalIterator last) {2151 if (first == middle || middle == last) return;2152 __inplace_merge_aux(first, middle, last, value_type(first),2153 distance_type(first));2154 }2155 2156 template <class BidirectionalIterator, class Compare>2157 inline void inplace_merge(BidirectionalIterator first,2158 BidirectionalIterator middle,2159 BidirectionalIterator last, Compare comp) {2160 if (first == middle || middle == last) return;2161 __inplace_merge_aux(first, middle, last, value_type(first),2162 distance_type(first), comp);2163 }2164 2165 // 判断[first2, last2)是否包含在[first1, last1)中,2166 // 注意: 两个区间要保证有序, 如果容器是降序排列, 那么要使用另一个版本,2167 // 并使用greater<>()来比较2168 template <class InputIterator1, class InputIterator2>2169 bool includes(InputIterator1 first1, InputIterator1 last1,2170 InputIterator2 first2, InputIterator2 last2)2171 {2172 while (first1 != last1 && first2 != last2)2173 if (*first2 < *first1)2174 return false;2175 else if(*first1 < *first2)2176 ++first1;2177 else2178 ++first1, ++first2;2179 2180 return first2 == last2;2181 }2182 2183 // 除了自己指定判别式, 其余同上2184 template <class InputIterator1, class InputIterator2, class Compare>2185 bool includes(InputIterator1 first1, InputIterator1 last1,2186 InputIterator2 first2, InputIterator2 last2, Compare comp)2187 {2188 while (first1 != last1 && first2 != last2)2189 if (comp(*first2, *first1))2190 return false;2191 else if(comp(*first1, *first2))2192 ++first1;2193 else2194 ++first1, ++first2;2195 2196 return first2 == last2;2197 }2198 2199 ////////////////////////////////////////////////////////////////////////////////2200 // 四个集合相关算法2201 ////////////////////////////////////////////////////////////////////////////////2202 2203 // 求两个集合的的并集, 和数学定义的并集有一些不一样2204 // 对于两个集合S1[first1, last1)和S2[first2, last2)2205 // 假设其中k元素在S1中出现n1次, 在S2中出现n2次2206 // 那么求出的并集选取max(n1, n2)为并集内k元素个数2207 // 注意: 集合相关操作均要求区间有序, 后面不再强调2208 template <class InputIterator1, class InputIterator2, class OutputIterator>2209 OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,2210 InputIterator2 first2, InputIterator2 last2,2211 OutputIterator result)2212 {2213 // 先进行历遍操作2214 while (first1 != last1 && first2 != last2) {2215 // 这里把现在能确定的并集先加入到result中2216 // 先把较小的加入到结果中, 否则如果相等, 那么也要加入2217 if (*first1 < *first2) {2218 *result = *first1;2219 ++first1;2220 }2221 else if (*first2 < *first1) {2222 *result = *first2;2223 ++first2;2224 }2225 else {2226 *result = *first1;2227 ++first1;2228 ++first2;2229 }2230 ++result;2231 }2232 2233 // 将剩余的元素加入到并集中2234 return copy(first2, last2, copy(first1, last1, result));2235 }2236 2237 // 使用用户指定的二元比较判别式, 其余同上面2238 template <class InputIterator1, class InputIterator2, class OutputIterator,2239 class Compare>2240 OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,2241 InputIterator2 first2, InputIterator2 last2,2242 OutputIterator result, Compare comp)2243 {2244 while (first1 != last1 && first2 != last2) {2245 if (comp(*first1, *first2)) {2246 *result = *first1;2247 ++first1;2248 }2249 else if (comp(*first2, *first1)) {2250 *result = *first2;2251 ++first2;2252 }2253 else {2254 *result = *first1;2255 ++first1;2256 ++first2;2257 }2258 ++result;2259 }2260 return copy(first2, last2, copy(first1, last1, result));2261 }2262 2263 // 求两个集合的的交集, 和数学定义的并集有一些不一样2264 // 对于两个集合S1[first1, last1)和S2[first2, last2)2265 // 假设其中k元素在S1中出现n1次, 在S2中出现n2次2266 // 那么求出的交集选取min(n1, n2)为交集内k元素个数2267 template <class InputIterator1, class InputIterator2, class OutputIterator>2268 OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,2269 InputIterator2 first2, InputIterator2 last2,2270 OutputIterator result)2271 {2272 // 算法很简单, 不进行说明2273 while (first1 != last1 && first2 != last2)2274 if (*first1 < *first2)2275 ++first1;2276 else if (*first2 < *first1)2277 ++first2;2278 else {2279 *result = *first1;2280 ++first1;2281 ++first2;2282 ++result;2283 }2284 return result;2285 }2286 2287 // 使用用户指定的二元比较判别式, 其余同上面2288 template <class InputIterator1, class InputIterator2, class OutputIterator,2289 class Compare>2290 OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,2291 InputIterator2 first2, InputIterator2 last2,2292 OutputIterator result, Compare comp)2293 {2294 while (first1 != last1 && first2 != last2)2295 if (comp(*first1, *first2))2296 ++first1;2297 else if (comp(*first2, *first1))2298 ++first2;2299 else {2300 *result = *first1;2301 ++first1;2302 ++first2;2303 ++result;2304 }2305 return result;2306 }2307 2308 // 求两个集合的的差集, 和数学定义的并集有一些不一样2309 // 对于两个集合S1[first1, last1)和S2[first2, last2)2310 // 假设其中k元素在S1中出现n1次, 在S2中出现n2次2311 // 那么求出的差集选取max(n1 - n2, 0)为差集内k元素个数2312 template <class InputIterator1, class InputIterator2, class OutputIterator>2313 OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,2314 InputIterator2 first2, InputIterator2 last2,2315 OutputIterator result)2316 {2317 while (first1 != last1 && first2 != last2)2318 if (*first1 < *first2) { // 找到了一个合适的元素, 加入到结果中2319 *result = *first1; // 向后调整迭代器2320 ++first1;2321 ++result;2322 }2323 else if (*first2 < *first1) // 元素不合适, 调整迭代器2324 ++first2;2325 else { // 这个用来处理出现相同元素的情况2326 ++first1;2327 ++first2;2328 }2329 2330 // 将剩余的元素加入到结果中2331 return copy(first1, last1, result);2332 }2333 2334 // 使用用户指定的二元比较判别式, 其余同上面2335 template <class InputIterator1, class InputIterator2, class OutputIterator,2336 class Compare>2337 OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,2338 InputIterator2 first2, InputIterator2 last2,2339 OutputIterator result, Compare comp) {2340 while (first1 != last1 && first2 != last2)2341 if (comp(*first1, *first2)) {2342 *result = *first1;2343 ++first1;2344 ++result;2345 }2346 else if (comp(*first2, *first1))2347 ++first2;2348 else {2349 ++first1;2350 ++first2;2351 }2352 return copy(first1, last1, result);2353 }2354 2355 // 求两个集合的的对称差集, 和数学定义的并集有一些不一样2356 // 其用公式可以表示为(S1 - S2) U (S2 - S1)2357 // 对于两个集合S1[first1, last1)和S2[first2, last2)2358 // 假设其中k元素在S1中出现n1次, 在S2中出现n2次2359 // 那么结果中会出现|n1 - n2|个k元素2360 template <class InputIterator1, class InputIterator2, class OutputIterator>2361 OutputIterator set_symmetric_difference(InputIterator1 first1,2362 InputIterator1 last1,2363 InputIterator2 first2,2364 InputIterator2 last2,2365 OutputIterator result)2366 {2367 // 算法和上面的差不多, 不解释2368 while (first1 != last1 && first2 != last2)2369 if (*first1 < *first2) {2370 *result = *first1;2371 ++first1;2372 ++result;2373 }2374 else if (*first2 < *first1) {2375 *result = *first2;2376 ++first2;2377 ++result;2378 }2379 else {2380 ++first1;2381 ++first2;2382 }2383 2384 return copy(first2, last2, copy(first1, last1, result));2385 }2386 2387 // 使用用户指定的二元比较判别式, 其余同上面2388 template <class InputIterator1, class InputIterator2, class OutputIterator,2389 class Compare>2390 OutputIterator set_symmetric_difference(InputIterator1 first1,2391 InputIterator1 last1,2392 InputIterator2 first2,2393 InputIterator2 last2,2394 OutputIterator result, Compare comp)2395 {2396 while (first1 != last1 && first2 != last2)2397 if (comp(*first1, *first2)) {2398 *result = *first1;2399 ++first1;2400 ++result;2401 }2402 else if (comp(*first2, *first1)) {2403 *result = *first2;2404 ++first2;2405 ++result;2406 }2407 else {2408 ++first1;2409 ++first2;2410 }2411 return copy(first2, last2, copy(first1, last1, result));2412 }2413 2414 // 查找指定区间内最大的元素2415 template <class ForwardIterator>2416 ForwardIterator max_element(ForwardIterator first, ForwardIterator last)2417 {2418 if (first == last) return first;2419 ForwardIterator result = first;2420 while (++first != last)2421 if (*result < *first) result = first;2422 return result;2423 }2424 2425 // 使用用户指定的二元比较判别式, 其余同上面2426 template <class ForwardIterator, class Compare>2427 ForwardIterator max_element(ForwardIterator first, ForwardIterator last,2428 Compare comp)2429 {2430 if (first == last) return first;2431 ForwardIterator result = first;2432 while (++first != last)2433 if (comp(*result, *first)) result = first;2434 return result;2435 }2436 2437 // 查找指定区间内最小的元素2438 template <class ForwardIterator>2439 ForwardIterator min_element(ForwardIterator first, ForwardIterator last)2440 {2441 if (first == last) return first;2442 ForwardIterator result = first;2443 while (++first != last)2444 if (*first < *result) result = first;2445 return result;2446 }2447 2448 template <class ForwardIterator, class Compare>2449 ForwardIterator min_element(ForwardIterator first, ForwardIterator last,2450 Compare comp)2451 {2452 if (first == last) return first;2453 ForwardIterator result = first;2454 while (++first != last)2455 if (comp(*first, *result)) result = first;2456 return result;2457 }2458 2459 // 获取下一个全排列2460 template <class BidirectionalIterator>2461 bool next_permutation(BidirectionalIterator first,2462 BidirectionalIterator last)2463 {2464 if (first == last) return false;2465 BidirectionalIterator i = first;2466 ++i;2467 if (i == last) return false;2468 i = last;2469 --i;2470 2471 for(;;) {2472 BidirectionalIterator ii = i;2473 --i;2474 if (*i < *ii) {2475 BidirectionalIterator j = last;2476 while (!(*i < *--j));2477 iter_swap(i, j);2478 reverse(ii, last);2479 return true;2480 }2481 if (i == first) {2482 reverse(first, last);2483 return false;2484 }2485 }2486 }2487 2488 template <class BidirectionalIterator, class Compare>2489 bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,2490 Compare comp) {2491 if (first == last) return false;2492 BidirectionalIterator i = first;2493 ++i;2494 if (i == last) return false;2495 i = last;2496 --i;2497 2498 for(;;) {2499 BidirectionalIterator ii = i;2500 --i;2501 if (comp(*i, *ii)) {2502 BidirectionalIterator j = last;2503 while (!comp(*i, *--j));2504 iter_swap(i, j);2505 reverse(ii, last);2506 return true;2507 }2508 if (i == first) {2509 reverse(first, last);2510 return false;2511 }2512 }2513 }2514 2515 template <class BidirectionalIterator>2516 bool prev_permutation(BidirectionalIterator first,2517 BidirectionalIterator last) {2518 if (first == last) return false;2519 BidirectionalIterator i = first;2520 ++i;2521 if (i == last) return false;2522 i = last;2523 --i;2524 2525 for(;;) {2526 BidirectionalIterator ii = i;2527 --i;2528 if (*ii < *i) {2529 BidirectionalIterator j = last;2530 while (!(*--j < *i));2531 iter_swap(i, j);2532 reverse(ii, last);2533 return true;2534 }2535 if (i == first) {2536 reverse(first, last);2537 return false;2538 }2539 }2540 }2541 2542 // 获取前一个全排列2543 template <class BidirectionalIterator, class Compare>2544 bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,2545 Compare comp) {2546 if (first == last) return false;2547 BidirectionalIterator i = first;2548 ++i;2549 if (i == last) return false;2550 i = last;2551 --i;2552 2553 for(;;) {2554 BidirectionalIterator ii = i;2555 --i;2556 if (comp(*ii, *i)) {2557 BidirectionalIterator j = last;2558 while (!comp(*--j, *i));2559 iter_swap(i, j);2560 reverse(ii, last);2561 return true;2562 }2563 if (i == first) {2564 reverse(first, last);2565 return false;2566 }2567 }2568 }2569 2570 // 在区间[first1, last1)内查找区间[first2, last2)第一次出现的位置2571 template <class InputIterator, class ForwardIterator>2572 InputIterator find_first_of(InputIterator first1, InputIterator last1,2573 ForwardIterator first2, ForwardIterator last2)2574 {2575 for ( ; first1 != last1; ++first1)2576 for (ForwardIterator iter = first2; iter != last2; ++iter)2577 if (*first1 == *iter)2578 return first1;2579 return last1;2580 }2581 2582 // 使用用户指定的判别式, 其余同上面2583 template <class InputIterator, class ForwardIterator, class BinaryPredicate>2584 InputIterator find_first_of(InputIterator first1, InputIterator last1,2585 ForwardIterator first2, ForwardIterator last2,2586 BinaryPredicate comp)2587 {2588 for ( ; first1 != last1; ++first1)2589 for (ForwardIterator iter = first2; iter != last2; ++iter)2590 if (comp(*first1, *iter))2591 return first1;2592 return last1;2593 }2594 2595 2596 // Search [first2, last2) as a subsequence in [first1, last1).2597 2598 // find_end for forward iterators.2599 template <class ForwardIterator1, class ForwardIterator2>2600 ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,2601 ForwardIterator2 first2, ForwardIterator2 last2,2602 forward_iterator_tag, forward_iterator_tag)2603 {2604 if (first2 == last2) // 如果查找的目标区间为空, 那么就返回last12605 return last1;2606 else {2607 ForwardIterator1 result = last1;2608 while (1) {2609 // 查找匹配区间2610 ForwardIterator1 new_result = search(first1, last1, first2, last2);2611 if (new_result == last1) // 没找到2612 return result;2613 else { // 找到了, 准备看后面还有没有匹配区间2614 result = new_result;2615 first1 = new_result;2616 ++first1;2617 }2618 }2619 }2620 }2621 2622 template <class ForwardIterator1, class ForwardIterator2,2623 class BinaryPredicate>2624 ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,2625 ForwardIterator2 first2, ForwardIterator2 last2,2626 forward_iterator_tag, forward_iterator_tag,2627 BinaryPredicate comp)2628 {2629 if (first2 == last2)2630 return last1;2631 else {2632 ForwardIterator1 result = last1;2633 while (1) {2634 ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);2635 if (new_result == last1)2636 return result;2637 else {2638 result = new_result;2639 first1 = new_result;2640 ++first1;2641 }2642 }2643 }2644 }2645 2646 // find_end for bidirectional iterators. Requires partial specialization.2647 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION2648 2649 template <class BidirectionalIterator1, class BidirectionalIterator2>2650 BidirectionalIterator12651 __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,2652 BidirectionalIterator2 first2, BidirectionalIterator2 last2,2653 bidirectional_iterator_tag, bidirectional_iterator_tag)2654 {2655 typedef reverse_iterator<BidirectionalIterator1> reviter1;2656 typedef reverse_iterator<BidirectionalIterator2> reviter2;2657 2658 reviter1 rlast1(first1);2659 reviter2 rlast2(first2);2660 reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2);2661 2662 if (rresult == rlast1)2663 return last1;2664 else {2665 BidirectionalIterator1 result = rresult.base();2666 advance(result, -distance(first2, last2));2667 return result;2668 }2669 }2670 2671 // 可以逆向查找, 速度块2672 template <class BidirectionalIterator1, class BidirectionalIterator2,2673 class BinaryPredicate>2674 BidirectionalIterator12675 __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,2676 BidirectionalIterator2 first2, BidirectionalIterator2 last2,2677 bidirectional_iterator_tag, bidirectional_iterator_tag,2678 BinaryPredicate comp)2679 {2680 typedef reverse_iterator<BidirectionalIterator1> reviter1;2681 typedef reverse_iterator<BidirectionalIterator2> reviter2;2682 2683 reviter1 rlast1(first1);2684 reviter2 rlast2(first2);2685 reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,2686 comp);2687 2688 if (rresult == rlast1)2689 return last1;2690 else {2691 BidirectionalIterator1 result = rresult.base();2692 advance(result, -distance(first2, last2));2693 return result;2694 }2695 }2696 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */2697 2698 // 在区间[first1, last1)内查找区间[first2, last2)最后一次出现的位置2699 template <class ForwardIterator1, class ForwardIterator2>2700 inline ForwardIterator12701 find_end(ForwardIterator1 first1, ForwardIterator1 last1,2702 ForwardIterator2 first2, ForwardIterator2 last2)2703 {2704 // 这里根据是否能逆向查找来派发函数2705 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION2706 typedef typename iterator_traits<ForwardIterator1>::iterator_category2707 category1;2708 typedef typename iterator_traits<ForwardIterator2>::iterator_category2709 category2;2710 return __find_end(first1, last1, first2, last2, category1(), category2());2711 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */2712 return __find_end(first1, last1, first2, last2,2713 forward_iterator_tag(), forward_iterator_tag());2714 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */2715 }2716 2717 // 使用用户指定的判别式, 其余同上面2718 template <class ForwardIterator1, class ForwardIterator2,2719 class BinaryPredicate>2720 inline ForwardIterator12721 find_end(ForwardIterator1 first1, ForwardIterator1 last1,2722 ForwardIterator2 first2, ForwardIterator2 last2,2723 BinaryPredicate comp)2724 {2725 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION2726 typedef typename iterator_traits<ForwardIterator1>::iterator_category2727 category1;2728 typedef typename iterator_traits<ForwardIterator2>::iterator_category2729 category2;2730 return __find_end(first1, last1, first2, last2, category1(), category2(),2731 comp);2732 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */2733 return __find_end(first1, last1, first2, last2,2734 forward_iterator_tag(), forward_iterator_tag(),2735 comp);2736 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */2737 }2738 2739 template <class RandomAccessIterator, class Distance>2740 bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,2741 Distance*)2742 {2743 const Distance n = last - first;2744 2745 Distance parent = 0;2746 for (Distance child = 1; child < n; ++child) {2747 if (first[parent] < first[child])2748 return false;2749 if ((child & 1) == 0)2750 ++parent;2751 }2752 return true;2753 }2754 2755 template <class RandomAccessIterator>2756 inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)2757 {2758 return __is_heap(first, last, distance_type(first));2759 }2760 2761 2762 template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>2763 bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,2764 StrictWeakOrdering comp,2765 Distance*)2766 {2767 const Distance n = last - first;2768 2769 Distance parent = 0;2770 for (Distance child = 1; child < n; ++child) {2771 if (comp(first[parent], first[child]))2772 return false;2773 if ((child & 1) == 0)2774 ++parent;2775 }2776 return true;2777 }2778 2779 template <class RandomAccessIterator, class StrictWeakOrdering>2780 inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,2781 StrictWeakOrdering comp)2782 {2783 return __is_heap(first, last, comp, distance_type(first));2784 }2785 2786 2787 template <class ForwardIterator>2788 bool is_sorted(ForwardIterator first, ForwardIterator last)2789 {2790 if (first == last)2791 return true;2792 2793 ForwardIterator next = first;2794 for (++next; next != last; first = next, ++next) {2795 if (*next < *first)2796 return false;2797 }2798 2799 return true;2800 }2801 2802 template <class ForwardIterator, class StrictWeakOrdering>2803 bool is_sorted(ForwardIterator first, ForwardIterator last,2804 StrictWeakOrdering comp)2805 {2806 if (first == last)2807 return true;2808 2809 ForwardIterator next = first;2810 for (++next; next != last; first = next, ++next) {2811 if (comp(*next, *first))2812 return false;2813 }2814 2815 return true;2816 }2817 2818 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)2819 #pragma reset woff 12092820 #endif2821 2822 __STL_END_NAMESPACE2823 2824 #endif /* __SGI_STL_INTERNAL_ALGO_H */2825 2826 // Local Variables:2827 // mode:C++2828 // End:
0 0
- C++STL源码剖析代码
- 《stl源码剖析》剖析
- STL源码剖析(1)
- STL源码剖析(2)
- STL源码剖析(3)
- STL源码剖析(4)
- STL源码剖析(5)
- STL源码剖析(一)
- STL源码剖析
- STL 源码剖析
- STL源码剖析 [笔记]
- 《STL源码剖析》-- memory
- stl vector源码剖析
- 剖析STL auto_ptr源码
- STL-sort()源码剖析
- STL源码剖析总结
- STL源码剖析---vector
- STL源码剖析---list
- 鸡兔同笼代码
- magento log问题
- OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)转到底部转到底部
- UNP卷一学习笔记:TCP状态
- App Store审核被拒的23个理由
- C++ STL源码剖析
- UE4的编译配置详解
- pip配置默认镜像源
- C++ STL基础
- RAC 环境中 gc block lost 和私网通信性能问题的诊断 (文档 ID 1674865.1)
- AS 项目转 Eclipse 收集
- 地理学史话:哈佛地理系之死
- CSDN-markdown编辑器
- 使用 Diagwait 作为诊断工具,获取用于诊断 Oracle Clusterware 节点驱逐的更多信息 (文档 ID 1525761.1)