![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.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:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 1. // Filename: defalloc.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. * 9 9. * Copyright (c) 1994 10 10. * Hewlett-Packard Company 11 11. * 12 12. * Permission to use, copy, modify, distribute and sell this software 13 13. * and its documentation for any purpose is hereby granted without fee, 14 14. * provided that the above copyright notice appear in all copies and 15 15. * that both that copyright notice and this permission notice appear 16 16. * in supporting documentation. Hewlett-Packard Company makes no 17 17. * representations about the suitability of this software for any 18 18. * purpose. It is provided "as is" without express or implied warranty. 19 19. * 20 20. */ 21 21. 22 22. // 这个文件提供原始的HP默认allocator, 仅仅是为了向后兼容 23 23. // 24 24. // 不要使用这个文件,除非你使用一个需要HP-style allocator的旧容器 25 25. // SGI STL使用一个不同的allocator接口 26 26. // SGI-style的allocator不针对对象类型进行参数化, 他使用void *指针 27 27. 28 28. #ifndef DEFALLOC_H 29 29. #define DEFALLOC_H 30 30. 31 31. #include <new.h> 32 32. #include <stddef.h> 33 33. #include <stdlib.h> 34 34. #include <limits.h> 35 35. #include <iostream.h> 36 36. #include <algobase.h> 37 37. 38 38. // 如果内存分配失败, 则直接退出程序 39 39. template <class T> 40 40. inline T* allocate(ptrdiff_t size, T*) 41 41. { 42 42. set_new_handler(0); 43 43. T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); 44 44. if (tmp == 0) { 45 45. cerr << "out of memory" << endl; 46 46. exit(1); 47 47. } 48 48. return tmp; 49 49. } 50 50. 51 51. template <class T> 52 52. inline void deallocate(T* buffer) 53 53. { 54 54. ::operator delete(buffer); 55 55. } 56 56. 57 57. // 标准的STL allocator接口 58 58. template <class T> 59 59. class allocator 60 60. { 61 61. public: 62 62. // STL type_traits需要的标准定义 63 63. typedef T value_type; 64 64. typedef T* pointer; 65 65. typedef const T* const_pointer; 66 66. typedef T& reference; 67 67. typedef const T& const_reference; 68 68. typedef size_t size_type; 69 69. typedef ptrdiff_t difference_type; 70 70. 71 71. 72 72. pointer allocate(size_type n) 73 73. { 74 74. return ::allocate((difference_type)n, (pointer)0); 75 75. } 76 76. void deallocate(pointer p) { ::deallocate(p); } 77 77. pointer address(reference x) { return (pointer)&x; } 78 78. const_pointer const_address(const_reference x) 79 79. { 80 80. return (const_pointer)&x; 81 81. } 82 82. // 83 83. size_type init_page_size() 84 84. { 85 85. return max(size_type(1), size_type(4096/sizeof(T))); 86 86. } 87 87. size_type max_size() const 88 88. { 89 89. return max(size_type(1), size_type(UINT_MAX/sizeof(T))); 90 90. } 91 91. }; 92 92. 93 93. // 仅使用void *类型的指针 94 94. class allocator<void> 95 95. { 96 96. public: 97 97. typedef void* pointer; 98 98. }; 99 99. 100 100. #endif
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 # // Comment By: 凝霜 2 # // E-mail: mdl2009@vip.qq.com 3 # // Blog: http://blog.csdn.net/mdl13412 4 # 5 # // 特别说明: SGI STL的allocator在我的编译环境下不使用内存池 6 # // 而其内存池不进行内存释放操作, 其释放时机为程序退出或者stack unwinding 7 # // 由操作系统保证内存的回收 8 # 9 # /* 10 # * Copyright (c) 1996-1997 11 # * Silicon Graphics Computer Systems, Inc. 12 # * 13 # * Permission to use, copy, modify, distribute and sell this software 14 # * and its documentation for any purpose is hereby granted without fee, 15 # * provided that the above copyright notice appear in all copies and 16 # * that both that copyright notice and this permission notice appear 17 # * in supporting documentation. Silicon Graphics makes no 18 # * representations about the suitability of this software for any 19 # * purpose. It is provided "as is" without express or implied warranty. 20 # */ 21 # 22 # /* NOTE: This is an internal header file, included by other STL headers. 23 # * You should not attempt to use it directly. 24 # */ 25 # 26 # #ifndef __SGI_STL_INTERNAL_ALLOC_H 27 # #define __SGI_STL_INTERNAL_ALLOC_H 28 # 29 # #ifdef __SUNPRO_CC 30 # # define __PRIVATE public 31 # // SUN编译器对private限制过多, 需要开放权限 32 # #else 33 # # define __PRIVATE private 34 # #endif 35 # 36 # // 为了保证兼容性, 对于不支持模板类静态成员的情况, 使用malloc()进行内存分配 37 # #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG 38 # # define __USE_MALLOC 39 # #endif 40 # 41 # // 实现了一些标准的node allocator 42 # // 但是不同于C++标准或者STL原始STL标准 43 # // 这些allocator没有封装不同指针类型 44 # // 事实上我们假定只有一种指针理性 45 # // allocation primitives意在分配不大于原始STL allocator分配的独立的对象 46 # 47 # #if 0 48 # # include <new> 49 # # define __THROW_BAD_ALLOC throw bad_alloc 50 # #elif !defined(__THROW_BAD_ALLOC) 51 # # include <iostream.h> 52 # # define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) 53 # #endif 54 # 55 # #ifndef __ALLOC 56 # # define __ALLOC alloc 57 # #endif 58 # #ifdef __STL_WIN32THREADS 59 # # include <windows.h> 60 # #endif 61 # 62 # #include <stddef.h> 63 # #include <stdlib.h> 64 # #include <string.h> 65 # #include <assert.h> 66 # #ifndef __RESTRICT 67 # # define __RESTRICT 68 # #endif 69 # 70 # // 多线程支持 71 # // __STL_PTHREADS // GCC编译器 72 # // _NOTHREADS // 不支持多线程 73 # // __STL_SGI_THREADS // SGI机器专用 74 # // __STL_WIN32THREADS // MSVC编译器 75 # #if !defined(__STL_PTHREADS) && !defined(_NOTHREADS) \ 76 # && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS) 77 # # define _NOTHREADS 78 # #endif 79 # 80 # # ifdef __STL_PTHREADS 81 # // POSIX Threads 82 # // This is dubious, since this is likely to be a high contention 83 # // lock. Performance may not be adequate. 84 # # include <pthread.h> 85 # # define __NODE_ALLOCATOR_LOCK \ 86 # if (threads) pthread_mutex_lock(&__node_allocator_lock) 87 # # define __NODE_ALLOCATOR_UNLOCK \ 88 # if (threads) pthread_mutex_unlock(&__node_allocator_lock) 89 # # define __NODE_ALLOCATOR_THREADS true 90 # # define __VOLATILE volatile // Needed at -O3 on SGI 91 # # endif 92 # # ifdef __STL_WIN32THREADS 93 # // The lock needs to be initialized by constructing an allocator 94 # // objects of the right type. We do that here explicitly for alloc. 95 # # define __NODE_ALLOCATOR_LOCK \ 96 # EnterCriticalSection(&__node_allocator_lock) 97 # # define __NODE_ALLOCATOR_UNLOCK \ 98 # LeaveCriticalSection(&__node_allocator_lock) 99 # # define __NODE_ALLOCATOR_THREADS true 100 # # define __VOLATILE volatile // may not be needed 101 # # endif /* WIN32THREADS */ 102 # # ifdef __STL_SGI_THREADS 103 # // This should work without threads, with sproc threads, or with 104 # // pthreads. It is suboptimal in all cases. 105 # // It is unlikely to even compile on nonSGI machines. 106 # 107 # extern "C" { 108 # extern int __us_rsthread_malloc; 109 # } 110 # // The above is copied from malloc.h. Including <malloc.h> 111 # // would be cleaner but fails with certain levels of standard 112 # // conformance. 113 # # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ 114 # { __lock(&__node_allocator_lock); } 115 # # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ 116 # { __unlock(&__node_allocator_lock); } 117 # # define __NODE_ALLOCATOR_THREADS true 118 # # define __VOLATILE volatile // Needed at -O3 on SGI 119 # # endif 120 # # ifdef _NOTHREADS 121 # // Thread-unsafe 122 # # define __NODE_ALLOCATOR_LOCK 123 # # define __NODE_ALLOCATOR_UNLOCK 124 # # define __NODE_ALLOCATOR_THREADS false 125 # # define __VOLATILE 126 # # endif 127 # 128 # __STL_BEGIN_NAMESPACE 129 # 130 # #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 131 # #pragma set woff 1174 132 # #endif 133 # 134 # // Malloc-based allocator. Typically slower than default alloc below. 135 # // Typically thread-safe and more storage efficient. 136 # #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG 137 # # ifdef __DECLARE_GLOBALS_HERE 138 # void (* __malloc_alloc_oom_handler)() = 0; 139 # // g++ 2.7.2 does not handle static template data members. 140 # # else 141 # extern void (* __malloc_alloc_oom_handler)(); 142 # # endif 143 # #endif 144 # 145 # // 一级配置器 146 # template <int inst> 147 # class __malloc_alloc_template 148 # { 149 # private: 150 # // 用于在设置了__malloc_alloc_oom_handler情况下循环分配内存, 151 # // 直到成功分配 152 # static void *oom_malloc(size_t); 153 # static void *oom_realloc(void *, size_t); 154 # 155 # // 如果编译器支持模板类静态成员, 则使用错误处理函数, 类似C++的set_new_handler() 156 # // 默认值为0, 如果不设置, 则内存分配失败时直接__THROW_BAD_ALLOC 157 # #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG 158 # static void (* __malloc_alloc_oom_handler)(); 159 # #endif 160 # 161 # public: 162 # // 分配指定大小的内存(size_t n), 如果分配失败, 则进入循环分配阶段 163 # // 循环分配前提是要保证正确设置了__malloc_alloc_oom_handler 164 # static void * allocate(size_t n) 165 # { 166 # void *result = malloc(n); 167 # if (0 == result) result = oom_malloc(n); 168 # return result; 169 # } 170 # 171 # // 后面的size_t是为了兼容operator delele 172 # static void deallocate(void *p, size_t /* n */) 173 # { free(p); } 174 # 175 # // 重新分配内存大小, 第二个参数是为了兼容operator new 176 # static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) 177 # { 178 # void * result = realloc(p, new_sz); 179 # if (0 == result) result = oom_realloc(p, new_sz); 180 # return result; 181 # } 182 # 183 # // 设置错误处理函数, 返回原来的函数指针 184 # // 不属于C++标准规定的接口 185 # static void (* set_malloc_handler(void (*f)()))() 186 # { 187 # void (* old)() = __malloc_alloc_oom_handler; 188 # __malloc_alloc_oom_handler = f; 189 # return(old); 190 # } 191 # }; 192 # 193 # // malloc_alloc out-of-memory handling 194 # 195 # #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG 196 # template <int inst> 197 # void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0; 198 # #endif 199 # 200 # // 如果设置了__malloc_alloc_oom_handler, 则首先执行错误处理函数, 然后循环分配直到成功 201 # // 如果未设置__malloc_alloc_oom_handler, __THROW_BAD_ALLOC 202 # template <int inst> 203 # void * __malloc_alloc_template<inst>::oom_malloc(size_t n) 204 # { 205 # void (* my_malloc_handler)(); 206 # void *result; 207 # 208 # for (;;) { 209 # my_malloc_handler = __malloc_alloc_oom_handler; 210 # if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } 211 # (*my_malloc_handler)(); 212 # result = malloc(n); 213 # if (result) return(result); 214 # } 215 # } 216 # 217 # template <int inst> 218 # void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n) 219 # { 220 # void (* my_malloc_handler)(); 221 # void *result; 222 # 223 # for (;;) { 224 # my_malloc_handler = __malloc_alloc_oom_handler; 225 # if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } 226 # (*my_malloc_handler)(); 227 # result = realloc(p, n); 228 # if (result) return(result); 229 # } 230 # } 231 # 232 # // 这个版本的STL并没有使用non-type模板参数 233 # typedef __malloc_alloc_template<0> malloc_alloc; 234 # 235 # // 这个类中的接口其实就是STL标准中的allocator的接口 236 # // 实际上所有的SGI STL都使用这个进行内存配置 237 # // 例如: stl_vector.h中 238 # // template <class T, class Alloc = alloc> 239 # // class vector 240 # // { 241 # // ... 242 # // protected: 243 # // typedef simple_alloc<value_type, Alloc> data_allocator; 244 # // ... 245 # //}; 246 # template<class T, class Alloc> 247 # class simple_alloc 248 # { 249 # public: 250 # static T *allocate(size_t n) 251 # { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); } 252 # static T *allocate(void) 253 # { return (T*) Alloc::allocate(sizeof (T)); } 254 # static void deallocate(T *p, size_t n) 255 # { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); } 256 # static void deallocate(T *p) 257 # { Alloc::deallocate(p, sizeof (T)); } 258 # }; 259 # 260 # // Allocator adaptor to check size arguments for debugging. 261 # // Reports errors using assert. Checking can be disabled with 262 # // NDEBUG, but it's far better to just use the underlying allocator 263 # // instead when no checking is desired. 264 # // There is some evidence that this can confuse Purify. 265 # template <class Alloc> 266 # class debug_alloc 267 # { 268 # private: 269 # enum {extra = 8}; // Size of space used to store size. Note 270 # // that this must be large enough to preserve 271 # // alignment. 272 # 273 # public: 274 # 275 # // extra 保证不会分配为0的内存空间, 而且要保证内存对齐 276 # // 把分配内存的最前面设置成n的大小, 用于后面校验 277 # // 内存对齐的作用就是保护前面extra大小的数据不被修改 278 # static void * allocate(size_t n) 279 # { 280 # char *result = (char *)Alloc::allocate(n + extra); 281 # *(size_t *)result = n; 282 # return result + extra; 283 # } 284 # 285 # // 如果*(size_t *)real_p != n则肯定发生向前越界 286 # static void deallocate(void *p, size_t n) 287 # { 288 # char * real_p = (char *)p - extra; 289 # assert(*(size_t *)real_p == n); 290 # Alloc::deallocate(real_p, n + extra); 291 # } 292 # 293 # static void * reallocate(void *p, size_t old_sz, size_t new_sz) 294 # { 295 # char * real_p = (char *)p - extra; 296 # assert(*(size_t *)real_p == old_sz); 297 # char * result = (char *) 298 # Alloc::reallocate(real_p, old_sz + extra, new_sz + extra); 299 # *(size_t *)result = new_sz; 300 # return result + extra; 301 # } 302 # }; 303 # 304 # # ifdef __USE_MALLOC 305 # 306 # typedef malloc_alloc alloc; 307 # typedef malloc_alloc single_client_alloc; 308 # 309 # # else 310 # 311 # // 默认的node allocator 312 # // 如果有合适的编译器, 速度上与原始的STL class-specific allocators大致等价 313 # // 但是具有产生更少内存碎片的优点 314 # // Default_alloc_template参数是用于实验性质的, 在未来可能会消失 315 # // 客户只能在当下使用alloc 316 # // 317 # // 重要的实现属性: 318 # // 1. 如果客户请求一个size > __MAX_BYTE的对象, 则直接使用malloc()分配 319 # // 2. 对于其它情况下, 我们将请求对象的大小按照内存对齐向上舍入ROUND_UP(requested_size) 320 # // TODO: 待翻译 321 # // 2. In all other cases, we allocate an object of size exactly 322 # // ROUND_UP(requested_size). Thus the client has enough size 323 # // information that we can return the object to the proper free list 324 # // without permanently losing part of the object. 325 # // 326 # 327 # // 第一个模板参数指定是否有多于一个线程使用本allocator 328 # // 在一个default_alloc实例中分配对象, 在另一个deallocate实例中释放对象, 是安全的 329 # // 这有效的转换其所有权到另一个对象 330 # // 这可能导致对我们引用的区域产生不良影响 331 # // 第二个模板参数仅仅用于创建多个default_alloc实例 332 # // 不同容器使用不同allocator实例创建的node拥有不同类型, 这限制了此方法的通用性 333 # 334 # // Sun C++ compiler需要在类外定义这些枚举 335 # #ifdef __SUNPRO_CC 336 # // breaks if we make these template class members: 337 # enum {__ALIGN = 8}; 338 # enum {__MAX_BYTES = 128}; 339 # enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; 340 # #endif 341 # 342 # template <bool threads, int inst> 343 # class __default_alloc_template 344 # { 345 # private: 346 # // Really we should use static const int x = N 347 # // instead of enum { x = N }, but few compilers accept the former. 348 # # ifndef __SUNPRO_CC 349 # enum {__ALIGN = 8}; 350 # enum {__MAX_BYTES = 128}; 351 # enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; 352 # # endif 353 # // 向上舍入操作 354 # // 解释一下, __ALIGN - 1指明的是实际内存对齐的粒度 355 # // 例如__ALIGN = 8时, 我们只需要7就可以实际表示8个数(0~7) 356 # // 那么~(__ALIGN - 1)就是进行舍入的粒度 357 # // 我们将(bytes) + __ALIGN-1)就是先进行进位, 然后截断 358 # // 这就保证了我是向上舍入的 359 # // 例如byte = 100, __ALIGN = 8的情况 360 # // ~(__ALIGN - 1) = (1 000)B 361 # // ((bytes) + __ALIGN-1) = (1 101 011)B 362 # // (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)) = (1 101 000 )B = (104)D 363 # // 104 / 8 = 13, 这就实现了向上舍入 364 # // 对于byte刚好满足内存对齐的情况下, 结果保持byte大小不变 365 # // 记得《Hacker's Delight》上面有相关的计算 366 # // 这个表达式与下面给出的等价 367 # // ((((bytes) + _ALIGN - 1) * _ALIGN) / _ALIGN) 368 # // 但是SGI STL使用的方法效率非常高 369 # static size_t ROUND_UP(size_t bytes) 370 # { 371 # return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)); 372 # } 373 # __PRIVATE: 374 # // 管理内存链表用 375 # // 为了尽最大可能减少内存的使用, 这里使用一个union 376 # // 如果使用第一个成员, 则指向另一个相同的union obj 377 # // 而如果使用第二个成员, 则指向实际的内存区域 378 # // 这样就实现了链表结点只使用一个指针的大小空间, 却能同时做索引和指向内存区域 379 # // 这个技巧性非常强, 值得学习 380 # union obj 381 # { 382 # union obj * free_list_link; 383 # char client_data[1]; /* The client sees this. */ 384 # }; 385 # private: 386 # # ifdef __SUNPRO_CC 387 # static obj * __VOLATILE free_list[]; 388 # // Specifying a size results in duplicate def for 4.1 389 # # else 390 # // 这里分配的free_list为16 391 # // 对应的内存链容量分别为8, 16, 32 ... 128 392 # static obj * __VOLATILE free_list[__NFREELISTS]; 393 # # endif 394 # // 根据待待分配的空间大小, 在free_list中选择合适的大小 395 # static size_t FREELIST_INDEX(size_t bytes) 396 # { 397 # return (((bytes) + __ALIGN-1)/__ALIGN - 1); 398 # } 399 # 400 # // Returns an object of size n, and optionally adds to size n free list. 401 # static void *refill(size_t n); 402 # // Allocates a chunk for nobjs of size "size". nobjs may be reduced 403 # // if it is inconvenient to allocate the requested number. 404 # static char *chunk_alloc(size_t size, int &nobjs); 405 # 406 # // 内存池 407 # static char *start_free; // 内存池起始点 408 # static char *end_free; // 内存池结束点 409 # static size_t heap_size; // 已经在堆上分配的空间大小 410 # 411 # // 下面三个条件编译给多线程条件下使用的锁提供必要支持 412 # # ifdef __STL_SGI_THREADS 413 # static volatile unsigned long __node_allocator_lock; 414 # static void __lock(volatile unsigned long *); 415 # static inline void __unlock(volatile unsigned long *); 416 # # endif 417 # 418 # # ifdef __STL_PTHREADS 419 # static pthread_mutex_t __node_allocator_lock; 420 # # endif 421 # 422 # # ifdef __STL_WIN32THREADS 423 # static CRITICAL_SECTION __node_allocator_lock; 424 # static bool __node_allocator_lock_initialized; 425 # 426 # public: 427 # __default_alloc_template() { 428 # // This assumes the first constructor is called before threads 429 # // are started. 430 # if (!__node_allocator_lock_initialized) { 431 # InitializeCriticalSection(&__node_allocator_lock); 432 # __node_allocator_lock_initialized = true; 433 # } 434 # } 435 # private: 436 # # endif 437 # 438 # // 用于多线程环境下锁定操作用 439 # class lock 440 # { 441 # public: 442 # lock() { __NODE_ALLOCATOR_LOCK; } 443 # ~lock() { __NODE_ALLOCATOR_UNLOCK; } 444 # }; 445 # friend class lock; 446 # 447 # public: 448 # /* n must be > 0 */ 449 # static void * allocate(size_t n) 450 # { 451 # obj * __VOLATILE * my_free_list; 452 # obj * __RESTRICT result; 453 # 454 # // 如果待分配对象大于__MAX_BYTES, 使用一级配置器分配 455 # if (n > (size_t) __MAX_BYTES) { 456 # return(malloc_alloc::allocate(n)); 457 # } 458 # my_free_list = free_list + FREELIST_INDEX(n); 459 # // Acquire the lock here with a constructor call. 460 # // This ensures that it is released in exit or during stack 461 # // unwinding. 462 # # ifndef _NOTHREADS 463 # /*REFERENCED*/ 464 # lock lock_instance; 465 # # endif 466 # result = *my_free_list; 467 # // 如果是第一次使用这个容量的链表, 则分配此链表需要的内存 468 # // 如果不是, 则判断内存吃容量, 不够则分配 469 # if (result == 0) { 470 # void *r = refill(ROUND_UP(n)); 471 # return r; 472 # } 473 # *my_free_list = result -> free_list_link; 474 # return (result); 475 # }; 476 # 477 # /* p may not be 0 */ 478 # static void deallocate(void *p, size_t n) 479 # { 480 # obj *q = (obj *)p; 481 # obj * __VOLATILE * my_free_list; 482 # 483 # // 对于大于__MAX_BYTES的对象, 因为采用的是一级配置器分配, 所以同样使用一级配置器释放 484 # if (n > (size_t) __MAX_BYTES) { 485 # malloc_alloc::deallocate(p, n); 486 # return; 487 # } 488 # my_free_list = free_list + FREELIST_INDEX(n); 489 # // acquire lock 490 # # ifndef _NOTHREADS 491 # /*REFERENCED*/ 492 # lock lock_instance; 493 # # endif /* _NOTHREADS */ 494 # q -> free_list_link = *my_free_list; 495 # *my_free_list = q; 496 # // lock is released here 497 # } 498 # 499 # static void * reallocate(void *p, size_t old_sz, size_t new_sz); 500 # } ; 501 # 502 # typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; 503 # typedef __default_alloc_template<false, 0> single_client_alloc; 504 # 505 # // 每次分配一大块内存, 防止多次分配小内存块带来的内存碎片 506 # // 进行分配操作时, 根据具体环境决定是否加锁 507 # // 我们假定要分配的内存满足内存对齐要求 508 # template <bool threads, int inst> 509 # char* 510 # __default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs) 511 # { 512 # char * result; 513 # size_t total_bytes = size * nobjs; 514 # size_t bytes_left = end_free - start_free; // 计算内存池剩余容量 515 # 516 # // 如果内存池中剩余内存>=需要分配的内内存, 返回start_free指向的内存块, 517 # // 并且重新设置内存池起始点 518 # if (bytes_left >= total_bytes) { 519 # result = start_free; 520 # start_free += total_bytes; 521 # return(result); 522 # } 523 # // 如果内存吃中剩余的容量不够分配, 但是能至少分配一个节点时, 524 # // 返回所能分配的最多的节点, 返回start_free指向的内存块 525 # // 并且重新设置内存池起始点 526 # else if (bytes_left >= size) { 527 # nobjs = bytes_left/size; 528 # total_bytes = size * nobjs; 529 # result = start_free; 530 # start_free += total_bytes; 531 # return(result); 532 # } 533 # // 内存池剩余内存连一个节点也不够分配 534 # else { 535 # size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); 536 # // 将剩余的内存分配给指定的free_list[FREELIST_INDEX(bytes_left)] 537 # if (bytes_left > 0) { 538 # obj * __VOLATILE * my_free_list = 539 # free_list + FREELIST_INDEX(bytes_left); 540 # 541 # ((obj *)start_free) -> free_list_link = *my_free_list; 542 # *my_free_list = (obj *)start_free; 543 # } 544 # start_free = (char *)malloc(bytes_to_get); 545 # // 分配失败, 搜索原来已经分配的内存块, 看是否有大于等于当前请求的内存块 546 # if (0 == start_free) { 547 # int i; 548 # obj * __VOLATILE * my_free_list, *p; 549 # // Try to make do with what we have. That can't 550 # // hurt. We do not try smaller requests, since that tends 551 # // to result in disaster on multi-process machines. 552 # for (i = size; i <= __MAX_BYTES; i += __ALIGN) { 553 # my_free_list = free_list + FREELIST_INDEX(i); 554 # p = *my_free_list; 555 # // 找到了一个, 将其加入内存池中 556 # if (0 != p) { 557 # *my_free_list = p -> free_list_link; 558 # start_free = (char *)p; 559 # end_free = start_free + i; 560 # // 内存池更新完毕, 重新分配需要的内存 561 # return(chunk_alloc(size, nobjs)); 562 # // Any leftover piece will eventually make it to the 563 # // right free list. 564 # } 565 # } 566 # 567 # // 再次失败, 直接调用一级配置器分配, 期待异常处理函数能提供帮助 568 # // 不过在我看来, 内存分配失败进行其它尝试已经没什么意义了, 569 # // 最好直接log, 然后让程序崩溃 570 # end_free = 0; // In case of exception. 571 # start_free = (char *)malloc_alloc::allocate(bytes_to_get); 572 # } 573 # heap_size += bytes_to_get; 574 # end_free = start_free + bytes_to_get; 575 # // 内存池更新完毕, 重新分配需要的内存 576 # return(chunk_alloc(size, nobjs)); 577 # } 578 # } 579 # 580 # 581 # // 返回一个大小为n的对象, 并且加入到free_list[FREELIST_INDEX(n)] 582 # // 进行分配操作时, 根据具体环境决定是否加锁 583 # // 我们假定要分配的内存满足内存对齐要求 584 # template <bool threads, int inst> 585 # void* __default_alloc_template<threads, inst>::refill(size_t n) 586 # { 587 # int nobjs = 20; 588 # char * chunk = chunk_alloc(n, nobjs); 589 # obj * __VOLATILE * my_free_list; 590 # obj * result; 591 # obj * current_obj, * next_obj; 592 # int i; 593 # 594 # // 如果内存池仅仅只够分配一个对象的空间, 直接返回即可 595 # if (1 == nobjs) return(chunk); 596 # 597 # // 内存池能分配更多的空间 598 # my_free_list = free_list + FREELIST_INDEX(n); 599 # 600 # // 在chunk的空间中建立free_list 601 # result = (obj *)chunk; 602 # *my_free_list = next_obj = (obj *)(chunk + n); 603 # for (i = 1; ; i++) { 604 # current_obj = next_obj; 605 # next_obj = (obj *)((char *)next_obj + n); 606 # if (nobjs - 1 == i) { 607 # current_obj -> free_list_link = 0; 608 # break; 609 # } else { 610 # current_obj -> free_list_link = next_obj; 611 # } 612 # } 613 # return(result); 614 # } 615 # 616 # template <bool threads, int inst> 617 # void* 618 # __default_alloc_template<threads, inst>::reallocate(void *p, 619 # size_t old_sz, 620 # size_t new_sz) 621 # { 622 # void * result; 623 # size_t copy_sz; 624 # 625 # // 如果old_size和new_size均大于__MAX_BYTES, 则直接调用realloc() 626 # // 因为这部分内存不是经过内存池分配的 627 # if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) { 628 # return(realloc(p, new_sz)); 629 # } 630 # // 如果ROUND_UP(old_sz) == ROUND_UP(new_sz), 内存大小没变化, 不进行重新分配 631 # if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); 632 # // 进行重新分配并拷贝数据 633 # result = allocate(new_sz); 634 # copy_sz = new_sz > old_sz? old_sz : new_sz; 635 # memcpy(result, p, copy_sz); 636 # deallocate(p, old_sz); 637 # return(result); 638 # } 639 # 640 # #ifdef __STL_PTHREADS 641 # template <bool threads, int inst> 642 # pthread_mutex_t 643 # __default_alloc_template<threads, inst>::__node_allocator_lock 644 # = PTHREAD_MUTEX_INITIALIZER; 645 # #endif 646 # 647 # #ifdef __STL_WIN32THREADS 648 # template <bool threads, int inst> CRITICAL_SECTION 649 # __default_alloc_template<threads, inst>::__node_allocator_lock; 650 # 651 # template <bool threads, int inst> bool 652 # __default_alloc_template<threads, inst>::__node_allocator_lock_initialized 653 # = false; 654 # #endif 655 # 656 # #ifdef __STL_SGI_THREADS 657 # __STL_END_NAMESPACE 658 # #include <mutex.h> 659 # #include <time.h> 660 # __STL_BEGIN_NAMESPACE 661 # // Somewhat generic lock implementations. We need only test-and-set 662 # // and some way to sleep. These should work with both SGI pthreads 663 # // and sproc threads. They may be useful on other systems. 664 # template <bool threads, int inst> 665 # volatile unsigned long 666 # __default_alloc_template<threads, inst>::__node_allocator_lock = 0; 667 # 668 # #if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) 669 # # define __test_and_set(l,v) test_and_set(l,v) 670 # #endif 671 # 672 # template <bool threads, int inst> 673 # void 674 # __default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock) 675 # { 676 # const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor 677 # const unsigned high_spin_max = 1000; // spin cycles for multiprocessor 678 # static unsigned spin_max = low_spin_max; 679 # unsigned my_spin_max; 680 # static unsigned last_spins = 0; 681 # unsigned my_last_spins; 682 # static struct timespec ts = {0, 1000}; 683 # unsigned junk; 684 # # define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk 685 # int i; 686 # 687 # if (!__test_and_set((unsigned long *)lock, 1)) { 688 # return; 689 # } 690 # my_spin_max = spin_max; 691 # my_last_spins = last_spins; 692 # for (i = 0; i < my_spin_max; i++) { 693 # if (i < my_last_spins/2 || *lock) { 694 # __ALLOC_PAUSE; 695 # continue; 696 # } 697 # if (!__test_and_set((unsigned long *)lock, 1)) { 698 # // got it! 699 # // Spinning worked. Thus we're probably not being scheduled 700 # // against the other process with which we were contending. 701 # // Thus it makes sense to spin longer the next time. 702 # last_spins = i; 703 # spin_max = high_spin_max; 704 # return; 705 # } 706 # } 707 # // We are probably being scheduled against the other process. Sleep. 708 # spin_max = low_spin_max; 709 # for (;;) { 710 # if (!__test_and_set((unsigned long *)lock, 1)) { 711 # return; 712 # } 713 # nanosleep(&ts, 0); 714 # } 715 # } 716 # 717 # template <bool threads, int inst> 718 # inline void 719 # __default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock) 720 # { 721 # # if defined(__GNUC__) && __mips >= 3 722 # asm("sync"); 723 # *lock = 0; 724 # # elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) 725 # __lock_release(lock); 726 # # else 727 # *lock = 0; 728 # // This is not sufficient on many multiprocessors, since 729 # // writes to protected variables and the lock may be reordered. 730 # # endif 731 # } 732 # #endif 733 # 734 # // 内存池起始位置 735 # template <bool threads, int inst> 736 # char *__default_alloc_template<threads, inst>::start_free = 0; 737 # // 内存池结束位置 738 # template <bool threads, int inst> 739 # char *__default_alloc_template<threads, inst>::end_free = 0; 740 # 741 # template <bool threads, int inst> 742 # size_t __default_alloc_template<threads, inst>::heap_size = 0; 743 # // 内存池容量索引数组 744 # template <bool threads, int inst> 745 # __default_alloc_template<threads, inst>::obj * __VOLATILE 746 # __default_alloc_template<threads, inst> ::free_list[ 747 # # ifdef __SUNPRO_CC 748 # __NFREELISTS 749 # # else 750 # __default_alloc_template<threads, inst>::__NFREELISTS 751 # # endif 752 # ] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; 753 # // The 16 zeros are necessary to make version 4.1 of the SunPro 754 # // compiler happy. Otherwise it appears to allocate too little 755 # // space for the array. 756 # 757 # # ifdef __STL_WIN32THREADS 758 # // Create one to get critical section initialized. 759 # // We do this onece per file, but only the first constructor 760 # // does anything. 761 # static alloc __node_allocator_dummy_instance; 762 # # endif 763 # 764 # #endif /* ! __USE_MALLOC */ 765 # 766 # #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 767 # #pragma reset woff 1174 768 # #endif 769 # 770 # __STL_END_NAMESPACE 771 # 772 # #undef __PRIVATE 773 # 774 # #endif /* __SGI_STL_INTERNAL_ALLOC_H */ 775 # 776 # // Local Variables: 777 # // mode:C++ 778 # // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 # // Filename: memory 2 # 3 # // Comment By: 凝霜 4 # // E-mail: mdl2009@vip.qq.com 5 # // Blog: http://blog.csdn.net/mdl13412 6 # 7 # // 智能指针在STL中只有一个auto_ptr, 用于对原生指针的生命周期进行管理, 8 # // 但是其本身有许多另其不安全的特性, 例如以一个auto_ptr去构造另一个 9 # // auto_ptr会导致对象所有权的转移, 另外如果两个只能指针同时指向一个 10 # // 原声指针就可能导致指针被意外的提前释放, 另一个auto_ptr对其解引用时, 11 # // 就会导致错误 12 # // 13 # // C++0x已经通过了::Boost::scoped_ptr的决案, 所以任何使用auto_ptr的 14 # // 情景都应该使用scoped_ptr替代, 因为其更安全, 但是仍然不能解决多个 15 # // 智能指针同时拥有一个对象导致的提前释放问题, 要解决这个问题, 请使用 16 # // ::Boost::shared_ptr 17 # 18 # // 我博客中还有一个我实现的auto_ptr, 大家可以参考 19 # // http://blog.csdn.net/mdl13412/article/details/6244631 20 # 21 # /* 22 # * Copyright (c) 1997 23 # * Silicon Graphics Computer Systems, Inc. 24 # * 25 # * Permission to use, copy, modify, distribute and sell this software 26 # * and its documentation for any purpose is hereby granted without fee, 27 # * provided that the above copyright notice appear in all copies and 28 # * that both that copyright notice and this permission notice appear 29 # * in supporting documentation. Silicon Graphics makes no 30 # * representations about the suitability of this software for any 31 # * purpose. It is provided "as is" without express or implied warranty. 32 # * 33 # */ 34 # 35 # #ifndef __SGI_STL_MEMORY 36 # #define __SGI_STL_MEMORY 37 # 38 # #include <stl_algobase.h> 39 # #include <stl_alloc.h> 40 # #include <stl_construct.h> 41 # #include <stl_tempbuf.h> 42 # #include <stl_uninitialized.h> 43 # #include <stl_raw_storage_iter.h> 44 # 45 # // Note: auto_ptr is commented out in this release because the details 46 # // of the interface are still being discussed by the C++ standardization 47 # // committee. It will be included once the iterface is finalized. 48 # 49 # #if 0 50 # #if defined(_MUTABLE_IS_KEYWORD) && defined(_EXPLICIT_IS_KEYWORD) && \ 51 # defined(__STL_MEMBER_TEMPLATES) 52 # 53 # __STL_BEGIN_NAMESPACE 54 # 55 # template <class X> class auto_ptr 56 # { 57 # private: 58 # X* ptr; // 托管的原生指针 59 # mutable bool owns; // 是否拥有托管指针 60 # public: 61 # typedef X element_type; 62 # 63 # // 显式构造函数, 防止隐式转换 64 # // 通常接收一个原生指针进行构造 65 # // 构造函数不能失败, 故不能抛出异常 66 # explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {} 67 # 68 # // auto_ptr 可以以相同类型的 auto_ptr 进行构造 69 # // 注意: 对象所有权发生转移, 用于构造的只能指针释放对象所有权 70 # auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { 71 # a.owns = 0; 72 # } 73 # 74 # // auto_ptr 可以以另一种相关类型的 auto_ptr 进行构造 75 # // 注意: T 必须能转换成 X 类型, 对象所有权发生转移 76 # template <class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW 77 # : ptr(a.ptr), owns(a.owns) { 78 # a.owns = 0; 79 # } 80 # 81 # // 重载operator =, 首先判断是否是本身, 如果不是则进行对象所有权的转移 82 # auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { 83 # if (&a != this) { 84 # if (owns) 85 # delete ptr; 86 # owns = a.owns; 87 # ptr = a.ptr; 88 # a.owns = 0; 89 # } 90 # // 个人感觉应该在此加上 91 # // return *this; 92 # } 93 # 94 # // 和上面的operator =功能一样, 但是提供了兼容类型的转换操作 95 # template <class T> auto_ptr& operator=(const auto_ptr<T>& a) __STL_NOTHROW { 96 # if (&a != this) { 97 # if (owns) 98 # delete ptr; 99 # owns = a.owns; 100 # ptr = a.ptr; 101 # a.owns = 0; 102 # } 103 # 104 # // 个人感觉应该在此加上 105 # // return *this; 106 # } 107 # 108 # // auto_ptr生命周期结束, 释放对象所有权, 实现资源释放目的 109 # ~auto_ptr() { 110 # if (owns) 111 # delete ptr; 112 # } 113 # 114 # // 提供和原生指针一样的操作 115 # X& operator*() const __STL_NOTHROW { return *ptr; } 116 # X* operator->() const __STL_NOTHROW { return ptr; } 117 # 118 # // 获取原生指针的地址, 主要用于一些只接受原生指针的函数 119 # X* get() const __STL_NOTHROW { return ptr; } 120 # // 释放指针所有权, 并返回原生指针 121 # // 主要用于取消指针托管 122 # X* release const __STL_NOTHROW { owns = false; return ptr } 123 # }; 124 # 125 # __STL_END_NAMESPACE 126 # #endif /* mutable && explicit && member templates */ 127 # #endif /* 0 */ 128 # 129 # 130 # #endif /* __SGI_STL_MEMORY */ 131 # 132 # 133 # // Local Variables: 134 # // mode:C++ 135 # // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_construct.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H 38 #define __SGI_STL_INTERNAL_CONSTRUCT_H 39 40 #include <new.h> // 需要placement new的原型 41 42 __STL_BEGIN_NAMESPACE 43 44 // 调用成员的析构函数, 需要类型具有non-trivial destructor 45 template <class T> 46 inline void destroy(T* pointer) 47 { 48 pointer->~T(); 49 } 50 51 // 使用placement new在已经分配的内存上构造对象 52 // 如果你不熟悉placement new, 请参考 53 // http://msdn.microsoft.com/en-us/library/kewsb8ba.aspx 54 // http://blogs.msdn.com/b/jaredpar/archive/ 55 // 2007/10/16/c-new-operator-and-placement-new.aspx 56 template <class T1, class T2> 57 inline void construct(T1* p, const T2& value) 58 { 59 new (p) T1(value); 60 } 61 62 // 析构一组对象, 用于具有non-trivial destructor 63 template <class ForwardIterator> 64 inline void 65 __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) 66 { 67 for ( ; first < last; ++first) 68 destroy(&*first); 69 } 70 71 // 如果没有类型non-trivial destructor, 则使用此函数 72 template <class ForwardIterator> 73 inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} 74 75 // 使用traits技术, 判断类型是否就有non-trivial destructor, 然后调用不同的函数 76 template <class ForwardIterator, class T> 77 inline void __destroy(ForwardIterator first, ForwardIterator last, T*) 78 { 79 typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor; 80 __destroy_aux(first, last, trivial_destructor()); 81 } 82 83 //// 84 // 用于销毁一组对象 85 //// 86 // char *特化版本 87 // ---------- destroy不进行析构 88 // | 89 // destroy(first, last) -------------------------- 特化 90 // | | 91 // | 泛化 ----------- destroy不进行析构 92 // | wchar_t *特化版本 93 // ↓ 94 // 调用 __destroy(first, last, value_type(first)); 95 // 根据是否具有trivial destructor进行函数转发 96 // | 97 // |---------------- has trivial destructor? 98 // | 99 // ------------------------------------------- 100 // No | | Yes 101 // | | 102 // ↓ ↓ 103 // __destroy_aux(..., __true_type) __destroy_aux(..., __false_type) 104 // 不进需要行析构操作 for ( ; first < last; ++first) 105 // destroy(&*first); 106 //// 107 108 template <class ForwardIterator> 109 inline void destroy(ForwardIterator first, ForwardIterator last) 110 { 111 __destroy(first, last, value_type(first)); 112 } 113 114 // 特化版本 115 inline void destroy(char*, char*) {} 116 inline void destroy(wchar_t*, wchar_t*) {} 117 118 __STL_END_NAMESPACE 119 120 #endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ 121 122 // Local Variables: 123 // mode:C++ 124 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_uninitialized.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // 主要接口: 8 // 9 // template <class InputIterator, class ForwardIterator> 10 // inline ForwardIterator 11 // uninitialized_copy(InputIterator first, InputIterator last, 12 // ForwardIterator result) 13 // 将[first, last)的对象复制一份到[result, result + (last - first)) 14 // 对于char和wchar_t提供特化版本, 以获取最佳效率 15 // 注: commit or rollback 16 // 17 // template <class InputIterator, class Size, class ForwardIterator> 18 // inline pair<InputIterator, ForwardIterator> 19 // uninitialized_copy_n(InputIterator first, Size count, 20 // ForwardIterator result) 21 // 从first开始, 复制count个对象到[result, result + n) 22 // 注: commit or rollback 23 // 24 // template <class ForwardIterator, class T> 25 // inline void uninitialized_fill(ForwardIterator first, 26 // ForwardIterator last, 27 // const T& x) 28 // 将x复制到pfirst, last) 29 // 注: commit or rollback 30 // 31 // template <class ForwardIterator, class Size, class T> 32 // inline ForwardIterator uninitialized_fill_n(ForwardIterator first, 33 // Size n, const T& x) 34 // 复制n个x对象到[first, first + n) 35 // 注: commit or rollback 36 37 /* 38 * 39 * Copyright (c) 1994 40 * Hewlett-Packard Company 41 * 42 * Permission to use, copy, modify, distribute and sell this software 43 * and its documentation for any purpose is hereby granted without fee, 44 * provided that the above copyright notice appear in all copies and 45 * that both that copyright notice and this permission notice appear 46 * in supporting documentation. Hewlett-Packard Company makes no 47 * representations about the suitability of this software for any 48 * purpose. It is provided "as is" without express or implied warranty. 49 * 50 * 51 * Copyright (c) 1996,1997 52 * Silicon Graphics Computer Systems, Inc. 53 * 54 * Permission to use, copy, modify, distribute and sell this software 55 * and its documentation for any purpose is hereby granted without fee, 56 * provided that the above copyright notice appear in all copies and 57 * that both that copyright notice and this permission notice appear 58 * in supporting documentation. Silicon Graphics makes no 59 * representations about the suitability of this software for any 60 * purpose. It is provided "as is" without express or implied warranty. 61 */ 62 63 /* NOTE: This is an internal header file, included by other STL headers. 64 * You should not attempt to use it directly. 65 */ 66 67 #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H 68 #define __SGI_STL_INTERNAL_UNINITIALIZED_H 69 70 __STL_BEGIN_NAMESPACE 71 72 //// 73 // uninitialized_copy()实现部分 74 //// 75 // 特化char版本 76 // |---------------> (char *, ...) <--- 字串串专用版本 77 // | 特化wchar_t版本 |--- 调用memmove() 78 // uninitialized_copy ------------------> (wchar_t, ...) <--- 获取最佳效率 79 // | 80 // | 81 // | 泛化 调用 __uninitialized_copy() 82 // |-----> 根据类型是否为POD进行函数派发 83 // | 84 // |---------------- Is POD? 85 // | 86 // ------------------------------------- 87 // No | | Yes 88 // ↓ | 89 // __uninitialized_copy_aux(..., __false_type) | 90 // for ( ; first != last; ++first, ++cur) | 91 // construct(&*cur, *first); ↓ 92 // __uninitialized_copy_aux(..., __true_type) 93 // copy(first, last, result) 94 //// 95 96 // 如果copy construction和operator =等效, 并且destructor is trivial 97 // 那么就可以使用本函数 98 // 返回值为目标地址的end 99 // 注: 使用copy()进行复制的时候, 调用的是对象的operator =, 100 // 所以要满足copy construction和operator =等效, 101 // destructor is trivial保证在此版本中不会进行析构, 102 // 以保证效率 103 template <class InputIterator, class ForwardIterator> 104 inline ForwardIterator 105 __uninitialized_copy_aux(InputIterator first, InputIterator last, 106 ForwardIterator result, 107 __true_type) 108 { 109 // 调用的是STL算法copy() 110 return copy(first, last, result); 111 } 112 113 // 如果copy construction和operator =不等效, 那么就要调用construct()进行构造 114 template <class InputIterator, class ForwardIterator> 115 ForwardIterator 116 __uninitialized_copy_aux(InputIterator first, InputIterator last, 117 ForwardIterator result, 118 __false_type) 119 { 120 ForwardIterator cur = result; 121 __STL_TRY { 122 // 因为copy construction和operator =不等效, 123 // 则必须每个对象都以其它对象为蓝本进行构造 124 // 本实作中使用的是placement new进行构造 125 for ( ; first != last; ++first, ++cur) 126 construct(&*cur, *first); 127 return cur; 128 } 129 // commit or rollback 130 // 如果分配失败就stack unwinding, 131 // 保证所有对象都被析构 132 __STL_UNWIND(destroy(result, cur)); 133 } 134 135 // 派发函数, traits出T是否为POD, 然后进行派发 136 template <class InputIterator, class ForwardIterator, class T> 137 inline ForwardIterator 138 __uninitialized_copy(InputIterator first, InputIterator last, 139 ForwardIterator result, T*) 140 { 141 // POD = Plain Old Data 142 // 其具有trvial constructor/destructor/copy constructor/operator = 143 // 所有的C++内置基本数据类型和传统C struct都属于POD 144 typedef typename __type_traits<T>::is_POD_type is_POD; 145 146 // 根据是否为POD类型进行派发, 以保证效率 147 return __uninitialized_copy_aux(first, last, result, is_POD()); 148 } 149 150 template <class InputIterator, class ForwardIterator> 151 inline ForwardIterator 152 uninitialized_copy(InputIterator first, InputIterator last, 153 ForwardIterator result) 154 { 155 // 调用派发函数, 根据是否为POD决议出最佳效率的函数 156 return __uninitialized_copy(first, last, result, value_type(result)); 157 } 158 159 // 提供给char专用, 效率最优化 160 inline char* uninitialized_copy(const char* first, const char* last, 161 char* result) 162 { 163 memmove(result, first, last - first); 164 return result + (last - first); 165 } 166 167 // 提供给wchar_t专用, 效率最优化 168 inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last, 169 wchar_t* result) 170 { 171 memmove(result, first, sizeof(wchar_t) * (last - first)); 172 return result + (last - first); 173 } 174 175 //// 176 // uninitialized_copy_n()实现部分 177 //// 178 // uninitialized_copy_n 179 // | 180 // |------------ 判断迭代器first的类别 181 // | 182 // ----------------------------------------- 183 // InputIterator | | RandomAccessIterator 184 // | | 185 // ↓ | 186 // __uninitialized_copy_n(..., input_iterator_tag) | 187 // for ( ; count > 0 ; --count, ++first, ++cur) | 188 // construct(&*cur, *first); | 189 // ↓ 190 // __uninitialized_copy_n(..., random_access_iterator_tag) 191 // last = first + count; 192 // uninitialized_copy(first, last, result) 193 //// 194 195 // POD版本 196 template <class InputIterator, class Size, class ForwardIterator> 197 pair<InputIterator, ForwardIterator> 198 __uninitialized_copy_n(InputIterator first, Size count, 199 ForwardIterator result, 200 input_iterator_tag) 201 { 202 ForwardIterator cur = result; 203 __STL_TRY { 204 for ( ; count > 0 ; --count, ++first, ++cur) 205 construct(&*cur, *first); 206 return pair<InputIterator, ForwardIterator>(first, cur); 207 } 208 __STL_UNWIND(destroy(result, cur)); 209 } 210 211 // 非POD版本 212 // 对于支持随机存取的迭代器, 可以直接使用uninitialized_copy()进行复制 213 template <class RandomAccessIterator, class Size, class ForwardIterator> 214 inline pair<RandomAccessIterator, ForwardIterator> 215 __uninitialized_copy_n(RandomAccessIterator first, Size count, 216 ForwardIterator result, 217 random_access_iterator_tag) 218 { 219 RandomAccessIterator last = first + count; 220 return make_pair(last, uninitialized_copy(first, last, result)); 221 } 222 223 template <class InputIterator, class Size, class ForwardIterator> 224 inline pair<InputIterator, ForwardIterator> 225 uninitialized_copy_n(InputIterator first, Size count, 226 ForwardIterator result) 227 { 228 return __uninitialized_copy_n(first, count, result, 229 iterator_category(first)); 230 } 231 232 //// 233 // uninitialized_fill()实现部分 234 //// 235 // uninitialized_fill 236 // | 237 // | 238 // ↓ 239 // 调用__uninitialized_fill() 240 // 根据类型是否为POD进行函数派发 241 // | 242 // |---------------- Is POD? 243 // No 泛化版本 | Yes 特化版本 244 // ------------------------------------------- 245 // | | 246 // | | 247 // ↓ | 248 // __uninitialized_fill_aux(..., __false_type) | 249 // for ( ; cur != last; ++cur) | 250 // construct(&*cur, x); ↓ 251 // __uninitialized_fill_aux(..., __true_type) 252 // fill(first, last, x); 253 //// 254 255 // POD版本 256 // 如果copy construction和operator =等效, 并且destructor is trivial 257 // 那么就可以使用本函数 258 template <class ForwardIterator, class T> 259 inline void 260 __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 261 const T& x, __true_type) 262 { 263 fill(first, last, x); 264 } 265 266 // 非POD版本 267 template <class ForwardIterator, class T> 268 void 269 __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 270 const T& x, __false_type) 271 { 272 ForwardIterator cur = first; 273 __STL_TRY { 274 for ( ; cur != last; ++cur) 275 construct(&*cur, x); 276 } 277 __STL_UNWIND(destroy(first, cur)); 278 } 279 280 // 派发函数 281 template <class ForwardIterator, class T, class T1> 282 inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, 283 const T& x, T1*) 284 { 285 typedef typename __type_traits<T1>::is_POD_type is_POD; 286 __uninitialized_fill_aux(first, last, x, is_POD()); 287 288 } 289 290 template <class ForwardIterator, class T> 291 inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, 292 const T& x) 293 { 294 __uninitialized_fill(first, last, x, value_type(first)); 295 } 296 297 //// 298 // uninitialized_fill_n()实现部分 299 //// 300 // uninitialized_fill_n 301 // | 302 // | 303 // ↓ 304 // 调用__uninitialized_fill_n() 305 // 根据类型是否为POD进行函数派发 306 // | 307 // |---------------- Is POD? 308 // No 泛化版本 | Yes 特化版本 309 // ------------------------------------------- 310 // | | 311 // | | 312 // ↓ | 313 // __uninitialized_fill_n_aux(..., __false_type) | 314 // for ( ; n > 0; --n, ++cur) | 315 // construct(&*cur, x); | 316 // ↓ 317 // __uninitialized_fill_n_aux(..., __true_type) 318 // fill_n(first, n, x); 319 //// 320 321 // 如果copy construction和operator =等效, 并且destructor is trivial 322 // 那么就可以使用本函数 323 template <class ForwardIterator, class Size, class T> 324 inline ForwardIterator 325 __uninitialized_fill_n_aux(ForwardIterator first, Size n, 326 const T& x, __true_type) 327 { 328 return fill_n(first, n, x); 329 } 330 331 template <class ForwardIterator, class Size, class T> 332 ForwardIterator 333 __uninitialized_fill_n_aux(ForwardIterator first, Size n, 334 const T& x, __false_type) 335 { 336 ForwardIterator cur = first; 337 __STL_TRY { 338 for ( ; n > 0; --n, ++cur) 339 construct(&*cur, x); 340 return cur; 341 } 342 __STL_UNWIND(destroy(first, cur)); 343 } 344 345 template <class ForwardIterator, class Size, class T, class T1> 346 inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, 347 const T& x, T1*) 348 { 349 typedef typename __type_traits<T1>::is_POD_type is_POD; 350 return __uninitialized_fill_n_aux(first, n, x, is_POD()); 351 352 } 353 354 template <class ForwardIterator, class Size, class T> 355 inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, 356 const T& x) 357 { 358 return __uninitialized_fill_n(first, n, x, value_type(first)); 359 } 360 361 //// 362 // 其它函数实现 363 //// 364 365 // Copies [first1, last1) into [result, result + (last1 - first1)), and 366 // copies [first2, last2) into 367 // [result, result + (last1 - first1) + (last2 - first2)). 368 369 // 我认为应该是把[first2, last2)copy到 370 // [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)) 371 // 大家可以讨论一下 372 template <class InputIterator1, class InputIterator2, class ForwardIterator> 373 inline ForwardIterator 374 __uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, 375 InputIterator2 first2, InputIterator2 last2, 376 ForwardIterator result) 377 { 378 ForwardIterator mid = uninitialized_copy(first1, last1, result); 379 __STL_TRY { 380 return uninitialized_copy(first2, last2, mid); 381 } 382 __STL_UNWIND(destroy(result, mid)); 383 } 384 385 // Fills [result, mid) with x, and copies [first, last) into 386 // [mid, mid + (last - first)). 387 template <class ForwardIterator, class T, class InputIterator> 388 inline ForwardIterator 389 __uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, 390 const T& x, 391 InputIterator first, InputIterator last) 392 { 393 uninitialized_fill(result, mid, x); 394 __STL_TRY { 395 return uninitialized_copy(first, last, mid); 396 } 397 __STL_UNWIND(destroy(result, mid)); 398 } 399 400 // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and 401 // fills [first2 + (last1 - first1), last2) with x. 402 template <class InputIterator, class ForwardIterator, class T> 403 inline void 404 __uninitialized_copy_fill(InputIterator first1, InputIterator last1, 405 ForwardIterator first2, ForwardIterator last2, 406 const T& x) 407 { 408 ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); 409 __STL_TRY { 410 uninitialized_fill(mid2, last2, x); 411 } 412 __STL_UNWIND(destroy(first2, mid2)); 413 } 414 415 __STL_END_NAMESPACE 416 417 #endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */ 418 419 // Local Variables: 420 // mode:C++ 421 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_iterator.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_ITERATOR_H 38 #define __SGI_STL_INTERNAL_ITERATOR_H 39 40 __STL_BEGIN_NAMESPACE 41 42 //// 43 // STL迭代器定义 44 //// 45 // STL中有五种迭代器类型 46 // Input Iterator read only 47 // Output Iterator write only 48 // Forward Iterator 允许"写入型"算法在其指向区间进行操作 49 // Bidirectional Iterator 提供双向访问能力 50 // Random Access Iterator 支持原生指针具有的全部能力 51 //// 52 // 类型从属关系, 子类适用于接受父类类型的算法, 但是效率可能不佳 53 // 54 // Input Iterator 55 // ↑ 56 // Forward Iterator 57 // ↑ 58 // Bidirectional Iterator 59 // ↑ 60 // Random Access Iterator 61 //// 62 63 // 用于标记迭代器类型 64 struct input_iterator_tag {}; 65 struct output_iterator_tag {}; 66 struct forward_iterator_tag : public input_iterator_tag {}; 67 struct bidirectional_iterator_tag : public forward_iterator_tag {}; 68 struct random_access_iterator_tag : public bidirectional_iterator_tag {}; 69 70 template <class T, class Distance> struct input_iterator 71 { 72 typedef input_iterator_tag iterator_category; 73 typedef T value_type; 74 typedef Distance difference_type; 75 typedef T* pointer; 76 typedef T& reference; 77 }; 78 79 struct output_iterator 80 { 81 typedef output_iterator_tag iterator_category; 82 typedef void value_type; 83 typedef void difference_type; 84 typedef void pointer; 85 typedef void reference; 86 }; 87 88 template <class T, class Distance> struct forward_iterator 89 { 90 typedef forward_iterator_tag iterator_category; 91 typedef T value_type; 92 typedef Distance difference_type; 93 typedef T* pointer; 94 typedef T& reference; 95 }; 96 97 template <class T, class Distance> struct bidirectional_iterator 98 { 99 typedef bidirectional_iterator_tag iterator_category; 100 typedef T value_type; 101 typedef Distance difference_type; 102 typedef T* pointer; 103 typedef T& reference; 104 }; 105 106 template <class T, class Distance> struct random_access_iterator 107 { 108 typedef random_access_iterator_tag iterator_category; 109 typedef T value_type; 110 typedef Distance difference_type; 111 typedef T* pointer; 112 typedef T& reference; 113 }; 114 115 #ifdef __STL_USE_NAMESPACES 116 template <class Category, class T, class Distance = ptrdiff_t, 117 class Pointer = T*, class Reference = T&> 118 struct iterator { 119 typedef Category iterator_category; 120 typedef T value_type; 121 typedef Distance difference_type; 122 typedef Pointer pointer; 123 typedef Reference reference; 124 }; 125 #endif /* __STL_USE_NAMESPACES */ 126 127 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 128 129 //// 130 // iterator_traits定义 131 //// 132 133 // 用于traits出迭代其所指对象的型别 134 template <class Iterator> 135 struct iterator_traits 136 { 137 // 迭代器类型, STL提供五种迭代器 138 typedef typename Iterator::iterator_category iterator_category; 139 140 // 迭代器所指对象的型别 141 // 如果想与STL算法兼容, 那么在类内需要提供value_type定义 142 typedef typename Iterator::value_type value_type; 143 144 // 这个是用于处理两个迭代器间距离的类型 145 typedef typename Iterator::difference_type difference_type; 146 147 // 直接指向对象的原生指针类型 148 typedef typename Iterator::pointer pointer; 149 150 // 这个是对象的引用类型 151 typedef typename Iterator::reference reference; 152 }; 153 154 // 针对指针提供特化版本 155 template <class T> 156 struct iterator_traits<T*> 157 { 158 typedef random_access_iterator_tag iterator_category; 159 typedef T value_type; 160 typedef ptrdiff_t difference_type; 161 typedef T* pointer; 162 typedef T& reference; 163 }; 164 165 // 针对指向常对象的指针提供特化 166 template <class T> 167 struct iterator_traits<const T*> 168 { 169 typedef random_access_iterator_tag iterator_category; 170 typedef T value_type; 171 typedef ptrdiff_t difference_type; 172 typedef const T* pointer; 173 typedef const T& reference; 174 }; 175 176 //// 177 // iterator_traits支持函数 178 //// 179 // iterator_category(const Iterator&) 返回迭代器类别 180 // distance_type(const Iterator&) 返回表示迭代器距离的类型 181 // value_type(const Iterator&) 返回迭代器所指对象的类型 182 //// 183 184 template <class Iterator> 185 inline typename iterator_traits<Iterator>::iterator_category 186 iterator_category(const Iterator&) 187 { 188 typedef typename iterator_traits<Iterator>::iterator_category category; 189 return category(); 190 } 191 192 template <class Iterator> 193 inline typename iterator_traits<Iterator>::difference_type* 194 distance_type(const Iterator&) 195 { 196 return static_cast<typename iterator_traits<Iterator>::difference_type*>(0); 197 } 198 199 template <class Iterator> 200 inline typename iterator_traits<Iterator>::value_type* 201 value_type(const Iterator&) 202 { 203 return static_cast<typename iterator_traits<Iterator>::value_type*>(0); 204 } 205 206 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 207 208 // 编译器不支持partial specialization of class templates(模板类偏特化) 209 // 需要对所有迭代器类型都提供定义 210 211 template <class T, class Distance> 212 inline input_iterator_tag 213 iterator_category(const input_iterator<T, Distance>&) 214 { 215 return input_iterator_tag(); 216 } 217 218 inline output_iterator_tag iterator_category(const output_iterator&) 219 { 220 return output_iterator_tag(); 221 } 222 223 template <class T, class Distance> 224 inline forward_iterator_tag 225 iterator_category(const forward_iterator<T, Distance>&) 226 { 227 return forward_iterator_tag(); 228 } 229 230 template <class T, class Distance> 231 inline bidirectional_iterator_tag 232 iterator_category(const bidirectional_iterator<T, Distance>&) 233 { 234 return bidirectional_iterator_tag(); 235 } 236 237 template <class T, class Distance> 238 inline random_access_iterator_tag 239 iterator_category(const random_access_iterator<T, Distance>&) 240 { 241 return random_access_iterator_tag(); 242 } 243 244 template <class T> 245 inline random_access_iterator_tag iterator_category(const T*) 246 { 247 return random_access_iterator_tag(); 248 } 249 250 template <class T, class Distance> 251 inline T* value_type(const input_iterator<T, Distance>&) 252 { 253 return (T*)(0); 254 } 255 256 template <class T, class Distance> 257 inline T* value_type(const forward_iterator<T, Distance>&) 258 { 259 return (T*)(0); 260 } 261 262 template <class T, class Distance> 263 inline T* value_type(const bidirectional_iterator<T, Distance>&) 264 { 265 return (T*)(0); 266 } 267 268 template <class T, class Distance> 269 inline T* value_type(const random_access_iterator<T, Distance>&) 270 { 271 return (T*)(0); 272 } 273 274 template <class T> 275 inline T* value_type(const T*) { return (T*)(0); } 276 277 template <class T, class Distance> 278 inline Distance* distance_type(const input_iterator<T, Distance>&) 279 { 280 return (Distance*)(0); 281 } 282 283 template <class T, class Distance> 284 inline Distance* distance_type(const forward_iterator<T, Distance>&) 285 { 286 return (Distance*)(0); 287 } 288 289 template <class T, class Distance> 290 inline Distance* 291 distance_type(const bidirectional_iterator<T, Distance>&) 292 { 293 return (Distance*)(0); 294 } 295 296 template <class T, class Distance> 297 inline Distance* 298 distance_type(const random_access_iterator<T, Distance>&) 299 { 300 return (Distance*)(0); 301 } 302 303 template <class T> 304 inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } 305 306 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 307 308 //// 309 // template <class InputIterator, class Distance> 310 // inline void distance(InputIterator first, InputIterator last, Distance& n) 311 //// 312 // distance 313 // | 314 // |---------------- 判断迭代器类型 315 // Input Iterator ↓ Random Access Iterator 316 // ------------------------------------------- 317 // | | 318 // | | 319 // ↓ | 320 // __distance(..., input_iterator_tag) | 321 // while (first != last) { ++first; ++n; } | 322 // ↓ 323 // __distance(..., random_access_iterator_tag) 324 // n += last - first; 325 //// 326 327 template <class InputIterator, class Distance> 328 inline void __distance(InputIterator first, InputIterator last, Distance& n, 329 input_iterator_tag) 330 { 331 while (first != last) { ++first; ++n; } 332 } 333 334 template <class RandomAccessIterator, class Distance> 335 inline void __distance(RandomAccessIterator first, RandomAccessIterator last, 336 Distance& n, random_access_iterator_tag) 337 { 338 n += last - first; 339 } 340 341 template <class InputIterator, class Distance> 342 inline void distance(InputIterator first, InputIterator last, Distance& n) 343 { 344 __distance(first, last, n, iterator_category(first)); 345 } 346 347 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 348 349 //// 350 // template <class InputIterator> 351 // inline iterator_traits<InputIterator>::difference_type 352 // distance(InputIterator first, InputIterator last) 353 //// 354 // distance 355 // | 356 // |---------------- 判断迭代器类型 357 // Input Iterator ↓ Random Access Iterator 358 // ------------------------------------------- 359 // | | 360 // | | 361 // ↓ | 362 // __distance(..., input_iterator_tag) | 363 // while (first != last) { | 364 // ++first; ++n; | 365 // } | 366 // return n; | 367 // ↓ 368 // __distance(..., random_access_iterator_tag) 369 // return last - first; 370 //// 371 372 template <class InputIterator> 373 inline iterator_traits<InputIterator>::difference_type 374 __distance(InputIterator first, InputIterator last, input_iterator_tag) 375 { 376 iterator_traits<InputIterator>::difference_type n = 0; 377 while (first != last) { 378 ++first; ++n; 379 } 380 return n; 381 } 382 383 template <class RandomAccessIterator> 384 inline iterator_traits<RandomAccessIterator>::difference_type 385 __distance(RandomAccessIterator first, RandomAccessIterator last, 386 random_access_iterator_tag) 387 { 388 return last - first; 389 } 390 391 template <class InputIterator> 392 inline iterator_traits<InputIterator>::difference_type 393 distance(InputIterator first, InputIterator last) 394 { 395 typedef typename iterator_traits<InputIterator>::iterator_category category; 396 return __distance(first, last, category()); 397 } 398 399 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 400 401 //// 402 // advance()实现部分 403 //// 404 // advance 405 // | 406 // |---------------- 判断迭代器类型 407 // Input Iterator ↓ 408 // --------------------------------------------------------------------- 409 // | Random Access Iterator | Bidirectional Iterator | 410 // | | | 411 // ↓ | | 412 // __advance(..., input_iterator_tag) | | 413 // while (n--) ++i; | | 414 // | | 415 // ↓ | 416 // __advance(..., random_access_iterator_tag) | 417 // i += n; | 418 // | 419 // ↓ 420 // __advance(..., bidirectional_iterator_tag) 421 // if (n >= 0) 422 // while (n--) ++i; 423 // else 424 // while (n++) --i; 425 //// 426 427 template <class InputIterator, class Distance> 428 inline void __advance(InputIterator& i, Distance n, input_iterator_tag) 429 { 430 while (n--) ++i; 431 } 432 433 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 434 #pragma set woff 1183 435 #endif 436 437 template <class BidirectionalIterator, class Distance> 438 inline void __advance(BidirectionalIterator& i, Distance n, 439 bidirectional_iterator_tag) 440 { 441 if (n >= 0) 442 while (n--) ++i; 443 else 444 while (n++) --i; 445 } 446 447 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 448 #pragma reset woff 1183 449 #endif 450 451 template <class RandomAccessIterator, class Distance> 452 inline void __advance(RandomAccessIterator& i, Distance n, 453 random_access_iterator_tag) 454 { 455 i += n; 456 } 457 458 template <class InputIterator, class Distance> 459 inline void advance(InputIterator& i, Distance n) 460 { 461 __advance(i, n, iterator_category(i)); 462 } 463 464 //// 465 // back_insert_iterator实现部分 466 //// 467 468 template <class Container> 469 class back_insert_iterator 470 { 471 protected: 472 Container* container; 473 public: 474 typedef output_iterator_tag iterator_category; 475 typedef void value_type; 476 typedef void difference_type; 477 typedef void pointer; 478 typedef void reference; 479 480 explicit back_insert_iterator(Container& x) : container(&x) {} 481 482 // 只有提供了push_back()操作的容器才能使用back_insert_iterator 483 back_insert_iterator<Container>& 484 operator=(const typename Container::value_type& value) 485 { 486 container->push_back(value); 487 return *this; 488 } 489 490 back_insert_iterator<Container>& operator*() { return *this; } 491 back_insert_iterator<Container>& operator++() { return *this; } 492 back_insert_iterator<Container>& operator++(int) { return *this; } 493 }; 494 495 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 496 497 // 用于traits出back_insert_iterator的迭代器类别 498 template <class Container> 499 inline output_iterator_tag 500 iterator_category(const back_insert_iterator<Container>&) 501 { 502 return output_iterator_tag(); 503 } 504 505 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 506 507 template <class Container> 508 inline back_insert_iterator<Container> back_inserter(Container& x) 509 { 510 return back_insert_iterator<Container>(x); 511 } 512 513 //// 514 // front_insert_iterator实现部分 515 //// 516 517 template <class Container> 518 class front_insert_iterator 519 { 520 protected: 521 Container* container; 522 public: 523 typedef output_iterator_tag iterator_category; 524 typedef void value_type; 525 typedef void difference_type; 526 typedef void pointer; 527 typedef void reference; 528 529 explicit front_insert_iterator(Container& x) : container(&x) {} 530 531 // 只有提供了push_front()操作的容器才能使用front_insert_iterator 532 front_insert_iterator<Container>& 533 operator=(const typename Container::value_type& value) 534 { 535 container->push_front(value); 536 return *this; 537 } 538 front_insert_iterator<Container>& operator*() { return *this; } 539 front_insert_iterator<Container>& operator++() { return *this; } 540 front_insert_iterator<Container>& operator++(int) { return *this; } 541 }; 542 543 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 544 545 template <class Container> 546 inline output_iterator_tag 547 iterator_category(const front_insert_iterator<Container>&) 548 { 549 return output_iterator_tag(); 550 } 551 552 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 553 554 template <class Container> 555 inline front_insert_iterator<Container> front_inserter(Container& x) 556 { 557 return front_insert_iterator<Container>(x); 558 } 559 560 //// 561 // insert_iterator实现部分 562 //// 563 564 template <class Container> 565 class insert_iterator 566 { 567 protected: 568 Container* container; 569 typename Container::iterator iter; 570 public: 571 typedef output_iterator_tag iterator_category; 572 typedef void value_type; 573 typedef void difference_type; 574 typedef void pointer; 575 typedef void reference; 576 577 insert_iterator(Container& x, typename Container::iterator i) 578 : container(&x), iter(i) {} 579 580 // 只有提供了insert操作的容器才能使用insert_iterator 581 insert_iterator<Container>& 582 operator=(const typename Container::value_type& value) 583 { 584 iter = container->insert(iter, value); 585 ++iter; 586 return *this; 587 } 588 insert_iterator<Container>& operator*() { return *this; } 589 insert_iterator<Container>& operator++() { return *this; } 590 insert_iterator<Container>& operator++(int) { return *this; } 591 }; 592 593 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 594 595 template <class Container> 596 inline output_iterator_tag 597 iterator_category(const insert_iterator<Container>&) 598 { 599 return output_iterator_tag(); 600 } 601 602 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 603 604 template <class Container, class Iterator> 605 inline insert_iterator<Container> inserter(Container& x, Iterator i) 606 { 607 typedef typename Container::iterator iter; 608 return insert_iterator<Container>(x, iter(i)); 609 } 610 611 //// 612 // reverse_bidirectional_iterator实现部分 613 //// 614 615 // reverse_bidirectional_iterator使用的是BidirectionalIterator 616 // 所以要对operator *(), ++(), ++(int)都提供处理 617 // 同时因为是反向迭代器, 所以重载运算符的操作要特殊处理 618 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 619 template <class BidirectionalIterator, class T, class Reference = T&, 620 class Distance = ptrdiff_t> 621 #else 622 template <class BidirectionalIterator, class T, class Reference, 623 class Distance> 624 #endif 625 class reverse_bidirectional_iterator 626 { 627 typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, 628 Distance> self; 629 protected: 630 BidirectionalIterator current; 631 public: 632 typedef bidirectional_iterator_tag iterator_category; 633 typedef T value_type; 634 typedef Distance difference_type; 635 typedef T* pointer; 636 typedef Reference reference; 637 638 reverse_bidirectional_iterator() {} 639 explicit reverse_bidirectional_iterator(BidirectionalIterator x) 640 : current(x) {} 641 BidirectionalIterator base() const { return current; } 642 Reference operator*() const { 643 BidirectionalIterator tmp = current; 644 return *--tmp; 645 } 646 #ifndef __SGI_STL_NO_ARROW_OPERATOR 647 pointer operator->() const { return &(operator*()); } 648 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 649 self& operator++() { 650 --current; 651 return *this; 652 } 653 self operator++(int) { 654 self tmp = *this; 655 --current; 656 return tmp; 657 } 658 self& operator--() { 659 ++current; 660 return *this; 661 } 662 self operator--(int) { 663 self tmp = *this; 664 ++current; 665 return tmp; 666 } 667 }; 668 669 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 670 671 template <class BidirectionalIterator, class T, class Reference, 672 class Distance> 673 inline bidirectional_iterator_tag 674 iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator, 675 T, 676 Reference, Distance>&) 677 { 678 return bidirectional_iterator_tag(); 679 } 680 681 template <class BidirectionalIterator, class T, class Reference, 682 class Distance> 683 inline T* 684 value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T, 685 Reference, Distance>&) 686 { 687 return (T*) 0; 688 } 689 690 template <class BidirectionalIterator, class T, class Reference, 691 class Distance> 692 inline Distance* 693 distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T, 694 Reference, Distance>&) 695 { 696 return (Distance*) 0; 697 } 698 699 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 700 701 template <class BidirectionalIterator, class T, class Reference, 702 class Distance> 703 inline bool operator==( 704 const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, 705 Distance>& x, 706 const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, 707 Distance>& y) 708 { 709 return x.base() == y.base(); 710 } 711 712 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 713 714 //// 715 // reverse_iterator实现部分 716 //// 717 718 // This is the new version of reverse_iterator, as defined in the 719 // draft C++ standard. It relies on the iterator_traits template, 720 // which in turn relies on partial specialization. The class 721 // reverse_bidirectional_iterator is no longer part of the draft 722 // standard, but it is retained for backward compatibility. 723 724 template <class Iterator> 725 class reverse_iterator 726 { 727 protected: 728 Iterator current; 729 public: 730 typedef typename iterator_traits<Iterator>::iterator_category 731 iterator_category; 732 typedef typename iterator_traits<Iterator>::value_type 733 value_type; 734 typedef typename iterator_traits<Iterator>::difference_type 735 difference_type; 736 typedef typename iterator_traits<Iterator>::pointer 737 pointer; 738 typedef typename iterator_traits<Iterator>::reference 739 reference; 740 741 typedef Iterator iterator_type; 742 typedef reverse_iterator<Iterator> self; 743 744 public: 745 reverse_iterator() {} 746 explicit reverse_iterator(iterator_type x) : current(x) {} 747 748 reverse_iterator(const self& x) : current(x.current) {} 749 #ifdef __STL_MEMBER_TEMPLATES 750 template <class Iter> 751 reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {} 752 #endif /* __STL_MEMBER_TEMPLATES */ 753 754 iterator_type base() const { return current; } 755 reference operator*() const { 756 Iterator tmp = current; 757 return *--tmp; 758 } 759 #ifndef __SGI_STL_NO_ARROW_OPERATOR 760 pointer operator->() const { return &(operator*()); } 761 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 762 763 self& operator++() { 764 --current; 765 return *this; 766 } 767 self operator++(int) { 768 self tmp = *this; 769 --current; 770 return tmp; 771 } 772 self& operator--() { 773 ++current; 774 return *this; 775 } 776 self operator--(int) { 777 self tmp = *this; 778 ++current; 779 return tmp; 780 } 781 782 self operator+(difference_type n) const { 783 return self(current - n); 784 } 785 self& operator+=(difference_type n) { 786 current -= n; 787 return *this; 788 } 789 self operator-(difference_type n) const { 790 return self(current + n); 791 } 792 self& operator-=(difference_type n) { 793 current += n; 794 return *this; 795 } 796 reference operator[](difference_type n) const { return *(*this + n); } 797 }; 798 799 template <class Iterator> 800 inline bool operator==(const reverse_iterator<Iterator>& x, 801 const reverse_iterator<Iterator>& y) 802 { 803 return x.base() == y.base(); 804 } 805 806 template <class Iterator> 807 inline bool operator<(const reverse_iterator<Iterator>& x, 808 const reverse_iterator<Iterator>& y) 809 { 810 return y.base() < x.base(); 811 } 812 813 template <class Iterator> 814 inline typename reverse_iterator<Iterator>::difference_type 815 operator-(const reverse_iterator<Iterator>& x, 816 const reverse_iterator<Iterator>& y) 817 { 818 return y.base() - x.base(); 819 } 820 821 template <class Iterator> 822 inline reverse_iterator<Iterator> 823 operator+(reverse_iterator<Iterator>::difference_type n, 824 const reverse_iterator<Iterator>& x) 825 { 826 return reverse_iterator<Iterator>(x.base() - n); 827 } 828 829 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 830 831 // 如果不支持partial specialization of class templates(模板类偏特化) 832 // 则使用HP STL的实现 833 834 // This is the old version of reverse_iterator, as found in the original 835 // HP STL. It does not use partial specialization. 836 837 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 838 template <class RandomAccessIterator, class T, class Reference = T&, 839 class Distance = ptrdiff_t> 840 #else 841 template <class RandomAccessIterator, class T, class Reference, 842 class Distance> 843 #endif 844 class reverse_iterator 845 { 846 typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance> 847 self; 848 protected: 849 RandomAccessIterator current; 850 public: 851 typedef random_access_iterator_tag iterator_category; 852 typedef T value_type; 853 typedef Distance difference_type; 854 typedef T* pointer; 855 typedef Reference reference; 856 857 reverse_iterator() {} 858 explicit reverse_iterator(RandomAccessIterator x) : current(x) {} 859 RandomAccessIterator base() const { return current; } 860 Reference operator*() const { return *(current - 1); } 861 #ifndef __SGI_STL_NO_ARROW_OPERATOR 862 pointer operator->() const { return &(operator*()); } 863 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 864 self& operator++() { 865 --current; 866 return *this; 867 } 868 self operator++(int) { 869 self tmp = *this; 870 --current; 871 return tmp; 872 } 873 self& operator--() { 874 ++current; 875 return *this; 876 } 877 self operator--(int) { 878 self tmp = *this; 879 ++current; 880 return tmp; 881 } 882 self operator+(Distance n) const { 883 return self(current - n); 884 } 885 self& operator+=(Distance n) { 886 current -= n; 887 return *this; 888 } 889 self operator-(Distance n) const { 890 return self(current + n); 891 } 892 self& operator-=(Distance n) { 893 current += n; 894 return *this; 895 } 896 Reference operator[](Distance n) const { return *(*this + n); } 897 }; 898 899 template <class RandomAccessIterator, class T, class Reference, class Distance> 900 inline random_access_iterator_tag 901 iterator_category(const reverse_iterator<RandomAccessIterator, T, 902 Reference, Distance>&) 903 { 904 return random_access_iterator_tag(); 905 } 906 907 template <class RandomAccessIterator, class T, class Reference, class Distance> 908 inline T* value_type(const reverse_iterator<RandomAccessIterator, T, 909 Reference, Distance>&) 910 { 911 return (T*) 0; 912 } 913 914 template <class RandomAccessIterator, class T, class Reference, class Distance> 915 inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T, 916 Reference, Distance>&) 917 { 918 return (Distance*) 0; 919 } 920 921 922 template <class RandomAccessIterator, class T, class Reference, class Distance> 923 inline bool operator==(const reverse_iterator<RandomAccessIterator, T, 924 Reference, Distance>& x, 925 const reverse_iterator<RandomAccessIterator, T, 926 Reference, Distance>& y) 927 { 928 return x.base() == y.base(); 929 } 930 931 template <class RandomAccessIterator, class T, class Reference, class Distance> 932 inline bool operator<(const reverse_iterator<RandomAccessIterator, T, 933 Reference, Distance>& x, 934 const reverse_iterator<RandomAccessIterator, T, 935 Reference, Distance>& y) 936 { 937 return y.base() < x.base(); 938 } 939 940 template <class RandomAccessIterator, class T, class Reference, class Distance> 941 inline Distance operator-(const reverse_iterator<RandomAccessIterator, T, 942 Reference, Distance>& x, 943 const reverse_iterator<RandomAccessIterator, T, 944 Reference, Distance>& y) 945 { 946 return y.base() - x.base(); 947 } 948 949 template <class RandomAccessIter, class T, class Ref, class Dist> 950 inline reverse_iterator<RandomAccessIter, T, Ref, Dist> 951 operator+(Dist n, const reverse_iterator<RandomAccessIter, T, Ref, Dist>& x) 952 { 953 return reverse_iterator<RandomAccessIter, T, Ref, Dist>(x.base() - n); 954 } 955 956 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 957 958 //// 959 // istream_iterator实现部分 960 //// 961 962 template <class T, class Distance = ptrdiff_t> 963 class istream_iterator 964 { 965 friend bool 966 operator== __STL_NULL_TMPL_ARGS (const istream_iterator<T, Distance>& x, 967 const istream_iterator<T, Distance>& y); 968 protected: 969 istream* stream; 970 T value; 971 bool end_marker; 972 void read() { 973 end_marker = (*stream) ? true : false; 974 if (end_marker) *stream >> value; 975 end_marker = (*stream) ? true : false; 976 } 977 public: 978 typedef input_iterator_tag iterator_category; 979 typedef T value_type; 980 typedef Distance difference_type; 981 typedef const T* pointer; 982 typedef const T& reference; 983 984 istream_iterator() : stream(&cin), end_marker(false) {} 985 istream_iterator(istream& s) : stream(&s) { read(); } 986 reference operator*() const { return value; } 987 #ifndef __SGI_STL_NO_ARROW_OPERATOR 988 pointer operator->() const { return &(operator*()); } 989 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 990 istream_iterator<T, Distance>& operator++() { 991 read(); 992 return *this; 993 } 994 istream_iterator<T, Distance> operator++(int) { 995 istream_iterator<T, Distance> tmp = *this; 996 read(); 997 return tmp; 998 } 999 }; 1000 1001 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 1002 1003 template <class T, class Distance> 1004 inline input_iterator_tag 1005 iterator_category(const istream_iterator<T, Distance>&) 1006 { 1007 return input_iterator_tag(); 1008 } 1009 1010 template <class T, class Distance> 1011 inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; } 1012 1013 template <class T, class Distance> 1014 inline Distance* distance_type(const istream_iterator<T, Distance>&) 1015 { 1016 return (Distance*) 0; 1017 } 1018 1019 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 1020 1021 template <class T, class Distance> 1022 inline bool operator==(const istream_iterator<T, Distance>& x, 1023 const istream_iterator<T, Distance>& y) 1024 { 1025 return x.stream == y.stream && x.end_marker == y.end_marker || 1026 x.end_marker == false && y.end_marker == false; 1027 } 1028 1029 //// 1030 // ostream_iterator实现部分 1031 //// 1032 1033 template <class T> 1034 class ostream_iterator 1035 { 1036 protected: 1037 ostream* stream; 1038 const char* string; 1039 public: 1040 typedef output_iterator_tag iterator_category; 1041 typedef void value_type; 1042 typedef void difference_type; 1043 typedef void pointer; 1044 typedef void reference; 1045 1046 ostream_iterator(ostream& s) : stream(&s), string(0) {} 1047 ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} 1048 ostream_iterator<T>& operator=(const T& value) { 1049 *stream << value; 1050 if (string) *stream << string; 1051 return *this; 1052 } 1053 ostream_iterator<T>& operator*() { return *this; } 1054 ostream_iterator<T>& operator++() { return *this; } 1055 ostream_iterator<T>& operator++(int) { return *this; } 1056 }; 1057 1058 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 1059 1060 template <class T> 1061 inline output_iterator_tag 1062 iterator_category(const ostream_iterator<T>&) 1063 { 1064 return output_iterator_tag(); 1065 } 1066 1067 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 1068 1069 __STL_END_NAMESPACE 1070 1071 #endif /* __SGI_STL_INTERNAL_ITERATOR_H */ 1072 1073 // Local Variables: 1074 // mode:C++ 1075 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: type_traits.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1997 10 * Silicon Graphics Computer Systems, Inc. 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Silicon Graphics makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 */ 20 21 #ifndef __TYPE_TRAITS_H 22 #define __TYPE_TRAITS_H 23 24 #ifndef __STL_CONFIG_H 25 #include <stl_config.h> 26 #endif 27 28 // 这个头文件提供了一个框架, 允许编译器在编译期根据类型属性派发函数的机制 29 // 这个框架对于编写模板代码非常有用 30 // 例如, 当我们需要拷贝一个未知类型的array, 它能帮助我们得知这个未知类型 31 // 是否具有一个trivial copy constructor, 以帮助我们决定memcpy()是否能使用 32 33 // __type_traits模板类提供了一些列的typedefs, 其值是__true_type或者__false_type 34 // __type_traits模板类可以接受任何类型的参数 35 // 模板类中的typedefs可以通过以下手段获取其正确值 36 // 1. general instantiation, 对于所有类型都要有保守值 37 // 2. 经过特化的版本 38 // 3. 一些编译器(例如Silicon Graphics N32 and N64 compilers) 39 // 会自动给所有类型提供合适的特化版本 40 // 41 // 例子: 42 // Copy an array of elements which have non-trivial copy constructors 43 // template <class T> void copy(T* source,T* destination,int n,__false_type); 44 // Copy an array of elements which have trivial copy constructors. Use memcpy. 45 // template <class T> void copy(T* source,T* destination,int n,__true_type); 46 // 47 // Copy an array of any type by using the most efficient copy mechanism 48 // template <class T> inline void copy(T* source,T* destination,int n) 49 // { 50 // copy(source,destination,n, 51 // typename __type_traits<T>::has_trivial_copy_constructor()); 52 // } 53 54 struct __true_type 55 { 56 }; 57 58 struct __false_type 59 { 60 }; 61 62 template <class type> 63 struct __type_traits 64 { 65 // 不要移除这个成员 66 // 它通知能自动特化__type_traits的编译器, 现在这个__type_traits template是特化的 67 // 这是为了确保万一编译器使用了__type_traits而与此处无任何关联的模板时 68 // 一切也能顺利运作 69 typedef __true_type this_dummy_member_must_be_first; 70 71 // 以下条款应当被遵守, 因为编译器有可能自动生成类型的特化版本 72 // - 你可以重新安排的成员次序 73 // - 你可以移除你想移除的成员 74 // - 一定不可以修改下列成员名称, 却没有修改编译器中的相应名称 75 // - 新加入的成员被当作一般成员, 除非编译器提供特殊支持 76 77 typedef __false_type has_trivial_default_constructor; 78 typedef __false_type has_trivial_copy_constructor; 79 typedef __false_type has_trivial_assignment_operator; 80 typedef __false_type has_trivial_destructor; 81 typedef __false_type is_POD_type; 82 }; 83 84 85 // 以下针对C++内置的基本数据类型提供特化版本, 使其具有trivial default constructor, 86 // copy constructor, assignment operator, destructor 87 // 并标记其为POD类型 88 // 89 // 特化类型: 90 // char, signed char, unsigned char, 91 // short, unsigned short 92 // int, unsigned int 93 // long, unsigned long 94 // float, double, long double 95 96 // Provide some specializations. This is harmless for compilers that 97 // have built-in __types_traits support, and essential for compilers 98 // that don't. 99 100 __STL_TEMPLATE_NULL struct __type_traits<char> 101 { 102 typedef __true_type has_trivial_default_constructor; 103 typedef __true_type has_trivial_copy_constructor; 104 typedef __true_type has_trivial_assignment_operator; 105 typedef __true_type has_trivial_destructor; 106 typedef __true_type is_POD_type; 107 }; 108 109 __STL_TEMPLATE_NULL struct __type_traits<signed char> 110 { 111 typedef __true_type has_trivial_default_constructor; 112 typedef __true_type has_trivial_copy_constructor; 113 typedef __true_type has_trivial_assignment_operator; 114 typedef __true_type has_trivial_destructor; 115 typedef __true_type is_POD_type; 116 }; 117 118 __STL_TEMPLATE_NULL struct __type_traits<unsigned char> 119 { 120 typedef __true_type has_trivial_default_constructor; 121 typedef __true_type has_trivial_copy_constructor; 122 typedef __true_type has_trivial_assignment_operator; 123 typedef __true_type has_trivial_destructor; 124 typedef __true_type is_POD_type; 125 }; 126 127 __STL_TEMPLATE_NULL struct __type_traits<short> 128 { 129 typedef __true_type has_trivial_default_constructor; 130 typedef __true_type has_trivial_copy_constructor; 131 typedef __true_type has_trivial_assignment_operator; 132 typedef __true_type has_trivial_destructor; 133 typedef __true_type is_POD_type; 134 }; 135 136 __STL_TEMPLATE_NULL struct __type_traits<unsigned short> 137 { 138 typedef __true_type has_trivial_default_constructor; 139 typedef __true_type has_trivial_copy_constructor; 140 typedef __true_type has_trivial_assignment_operator; 141 typedef __true_type has_trivial_destructor; 142 typedef __true_type is_POD_type; 143 }; 144 145 __STL_TEMPLATE_NULL struct __type_traits<int> 146 { 147 typedef __true_type has_trivial_default_constructor; 148 typedef __true_type has_trivial_copy_constructor; 149 typedef __true_type has_trivial_assignment_operator; 150 typedef __true_type has_trivial_destructor; 151 typedef __true_type is_POD_type; 152 }; 153 154 __STL_TEMPLATE_NULL struct __type_traits<unsigned int> 155 { 156 typedef __true_type has_trivial_default_constructor; 157 typedef __true_type has_trivial_copy_constructor; 158 typedef __true_type has_trivial_assignment_operator; 159 typedef __true_type has_trivial_destructor; 160 typedef __true_type is_POD_type; 161 }; 162 163 __STL_TEMPLATE_NULL struct __type_traits<long> 164 { 165 typedef __true_type has_trivial_default_constructor; 166 typedef __true_type has_trivial_copy_constructor; 167 typedef __true_type has_trivial_assignment_operator; 168 typedef __true_type has_trivial_destructor; 169 typedef __true_type is_POD_type; 170 }; 171 172 __STL_TEMPLATE_NULL struct __type_traits<unsigned long> 173 { 174 typedef __true_type has_trivial_default_constructor; 175 typedef __true_type has_trivial_copy_constructor; 176 typedef __true_type has_trivial_assignment_operator; 177 typedef __true_type has_trivial_destructor; 178 typedef __true_type is_POD_type; 179 }; 180 181 __STL_TEMPLATE_NULL struct __type_traits<float> 182 { 183 typedef __true_type has_trivial_default_constructor; 184 typedef __true_type has_trivial_copy_constructor; 185 typedef __true_type has_trivial_assignment_operator; 186 typedef __true_type has_trivial_destructor; 187 typedef __true_type is_POD_type; 188 }; 189 190 __STL_TEMPLATE_NULL struct __type_traits<double> 191 { 192 typedef __true_type has_trivial_default_constructor; 193 typedef __true_type has_trivial_copy_constructor; 194 typedef __true_type has_trivial_assignment_operator; 195 typedef __true_type has_trivial_destructor; 196 typedef __true_type is_POD_type; 197 }; 198 199 __STL_TEMPLATE_NULL struct __type_traits<long double> 200 { 201 typedef __true_type has_trivial_default_constructor; 202 typedef __true_type has_trivial_copy_constructor; 203 typedef __true_type has_trivial_assignment_operator; 204 typedef __true_type has_trivial_destructor; 205 typedef __true_type is_POD_type; 206 }; 207 208 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 209 210 // 针对指针提供特化 211 template <class T> 212 struct __type_traits<T*> 213 { 214 typedef __true_type has_trivial_default_constructor; 215 typedef __true_type has_trivial_copy_constructor; 216 typedef __true_type has_trivial_assignment_operator; 217 typedef __true_type has_trivial_destructor; 218 typedef __true_type is_POD_type; 219 }; 220 221 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 222 223 // 针对char *, signed char *, unsigned char *提供特化 224 225 struct __type_traits<char*> 226 { 227 typedef __true_type has_trivial_default_constructor; 228 typedef __true_type has_trivial_copy_constructor; 229 typedef __true_type has_trivial_assignment_operator; 230 typedef __true_type has_trivial_destructor; 231 typedef __true_type is_POD_type; 232 }; 233 234 struct __type_traits<signed char*> 235 { 236 typedef __true_type has_trivial_default_constructor; 237 typedef __true_type has_trivial_copy_constructor; 238 typedef __true_type has_trivial_assignment_operator; 239 typedef __true_type has_trivial_destructor; 240 typedef __true_type is_POD_type; 241 }; 242 243 struct __type_traits<unsigned char*> 244 { 245 typedef __true_type has_trivial_default_constructor; 246 typedef __true_type has_trivial_copy_constructor; 247 typedef __true_type has_trivial_assignment_operator; 248 typedef __true_type has_trivial_destructor; 249 typedef __true_type is_POD_type; 250 }; 251 252 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 253 254 255 #endif /* __TYPE_TRAITS_H */ 256 257 // Local Variables: 258 // mode:C++ 259 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_vector.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_VECTOR_H 38 #define __SGI_STL_INTERNAL_VECTOR_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 47 //// 48 // 49 //// 50 51 52 // 默认allocator为alloc, 其具体使用版本请参照<stl_alloc.h> 53 template <class T, class Alloc = alloc> 54 class vector 55 { 56 public: 57 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 58 typedef T value_type; // STL标准强制要求 59 typedef value_type* pointer; // STL标准强制要求 60 typedef const value_type* const_pointer; 61 // 由于vector的特性, 一般我们实作的时候都分配给其连续的内存空间, 62 // 所以其迭代器只需要定义成原生指针即可满足需要 63 typedef value_type* iterator; // STL标准强制要求 64 typedef const value_type* const_iterator; 65 typedef value_type& reference; // STL标准强制要求 66 typedef const value_type& const_reference; 67 typedef size_t size_type; 68 typedef ptrdiff_t difference_type; // STL标准强制要求 69 70 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 71 typedef reverse_iterator<const_iterator> const_reverse_iterator; 72 typedef reverse_iterator<iterator> reverse_iterator; 73 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 74 typedef reverse_iterator<const_iterator, value_type, const_reference, 75 difference_type> const_reverse_iterator; 76 typedef reverse_iterator<iterator, value_type, reference, difference_type> 77 reverse_iterator; 78 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 79 80 protected: 81 // 这个提供STL标准的allocator接口 82 typedef simple_alloc<value_type, Alloc> data_allocator; 83 84 iterator start; // 内存空间起始点 85 iterator finish; // 当前使用的内存空间结束点 86 iterator end_of_storage; // 实际分配内存空间的结束点 87 88 void insert_aux(iterator position, const T& x); 89 90 // 释放分配的内存空间 91 void deallocate() 92 { 93 // 由于使用的是data_allocator进行内存空间的分配, 94 // 所以需要同样嗲用data_allocator::deallocate()进行释放 95 // 如果直接释放, 对于data_allocator内部使用内存池的版本 96 // 就会发生错误 97 if (start) data_allocator::deallocate(start, end_of_storage - start); 98 } 99 100 void fill_initialize(size_type n, const T& value) 101 { 102 start = allocate_and_fill(n, value); 103 finish = start + n; // 设置当前使用内存空间的结束点 104 // 构造阶段, 此实作不多分配内存, 105 // 所以要设置内存空间结束点和, 已经使用的内存空间结束点相同 106 end_of_storage = finish; 107 } 108 109 public: 110 // 获取几种迭代器 111 iterator begin() { return start; } 112 const_iterator begin() const { return start; } 113 iterator end() { return finish; } 114 const_iterator end() const { return finish; } 115 reverse_iterator rbegin() { return reverse_iterator(end()); } 116 const_reverse_iterator rbegin() const { 117 return const_reverse_iterator(end()); 118 } 119 reverse_iterator rend() { return reverse_iterator(begin()); } 120 const_reverse_iterator rend() const { 121 return const_reverse_iterator(begin()); 122 } 123 124 // 返回当前对象个数 125 size_type size() const { return size_type(end() - begin()); } 126 size_type max_size() const { return size_type(-1) / sizeof(T); } 127 // 返回重新分配内存前最多能存储的对象个数 128 size_type capacity() const { return size_type(end_of_storage - begin()); } 129 bool empty() const { return begin() == end(); } 130 reference operator[](size_type n) { return *(begin() + n); } 131 const_reference operator[](size_type n) const { return *(begin() + n); } 132 133 // 本实作中默认构造出的vector不分配内存空间 134 vector() : start(0), finish(0), end_of_storage(0) {} 135 136 //// 137 // 本实作中给定个数和对象, 则只分配所需内存, 不会多分配 138 //// 139 // vector(size_type n, const T& value) 140 // ↓ 141 // fill_initialize(n, value) 142 // ↓ 143 // allocate_and_fill(n, value) 144 // ↓ 145 // data_allocator::allocate(n) <stl_alloc.h> 146 // uninitialized_fill_n(result, n, x) <stl_uninitialized.h> 147 //// 148 149 vector(size_type n, const T& value) { fill_initialize(n, value); } 150 vector(int n, const T& value) { fill_initialize(n, value); } 151 vector(long n, const T& value) { fill_initialize(n, value); } 152 153 // 需要对象提供默认构造函数 154 explicit vector(size_type n) { fill_initialize(n, T()); } 155 156 //// 157 // 复制构造, 同样不会多分配内存 158 //// 159 // vector(const vector<T, Alloc>& x) 160 // ↓ 161 // allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); 162 // ↓ 163 // data_allocator::allocate(n) <stl_alloc.h> 164 // uninitialized_copy(first, last, result); <stl_uninitialized.h> 165 //// 166 167 vector(const vector<T, Alloc>& x) 168 { 169 start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); 170 finish = start + (x.end() - x.begin()); 171 end_of_storage = finish; 172 } 173 174 // 复制指定区间的元素, 同样不多分配内存 175 #ifdef __STL_MEMBER_TEMPLATES 176 //// 177 // 复制一个区间进行构造, 可能会导致多分配内存 178 //// 179 // vector(InputIterator first, InputIterator last) 180 // ↓ 181 // range_initialize(first, last, iterator_category(first)); 182 // ↓ 183 // for ( ; first != last; ++first) 184 // push_back(*first); 185 // 由于使用push_back()操作, 可能导致多次重复分配内存,个人感觉应该先 186 // data_allocator::allocate((last - first) * sizeof(T)); 187 // 然后uninitialized_copy(first, last, result); 188 // 这样不会多分配内存, 也不会导致多次重新分配内存问题 189 //// 190 191 template <class InputIterator> 192 vector(InputIterator first, InputIterator last) : 193 start(0), finish(0), end_of_storage(0) 194 { 195 range_initialize(first, last, iterator_category(first)); 196 } 197 #else /* __STL_MEMBER_TEMPLATES */ 198 199 //// 200 // 复制一个区间进行构造, 可能会导致多分配内存 201 //// 202 // vector(const_iterator first, const_iterator last) 203 // ↓ 204 // distance(first, last, n); 205 // ↓ 206 // allocate_and_copy(n, first, last); 207 // ↓ 208 // data_allocator::allocate(n) <stl_alloc.h> 209 // uninitialized_copy(first, last, result); <stl_uninitialized.h> 210 //// 211 212 vector(const_iterator first, const_iterator last) { 213 size_type n = 0; 214 distance(first, last, n); 215 start = allocate_and_copy(n, first, last); 216 finish = start + n; 217 end_of_storage = finish; 218 } 219 #endif /* __STL_MEMBER_TEMPLATES */ 220 221 ~vector() 222 { 223 // 析构对象 224 destroy(start, finish); 225 // 释放内存 226 deallocate(); 227 } 228 229 vector<T, Alloc>& operator=(const vector<T, Alloc>& x); 230 231 //// 232 // 预留一定空间, 如果n < capacity(), 并不会减少空间 233 //// 234 // reserve(size_type n) 235 // ↓ 236 // allocate_and_copy(n, start, finish) 237 // destroy(start, finish); <stl_construct.h> 238 // deallocate(); 239 //// 240 241 void reserve(size_type n) 242 { 243 if (capacity() < n) { 244 const size_type old_size = size(); 245 iterator tmp = allocate_and_copy(n, start, finish); 246 destroy(start, finish); 247 deallocate(); 248 start = tmp; 249 finish = tmp + old_size; 250 end_of_storage = start + n; 251 } 252 } 253 254 // 提供访问函数 255 reference front() { return *begin(); } 256 const_reference front() const { return *begin(); } 257 reference back() { return *(end() - 1); } 258 const_reference back() const { return *(end() - 1); } 259 260 //// 261 // 向容器尾追加一个元素, 可能导致内存重新分配 262 //// 263 // push_back(const T& x) 264 // | 265 // |---------------- 容量已满? 266 // | 267 // ---------------------------- 268 // No | | Yes 269 // | | 270 // ↓ ↓ 271 // construct(finish, x); insert_aux(end(), x); 272 // ++finish; | 273 // |------ 内存不足, 重新分配 274 // | 大小为原来的2倍 275 // new_finish = data_allocator::allocate(len); <stl_alloc.h> 276 // uninitialized_copy(start, position, new_start); <stl_uninitialized.h> 277 // construct(new_finish, x); <stl_construct.h> 278 // ++new_finish; 279 // uninitialized_copy(position, finish, new_finish); <stl_uninitialized.h> 280 //// 281 282 void push_back(const T& x) 283 { 284 // 内存满足条件则直接追加元素, 否则需要重新分配内存空间 285 if (finish != end_of_storage) { 286 construct(finish, x); 287 ++finish; 288 } 289 else 290 insert_aux(end(), x); 291 } 292 293 // 交换两个vector, 实际上是交换内部的状态指针 294 void swap(vector<T, Alloc>& x) 295 { 296 __STD::swap(start, x.start); 297 __STD::swap(finish, x.finish); 298 __STD::swap(end_of_storage, x.end_of_storage); 299 } 300 301 //// 302 // 在指定位置插入元素 303 //// 304 // insert(iterator position, const T& x) 305 // | 306 // |------------ 容量是否足够 && 是否是end()? 307 // | 308 // ------------------------------------------- 309 // No | | Yes 310 // | | 311 // ↓ ↓ 312 // insert_aux(position, x); construct(finish, x); 313 // | ++finish; 314 // |-------- 容量是否够用? 315 // | 316 // -------------------------------------------------- 317 // Yes | | No 318 // | | 319 // ↓ | 320 // construct(finish, *(finish - 1)); | 321 // ++finish; | 322 // T x_copy = x; | 323 // copy_backward(position, finish - 2, finish - 1); | 324 // *position = x_copy; | 325 // ↓ 326 // data_allocator::allocate(len); <stl_alloc.h> 327 // uninitialized_copy(start, position, new_start); <stl_uninitialized.h> 328 // construct(new_finish, x); <stl_construct.h> 329 // ++new_finish; 330 // uninitialized_copy(position, finish, new_finish); <stl_uninitialized.h> 331 // destroy(begin(), end()); <stl_construct.h> 332 // deallocate(); 333 //// 334 335 iterator insert(iterator position, const T& x) 336 { 337 size_type n = position - begin(); 338 if (finish != end_of_storage && position == end()) { 339 construct(finish, x); 340 ++finish; 341 } 342 else 343 insert_aux(position, x); 344 return begin() + n; 345 } 346 347 iterator insert(iterator position) { return insert(position, T()); } 348 349 #ifdef __STL_MEMBER_TEMPLATES 350 //// 351 // 在指定位置插入一个区间 352 //// 353 // insert(iterator position, InputIterator first, InputIterator last) 354 // ↓ 355 // range_insert(position, first, last, iterator_category(first)); 356 // ↓ 357 // for ( ; first != last; ++first) { 358 // pos = insert(pos, *first); 359 // ++pos; 360 // } 361 //// 362 363 template <class InputIterator> 364 void insert(iterator position, InputIterator first, InputIterator last) 365 { 366 range_insert(position, first, last, iterator_category(first)); 367 } 368 #else /* __STL_MEMBER_TEMPLATES */ 369 void insert(iterator position, 370 const_iterator first, const_iterator last); 371 #endif /* __STL_MEMBER_TEMPLATES */ 372 373 void insert (iterator pos, size_type n, const T& x); 374 375 void insert (iterator pos, int n, const T& x) 376 { 377 insert(pos, (size_type) n, x); 378 } 379 380 void insert (iterator pos, long n, const T& x) 381 { 382 insert(pos, (size_type) n, x); 383 } 384 385 void pop_back() 386 { 387 --finish; 388 destroy(finish); 389 } 390 391 iterator erase(iterator position) 392 { 393 if (position + 1 != end()) 394 copy(position + 1, finish, position); 395 --finish; 396 destroy(finish); 397 return position; 398 } 399 400 //// 401 // 擦除指定区间的元素 402 //// 403 // erase(iterator first, iterator last) 404 // ↓ 405 // ---------- copy(last, finish, first); <stl_algobase.h> 406 // | destroy(i, finish); <stl_construct.h> 407 // | 408 // | -------------- copy(...) 409 // | 特化 | char *特化 memmove() 410 // ---------------------------------------| 411 // | 泛化 | wchar_t特化 copy(...) 412 // | -------------- memmove() 413 // | 414 // 调用__copy_dispatch<InputIterator,OutputIterator>()(first, last, result); 415 // 进行__copy(first, last, result, iterator_category(first));派发 416 // | 417 // | 418 // | random_access_iterator_tag 419 // -------------------------------------------------------------- 420 // | input_iterator_tag | 421 // | | 422 // ↓ | 423 // __copy(..., input_iterator_tag) | 424 // for ( ; first != last; ++result, ++first) | 425 // *result = *first; ↓ 426 // __copy(..., random_access_iterator_tag) 427 // __copy_d(first, last, result, distance_type(first)); 428 // | 429 // | 430 // ↓ 431 // for (Distance n = last - first; n > 0; --n, ++result, ++first) 432 // *result = *first; 433 //// 434 iterator erase(iterator first, iterator last) 435 { 436 iterator i = copy(last, finish, first); 437 // 析构掉需要析构的元素 438 destroy(i, finish); 439 finish = finish - (last - first); 440 return first; 441 } 442 443 // 调整size, 但是并不会重新分配内存空间 444 void resize(size_type new_size, const T& x) 445 { 446 if (new_size < size()) 447 erase(begin() + new_size, end()); 448 else 449 insert(end(), new_size - size(), x); 450 } 451 void resize(size_type new_size) { resize(new_size, T()); } 452 453 void clear() { erase(begin(), end()); } 454 455 protected: 456 // 分配空间, 并且复制对象到分配的空间处 457 iterator allocate_and_fill(size_type n, const T& x) 458 { 459 iterator result = data_allocator::allocate(n); 460 __STL_TRY { 461 uninitialized_fill_n(result, n, x); 462 return result; 463 } 464 __STL_UNWIND(data_allocator::deallocate(result, n)); 465 } 466 467 // 分配空间并且拷贝一个区间的元素到新分配空间处 468 #ifdef __STL_MEMBER_TEMPLATES 469 template <class ForwardIterator> 470 iterator allocate_and_copy(size_type n, 471 ForwardIterator first, ForwardIterator last) 472 { 473 iterator result = data_allocator::allocate(n); 474 __STL_TRY { 475 uninitialized_copy(first, last, result); 476 return result; 477 } 478 __STL_UNWIND(data_allocator::deallocate(result, n)); 479 } 480 #else /* __STL_MEMBER_TEMPLATES */ 481 iterator allocate_and_copy(size_type n, 482 const_iterator first, const_iterator last) 483 { 484 iterator result = data_allocator::allocate(n); 485 __STL_TRY { 486 uninitialized_copy(first, last, result); 487 return result; 488 } 489 __STL_UNWIND(data_allocator::deallocate(result, n)); 490 } 491 #endif /* __STL_MEMBER_TEMPLATES */ 492 493 494 #ifdef __STL_MEMBER_TEMPLATES 495 // 初始化一个区间, 使用push_back()操作, 可能引发内存多次重新分配 496 // 解决方案见 497 // template <class InputIterator> 498 // vector(InputIterator first, InputIterator last) 499 // 我评注部分 500 template <class InputIterator> 501 void range_initialize(InputIterator first, InputIterator last, 502 input_iterator_tag) 503 { 504 for ( ; first != last; ++first) 505 push_back(*first); 506 } 507 508 // This function is only called by the constructor. We have to worry 509 // about resource leaks, but not about maintaining invariants. 510 template <class ForwardIterator> 511 void range_initialize(ForwardIterator first, ForwardIterator last, 512 forward_iterator_tag) 513 { 514 size_type n = 0; 515 distance(first, last, n); 516 start = allocate_and_copy(n, first, last); 517 finish = start + n; 518 end_of_storage = finish; 519 } 520 521 template <class InputIterator> 522 void range_insert(iterator pos, 523 InputIterator first, InputIterator last, 524 input_iterator_tag); 525 526 template <class ForwardIterator> 527 void range_insert(iterator pos, 528 ForwardIterator first, ForwardIterator last, 529 forward_iterator_tag); 530 531 #endif /* __STL_MEMBER_TEMPLATES */ 532 }; 533 534 //// 535 // vector实现部分 536 //// 537 538 template <class T, class Alloc> 539 inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) 540 { 541 return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); 542 } 543 544 // 字典序比较 545 template <class T, class Alloc> 546 inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) 547 { 548 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); 549 } 550 551 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 552 553 template <class T, class Alloc> 554 inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) 555 { 556 x.swap(y); 557 } 558 559 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 560 561 //// 562 // 重载赋值运算符 563 //// 564 // operator=(const vector<T, Alloc>& x) 565 // | 566 // |---------------- 是否是自赋值? 567 // ↓ 568 // ----------------------------------------- 569 // No | | Yes 570 // | | 571 // ↓ |------- 容量判断 572 // return *this; | 573 // ↓ 574 // ----------------------------------------------------------------- 575 // |x.size() > capacity() | size() >= x.size() | other 576 // | | | 577 // ↓ ↓ | 578 // 容量不足, 需要重新分配 容量足够, 只需要析构掉多余的对象 | 579 // allocate_and_copy( copy(x.begin(), x.end(), begin()); | 580 // x.end() - x.begin(), destroy(i, finish); | 581 // x.begin(), x.end()); | 582 // destroy(start, finish); | 583 // deallocate(); ↓ 584 // copy(x.begin(), x.begin() + size(), start); 585 // uninitialized_copy(x.begin() + size(), x.end(), finish); 586 //// 587 588 template <class T, class Alloc> 589 vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) 590 { 591 if (&x != this) { 592 // 如果x.size() > capacity()那么就需要重新分配内存 593 // 首先分配内存, 并将容器内原来的元素拷贝到新分配内存中 594 // 然后析构原容器中元素, 调整内存状态变量 595 if (x.size() > capacity()) { 596 iterator tmp = allocate_and_copy(x.end() - x.begin(), 597 x.begin(), x.end()); 598 destroy(start, finish); 599 deallocate(); 600 start = tmp; 601 end_of_storage = start + (x.end() - x.begin()); 602 } 603 else if (size() >= x.size()) { 604 iterator i = copy(x.begin(), x.end(), begin()); 605 destroy(i, finish); 606 } 607 else { 608 copy(x.begin(), x.begin() + size(), start); 609 uninitialized_copy(x.begin() + size(), x.end(), finish); 610 } 611 finish = start + x.size(); 612 } 613 return *this; 614 } 615 616 //// 617 // 提供插入操作 618 //// 619 // insert_aux(iterator position, const T& x) 620 // | 621 // |---------------- 容量是否足够? 622 // ↓ 623 // ----------------------------------------- 624 // Yes | | No 625 // | | 626 // ↓ | 627 // 从opsition开始, 整体向后移动一个位置 | 628 // construct(finish, *(finish - 1)); | 629 // ++finish; | 630 // T x_copy = x; | 631 // copy_backward(position, finish - 2, finish - 1); | 632 // *position = x_copy; | 633 // ↓ 634 // data_allocator::allocate(len); 635 // uninitialized_copy(start, position, new_start); 636 // construct(new_finish, x); 637 // ++new_finish; 638 // uninitialized_copy(position, finish, new_finish); 639 // destroy(begin(), end()); 640 // deallocate(); 641 //// 642 643 template <class T, class Alloc> 644 void vector<T, Alloc>::insert_aux(iterator position, const T& x) 645 { 646 if (finish != end_of_storage) { // 还有剩余内存 647 construct(finish, *(finish - 1)); 648 ++finish; 649 T x_copy = x; 650 copy_backward(position, finish - 2, finish - 1); 651 *position = x_copy; 652 } 653 else { // 内存不足, 需要重新分配 654 // 本实作中是按原内存2倍进行重新分配 655 const size_type old_size = size(); 656 const size_type len = old_size != 0 ? 2 * old_size : 1; 657 iterator new_start = data_allocator::allocate(len); 658 iterator new_finish = new_start; 659 // 将内存重新配置 660 __STL_TRY { 661 new_finish = uninitialized_copy(start, position, new_start); 662 construct(new_finish, x); 663 ++new_finish; 664 new_finish = uninitialized_copy(position, finish, new_finish); 665 } 666 // 分配失败则抛出异常 667 # ifdef __STL_USE_EXCEPTIONS 668 catch(...) { 669 destroy(new_start, new_finish); 670 data_allocator::deallocate(new_start, len); 671 throw; 672 } 673 # endif /* __STL_USE_EXCEPTIONS */ 674 // 析构原容器中的对象 675 destroy(begin(), end()); 676 // 释放原容器分配的内存 677 deallocate(); 678 // 调整内存指针状态 679 start = new_start; 680 finish = new_finish; 681 end_of_storage = new_start + len; 682 } 683 } 684 685 //// 686 // 在指定位置插入n个元素 687 //// 688 // insert(iterator position, size_type n, const T& x) 689 // | 690 // |---------------- 插入元素个数是否为0? 691 // ↓ 692 // ----------------------------------------- 693 // No | | Yes 694 // | | 695 // | ↓ 696 // | return; 697 // |----------- 内存是否足够? 698 // | 699 // ------------------------------------------------- 700 // Yes | | No 701 // | | 702 // |------ (finish - position) > n? | 703 // | 分别调整指针 | 704 // ↓ | 705 // ---------------------------- | 706 // No | | Yes | 707 // | | | 708 // ↓ ↓ | 709 // 插入操作, 调整指针 插入操作, 调整指针 | 710 // ↓ 711 // data_allocator::allocate(len); 712 // new_finish = uninitialized_copy(start, position, new_start); 713 // new_finish = uninitialized_fill_n(new_finish, n, x); 714 // new_finish = uninitialized_copy(position, finish, new_finish); 715 // destroy(start, finish); 716 // deallocate(); 717 //// 718 719 template <class T, class Alloc> 720 void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) 721 { 722 // 如果n为0则不进行任何操作 723 if (n != 0) { 724 if (size_type(end_of_storage - finish) >= n) { // 剩下的内存够分配 725 T x_copy = x; 726 const size_type elems_after = finish - position; 727 iterator old_finish = finish; 728 if (elems_after > n) { 729 uninitialized_copy(finish - n, finish, finish); 730 finish += n; 731 copy_backward(position, old_finish - n, old_finish); 732 fill(position, position + n, x_copy); 733 } 734 else { 735 uninitialized_fill_n(finish, n - elems_after, x_copy); 736 finish += n - elems_after; 737 uninitialized_copy(position, old_finish, finish); 738 finish += elems_after; 739 fill(position, old_finish, x_copy); 740 } 741 } 742 else { // 剩下的内存不够分配, 需要重新分配 743 const size_type old_size = size(); 744 const size_type len = old_size + max(old_size, n); 745 iterator new_start = data_allocator::allocate(len); 746 iterator new_finish = new_start; 747 __STL_TRY { 748 new_finish = uninitialized_copy(start, position, new_start); 749 new_finish = uninitialized_fill_n(new_finish, n, x); 750 new_finish = uninitialized_copy(position, finish, new_finish); 751 } 752 # ifdef __STL_USE_EXCEPTIONS 753 catch(...) { 754 destroy(new_start, new_finish); 755 data_allocator::deallocate(new_start, len); 756 throw; 757 } 758 # endif /* __STL_USE_EXCEPTIONS */ 759 destroy(start, finish); 760 deallocate(); 761 start = new_start; 762 finish = new_finish; 763 end_of_storage = new_start + len; 764 } 765 } 766 } 767 768 #ifdef __STL_MEMBER_TEMPLATES 769 770 // 在指定位置插入指定区间的对象 771 template <class T, class Alloc> template <class InputIterator> 772 void vector<T, Alloc>::range_insert(iterator pos, 773 InputIterator first, InputIterator last, 774 input_iterator_tag) 775 { 776 for ( ; first != last; ++first) { 777 pos = insert(pos, *first); 778 ++pos; 779 } 780 } 781 782 template <class T, class Alloc> template <class ForwardIterator> 783 void vector<T, Alloc>::range_insert(iterator position, 784 ForwardIterator first, 785 ForwardIterator last, 786 forward_iterator_tag) 787 { 788 if (first != last) { 789 size_type n = 0; 790 distance(first, last, n); 791 if (size_type(end_of_storage - finish) >= n) { 792 const size_type elems_after = finish - position; 793 iterator old_finish = finish; 794 if (elems_after > n) { 795 uninitialized_copy(finish - n, finish, finish); 796 finish += n; 797 copy_backward(position, old_finish - n, old_finish); 798 copy(first, last, position); 799 } 800 else { 801 ForwardIterator mid = first; 802 advance(mid, elems_after); 803 uninitialized_copy(mid, last, finish); 804 finish += n - elems_after; 805 uninitialized_copy(position, old_finish, finish); 806 finish += elems_after; 807 copy(first, mid, position); 808 } 809 } 810 else { 811 const size_type old_size = size(); 812 const size_type len = old_size + max(old_size, n); 813 iterator new_start = data_allocator::allocate(len); 814 iterator new_finish = new_start; 815 __STL_TRY { 816 new_finish = uninitialized_copy(start, position, new_start); 817 new_finish = uninitialized_copy(first, last, new_finish); 818 new_finish = uninitialized_copy(position, finish, new_finish); 819 } 820 # ifdef __STL_USE_EXCEPTIONS 821 catch(...) { 822 destroy(new_start, new_finish); 823 data_allocator::deallocate(new_start, len); 824 throw; 825 } 826 # endif /* __STL_USE_EXCEPTIONS */ 827 destroy(start, finish); 828 deallocate(); 829 start = new_start; 830 finish = new_finish; 831 end_of_storage = new_start + len; 832 } 833 } 834 } 835 836 #else /* __STL_MEMBER_TEMPLATES */ 837 838 template <class T, class Alloc> 839 void vector<T, Alloc>::insert(iterator position, 840 const_iterator first, 841 const_iterator last) { 842 if (first != last) { 843 size_type n = 0; 844 distance(first, last, n); 845 if (size_type(end_of_storage - finish) >= n) { 846 const size_type elems_after = finish - position; 847 iterator old_finish = finish; 848 if (elems_after > n) { 849 uninitialized_copy(finish - n, finish, finish); 850 finish += n; 851 copy_backward(position, old_finish - n, old_finish); 852 copy(first, last, position); 853 } 854 else { 855 uninitialized_copy(first + elems_after, last, finish); 856 finish += n - elems_after; 857 uninitialized_copy(position, old_finish, finish); 858 finish += elems_after; 859 copy(first, first + elems_after, position); 860 } 861 } 862 else { 863 const size_type old_size = size(); 864 const size_type len = old_size + max(old_size, n); 865 iterator new_start = data_allocator::allocate(len); 866 iterator new_finish = new_start; 867 __STL_TRY { 868 new_finish = uninitialized_copy(start, position, new_start); 869 new_finish = uninitialized_copy(first, last, new_finish); 870 new_finish = uninitialized_copy(position, finish, new_finish); 871 } 872 # ifdef __STL_USE_EXCEPTIONS 873 catch(...) { 874 destroy(new_start, new_finish); 875 data_allocator::deallocate(new_start, len); 876 throw; 877 } 878 # endif /* __STL_USE_EXCEPTIONS */ 879 destroy(start, finish); 880 deallocate(); 881 start = new_start; 882 finish = new_finish; 883 end_of_storage = new_start + len; 884 } 885 } 886 } 887 888 #endif /* __STL_MEMBER_TEMPLATES */ 889 890 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 891 #pragma reset woff 1174 892 #endif 893 894 __STL_END_NAMESPACE 895 896 #endif /* __SGI_STL_INTERNAL_VECTOR_H */ 897 898 // Local Variables: 899 // mode:C++ 900 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_pair.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_PAIR_H 38 #define __SGI_STL_INTERNAL_PAIR_H 39 40 __STL_BEGIN_NAMESPACE 41 42 // pair只是一个wraper, 所以要提供最佳效率 43 // 使用struct的原因是我们要能方便的存取内部元素 44 // pair在关联式容器中的使用极为广泛, 其本身也可以嵌套使用 45 template <class T1, class T2> 46 struct pair 47 { 48 typedef T1 first_type; 49 typedef T2 second_type; 50 51 T1 first; 52 T2 second; 53 pair() : first(T1()), second(T2()) {} 54 pair(const T1& a, const T2& b) : first(a), second(b) {} 55 56 // 此版本并未提供operator =()的支持, 个人认为应该提供 57 58 #ifdef __STL_MEMBER_TEMPLATES 59 // 允许使用兼容的pair进行复制构造 60 template <class U1, class U2> 61 pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {} 62 #endif 63 }; 64 65 // 只有当pair中的两个成员均相等时, 才判定两个pair相等 66 // 使用自定义类型时最好提供operator ==重载 67 template <class T1, class T2> 68 inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) 69 { 70 return x.first == y.first && x.second == y.second; 71 } 72 73 // 连个pair进行比较操作时, 以第一个元素为主, 如果第一个元素不能决定表达式的值 74 // 那么再进行第二个元素的比较 75 // 使用自定义类型时最好提供operator <重载 76 template <class T1, class T2> 77 inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) 78 { 79 return x.first < y.first || (!(y.first < x.first) && x.second < y.second); 80 } 81 82 // 至于为什么没有提供operator !=, >, >=, <= 83 // 这个是因为其在<stl_relops.h>中有实现, 其只依赖operator <和== 84 // 所以在此特化operator ==, <就能满足要求 85 // 提供<stl_relops.h>的作用是如果需要特化operator XXX 86 // 那么我们仅需要特化operator ==和<即可同时重载所有operator 87 88 // 这里使用了RVO(Return Value Optimization)机制, 如果编译器支持, 89 // 则可以消除临时对象的构造和析构负担 90 // 详细细节见<Inside The C++ Object Model> 91 template <class T1, class T2> 92 inline pair<T1, T2> make_pair(const T1& x, const T2& y) 93 { 94 return pair<T1, T2>(x, y); 95 } 96 97 __STL_END_NAMESPACE 98 99 #endif /* __SGI_STL_INTERNAL_PAIR_H */ 100 101 // Local Variables: 102 // mode:C++ 103 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_list.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_LIST_H 38 #define __SGI_STL_INTERNAL_LIST_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 //// 47 // list结点, 提供双向访问能力 48 //// 49 // -------- -------- -------- -------- 50 // | next |---------->| next |---------->| next |---------->| next | 51 // -------- -------- -------- -------- 52 // | prev |<----------| prev |<----------| prev |<----------| prev | 53 // -------- -------- -------- -------- 54 // | data | | data | | data | | data | 55 // -------- -------- -------- -------- 56 //// 57 58 template <class T> 59 struct __list_node 60 { 61 typedef void* void_pointer; 62 void_pointer next; 63 void_pointer prev; 64 T data; 65 }; 66 67 // 至于为什么不使用默认参数, 这个是因为有一些编译器不能提供推导能力, 68 // 而作者又不想维护两份代码, 故不使用默认参数 69 template<class T, class Ref, class Ptr> 70 struct __list_iterator 71 { 72 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 73 typedef __list_iterator<T, T&, T*> iterator; // STL标准强制要求 74 typedef __list_iterator<T, const T&, const T*> const_iterator; 75 typedef __list_iterator<T, Ref, Ptr> self; 76 77 typedef bidirectional_iterator_tag iterator_category; 78 typedef T value_type; // STL标准强制要求 79 typedef Ptr pointer; // STL标准强制要求 80 typedef Ref reference; // STL标准强制要求 81 typedef __list_node<T>* link_type; 82 typedef size_t size_type; 83 typedef ptrdiff_t difference_type; // STL标准强制要求 84 85 // 这个是迭代器实际管理的资源指针 86 link_type node; 87 88 __list_iterator(link_type x) : node(x) {} 89 __list_iterator() {} 90 __list_iterator(const iterator& x) : node(x.node) {} 91 92 // 在STL算法中需要迭代器提供支持 93 bool operator==(const self& x) const { return node == x.node; } 94 bool operator!=(const self& x) const { return node != x.node; } 95 96 // 重载operator *, 返回实际维护的数据 97 reference operator*() const { return (*node).data; } 98 99 #ifndef __SGI_STL_NO_ARROW_OPERATOR 100 // 如果支持'->'则重载之 101 // 解释一下为什么要返回地址 102 // class A 103 // { 104 // public: 105 // // ... 106 // void fun(); 107 // // ... 108 // } 109 // __list_iterator<A, A&, A*> iter(new A) 110 // iter->fun(); 111 // 这就相当于调用(iter.operator())->fun(); 112 // 经过重载使其行为和原生指针一致 113 pointer operator->() const { return &(operator*()); } 114 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 115 116 // 前缀自加 117 self& operator++() 118 { 119 node = (link_type)((*node).next); 120 return *this; 121 } 122 123 // 后缀自加, 需要先产生自身的一个副本, 然会再对自身操作, 最后返回副本 124 self operator++(int) 125 { 126 self tmp = *this; 127 ++*this; 128 return tmp; 129 } 130 131 self& operator--() 132 { 133 node = (link_type)((*node).prev); 134 return *this; 135 } 136 137 self operator--(int) 138 { 139 self tmp = *this; 140 --*this; 141 return tmp; 142 } 143 }; 144 145 // 如果编译器支持模板类偏特化那么就不需要提供以下traits函数 146 // 直接使用<stl_iterator.h>中的 147 // template <class Iterator> 148 // struct iterator_traits 149 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 150 151 template <class T, class Ref, class Ptr> 152 inline bidirectional_iterator_tag 153 iterator_category(const __list_iterator<T, Ref, Ptr>&) { 154 return bidirectional_iterator_tag(); 155 } 156 157 template <class T, class Ref, class Ptr> 158 inline T* 159 value_type(const __list_iterator<T, Ref, Ptr>&) { 160 return 0; 161 } 162 163 template <class T, class Ref, class Ptr> 164 inline ptrdiff_t* 165 distance_type(const __list_iterator<T, Ref, Ptr>&) { 166 return 0; 167 } 168 169 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 170 171 //// 172 // 链表本身成环, 且是双向链表, 这样计算begin()和end()是常数时间 173 //// 174 // end() 头结点 begin() 175 // ↓ ↓ ↓ 176 // -------- -------- -------- -------- 177 // ---->| next |---------->| next |---------->| next |---------->| next |------ 178 // | -------- -------- -------- -------- | 179 // | --| prev |<----------| prev |<----------| prev |<----------| prev |<--| | 180 // | | -------- -------- -------- -------- | | 181 // | | | data | | data | | data | | data | | | 182 // | | -------- -------- -------- -------- | | 183 // | | | | 184 // | | -------- -------- -------- -------- | | 185 // ---|-| next |<----------| next |<----------| next |<----------| next |<--|-- 186 // | -------- -------- -------- -------- | 187 // ->| prev |---------->| prev |---------->| prev |---------->| prev |---- 188 // -------- -------- -------- -------- 189 // | data | | data | | data | | data | 190 // -------- -------- -------- -------- 191 //// 192 193 // 默认allocator为alloc, 其具体使用版本请参照<stl_alloc.h> 194 template <class T, class Alloc = alloc> 195 class list 196 { 197 protected: 198 typedef void* void_pointer; 199 typedef __list_node<T> list_node; 200 201 // 这个提供STL标准的allocator接口 202 typedef simple_alloc<list_node, Alloc> list_node_allocator; 203 204 public: 205 typedef T value_type; 206 typedef value_type* pointer; 207 typedef const value_type* const_pointer; 208 typedef value_type& reference; 209 typedef const value_type& const_reference; 210 typedef list_node* link_type; 211 typedef size_t size_type; 212 typedef ptrdiff_t difference_type; 213 214 public: 215 typedef __list_iterator<T, T&, T*> iterator; 216 typedef __list_iterator<T, const T&, const T*> const_iterator; 217 218 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 219 typedef reverse_iterator<const_iterator> const_reverse_iterator; 220 typedef reverse_iterator<iterator> reverse_iterator; 221 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 222 typedef reverse_bidirectional_iterator<const_iterator, value_type, 223 const_reference, difference_type> 224 const_reverse_iterator; 225 typedef reverse_bidirectional_iterator<iterator, value_type, reference, 226 difference_type> 227 reverse_iterator; 228 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 229 230 protected: 231 // 分配一个新结点, 注意这里并不进行构造, 232 // 构造交给全局的construct, 见<stl_stl_uninitialized.h> 233 link_type get_node() { return list_node_allocator::allocate(); } 234 235 // 释放指定结点, 不进行析构, 析构交给全局的destroy, 236 // 见<stl_stl_uninitialized.h> 237 void put_node(link_type p) { list_node_allocator::deallocate(p); } 238 239 // 创建结点, 首先分配内存, 然后进行构造 240 // 注: commit or rollback 241 link_type create_node(const T& x) 242 { 243 link_type p = get_node(); 244 __STL_TRY { 245 construct(&p->data, x); 246 } 247 __STL_UNWIND(put_node(p)); 248 return p; 249 } 250 251 // 析构结点元素, 并释放内存 252 void destroy_node(link_type p) 253 { 254 destroy(&p->data); 255 put_node(p); 256 } 257 258 protected: 259 // 用于空链表的建立 260 void empty_initialize() 261 { 262 node = get_node(); 263 node->next = node; 264 node->prev = node; 265 } 266 267 // 创建值为value共n个结点的链表 268 // 注: commit or rollback 269 void fill_initialize(size_type n, const T& value) 270 { 271 empty_initialize(); 272 __STL_TRY { 273 // 此处插入操作时间复杂度O(1) 274 insert(begin(), n, value); 275 } 276 __STL_UNWIND(clear(); put_node(node)); 277 } 278 279 // 以一个区间初始化链表 280 // 注: commit or rollback 281 #ifdef __STL_MEMBER_TEMPLATES 282 template <class InputIterator> 283 void range_initialize(InputIterator first, InputIterator last) 284 { 285 empty_initialize(); 286 __STL_TRY { 287 insert(begin(), first, last); 288 } 289 __STL_UNWIND(clear(); put_node(node)); 290 } 291 #else /* __STL_MEMBER_TEMPLATES */ 292 void range_initialize(const T* first, const T* last) { 293 empty_initialize(); 294 __STL_TRY { 295 insert(begin(), first, last); 296 } 297 __STL_UNWIND(clear(); put_node(node)); 298 } 299 void range_initialize(const_iterator first, const_iterator last) { 300 empty_initialize(); 301 __STL_TRY { 302 insert(begin(), first, last); 303 } 304 __STL_UNWIND(clear(); put_node(node)); 305 } 306 #endif /* __STL_MEMBER_TEMPLATES */ 307 308 protected: 309 // 好吧, 这个是链表头结点, 其本身不保存数据 310 link_type node; 311 312 public: 313 list() { empty_initialize(); } 314 315 iterator begin() { return (link_type)((*node).next); } 316 const_iterator begin() const { return (link_type)((*node).next); } 317 318 // 链表成环, 当指所以头节点也就是end 319 iterator end() { return node; } 320 const_iterator end() const { return node; } 321 reverse_iterator rbegin() { return reverse_iterator(end()); } 322 const_reverse_iterator rbegin() const { 323 return const_reverse_iterator(end()); 324 } 325 reverse_iterator rend() { return reverse_iterator(begin()); } 326 const_reverse_iterator rend() const { 327 return const_reverse_iterator(begin()); 328 } 329 330 // 头结点指向自身说明链表中无元素 331 bool empty() const { return node->next == node; } 332 333 // 使用全局函数distance()进行计算, 时间复杂度O(n) 334 size_type size() const 335 { 336 size_type result = 0; 337 distance(begin(), end(), result); 338 return result; 339 } 340 341 size_type max_size() const { return size_type(-1); } 342 reference front() { return *begin(); } 343 const_reference front() const { return *begin(); } 344 reference back() { return *(--end()); } 345 const_reference back() const { return *(--end()); } 346 void swap(list<T, Alloc>& x) { __STD::swap(node, x.node); } 347 348 //// 349 // 在指定位置插入元素 350 //// 351 // insert(iterator position, const T& x) 352 // ↓ 353 // create_node(x) 354 // p = get_node();-------->list_node_allocator::allocate(); 355 // construct(&p->data, x); 356 // ↓ 357 // tmp->next = position.node; 358 // tmp->prev = position.node->prev; 359 // (link_type(position.node->prev))->next = tmp; 360 // position.node->prev = tmp; 361 //// 362 363 iterator insert(iterator position, const T& x) 364 { 365 link_type tmp = create_node(x); 366 tmp->next = position.node; 367 tmp->prev = position.node->prev; 368 (link_type(position.node->prev))->next = tmp; 369 position.node->prev = tmp; 370 return tmp; 371 } 372 373 iterator insert(iterator position) { return insert(position, T()); } 374 #ifdef __STL_MEMBER_TEMPLATES 375 template <class InputIterator> 376 void insert(iterator position, InputIterator first, InputIterator last); 377 #else /* __STL_MEMBER_TEMPLATES */ 378 void insert(iterator position, const T* first, const T* last); 379 void insert(iterator position, 380 const_iterator first, const_iterator last); 381 #endif /* __STL_MEMBER_TEMPLATES */ 382 383 // 指定位置插入n个值为x的元素, 详细解析见实现部分 384 void insert(iterator pos, size_type n, const T& x); 385 void insert(iterator pos, int n, const T& x) 386 { 387 insert(pos, (size_type)n, x); 388 } 389 void insert(iterator pos, long n, const T& x) 390 { 391 insert(pos, (size_type)n, x); 392 } 393 394 // 在链表前端插入结点 395 void push_front(const T& x) { insert(begin(), x); } 396 // 在链表最后插入结点 397 void push_back(const T& x) { insert(end(), x); } 398 399 // 擦除指定结点 400 iterator erase(iterator position) 401 { 402 link_type next_node = link_type(position.node->next); 403 link_type prev_node = link_type(position.node->prev); 404 prev_node->next = next_node; 405 next_node->prev = prev_node; 406 destroy_node(position.node); 407 return iterator(next_node); 408 } 409 410 // 擦除一个区间的结点, 详细解析见实现部分 411 iterator erase(iterator first, iterator last); 412 413 void resize(size_type new_size, const T& x); 414 void resize(size_type new_size) { resize(new_size, T()); } 415 void clear(); 416 417 // 删除链表第一个结点 418 void pop_front() { erase(begin()); } 419 // 删除链表最后一个结点 420 void pop_back() 421 { 422 iterator tmp = end(); 423 erase(--tmp); 424 } 425 426 list(size_type n, const T& value) { fill_initialize(n, value); } 427 list(int n, const T& value) { fill_initialize(n, value); } 428 list(long n, const T& value) { fill_initialize(n, value); } 429 430 explicit list(size_type n) { fill_initialize(n, T()); } 431 432 // 以一个区间元素为蓝本创建链表 433 #ifdef __STL_MEMBER_TEMPLATES 434 template <class InputIterator> 435 list(InputIterator first, InputIterator last) 436 { 437 range_initialize(first, last); 438 } 439 440 #else /* __STL_MEMBER_TEMPLATES */ 441 list(const T* first, const T* last) { range_initialize(first, last); } 442 list(const_iterator first, const_iterator last) { 443 range_initialize(first, last); 444 } 445 #endif /* __STL_MEMBER_TEMPLATES */ 446 447 // 复制构造 448 list(const list<T, Alloc>& x) 449 { 450 range_initialize(x.begin(), x.end()); 451 } 452 453 ~list() 454 { 455 // 释放所有结点 // 使用全局函数distance()进行计算, 时间复杂度O(n) 456 size_type size() const 457 { 458 size_type result = 0; 459 distance(begin(), end(), result); 460 return result; 461 } 462 clear(); 463 // 释放头结点 464 put_node(node); 465 } 466 467 list<T, Alloc>& operator=(const list<T, Alloc>& x); 468 469 protected: 470 471 //// 472 // 将[first, last)区间插入到position 473 // 如果last == position, 则相当于链表不变化, 不进行操作 474 //// 475 // 初始状态 476 // first last 477 // ↓ ↓ 478 // -------- -------- -------- -------- -------- -------- 479 // | next |-->| next |-->| next | | next |-->| next |-->| next | 480 // ... -------- -------- -------- ... -------- -------- -------- ... 481 // | prev |<--| prev |<--| prev | | prev |<--| prev |<--| prev | 482 // -------- -------- -------- -------- -------- -------- 483 // 484 // position 485 // ↓ 486 // -------- -------- -------- -------- -------- -------- 487 // | next |-->| next |-->| next |-->| next |-->| next |-->| next | 488 // ... -------- -------- -------- -------- -------- -------- ... 489 // | prev |<--| prev |<--| prev |<--| prev |<--| prev |<--| prev | 490 // -------- -------- -------- -------- -------- -------- 491 // 492 // 操作完成后状态 493 // first 494 // | 495 // --------------|-------------------------------------- 496 // | ------------|------------------------------------ | last 497 // | | ↓ | | ↓ 498 // -------- | | -------- -------- -------- | | -------- -------- 499 // | next |-- | ----->| next |-->| next | | next |----- | -->| next |-->| next | 500 // ... -------- | | -------- -------- ... -------- | | -------- -------- ... 501 // | prev |<--- | ---| prev |<--| prev | | prev |<-- | -----| prev |<--| prev | 502 // -------- | | -------- -------- -------- | | -------- -------- 503 // | | | | 504 // | ------ | | 505 // ------- | ------------------------------ | 506 // | | | | 507 // | | | ----------------------------- 508 // | | | | 509 // | | | | position 510 // | | | | ↓ 511 // -------- -------- | | | | -------- -------- -------- -------- 512 // | next |-->| next |-- | | -->| next |-->| next |-->| next |-->| next | 513 // ... -------- -------- | | -------- -------- -------- -------- ... 514 // | prev |<--| prev |<--- ------| prev |<--| prev |<--| prev |<--| prev | 515 // -------- -------- -------- -------- -------- -------- 516 //// 517 void transfer(iterator position, iterator first, iterator last) 518 { 519 if (position != last) 520 { 521 (*(link_type((*last.node).prev))).next = position.node; 522 (*(link_type((*first.node).prev))).next = last.node; 523 (*(link_type((*position.node).prev))).next = first.node; 524 link_type tmp = link_type((*position.node).prev); 525 (*position.node).prev = (*last.node).prev; 526 (*last.node).prev = (*first.node).prev; 527 (*first.node).prev = tmp; 528 } 529 } 530 531 public: 532 // 将链表x移动到position之前 533 void splice(iterator position, list& x) 534 { 535 if (!x.empty()) 536 transfer(position, x.begin(), x.end()); 537 } 538 539 // 将链表中i指向的内容移动到position之前 540 void splice(iterator position, list&, iterator i) 541 { 542 iterator j = i; 543 ++j; 544 if (position == i || position == j) return; 545 transfer(position, i, j); 546 } 547 548 // 将[first, last}元素移动到position之前 549 void splice(iterator position, list&, iterator first, iterator last) 550 { 551 if (first != last) 552 transfer(position, first, last); 553 } 554 555 void remove(const T& value); 556 void unique(); 557 void merge(list& x); 558 void reverse(); 559 void sort(); 560 561 #ifdef __STL_MEMBER_TEMPLATES 562 template <class Predicate> void remove_if(Predicate); 563 template <class BinaryPredicate> void unique(BinaryPredicate); 564 template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering); 565 template <class StrictWeakOrdering> void sort(StrictWeakOrdering); 566 #endif /* __STL_MEMBER_TEMPLATES */ 567 568 friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y); 569 }; 570 571 // 判断两个链表是否相等 572 template <class T, class Alloc> 573 inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) 574 { 575 typedef typename list<T,Alloc>::link_type link_type; 576 link_type e1 = x.node; 577 link_type e2 = y.node; 578 link_type n1 = (link_type) e1->next; 579 link_type n2 = (link_type) e2->next; 580 for ( ; n1 != e1 && n2 != e2 ; 581 n1 = (link_type) n1->next, n2 = (link_type) n2->next) 582 if (n1->data != n2->data) 583 return false; 584 return n1 == e1 && n2 == e2; 585 } 586 587 // 链表比较大小使用的是字典顺序 588 template <class T, class Alloc> 589 inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) 590 { 591 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); 592 } 593 594 // 如果编译器支持模板函数特化优先级 595 // 那么将全局的swap实现为使用list私有的swap以提高效率 596 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 597 598 template <class T, class Alloc> 599 inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) 600 { 601 x.swap(y); 602 } 603 604 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 605 606 // 将[first, last)区间插入到position之前 607 #ifdef __STL_MEMBER_TEMPLATES 608 609 template <class T, class Alloc> template <class InputIterator> 610 void list<T, Alloc>::insert(iterator position, 611 InputIterator first, InputIterator last) 612 { 613 for ( ; first != last; ++first) 614 insert(position, *first); 615 } 616 617 #else /* __STL_MEMBER_TEMPLATES */ 618 619 template <class T, class Alloc> 620 void list<T, Alloc>::insert(iterator position, const T* first, const T* last) { 621 for ( ; first != last; ++first) 622 insert(position, *first); 623 } 624 625 template <class T, class Alloc> 626 void list<T, Alloc>::insert(iterator position, 627 const_iterator first, const_iterator last) { 628 for ( ; first != last; ++first) 629 insert(position, *first); 630 } 631 632 #endif /* __STL_MEMBER_TEMPLATES */ 633 634 // 在position前插入n个值为x的元素 635 template <class T, class Alloc> 636 void list<T, Alloc>::insert(iterator position, size_type n, const T& x) 637 { 638 for ( ; n > 0; --n) 639 insert(position, x); 640 } 641 642 // 擦除[first, last)间的结点 643 template <class T, class Alloc> 644 list<T,Alloc>::iterator list<T, Alloc>::erase(iterator first, iterator last) 645 { 646 while (first != last) erase(first++); 647 return last; 648 } 649 650 // 重新设置容量大小 651 // 如果当前容量小于新容量, 则新增加值为x的元素, 使容量增加至新指定大小 652 // 如果当前容量大于新容量, 则析构出来的元素 653 template <class T, class Alloc> 654 void list<T, Alloc>::resize(size_type new_size, const T& x) 655 { 656 iterator i = begin(); 657 size_type len = 0; 658 for ( ; i != end() && len < new_size; ++i, ++len) 659 ; 660 if (len == new_size) 661 erase(i, end()); 662 else // i == end() 663 insert(end(), new_size - len, x); 664 } 665 666 // 销毁所有结点, 将链表置空 667 template <class T, class Alloc> 668 void list<T, Alloc>::clear() 669 { 670 link_type cur = (link_type) node->next; 671 while (cur != node) { 672 link_type tmp = cur; 673 cur = (link_type) cur->next; 674 destroy_node(tmp); 675 } 676 node->next = node; 677 node->prev = node; 678 } 679 680 // 链表赋值操作 681 // 如果当前容器元素少于x容器, 则析构多余元素, 682 // 否则将调用insert插入x中剩余的元素 683 template <class T, class Alloc> 684 list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) 685 { 686 if (this != &x) { 687 iterator first1 = begin(); 688 iterator last1 = end(); 689 const_iterator first2 = x.begin(); 690 const_iterator last2 = x.end(); 691 while (first1 != last1 && first2 != last2) *first1++ = *first2++; 692 if (first2 == last2) 693 erase(first1, last1); 694 else 695 insert(last1, first2, last2); 696 } 697 return *this; 698 } 699 700 // 移除特定值的所有结点 701 // 时间复杂度O(n) 702 template <class T, class Alloc> 703 void list<T, Alloc>::remove(const T& value) 704 { 705 iterator first = begin(); 706 iterator last = end(); 707 while (first != last) { 708 iterator next = first; 709 ++next; 710 if (*first == value) erase(first); 711 first = next; 712 } 713 } 714 715 // 移除容器内所有的相邻的重复结点 716 // 时间复杂度O(n) 717 // 用户自定义数据类型需要提供operator ==()重载 718 template <class T, class Alloc> 719 void list<T, Alloc>::unique() 720 { 721 iterator first = begin(); 722 iterator last = end(); 723 if (first == last) return; 724 iterator next = first; 725 while (++next != last) { 726 if (*first == *next) 727 erase(next); 728 else 729 first = next; 730 next = first; 731 } 732 } 733 734 // 假设当前容器和x都已序, 保证两容器合并后仍然有序 735 template <class T, class Alloc> 736 void list<T, Alloc>::merge(list<T, Alloc>& x) 737 { 738 iterator first1 = begin(); 739 iterator last1 = end(); 740 iterator first2 = x.begin(); 741 iterator last2 = x.end(); 742 while (first1 != last1 && first2 != last2) 743 if (*first2 < *first1) { 744 iterator next = first2; 745 transfer(first1, first2, ++next); 746 first2 = next; 747 } 748 else 749 ++first1; 750 if (first2 != last2) transfer(last1, first2, last2); 751 } 752 753 // 将链表倒置 754 // 其算法核心是历遍链表, 每次取出一个结点, 并插入到链表起始点 755 // 历遍完成后链表满足倒置 756 template <class T, class Alloc> 757 void list<T, Alloc>::reverse() 758 { 759 if (node->next == node || link_type(node->next)->next == node) return; 760 iterator first = begin(); 761 ++first; 762 while (first != end()) { 763 iterator old = first; 764 ++first; 765 transfer(begin(), old, first); 766 } 767 } 768 769 // 按照升序排序 770 template <class T, class Alloc> 771 void list<T, Alloc>::sort() 772 { 773 if (node->next == node || link_type(node->next)->next == node) return; 774 list<T, Alloc> carry; 775 list<T, Alloc> counter[64]; 776 int fill = 0; 777 while (!empty()) { 778 carry.splice(carry.begin(), *this, begin()); 779 int i = 0; 780 while(i < fill && !counter[i].empty()) { 781 counter[i].merge(carry); 782 carry.swap(counter[i++]); 783 } 784 carry.swap(counter[i]); 785 if (i == fill) ++fill; 786 } 787 788 for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]); 789 swap(counter[fill-1]); 790 } 791 792 #ifdef __STL_MEMBER_TEMPLATES 793 794 // 给定一个仿函数, 如果仿函数值为真则进行相应元素的移除 795 template <class T, class Alloc> template <class Predicate> 796 void list<T, Alloc>::remove_if(Predicate pred) 797 { 798 iterator first = begin(); 799 iterator last = end(); 800 while (first != last) { 801 iterator next = first; 802 ++next; 803 if (pred(*first)) erase(first); 804 first = next; 805 } 806 } 807 808 // 根据仿函数, 决定如何移除相邻的重复结点 809 template <class T, class Alloc> template <class BinaryPredicate> 810 void list<T, Alloc>::unique(BinaryPredicate binary_pred) 811 { 812 iterator first = begin(); 813 iterator last = end(); 814 if (first == last) return; 815 iterator next = first; 816 while (++next != last) { 817 if (binary_pred(*first, *next)) 818 erase(next); 819 else 820 first = next; 821 next = first; 822 } 823 } 824 825 // 假设当前容器和x均已序, 将x合并到当前容器中, 并保证在comp仿函数 826 // 判定下仍然有序 827 template <class T, class Alloc> template <class StrictWeakOrdering> 828 void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) 829 { 830 iterator first1 = begin(); 831 iterator last1 = end(); 832 iterator first2 = x.begin(); 833 iterator last2 = x.end(); 834 while (first1 != last1 && first2 != last2) 835 if (comp(*first2, *first1)) { 836 iterator next = first2; 837 transfer(first1, first2, ++next); 838 first2 = next; 839 } 840 else 841 ++first1; 842 if (first2 != last2) transfer(last1, first2, last2); 843 } 844 845 // 根据仿函数comp据定如何排序 846 template <class T, class Alloc> template <class StrictWeakOrdering> 847 void list<T, Alloc>::sort(StrictWeakOrdering comp) 848 { 849 if (node->next == node || link_type(node->next)->next == node) return; 850 list<T, Alloc> carry; 851 list<T, Alloc> counter[64]; 852 int fill = 0; 853 while (!empty()) { 854 carry.splice(carry.begin(), *this, begin()); 855 int i = 0; 856 while(i < fill && !counter[i].empty()) { 857 counter[i].merge(carry, comp); 858 carry.swap(counter[i++]); 859 } 860 carry.swap(counter[i]); 861 if (i == fill) ++fill; 862 } 863 864 for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp); 865 swap(counter[fill-1]); 866 } 867 868 #endif /* __STL_MEMBER_TEMPLATES */ 869 870 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 871 #pragma reset woff 1174 872 #endif 873 874 __STL_END_NAMESPACE 875 876 #endif /* __SGI_STL_INTERNAL_LIST_H */ 877 878 // Local Variables: 879 // mode:C++ 880 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_deque.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // 如果vector能满足你的需求, 那么就使用vector 8 // 如果不得不使用deque, 那么在进行一算法(尤其是sort)操作时 9 // 应该先把deque中的元素复制到vector中 10 // 执行完算法再复制回去 11 // 这样的效率往往要高于直接使用算法的效率 12 13 /* 14 * 15 * Copyright (c) 1994 16 * Hewlett-Packard Company 17 * 18 * Permission to use, copy, modify, distribute and sell this software 19 * and its documentation for any purpose is hereby granted without fee, 20 * provided that the above copyright notice appear in all copies and 21 * that both that copyright notice and this permission notice appear 22 * in supporting documentation. Hewlett-Packard Company makes no 23 * representations about the suitability of this software for any 24 * purpose. It is provided "as is" without express or implied warranty. 25 * 26 * 27 * Copyright (c) 1997 28 * Silicon Graphics Computer Systems, Inc. 29 * 30 * Permission to use, copy, modify, distribute and sell this software 31 * and its documentation for any purpose is hereby granted without fee, 32 * provided that the above copyright notice appear in all copies and 33 * that both that copyright notice and this permission notice appear 34 * in supporting documentation. Silicon Graphics makes no 35 * representations about the suitability of this software for any 36 * purpose. It is provided "as is" without express or implied warranty. 37 */ 38 39 /* NOTE: This is an internal header file, included by other STL headers. 40 * You should not attempt to use it directly. 41 */ 42 43 #ifndef __SGI_STL_INTERNAL_DEQUE_H 44 #define __SGI_STL_INTERNAL_DEQUE_H 45 46 // 特性: 47 // 对于任何的非奇异(nonsingular)的迭代器i 48 // i.node是map array中的某元素的地址. i.node的内容是一个指向某个结点的头的指针 49 // i.first == *(i.node) 50 // i.last == i.first + node_size 51 // i.cur是一个指向[i.first, i.last)之间的指针 52 // 注意: 这意味着i.cur永远是一个可以解引用的指针, 53 // 即使其是一个指向结尾后元素的迭代器 54 // 55 // 起点和终点总是非奇异(nonsingular)的迭代器. 56 // 注意: 这意味着空deque一定有一个node, 而一个具有N个元素的deque 57 // (N是Buffer Size)一定有有两个nodes 58 // 59 // 对于除了start.node和finish.node之外的每一个node, 每一个node中的元素 60 // 都是一个初始化过的对象. 如果start.node == finish.node, 61 // 那么[start.cur, finish.cur)都是未初始化的空间. 62 // 否则, [start.cur, start.last)和[finish.first, finish.cur)都是初始化的对象, 63 // 而[start.first, start.cur)和[finish.cur, finish.last)是未初始化的空间 64 // 65 // [map, map + map_size)是一个合法的非空区间 66 // [start.node, finish.node]是内含在[map, map + map_size)区间的合法区间 67 // 一个在[map, map + map_size)区间内的指针指向一个分配过的node, 68 // 当且仅当此指针在[start.node, finish.node]区间内 69 70 // 在前一个版本的deque中, node_size被设定为定植. 71 // 然而在这个版本中, 用户可以自定义node_size的大小. 72 // deque有三个模板参数, 第三个参数为size_t类型, 代表每个结点内的元素数目. 73 // 如果第三个参数被设定为0(默认值), deque使用默认结点大小 74 // 75 // 使用不同结点大小的唯一理由是, 你的程序需要不同的效率, 并愿意为此付出代价, 76 // 例如, 如果你的程序中有许多deque, 但是每个deque都只包含很少的元素, 77 // 那么你可以使用较小的node_size来进行管理, 但是会对访问操作带来效率损失 78 // 79 // 不幸的是, 一些编译器不能正确处理non-type template parameters; 80 // 如果这样, 在<stl_config.h>会定义__STL_NON_TYPE_TMPL_PARAM_BUG 81 // 如果你的编译器不幸在列, 你只能使用默认的大小, 而不能更改 82 83 __STL_BEGIN_NAMESPACE 84 85 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 86 #pragma set woff 1174 87 #endif 88 89 // 这个函数是为了防止不同编译器在处理常量表达式时的Bug 90 // 如果n != 0, 那么就返回n, 表示buffer size为使用者自定义 91 // 如果n ==0, 就返回默认值表示buffer size,默认值计算方法如下 92 // 如果sz(元素类型大小sizeof(type))小于512, 返回512 / sz 93 // 否则返回1 94 inline size_t __deque_buf_size(size_t n, size_t sz) 95 { 96 return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1)); 97 } 98 99 // 注意这里未继承自std::iterator 100 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG 101 template <class T, class Ref, class Ptr, size_t BufSiz> 102 struct __deque_iterator { 103 typedef __deque_iterator<T, T&, T*, BufSiz> iterator; 104 typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator; 105 static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); } 106 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 107 template <class T, class Ref, class Ptr> 108 struct __deque_iterator { 109 typedef __deque_iterator<T, T&, T*> iterator; 110 typedef __deque_iterator<T, const T&, const T*> const_iterator; 111 static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); } 112 #endif 113 114 typedef random_access_iterator_tag iterator_category; // STL标准强制要求 115 typedef T value_type; // STL标准强制要求 116 typedef Ptr pointer; // STL标准强制要求 117 typedef Ref reference; // STL标准强制要求 118 typedef size_t size_type; 119 typedef ptrdiff_t difference_type; // STL标准强制要求 120 typedef T** map_pointer; 121 122 typedef __deque_iterator self; 123 124 // 保存容器中的结点 125 T* cur; // 指向当前缓冲区中的元素 126 T* first; // 当前缓冲区的起点 127 T* last; // 当前缓冲区的终点 128 129 //// 130 // 这个是deque内存管理的关键, 其模型如下 131 //// 132 // 133 // --------------------------------------------- 134 // map-->| | | | | | | ..... | | | |<------------------ 135 // --------------------------------------------- | 136 // | | 137 // | | 138 // | node | 139 // | 缓冲区buffer, 这里实际存储元素 | 140 // | --------------------------------------------- | 141 // --->| | | | | | | ..... | | | X | | 142 // --------------------------------------------- | 143 // ↑ ↑ ↑ | 144 // ------ | | | 145 // | | | | 146 // | ----------- --------------------------- | 147 // ----|----- | | 148 // | | | | 149 // | | | | 150 // | | | | 151 // --------------------------- | 152 // | cur | first | end | map |------------------------------ 153 // --------------------------- 154 // 迭代器, 其内部维护着一个缓冲区状态 155 //// 156 map_pointer node; 157 158 __deque_iterator(T* x, map_pointer y) 159 : cur(x), first(*y), last(*y + buffer_size()), node(y) {} 160 __deque_iterator() : cur(0), first(0), last(0), node(0) {} 161 __deque_iterator(const iterator& x) 162 : cur(x.cur), first(x.first), last(x.last), node(x.node) {} 163 164 reference operator*() const { return *cur; } 165 166 #ifndef __SGI_STL_NO_ARROW_OPERATOR 167 // 如果编译器支持'->'则重载, 详细见我在<stl_list.h>中的剖析 168 pointer operator->() const { return &(operator*()); } 169 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 170 171 // 判断两个迭代器间的距离 172 173 difference_type operator-(const self& x) const 174 { 175 return difference_type(buffer_size()) * (node - x.node - 1) + 176 (cur - first) + (x.last - x.cur); 177 } 178 179 //// 180 // 下面重载的这些是运算符是让deque从外界看上去维护的是一段连续空间的关键!!! 181 //// 182 183 //// 184 // 前缀自增 185 //// 186 // 如果当前迭代器指向元素是当前缓冲区的最后一个元素, 187 // 则将迭代器状态调整为下一个缓冲区的第一个元素 188 //// 189 // 不是当前缓冲区最后一个元素 190 // 191 // 执行前缀自增前的状态 192 // first cur end 193 // ↓ ↓ ↓ 194 // --------------------------------------------- 195 // | | | | | | | ..... | | | X | <----- 当前缓冲区 196 // --------------------------------------------- 197 // 198 // 执行完成后的状态 199 // first cur end 200 // ↓ ↓ ↓ 201 // --------------------------------------------- 202 // | | | | | | | ..... | | | X | <----- 当前缓冲区 203 // --------------------------------------------- 204 // 205 //// 206 // 当前元素为当前缓冲区的最后一个元素 207 // 208 // 执行前缀自增前的状态 209 // first cur end 210 // ↓ ↓ ↓ 211 // --------------------------------------------- 212 // | | | | | | | ..... | | | X | <----- 当前缓冲区 213 // --------------------------------------------- 214 // 215 // 执行完成后的状态 216 // first end 217 // ↓ ↓ 218 // --------------------------------------------- 219 // | | | | | | | ..... | | | X | <----- 下一缓冲区 220 // --------------------------------------------- 221 // ↑ 222 // cur 223 // 224 //// 225 self& operator++() 226 { 227 ++cur; 228 if (cur == last) { 229 set_node(node + 1); 230 cur = first; 231 } 232 return *this; 233 } 234 235 // 后缀自增 236 // 返回当前迭代器的一个副本, 并调用前缀自增运算符实现迭代器自身的自增 237 self operator++(int) { 238 self tmp = *this; 239 ++*this; 240 return tmp; 241 } 242 243 // 前缀自减, 处理方式类似于前缀自增 244 // 如果当前迭代器指向元素是当前缓冲区的第一个元素 245 // 则将迭代器状态调整为前一个缓冲区的最后一个元素 246 self& operator--() 247 { 248 if (cur == first) { 249 set_node(node - 1); 250 cur = last; 251 } 252 --cur; 253 return *this; 254 } 255 256 self operator--(int) 257 { 258 self tmp = *this; 259 --*this; 260 return tmp; 261 } 262 263 //// 264 // 将迭代器向前移动n个元素, n可以为负 265 //// 266 // operator+=(difference_type n) 267 // ↓ 268 // offset = n + (cur - first) 269 // | 270 // |---------- offset > 0 ? && 271 // | 移动后是否超出当前缓冲区? 272 // ---------------------------- 273 // No | | Yes 274 // | | 275 // ↓ |---------- offset > 0? 276 // cur += n; | 277 // ---------------------------- 278 // Yes | | No 279 // | | 280 // ↓ | 281 // 计算要向后移动多少个缓冲区 | 282 // node_offset = | 283 // offset / difference_type | 284 // (buffer_size()); ↓ 285 // | 计算要向前移动多少个缓冲区 286 // | node_offset = -difference_type 287 // | ((-offset - 1) / buffer_size()) - 1; 288 // | | 289 // ---------------------------- 290 // | 291 // | 292 // ↓ 293 // 调整缓冲区 294 // set_node(node + node_offset); 295 // 计算并调整cur指针 296 //// 297 298 self& operator+=(difference_type n) 299 { 300 difference_type offset = n + (cur - first); 301 if (offset >= 0 && offset < difference_type(buffer_size())) 302 cur += n; 303 else { 304 difference_type node_offset = 305 offset > 0 ? offset / difference_type(buffer_size()) 306 : -difference_type((-offset - 1) / buffer_size()) - 1; 307 set_node(node + node_offset); 308 cur = first + (offset - node_offset * difference_type(buffer_size())); 309 } 310 return *this; 311 } 312 313 self operator+(difference_type n) const 314 { 315 self tmp = *this; 316 317 // 这里调用了operator +=()可以自动调整指针状态 318 return tmp += n; 319 } 320 321 // :-), 将n变为-n就可以使用operator +=()了, 322 // 初等数学是神奇的, 还记得我们刚学编程时求绝对值是怎么写的吗? :P 323 self& operator-=(difference_type n) { return *this += -n; } 324 325 self operator-(difference_type n) const { 326 self tmp = *this; 327 return tmp -= n; 328 } 329 330 reference operator[](difference_type n) const { return *(*this + n); } 331 332 bool operator==(const self& x) const { return cur == x.cur; } 333 bool operator!=(const self& x) const { return !(*this == x); } 334 bool operator<(const self& x) const { 335 return (node == x.node) ? (cur < x.cur) : (node < x.node); 336 } 337 338 void set_node(map_pointer new_node) 339 { 340 node = new_node; 341 first = *new_node; 342 last = first + difference_type(buffer_size()); 343 } 344 }; 345 346 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 347 348 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG 349 350 template <class T, class Ref, class Ptr, size_t BufSiz> 351 inline random_access_iterator_tag 352 iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { 353 return random_access_iterator_tag(); 354 } 355 356 template <class T, class Ref, class Ptr, size_t BufSiz> 357 inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { 358 return 0; 359 } 360 361 template <class T, class Ref, class Ptr, size_t BufSiz> 362 inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { 363 return 0; 364 } 365 366 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 367 368 template <class T, class Ref, class Ptr> 369 inline random_access_iterator_tag 370 iterator_category(const __deque_iterator<T, Ref, Ptr>&) { 371 return random_access_iterator_tag(); 372 } 373 374 template <class T, class Ref, class Ptr> 375 inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; } 376 377 template <class T, class Ref, class Ptr> 378 inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) { 379 return 0; 380 } 381 382 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 383 384 // 其实剖析到这里就没有什么难的了, deque的运算符才是核心 385 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 386 387 // See __deque_buf_size(). The only reason that the default value is 0 388 // is as a workaround for bugs in the way that some compilers handle 389 // constant expressions. 390 template <class T, class Alloc = alloc, size_t BufSiz = 0> 391 class deque { 392 public: // Basic types 393 typedef T value_type; 394 typedef value_type* pointer; 395 typedef const value_type* const_pointer; 396 typedef value_type& reference; 397 typedef const value_type& const_reference; 398 typedef size_t size_type; 399 typedef ptrdiff_t difference_type; 400 401 public: // Iterators 402 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG 403 typedef __deque_iterator<T, T&, T*, BufSiz> iterator; 404 405 typedef __deque_iterator<T, const T&, const T&, BufSiz> const_iterator; 406 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 407 typedef __deque_iterator<T, T&, T*> iterator; 408 typedef __deque_iterator<T, const T&, const T*> const_iterator; 409 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 410 411 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 412 typedef reverse_iterator<const_iterator> const_reverse_iterator; 413 typedef reverse_iterator<iterator> reverse_iterator; 414 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 415 typedef reverse_iterator<const_iterator, value_type, const_reference, 416 difference_type> 417 const_reverse_iterator; 418 typedef reverse_iterator<iterator, value_type, reference, difference_type> 419 reverse_iterator; 420 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 421 422 protected: // Internal typedefs 423 424 typedef pointer* map_pointer; 425 426 // 这个提供STL标准的allocator接口, 见<stl_alloc.h> 427 typedef simple_alloc<value_type, Alloc> data_allocator; 428 typedef simple_alloc<pointer, Alloc> map_allocator; 429 430 // 获取缓冲区最大存储元素数量 431 static size_type buffer_size() 432 { 433 return __deque_buf_size(BufSiz, sizeof(value_type)); 434 } 435 436 static size_type initial_map_size() { return 8; } 437 438 protected: // Data members 439 iterator start; // 起始缓冲区 440 iterator finish; // 最后一个缓冲区 441 442 // 指向map, map是一个连续的空间, 其每个元素都是一个指向缓冲区的指针 443 // 其模型见前面的__deque_iterator 444 map_pointer map; 445 size_type map_size; // map容量 446 447 public: // Basic accessors 448 iterator begin() { return start; } 449 iterator end() { return finish; } 450 const_iterator begin() const { return start; } 451 const_iterator end() const { return finish; } 452 453 reverse_iterator rbegin() { return reverse_iterator(finish); } 454 reverse_iterator rend() { return reverse_iterator(start); } 455 const_reverse_iterator rbegin() const { 456 return const_reverse_iterator(finish); 457 } 458 const_reverse_iterator rend() const { 459 return const_reverse_iterator(start); 460 } 461 462 // 提供随机访问能力, 其调用的是迭代器重载的operator [] 463 // 其实际地址需要进行一些列的计算, 效率有损失 464 reference operator[](size_type n) { return start[difference_type(n)]; } 465 const_reference operator[](size_type n) const { 466 return start[difference_type(n)]; 467 } 468 469 reference front() { return *start; } 470 reference back() { 471 iterator tmp = finish; 472 --tmp; 473 return *tmp; 474 } 475 const_reference front() const { return *start; } 476 const_reference back() const { 477 const_iterator tmp = finish; 478 --tmp; 479 return *tmp; 480 } 481 482 // 当前容器拥有的元素个数, 调用迭代器重载的operator - 483 size_type size() const { return finish - start;; } 484 size_type max_size() const { return size_type(-1); } 485 486 // deque为空的时, 只有一个缓冲区 487 bool empty() const { return finish == start; } 488 489 public: // Constructor, destructor. 490 deque() 491 : start(), finish(), map(0), map_size(0) 492 { 493 create_map_and_nodes(0); 494 } 495 496 // 注: commit or rollback 497 deque(const deque& x) 498 : start(), finish(), map(0), map_size(0) 499 { 500 create_map_and_nodes(x.size()); 501 __STL_TRY { 502 uninitialized_copy(x.begin(), x.end(), start); // <stl_uninitialized.h> 503 } 504 __STL_UNWIND(destroy_map_and_nodes()); 505 } 506 507 deque(size_type n, const value_type& value) 508 : start(), finish(), map(0), map_size(0) 509 { 510 fill_initialize(n, value); 511 } 512 513 deque(int n, const value_type& value) 514 : start(), finish(), map(0), map_size(0) 515 { 516 fill_initialize(n, value); 517 } 518 519 deque(long n, const value_type& value) 520 : start(), finish(), map(0), map_size(0) 521 { 522 fill_initialize(n, value); 523 } 524 525 explicit deque(size_type n) 526 : start(), finish(), map(0), map_size(0) 527 { 528 fill_initialize(n, value_type()); 529 } 530 531 #ifdef __STL_MEMBER_TEMPLATES 532 533 template <class InputIterator> 534 deque(InputIterator first, InputIterator last) 535 : start(), finish(), map(0), map_size(0) 536 { 537 range_initialize(first, last, iterator_category(first)); 538 } 539 540 #else /* __STL_MEMBER_TEMPLATES */ 541 542 deque(const value_type* first, const value_type* last) 543 : start(), finish(), map(0), map_size(0) 544 { 545 create_map_and_nodes(last - first); 546 __STL_TRY { 547 uninitialized_copy(first, last, start); 548 } 549 __STL_UNWIND(destroy_map_and_nodes()); 550 } 551 552 deque(const_iterator first, const_iterator last) 553 : start(), finish(), map(0), map_size(0) 554 { 555 create_map_and_nodes(last - first); 556 __STL_TRY { 557 uninitialized_copy(first, last, start); 558 } 559 __STL_UNWIND(destroy_map_and_nodes()); 560 } 561 562 #endif /* __STL_MEMBER_TEMPLATES */ 563 564 ~deque() 565 { 566 destroy(start, finish); // <stl_construct.h> 567 destroy_map_and_nodes(); 568 } 569 570 deque& operator= (const deque& x) 571 { 572 // 其实我觉得把这个操作放在if内效率更高 573 const size_type len = size(); 574 if (&x != this) { 575 // 当前容器比x容器拥有元素多, 析构多余元素 576 if (len >= x.size()) 577 erase(copy(x.begin(), x.end(), start), finish); 578 // 将x所有超出部分的元素使用insert()追加进去 579 else { 580 const_iterator mid = x.begin() + difference_type(len); 581 copy(x.begin(), mid, start); 582 insert(finish, mid, x.end()); 583 } 584 } 585 return *this; 586 } 587 588 // 其实要交换两个容器, 只需要交换其内部维护的指针即可^_^ 589 void swap(deque& x) 590 { 591 __STD::swap(start, x.start); 592 __STD::swap(finish, x.finish); 593 __STD::swap(map, x.map); 594 __STD::swap(map_size, x.map_size); 595 } 596 597 public: // push_* and pop_* 598 599 void push_back(const value_type& t) 600 { 601 // STL使用前闭后开的区间, 所以如果还有剩余容量, 602 // 则直接在finish.cur上构造对象即可, 然后更新迭代器 603 if (finish.cur != finish.last - 1) { 604 construct(finish.cur, t); 605 ++finish.cur; 606 } 607 // 容量已满就要新申请内存了 608 else 609 push_back_aux(t); 610 } 611 612 void push_front(const value_type& t) 613 { 614 if (start.cur != start.first) { 615 construct(start.cur - 1, t); 616 --start.cur; 617 } 618 else 619 push_front_aux(t); 620 } 621 622 void pop_back() 623 { 624 if (finish.cur != finish.first) { 625 --finish.cur; 626 destroy(finish.cur); 627 } 628 else 629 pop_back_aux(); 630 } 631 632 void pop_front() { 633 if (start.cur != start.last - 1) 634 { 635 destroy(start.cur); 636 ++start.cur; 637 } 638 else 639 pop_front_aux(); 640 } 641 642 public: // Insert 643 644 //// 645 // 在指定位置前插入元素 646 //// 647 // insert(iterator position, const value_type& x) 648 // | 649 // |---------------- 判断插入位置 650 // | 651 // ----------------------------------------------- 652 // deque.begin() | deque.emd() | | 653 // | | | 654 // ↓ ↓ | 655 // push_front(x); push_back(x); | 656 // ↓ 657 // insert_aux(position, x); 658 // 具体剖析见后面实现 659 //// 660 661 iterator insert(iterator position, const value_type& x) 662 { 663 // 如果是在deque的最前端插入, 那么直接push_front()即可 664 if (position.cur == start.cur) { 665 push_front(x); 666 return start; 667 } 668 // 如果是在deque的末尾插入, 直接调用push_back() 669 else if (position.cur == finish.cur) { 670 push_back(x); 671 iterator tmp = finish; 672 --tmp; 673 return tmp; 674 } 675 else { 676 return insert_aux(position, x); 677 } 678 } 679 680 iterator insert(iterator position) { return insert(position, value_type()); } 681 682 // 详解见实现部分 683 void insert(iterator pos, size_type n, const value_type& x); 684 685 void insert(iterator pos, int n, const value_type& x) 686 { 687 insert(pos, (size_type) n, x); 688 } 689 void insert(iterator pos, long n, const value_type& x) 690 { 691 insert(pos, (size_type) n, x); 692 } 693 694 #ifdef __STL_MEMBER_TEMPLATES 695 696 template <class InputIterator> 697 void insert(iterator pos, InputIterator first, InputIterator last) 698 { 699 insert(pos, first, last, iterator_category(first)); 700 } 701 702 #else /* __STL_MEMBER_TEMPLATES */ 703 704 void insert(iterator pos, const value_type* first, const value_type* last); 705 void insert(iterator pos, const_iterator first, const_iterator last); 706 707 #endif /* __STL_MEMBER_TEMPLATES */ 708 709 // 如果new_size < size(), 那么就析构掉多余的元素, 710 // 否则以x为蓝本进行剩余元素的填充 711 void resize(size_type new_size, const value_type& x) 712 { 713 const size_type len = size(); 714 if (new_size < len) 715 erase(start + new_size, finish); 716 else 717 insert(finish, new_size - len, x); 718 } 719 720 void resize(size_type new_size) { resize(new_size, value_type()); } 721 722 public: // Erase 723 724 iterator erase(iterator pos) 725 { 726 iterator next = pos; 727 ++next; 728 729 // 计算待擦除点前的元素个数 730 difference_type index = pos - start; 731 732 // 判断待擦除结点前后元素的个数, 哪部分少就移动哪部分 733 if (index < (size() >> 1)) 734 { 735 // 前面部分的元素少 736 copy_backward(start, pos, next); // <stl_algobase.h> 737 pop_front(); 738 } 739 // 后面部分的元素少 740 else { 741 copy(next, finish, pos); // <stl_algobase.h> 742 pop_back(); 743 } 744 return start + index; 745 } 746 747 // 详解见实现部分 748 iterator erase(iterator first, iterator last); 749 void clear(); 750 751 protected: // Internal construction/destruction 752 753 // 详解见实现部分 754 void create_map_and_nodes(size_type num_elements); 755 void destroy_map_and_nodes(); 756 void fill_initialize(size_type n, const value_type& value); 757 758 #ifdef __STL_MEMBER_TEMPLATES 759 760 template <class InputIterator> 761 void range_initialize(InputIterator first, InputIterator last, 762 input_iterator_tag); 763 764 template <class ForwardIterator> 765 void range_initialize(ForwardIterator first, ForwardIterator last, 766 forward_iterator_tag); 767 768 #endif /* __STL_MEMBER_TEMPLATES */ 769 770 protected: // Internal push_* and pop_* 771 772 // 详解见实现部分 773 void push_back_aux(const value_type& t); 774 void push_front_aux(const value_type& t); 775 void pop_back_aux(); 776 void pop_front_aux(); 777 778 protected: // Internal insert functions 779 780 #ifdef __STL_MEMBER_TEMPLATES 781 782 template <class InputIterator> 783 void insert(iterator pos, InputIterator first, InputIterator last, 784 input_iterator_tag); 785 786 template <class ForwardIterator> 787 void insert(iterator pos, ForwardIterator first, ForwardIterator last, 788 forward_iterator_tag); 789 790 #endif /* __STL_MEMBER_TEMPLATES */ 791 792 iterator insert_aux(iterator pos, const value_type& x); 793 void insert_aux(iterator pos, size_type n, const value_type& x); 794 795 #ifdef __STL_MEMBER_TEMPLATES 796 797 template <class ForwardIterator> 798 void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, 799 size_type n); 800 801 #else /* __STL_MEMBER_TEMPLATES */ 802 803 void insert_aux(iterator pos, 804 const value_type* first, const value_type* last, 805 size_type n); 806 807 void insert_aux(iterator pos, const_iterator first, const_iterator last, 808 size_type n); 809 810 #endif /* __STL_MEMBER_TEMPLATES */ 811 812 // 在起始缓冲区预留大小为n的空间 813 // 如果缓冲区不足则重新分配 814 iterator reserve_elements_at_front(size_type n) 815 { 816 size_type vacancies = start.cur - start.first; 817 if (n > vacancies) 818 new_elements_at_front(n - vacancies); 819 return start - difference_type(n); 820 } 821 822 iterator reserve_elements_at_back(size_type n) 823 { 824 size_type vacancies = (finish.last - finish.cur) - 1; 825 if (n > vacancies) 826 new_elements_at_back(n - vacancies); 827 return finish + difference_type(n); 828 } 829 830 void new_elements_at_front(size_type new_elements); 831 void new_elements_at_back(size_type new_elements); 832 833 void destroy_nodes_at_front(iterator before_start); 834 void destroy_nodes_at_back(iterator after_finish); 835 836 protected: // Allocation of map and nodes 837 838 // Makes sure the map has space for new nodes. Does not actually 839 // add the nodes. Can invalidate map pointers. (And consequently, 840 // deque iterators.) 841 842 void reserve_map_at_back (size_type nodes_to_add = 1) 843 { 844 if (nodes_to_add + 1 > map_size - (finish.node - map)) 845 reallocate_map(nodes_to_add, false); 846 } 847 848 void reserve_map_at_front (size_type nodes_to_add = 1) 849 { 850 if (nodes_to_add > start.node - map) 851 reallocate_map(nodes_to_add, true); 852 } 853 854 void reallocate_map(size_type nodes_to_add, bool add_at_front); 855 856 // 分配内存, 不进行构造 857 pointer allocate_node() { return data_allocator::allocate(buffer_size()); } 858 859 // 释放内存, 不进行析构 860 void deallocate_node(pointer n) 861 { 862 data_allocator::deallocate(n, buffer_size()); 863 } 864 865 #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG 866 public: 867 bool operator==(const deque<T, Alloc, 0>& x) const { 868 return size() == x.size() && equal(begin(), end(), x.begin()); 869 } 870 bool operator!=(const deque<T, Alloc, 0>& x) const { 871 return size() != x.size() || !equal(begin(), end(), x.begin()); 872 } 873 bool operator<(const deque<T, Alloc, 0>& x) const { 874 return lexicographical_compare(begin(), end(), x.begin(), x.end()); 875 } 876 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 877 }; 878 879 //// 880 // 不进行内联的成员函数 881 //// 882 883 //// 884 // 在指定位置前插入n个值为x的元素 885 //// 886 // insert(iterator pos, size_type n, const value_type& x) 887 // | 888 // |---------------- 判断插入位置 889 // | 890 // --------------------------------------------------------- 891 // deque.begin() | deque.end() | | 892 // | | | 893 // ↓ | | 894 // reserve_elements_at_front(n); | | 895 // uninitialized_fill(new_start, start, x); | | 896 // ↓ | 897 // reserve_elements_at_back(n); | 898 // uninitialized_fill(finish, new_finish, x); | 899 // ↓ 900 // insert_aux(pos, n, x); 901 // 剖析见后面实现 902 //// 903 904 template <class T, class Alloc, size_t BufSize> 905 void deque<T, Alloc, BufSize>::insert(iterator pos, 906 size_type n, const value_type& x) 907 { 908 if (pos.cur == start.cur) { 909 iterator new_start = reserve_elements_at_front(n); 910 uninitialized_fill(new_start, start, x); 911 start = new_start; 912 } 913 else if (pos.cur == finish.cur) { 914 iterator new_finish = reserve_elements_at_back(n); 915 uninitialized_fill(finish, new_finish, x); 916 finish = new_finish; 917 } 918 else 919 insert_aux(pos, n, x); 920 } 921 922 // 给不支持成员函数模板的编译器提供支持函数 923 #ifndef __STL_MEMBER_TEMPLATES 924 925 template <class T, class Alloc, size_t BufSize> 926 void deque<T, Alloc, BufSize>::insert(iterator pos, 927 const value_type* first, 928 const value_type* last) { 929 size_type n = last - first; 930 if (pos.cur == start.cur) { 931 iterator new_start = reserve_elements_at_front(n); 932 __STL_TRY { 933 uninitialized_copy(first, last, new_start); 934 start = new_start; 935 } 936 __STL_UNWIND(destroy_nodes_at_front(new_start)); 937 } 938 else if (pos.cur == finish.cur) { 939 iterator new_finish = reserve_elements_at_back(n); 940 __STL_TRY { 941 uninitialized_copy(first, last, finish); 942 finish = new_finish; 943 } 944 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 945 } 946 else 947 insert_aux(pos, first, last, n); 948 } 949 950 template <class T, class Alloc, size_t BufSize> 951 void deque<T, Alloc, BufSize>::insert(iterator pos, 952 const_iterator first, 953 const_iterator last) 954 { 955 size_type n = last - first; 956 if (pos.cur == start.cur) { 957 iterator new_start = reserve_elements_at_front(n); 958 __STL_TRY { 959 uninitialized_copy(first, last, new_start); 960 start = new_start; 961 } 962 __STL_UNWIND(destroy_nodes_at_front(new_start)); 963 } 964 else if (pos.cur == finish.cur) { 965 iterator new_finish = reserve_elements_at_back(n); 966 __STL_TRY { 967 uninitialized_copy(first, last, finish); 968 finish = new_finish; 969 } 970 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 971 } 972 else 973 insert_aux(pos, first, last, n); 974 } 975 976 #endif /* __STL_MEMBER_TEMPLATES */ 977 978 //// 979 // 擦除[first, last)区间的元素 980 //// 981 // erase(iterator first, iterator last) 982 // | 983 // |---------------- 是否要删除整个区间? 984 // | 985 // ------------------------------------------ 986 // Yes | | No 987 // | | 988 // ↓ | --- 判断哪侧元素少 989 // clear(); ↓ 990 // ----------------------------------------------------------------- 991 // 左侧少 | 右侧少 | 992 // | | 993 // ↓ ↓ 994 // copy_backward(start, first, last); copy(last, finish, first); 995 // new_start = start + n; new_finish = finish - n; 996 // 析构多余的元素 析构多余的元素 997 // destroy(start, new_start); destroy(new_finish, finish); 998 // 释放多余内存空间 释放多余内存空间 999 // for (...) for (...) 1000 // ... ... 1001 // 更新map状态 更新map状态 1002 //// 1003 template <class T, class Alloc, size_t BufSize> 1004 deque<T, Alloc, BufSize>::iterator 1005 deque<T, Alloc, BufSize>::erase(iterator first, iterator last) 1006 { 1007 if (first == start && last == finish) { 1008 clear(); 1009 return finish; 1010 } 1011 else { 1012 difference_type n = last - first; 1013 difference_type elems_before = first - start; 1014 if (elems_before < (size() - n) / 2) { 1015 copy_backward(start, first, last); 1016 iterator new_start = start + n; 1017 destroy(start, new_start); 1018 for (map_pointer cur = start.node; cur < new_start.node; ++cur) 1019 data_allocator::deallocate(*cur, buffer_size()); 1020 start = new_start; 1021 } 1022 else { 1023 copy(last, finish, first); 1024 iterator new_finish = finish - n; 1025 destroy(new_finish, finish); 1026 for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) 1027 data_allocator::deallocate(*cur, buffer_size()); 1028 finish = new_finish; 1029 } 1030 return start + elems_before; 1031 } 1032 } 1033 1034 template <class T, class Alloc, size_t BufSize> 1035 void deque<T, Alloc, BufSize>::clear() 1036 { 1037 // 首先析构除起点和终点的所有元素, 并释放相应空间 1038 for (map_pointer node = start.node + 1; node < finish.node; ++node) { 1039 destroy(*node, *node + buffer_size()); 1040 data_allocator::deallocate(*node, buffer_size()); 1041 } 1042 1043 // 如果deque本身不为空, 析构所有对象, 并释放掉结尾的内存 1044 if (start.node != finish.node) { 1045 destroy(start.cur, start.last); 1046 destroy(finish.first, finish.cur); 1047 data_allocator::deallocate(finish.first, buffer_size()); 1048 } 1049 // 析构所有元素, 但是不释放空间, 因为deque要满足这个前置条件 1050 // 具体的细节见本文件开头'特性' 1051 else 1052 destroy(start.cur, finish.cur); 1053 1054 finish = start; 1055 } 1056 1057 // 创建内部使用的map 1058 template <class T, class Alloc, size_t BufSize> 1059 void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) 1060 { 1061 // 需要的结点数, 元素个数 / 每个缓冲区能容纳的元素数 + 1 1062 size_type num_nodes = num_elements / buffer_size() + 1; 1063 1064 // map要维护的结点, 这里最小的值为8, 见initial_map_size() 1065 map_size = max(initial_map_size(), num_nodes + 2); 1066 map = map_allocator::allocate(map_size); 1067 1068 // 将[nstart, nfinish)区间设置在map的中间, 1069 // 这样就能保证前后增长而尽可能减少map的重新分配次数 1070 map_pointer nstart = map + (map_size - num_nodes) / 2; 1071 map_pointer nfinish = nstart + num_nodes - 1; 1072 1073 // 分配结点空间 1074 map_pointer cur; 1075 __STL_TRY { 1076 for (cur = nstart; cur <= nfinish; ++cur) 1077 *cur = allocate_node(); 1078 } 1079 # ifdef __STL_USE_EXCEPTIONS 1080 catch(...) { 1081 for (map_pointer n = nstart; n < cur; ++n) 1082 deallocate_node(*n); 1083 map_allocator::deallocate(map, map_size); 1084 throw; 1085 } 1086 # endif /* __STL_USE_EXCEPTIONS */ 1087 1088 // 维护指针状态 1089 start.set_node(nstart); 1090 finish.set_node(nfinish); 1091 start.cur = start.first; 1092 finish.cur = finish.first + num_elements % buffer_size(); 1093 } 1094 1095 // This is only used as a cleanup function in catch clauses. 1096 template <class T, class Alloc, size_t BufSize> 1097 void deque<T, Alloc, BufSize>::destroy_map_and_nodes() 1098 { 1099 for (map_pointer cur = start.node; cur <= finish.node; ++cur) 1100 deallocate_node(*cur); 1101 map_allocator::deallocate(map, map_size); 1102 } 1103 1104 // 分配n个结点, 并以value为蓝本初始化 1105 template <class T, class Alloc, size_t BufSize> 1106 void deque<T, Alloc, BufSize>::fill_initialize(size_type n, 1107 const value_type& value) 1108 { 1109 create_map_and_nodes(n); 1110 map_pointer cur; 1111 __STL_TRY { 1112 for (cur = start.node; cur < finish.node; ++cur) 1113 uninitialized_fill(*cur, *cur + buffer_size(), value); 1114 uninitialized_fill(finish.first, finish.cur, value); 1115 } 1116 # ifdef __STL_USE_EXCEPTIONS 1117 catch(...) { 1118 for (map_pointer n = start.node; n < cur; ++n) 1119 destroy(*n, *n + buffer_size()); 1120 destroy_map_and_nodes(); 1121 throw; 1122 } 1123 # endif /* __STL_USE_EXCEPTIONS */ 1124 } 1125 1126 1127 #ifdef __STL_MEMBER_TEMPLATES 1128 1129 template <class T, class Alloc, size_t BufSize> 1130 template <class InputIterator> 1131 void deque<T, Alloc, BufSize>::range_initialize(InputIterator first, 1132 InputIterator last, 1133 input_iterator_tag) { 1134 create_map_and_nodes(0); 1135 for ( ; first != last; ++first) 1136 push_back(*first); 1137 } 1138 1139 template <class T, class Alloc, size_t BufSize> 1140 template <class ForwardIterator> 1141 void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first, 1142 ForwardIterator last, 1143 forward_iterator_tag) { 1144 size_type n = 0; 1145 distance(first, last, n); 1146 create_map_and_nodes(n); 1147 __STL_TRY { 1148 uninitialized_copy(first, last, start); 1149 } 1150 __STL_UNWIND(destroy_map_and_nodes()); 1151 } 1152 1153 #endif /* __STL_MEMBER_TEMPLATES */ 1154 1155 // 仅当finish.cur == finish.last - 1才调用 1156 // 即最后一个缓冲区没有空间才调用 1157 template <class T, class Alloc, size_t BufSize> 1158 void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) 1159 { 1160 value_type t_copy = t; 1161 reserve_map_at_back(); 1162 *(finish.node + 1) = allocate_node(); 1163 __STL_TRY { 1164 construct(finish.cur, t_copy); 1165 finish.set_node(finish.node + 1); 1166 finish.cur = finish.first; 1167 } 1168 __STL_UNWIND(deallocate_node(*(finish.node + 1))); 1169 } 1170 1171 // Called only if start.cur == start.first. 1172 template <class T, class Alloc, size_t BufSize> 1173 void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) 1174 { 1175 value_type t_copy = t; 1176 reserve_map_at_front(); 1177 *(start.node - 1) = allocate_node(); 1178 __STL_TRY { 1179 start.set_node(start.node - 1); 1180 start.cur = start.last - 1; 1181 construct(start.cur, t_copy); 1182 } 1183 # ifdef __STL_USE_EXCEPTIONS 1184 catch(...) { 1185 start.set_node(start.node + 1); 1186 start.cur = start.first; 1187 deallocate_node(*(start.node - 1)); 1188 throw; 1189 } 1190 # endif /* __STL_USE_EXCEPTIONS */ 1191 } 1192 1193 // Called only if finish.cur == finish.first. 1194 template <class T, class Alloc, size_t BufSize> 1195 void deque<T, Alloc, BufSize>:: pop_back_aux() 1196 { 1197 deallocate_node(finish.first); 1198 finish.set_node(finish.node - 1); 1199 finish.cur = finish.last - 1; 1200 destroy(finish.cur); 1201 } 1202 1203 // Called only if start.cur == start.last - 1. Note that if the deque 1204 // has at least one element (a necessary precondition for this member 1205 // function), and if start.cur == start.last, then the deque must have 1206 // at least two nodes. 1207 template <class T, class Alloc, size_t BufSize> 1208 void deque<T, Alloc, BufSize>::pop_front_aux() 1209 { 1210 destroy(start.cur); 1211 deallocate_node(start.first); 1212 start.set_node(start.node + 1); 1213 start.cur = start.first; 1214 } 1215 1216 #ifdef __STL_MEMBER_TEMPLATES 1217 1218 // 将[first, last)区间元素插入到pos前 1219 1220 template <class T, class Alloc, size_t BufSize> 1221 template <class InputIterator> 1222 void deque<T, Alloc, BufSize>::insert(iterator pos, 1223 InputIterator first, InputIterator last, 1224 input_iterator_tag) 1225 { 1226 // 由于是Input Iterator, 则使用通用的inserter完成插入操作 1227 copy(first, last, inserter(*this, pos)); 1228 } 1229 1230 1231 template <class T, class Alloc, size_t BufSize> 1232 template <class ForwardIterator> 1233 void deque<T, Alloc, BufSize>::insert(iterator pos, 1234 ForwardIterator first, 1235 ForwardIterator last, 1236 forward_iterator_tag) 1237 { 1238 size_type n = 0; 1239 distance(first, last, n); 1240 if (pos.cur == start.cur) { 1241 iterator new_start = reserve_elements_at_front(n); 1242 __STL_TRY { 1243 uninitialized_copy(first, last, new_start); 1244 start = new_start; 1245 } 1246 __STL_UNWIND(destroy_nodes_at_front(new_start)); 1247 } 1248 else if (pos.cur == finish.cur) { 1249 iterator new_finish = reserve_elements_at_back(n); 1250 __STL_TRY { 1251 uninitialized_copy(first, last, finish); 1252 finish = new_finish; 1253 } 1254 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 1255 } 1256 else 1257 insert_aux(pos, first, last, n); 1258 } 1259 1260 #endif /* __STL_MEMBER_TEMPLATES */ 1261 1262 //// 1263 // 在指定位置前插入元素 1264 //// 1265 // insert_aux(iterator pos, const value_type& x) 1266 // | 1267 // |----------- 判断pos前端元素少还是后端元素少 1268 // | 1269 // ----------------------------------------------- 1270 // 前端少 | 后端少 | 1271 // | | 1272 // ↓ | 1273 // 进行相关操作 进行相关操作 1274 //// 1275 // 下面以pos前面元素少的情形进行说明, 为了简化, 假设操作不会超过一个缓冲区区间 1276 // 1277 // 插入前状态 1278 // start pos end 1279 // ↓ ↓ ↓ 1280 // --------------------------------------------------------------------- 1281 // | | | | | | | | | | | | | | | | | X | 1282 // --------------------------------------------------------------------- 1283 // 1284 // 需要进行操作的区间 1285 // 需要拷贝的区间 1286 // ------------- 1287 // start | | end 1288 // ↓ ↓ ↓ ↓ 1289 // --------------------------------------------------------------------- 1290 // | | | | | | | | | | | | | | | | | X | 1291 // --------------------------------------------------------------------- 1292 // ↑ ↑ ↑ ↑ 1293 // front1 | | | 1294 // | | | 1295 // front2 | | 1296 // | | 1297 // pos | 1298 // | 1299 // pos1 1300 // 拷贝操作完成后 1301 // 1302 // 这是[front2, pos1) 1303 // ------------- --------- 这里是给待插入元素预留的空间 1304 // start | | | end 1305 // ↓ ↓ ↓ ↓ ↓ 1306 // --------------------------------------------------------------------- 1307 // | | | | | | | | | | | | | | | | | X | 1308 // --------------------------------------------------------------------- 1309 // ↑ 1310 // 这里存储的是原来的front() 1311 // 1312 //// 1313 1314 template <class T, class Alloc, size_t BufSize> 1315 typename deque<T, Alloc, BufSize>::iterator 1316 deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) 1317 { 1318 difference_type index = pos - start; 1319 value_type x_copy = x; 1320 1321 // 前面的时候用的移位操作, 这里怎么不用了呢^_^? 1322 if (index < size() / 2) { 1323 push_front(front()); 1324 iterator front1 = start; 1325 ++front1; 1326 iterator front2 = front1; 1327 ++front2; 1328 pos = start + index; 1329 iterator pos1 = pos; 1330 ++pos1; 1331 copy(front2, pos1, front1); 1332 } 1333 else { 1334 push_back(back()); 1335 iterator back1 = finish; 1336 --back1; 1337 iterator back2 = back1; 1338 --back2; 1339 pos = start + index; 1340 copy_backward(pos, back2, back1); 1341 } 1342 *pos = x_copy; 1343 return pos; 1344 } 1345 1346 //// 1347 // 在pos前插入n个值为x的元素 1348 //// 1349 // insert_aux(iterator pos, size_type n, const value_type& x) 1350 // ↓ 1351 // elems_before = pos - start; 1352 // length = size(); 1353 // | 1354 // |---------- elems_before < length / 2 ? 1355 // | 判断哪侧元素少, 就对哪侧进行操作 1356 // --------------------------------------- 1357 // Yes | | No 1358 // | | 1359 // ↓ ↓ 1360 // reserve_elements_at_front(n); reserve_elements_at_back(n); 1361 // 根据具体情况进行元素的拷贝操作 根据具体情况进行元素的拷贝操作 1362 //// 1363 1364 template <class T, class Alloc, size_t BufSize> 1365 void deque<T, Alloc, BufSize>::insert_aux(iterator pos, 1366 size_type n, const value_type& x) 1367 { 1368 const difference_type elems_before = pos - start; 1369 size_type length = size(); 1370 value_type x_copy = x; 1371 if (elems_before < length / 2) { 1372 iterator new_start = reserve_elements_at_front(n); 1373 iterator old_start = start; 1374 pos = start + elems_before; 1375 __STL_TRY { 1376 if (elems_before >= difference_type(n)) { 1377 iterator start_n = start + difference_type(n); 1378 uninitialized_copy(start, start_n, new_start); 1379 start = new_start; 1380 copy(start_n, pos, old_start); 1381 fill(pos - difference_type(n), pos, x_copy); 1382 } 1383 else { 1384 __uninitialized_copy_fill(start, pos, new_start, start, x_copy); 1385 start = new_start; 1386 fill(old_start, pos, x_copy); 1387 } 1388 } 1389 __STL_UNWIND(destroy_nodes_at_front(new_start)); 1390 } 1391 else { 1392 iterator new_finish = reserve_elements_at_back(n); 1393 iterator old_finish = finish; 1394 const difference_type elems_after = difference_type(length) - elems_before; 1395 pos = finish - elems_after; 1396 __STL_TRY { 1397 if (elems_after > difference_type(n)) { 1398 iterator finish_n = finish - difference_type(n); 1399 uninitialized_copy(finish_n, finish, finish); 1400 finish = new_finish; 1401 copy_backward(pos, finish_n, old_finish); 1402 fill(pos, pos + difference_type(n), x_copy); 1403 } 1404 else { 1405 __uninitialized_fill_copy(finish, pos + difference_type(n), 1406 x_copy, 1407 pos, finish); 1408 finish = new_finish; 1409 fill(pos, old_finish, x_copy); 1410 } 1411 } 1412 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 1413 } 1414 } 1415 1416 #ifdef __STL_MEMBER_TEMPLATES 1417 1418 // 供给insert(iterator pos, ForwardIterator first, ForwardIterator last,) 1419 // 处理通用情况 1420 template <class T, class Alloc, size_t BufSize> 1421 template <class ForwardIterator> 1422 void deque<T, Alloc, BufSize>::insert_aux(iterator pos, 1423 ForwardIterator first, 1424 ForwardIterator last, 1425 size_type n) 1426 { 1427 const difference_type elems_before = pos - start; 1428 size_type length = size(); 1429 if (elems_before < length / 2) { 1430 iterator new_start = reserve_elements_at_front(n); 1431 iterator old_start = start; 1432 pos = start + elems_before; 1433 __STL_TRY { 1434 if (elems_before >= difference_type(n)) { 1435 iterator start_n = start + difference_type(n); 1436 uninitialized_copy(start, start_n, new_start); 1437 start = new_start; 1438 copy(start_n, pos, old_start); 1439 copy(first, last, pos - difference_type(n)); 1440 } 1441 else { 1442 ForwardIterator mid = first; 1443 advance(mid, difference_type(n) - elems_before); 1444 __uninitialized_copy_copy(start, pos, first, mid, new_start); 1445 start = new_start; 1446 copy(mid, last, old_start); 1447 } 1448 } 1449 __STL_UNWIND(destroy_nodes_at_front(new_start)); 1450 } 1451 else { 1452 iterator new_finish = reserve_elements_at_back(n); 1453 iterator old_finish = finish; 1454 const difference_type elems_after = difference_type(length) - elems_before; 1455 pos = finish - elems_after; 1456 __STL_TRY { 1457 if (elems_after > difference_type(n)) { 1458 iterator finish_n = finish - difference_type(n); 1459 uninitialized_copy(finish_n, finish, finish); 1460 finish = new_finish; 1461 copy_backward(pos, finish_n, old_finish); 1462 copy(first, last, pos); 1463 } 1464 else { 1465 ForwardIterator mid = first; 1466 advance(mid, elems_after); 1467 __uninitialized_copy_copy(mid, last, pos, finish, finish); 1468 finish = new_finish; 1469 copy(first, mid, pos); 1470 } 1471 } 1472 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 1473 } 1474 } 1475 1476 #else /* __STL_MEMBER_TEMPLATES */ 1477 1478 template <class T, class Alloc, size_t BufSize> 1479 void deque<T, Alloc, BufSize>::insert_aux(iterator pos, 1480 const value_type* first, 1481 const value_type* last, 1482 size_type n) 1483 { 1484 const difference_type elems_before = pos - start; 1485 size_type length = size(); 1486 if (elems_before < length / 2) { 1487 iterator new_start = reserve_elements_at_front(n); 1488 iterator old_start = start; 1489 pos = start + elems_before; 1490 __STL_TRY { 1491 if (elems_before >= difference_type(n)) { 1492 iterator start_n = start + difference_type(n); 1493 uninitialized_copy(start, start_n, new_start); 1494 start = new_start; 1495 copy(start_n, pos, old_start); 1496 copy(first, last, pos - difference_type(n)); 1497 } 1498 else { 1499 const value_type* mid = first + (difference_type(n) - elems_before); 1500 __uninitialized_copy_copy(start, pos, first, mid, new_start); 1501 start = new_start; 1502 copy(mid, last, old_start); 1503 } 1504 } 1505 __STL_UNWIND(destroy_nodes_at_front(new_start)); 1506 } 1507 else { 1508 iterator new_finish = reserve_elements_at_back(n); 1509 iterator old_finish = finish; 1510 const difference_type elems_after = difference_type(length) - elems_before; 1511 pos = finish - elems_after; 1512 __STL_TRY { 1513 if (elems_after > difference_type(n)) { 1514 iterator finish_n = finish - difference_type(n); 1515 uninitialized_copy(finish_n, finish, finish); 1516 finish = new_finish; 1517 copy_backward(pos, finish_n, old_finish); 1518 copy(first, last, pos); 1519 } 1520 else { 1521 const value_type* mid = first + elems_after; 1522 __uninitialized_copy_copy(mid, last, pos, finish, finish); 1523 finish = new_finish; 1524 copy(first, mid, pos); 1525 } 1526 } 1527 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 1528 } 1529 } 1530 1531 template <class T, class Alloc, size_t BufSize> 1532 void deque<T, Alloc, BufSize>::insert_aux(iterator pos, 1533 const_iterator first, 1534 const_iterator last, 1535 size_type n) 1536 { 1537 const difference_type elems_before = pos - start; 1538 size_type length = size(); 1539 if (elems_before < length / 2) { 1540 iterator new_start = reserve_elements_at_front(n); 1541 iterator old_start = start; 1542 pos = start + elems_before; 1543 __STL_TRY { 1544 if (elems_before >= n) { 1545 iterator start_n = start + n; 1546 uninitialized_copy(start, start_n, new_start); 1547 start = new_start; 1548 copy(start_n, pos, old_start); 1549 copy(first, last, pos - difference_type(n)); 1550 } 1551 else { 1552 const_iterator mid = first + (n - elems_before); 1553 __uninitialized_copy_copy(start, pos, first, mid, new_start); 1554 start = new_start; 1555 copy(mid, last, old_start); 1556 } 1557 } 1558 __STL_UNWIND(destroy_nodes_at_front(new_start)); 1559 } 1560 else { 1561 iterator new_finish = reserve_elements_at_back(n); 1562 iterator old_finish = finish; 1563 const difference_type elems_after = length - elems_before; 1564 pos = finish - elems_after; 1565 __STL_TRY { 1566 if (elems_after > n) { 1567 iterator finish_n = finish - difference_type(n); 1568 uninitialized_copy(finish_n, finish, finish); 1569 finish = new_finish; 1570 copy_backward(pos, finish_n, old_finish); 1571 copy(first, last, pos); 1572 } 1573 else { 1574 const_iterator mid = first + elems_after; 1575 __uninitialized_copy_copy(mid, last, pos, finish, finish); 1576 finish = new_finish; 1577 copy(first, mid, pos); 1578 } 1579 } 1580 __STL_UNWIND(destroy_nodes_at_back(new_finish)); 1581 } 1582 } 1583 1584 #endif /* __STL_MEMBER_TEMPLATES */ 1585 1586 // 在deque前端分配新结点 1587 template <class T, class Alloc, size_t BufSize> 1588 void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) 1589 { 1590 size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); 1591 reserve_map_at_front(new_nodes); 1592 size_type i; 1593 __STL_TRY { 1594 for (i = 1; i <= new_nodes; ++i) 1595 *(start.node - i) = allocate_node(); 1596 } 1597 # ifdef __STL_USE_EXCEPTIONS 1598 catch(...) { 1599 for (size_type j = 1; j < i; ++j) 1600 deallocate_node(*(start.node - j)); 1601 throw; 1602 } 1603 # endif /* __STL_USE_EXCEPTIONS */ 1604 } 1605 1606 // 在deque末尾分配新结点 1607 template <class T, class Alloc, size_t BufSize> 1608 void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) { 1609 size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); 1610 reserve_map_at_back(new_nodes); 1611 size_type i; 1612 __STL_TRY { 1613 for (i = 1; i <= new_nodes; ++i) 1614 *(finish.node + i) = allocate_node(); 1615 } 1616 # ifdef __STL_USE_EXCEPTIONS 1617 catch(...) { 1618 for (size_type j = 1; j < i; ++j) 1619 deallocate_node(*(finish.node + j)); 1620 throw; 1621 } 1622 # endif /* __STL_USE_EXCEPTIONS */ 1623 } 1624 1625 // 释放[before_start.node, start.node)的结点 1626 template <class T, class Alloc, size_t BufSize> 1627 void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) 1628 { 1629 for (map_pointer n = before_start.node; n < start.node; ++n) 1630 deallocate_node(*n); 1631 } 1632 1633 // 释放(finish.node, after_finish.node]的结点 1634 template <class T, class Alloc, size_t BufSize> 1635 void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) 1636 { 1637 for (map_pointer n = after_finish.node; n > finish.node; --n) 1638 deallocate_node(*n); 1639 } 1640 1641 // 重新配置map, 不会对缓冲区进行操作, map维护的是指向缓冲区的指针 1642 template <class T, class Alloc, size_t BufSize> 1643 void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add, 1644 bool add_at_front) 1645 { 1646 size_type old_num_nodes = finish.node - start.node + 1; 1647 size_type new_num_nodes = old_num_nodes + nodes_to_add; 1648 1649 map_pointer new_nstart; 1650 if (map_size > 2 * new_num_nodes) { 1651 new_nstart = map + (map_size - new_num_nodes) / 2 1652 + (add_at_front ? nodes_to_add : 0); 1653 if (new_nstart < start.node) 1654 copy(start.node, finish.node + 1, new_nstart); 1655 else 1656 copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes); 1657 } 1658 else { 1659 size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2; 1660 1661 map_pointer new_map = map_allocator::allocate(new_map_size); 1662 new_nstart = new_map + (new_map_size - new_num_nodes) / 2 1663 + (add_at_front ? nodes_to_add : 0); 1664 copy(start.node, finish.node + 1, new_nstart); 1665 map_allocator::deallocate(map, map_size); 1666 1667 map = new_map; 1668 map_size = new_map_size; 1669 } 1670 1671 start.set_node(new_nstart); 1672 finish.set_node(new_nstart + old_num_nodes - 1); 1673 } 1674 1675 1676 // Nonmember functions. 1677 1678 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG 1679 1680 template <class T, class Alloc, size_t BufSiz> 1681 bool operator==(const deque<T, Alloc, BufSiz>& x, 1682 const deque<T, Alloc, BufSiz>& y) { 1683 return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); 1684 } 1685 1686 template <class T, class Alloc, size_t BufSiz> 1687 bool operator<(const deque<T, Alloc, BufSiz>& x, 1688 const deque<T, Alloc, BufSiz>& y) { 1689 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); 1690 } 1691 1692 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ 1693 1694 #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ 1695 !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) 1696 1697 template <class T, class Alloc, size_t BufSiz> 1698 inline void swap(deque<T, Alloc, BufSiz>& x, deque<T, Alloc, BufSiz>& y) { 1699 x.swap(y); 1700 } 1701 1702 #endif 1703 1704 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 1705 #pragma reset woff 1174 1706 #endif 1707 1708 __STL_END_NAMESPACE 1709 1710 #endif /* __SGI_STL_INTERNAL_DEQUE_H */ 1711 1712 // Local Variables: 1713 // mode:C++ 1714 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_stack.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 //// 8 // stack是一种先进后出(First In Last Out, FILO)的数据结构, 其只有一个出口 9 // 支持对栈顶元素的追加, 弹出, 获取, 但是不提供对其它位置元素的访问 10 //// 11 // 以下为使用deque时的布局 12 // 13 // 栈底 当前栈顶 预留的内存边界 14 // ↓ ↓ ↓ 15 // -------------------------------------------------------------------- 16 // | | | ...... | | | | | | | | ...... | | | X | 17 // -------------------------------------------------------------------- 18 // ↑ ↑ ↑ 19 // | | | 20 // | ------------------------------- 21 // | 这里是尚未使用的预留内存, 可能为0 22 // | 23 // 仅支持在这里进行push(), pop(), top()操作 24 //// 25 26 /* 27 * 28 * Copyright (c) 1994 29 * Hewlett-Packard Company 30 * 31 * Permission to use, copy, modify, distribute and sell this software 32 * and its documentation for any purpose is hereby granted without fee, 33 * provided that the above copyright notice appear in all copies and 34 * that both that copyright notice and this permission notice appear 35 * in supporting documentation. Hewlett-Packard Company makes no 36 * representations about the suitability of this software for any 37 * purpose. It is provided "as is" without express or implied warranty. 38 * 39 * 40 * Copyright (c) 1996,1997 41 * Silicon Graphics Computer Systems, Inc. 42 * 43 * Permission to use, copy, modify, distribute and sell this software 44 * and its documentation for any purpose is hereby granted without fee, 45 * provided that the above copyright notice appear in all copies and 46 * that both that copyright notice and this permission notice appear 47 * in supporting documentation. Silicon Graphics makes no 48 * representations about the suitability of this software for any 49 * purpose. It is provided "as is" without express or implied warranty. 50 */ 51 52 /* NOTE: This is an internal header file, included by other STL headers. 53 * You should not attempt to use it directly. 54 */ 55 56 #ifndef __SGI_STL_INTERNAL_STACK_H 57 #define __SGI_STL_INTERNAL_STACK_H 58 59 __STL_BEGIN_NAMESPACE 60 61 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 62 // 那么就需要手工指定, 本实作stack内部容器默认使用deque 63 // 选用deque可以在存储空间不足时可以动态增加, 而且代价很低 64 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 65 template <class T, class Sequence = deque<T> > 66 #else 67 template <class T, class Sequence> 68 #endif 69 class stack 70 { 71 // 特化的全局运算符, 提供operator==和<重载则构建出所有运算符 72 // 其具体细节见<stl_pair.h>中的说明 73 friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); 74 friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); 75 76 public: 77 // 由于stack仅支持对栈顶元素的操作, 所以不定义STL要求的 78 // pointer, iterator, difference_type 79 typedef typename Sequence::value_type value_type; 80 typedef typename Sequence::size_type size_type; 81 typedef typename Sequence::reference reference; 82 typedef typename Sequence::const_reference const_reference; 83 84 protected: 85 Sequence c; // 这个是我们实际维护的容器 86 87 public: 88 // 下面的操作完全使用内部容器的成员函数实现 89 // 这再次体现了STL高度的可复用性:-) 90 91 // 判断stack是否为空 92 bool empty() const { return c.empty(); } 93 94 // stack中元素个数 95 size_type size() const { return c.size(); } 96 97 // 返回栈顶元素, 注意这里返回的是引用!!! 98 reference top() { return c.back(); } 99 const_reference top() const { return c.back(); } 100 101 // 在栈顶追加新元素 102 void push(const value_type& x) { c.push_back(x); } 103 104 // 移除栈顶元素, 注意不返回元素的引用, 105 // 很多初学者随机用此容器时经常误认为pop()操作同时会返回栈顶元素的引用 106 void pop() { c.pop_back(); } 107 }; 108 109 // 判断两个stack是否相等, 就要测试其内部维护容器是否相等 110 // x.c == y.c会调用容器重载的operator == 111 template <class T, class Sequence> 112 bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) 113 { 114 return x.c == y.c; 115 } 116 117 template <class T, class Sequence> 118 bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) 119 { 120 return x.c < y.c; 121 } 122 123 __STL_END_NAMESPACE 124 125 #endif /* __SGI_STL_INTERNAL_STACK_H */ 126 127 // Local Variables: 128 // mode:C++ 129 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_queue.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 //// 8 // queue是一种先进先出(First In First Out, FIFO)的数据结构 9 // 它在前后有两个出口, 分别成为队头和队尾 10 // queue允许在队尾追加元素和访问队尾元素, 在队头获取和移除元素 11 // 除此之外其不支持其它元素的访问 12 //// 13 // 以下为使用deque时的布局 14 // 15 // 支持front()和pop() 支持back()和push() 16 // ↓ ↓ 17 // 队头, 队尾 18 // ↓ ↓ 19 // --------------------------------------------------------------------- 20 // | | | ...... | | | ...... | | | | ...... | | | X | 21 // --------------------------------------------------------------------- 22 // ↑ ↑ ↑ ↑ 23 // | | | | 24 // ---------------------- ----------------------- 25 // 这里是尚未使用的预留内存, 可能为0 这里是尚未使用的预留内存, 可能为0 26 // 27 //// 28 29 //// 30 // priority_queue是一种允许用户以任何顺序将任何元素压入容器, 31 // 但是取出元素时一定是从最高优先级的元素开始取出 32 // 其默认使用的是vector作为容器, 默认的优先级比较使用less 33 // 其算法是使用binary-heap 34 //// 35 // 下面是其原理模型, 容器使用vector, 优先级比较决议用less 36 // 37 // 队尾, 支持push() 38 // ↓ 39 // -------------------------------------------------------- 40 // 支持pop()和top()--->| | | ...... | | | | | ...... | | | X | 41 // -------------------------------------------------------- 42 // ↑ ↑ ↑ 43 // | ----------------------- 44 // 内部使用的是heap 这里是尚未使用的预留内存, 可能为0 45 //// 46 // 下面是容器使用vector, 优先级比较决议用less的情况下的一种实现技巧, 47 // 借用的是侯捷老师的例子, 本实作中使用的不是此技巧 48 // [A] 49 // | 50 // --------------------------------- 51 // | | 52 // [B] [C] 53 // | | 54 // ----------------------- ----------------------- 55 // | | | | 56 // [D] [E] [F] [G] 57 // | | 58 // ----------- | 59 // | | | 60 // [H] [I] [J] 61 // vector中预留的内存, 了能为0 62 // ------------------ 63 // ↓ ↓ 64 // -------------------------------------------------------------------------- 65 // | Not Use | A | B | C | D | E | F | G | H | I | J | | ...... | | end | 66 // -------------------------------------------------------------------------- 67 // 68 // 具体算法请参看任意一本算法书, 如果没有, 扔了它:-) 69 //// 70 71 /* 72 * 73 * Copyright (c) 1994 74 * Hewlett-Packard Company 75 * 76 * Permission to use, copy, modify, distribute and sell this software 77 * and its documentation for any purpose is hereby granted without fee, 78 * provided that the above copyright notice appear in all copies and 79 * that both that copyright notice and this permission notice appear 80 * in supporting documentation. Hewlett-Packard Company makes no 81 * representations about the suitability of this software for any 82 * purpose. It is provided "as is" without express or implied warranty. 83 * 84 * 85 * Copyright (c) 1996,1997 86 * Silicon Graphics Computer Systems, Inc. 87 * 88 * Permission to use, copy, modify, distribute and sell this software 89 * and its documentation for any purpose is hereby granted without fee, 90 * provided that the above copyright notice appear in all copies and 91 * that both that copyright notice and this permission notice appear 92 * in supporting documentation. Silicon Graphics makes no 93 * representations about the suitability of this software for any 94 * purpose. It is provided "as is" without express or implied warranty. 95 */ 96 97 /* NOTE: This is an internal header file, included by other STL headers. 98 * You should not attempt to use it directly. 99 */ 100 101 #ifndef __SGI_STL_INTERNAL_QUEUE_H 102 #define __SGI_STL_INTERNAL_QUEUE_H 103 104 __STL_BEGIN_NAMESPACE 105 106 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 107 // 那么就需要手工指定, 本实作queue内部容器默认使用deque 108 // 由于queue要求在队尾追加元素, 在队头获取和移除元素 109 // 所以非常适合使用deque 110 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 111 template <class T, class Sequence = deque<T> > 112 #else 113 template <class T, class Sequence> 114 #endif 115 class queue 116 { 117 // 讲解见<stl_pair.h>中的运算符剖析 118 friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); 119 friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); 120 121 public: 122 // 由于queue仅支持对队头和队尾的操作, 所以不定义STL要求的 123 // pointer, iterator, difference_type 124 typedef typename Sequence::value_type value_type; 125 typedef typename Sequence::size_type size_type; 126 typedef typename Sequence::reference reference; 127 typedef typename Sequence::const_reference const_reference; 128 129 protected: 130 Sequence c; // 这个是我们实际维护的容器 131 132 public: 133 134 // 这些是STL queue的标准接口, 都调用容器的成员函数进行实现 135 // 其接口和stack实现很接近, 参考<stl_stack.h> 136 bool empty() const { return c.empty(); } 137 size_type size() const { return c.size(); } 138 reference front() { return c.front(); } 139 const_reference front() const { return c.front(); } 140 reference back() { return c.back(); } 141 const_reference back() const { return c.back(); } 142 void push(const value_type& x) { c.push_back(x); } 143 void pop() { c.pop_front(); } 144 }; 145 146 // 详细讲解见<stl_pair.h> 147 template <class T, class Sequence> 148 bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) 149 { 150 return x.c == y.c; 151 } 152 153 template <class T, class Sequence> 154 bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) 155 { 156 return x.c < y.c; 157 } 158 159 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 160 template <class T, class Sequence = vector<T>, 161 class Compare = less<typename Sequence::value_type> > 162 #else 163 template <class T, class Sequence, class Compare> 164 #endif 165 class priority_queue 166 { 167 public: 168 typedef typename Sequence::value_type value_type; 169 typedef typename Sequence::size_type size_type; 170 typedef typename Sequence::reference reference; 171 typedef typename Sequence::const_reference const_reference; 172 173 protected: 174 Sequence c; // 内部维护的容器 175 Compare comp; // 优先级决策判别式 176 177 public: 178 priority_queue() : c() {} 179 180 // 用户可以指定自己的优先级决策函数 181 explicit priority_queue(const Compare& x) : c(), comp(x) {} 182 183 // 使用[first, last)区间构造priority_queue 184 #ifdef __STL_MEMBER_TEMPLATES 185 template <class InputIterator> 186 priority_queue(InputIterator first, InputIterator last, const Compare& x) 187 : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } 188 template <class InputIterator> 189 priority_queue(InputIterator first, InputIterator last) 190 : c(first, last) { make_heap(c.begin(), c.end(), comp); } 191 #else /* __STL_MEMBER_TEMPLATES */ 192 priority_queue(const value_type* first, const value_type* last, 193 const Compare& x) : c(first, last), comp(x) { 194 make_heap(c.begin(), c.end(), comp); 195 } 196 priority_queue(const value_type* first, const value_type* last) 197 : c(first, last) { make_heap(c.begin(), c.end(), comp); } 198 #endif /* __STL_MEMBER_TEMPLATES */ 199 200 // STL priority_queue标准接口 201 bool empty() const { return c.empty(); } 202 size_type size() const { return c.size(); } 203 204 // 返回优先级最高的元素 205 const_reference top() const { return c.front(); } 206 207 // 插入元素, 并调整heap 208 void push(const value_type& x) 209 { 210 __STL_TRY { 211 c.push_back(x); 212 // 详细分析见<stl_heap.h> 213 push_heap(c.begin(), c.end(), comp); 214 } 215 __STL_UNWIND(c.clear()); 216 } 217 218 // 弹出优先级最高的元素 219 void pop() { 220 __STL_TRY { 221 // 详细分析见<stl_heap.h> 222 pop_heap(c.begin(), c.end(), comp); 223 c.pop_back(); 224 } 225 __STL_UNWIND(c.clear()); 226 } 227 }; 228 229 // 不提供比较操作 230 231 __STL_END_NAMESPACE 232 233 #endif /* __SGI_STL_INTERNAL_QUEUE_H */ 234 235 // Local Variables: 236 // mode:C++ 237 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.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_base 136 { 137 T data; 138 }; 139 140 struct __slist_iterator_base 141 { 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) const 152 { 153 return node == x.node; 154 } 155 bool operator!=(const __slist_iterator_base& x) const 156 { 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_base 166 { 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_OPERATOR 182 // 如果编译器支持'->'则重载, 详细见我在<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_SPECIALIZATION 200 201 inline ptrdiff_t* 202 distance_type(const __slist_iterator_base&) 203 { 204 return 0; 205 } 206 207 inline forward_iterator_tag 208 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 slist 232 { 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_TEMPLATES 300 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_TEMPLATES 338 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) const 409 { 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_TEMPLATES 431 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_TEMPLATES 506 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_TEMPLATES 547 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 immediately 598 // 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_TEMPLATES 642 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 else 666 _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_ORDER 698 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 else 721 _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 else 732 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 else 745 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_TEMPLATES 792 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 else 801 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 else 814 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 1174 865 #endif 866 867 __STL_END_NAMESPACE 868 869 #endif /* __SGI_STL_INTERNAL_SLIST_H */ 870 871 // Local Variables: 872 // mode:C++ 873 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_heap.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * Copyright (c) 1997 21 * Silicon Graphics Computer Systems, Inc. 22 * 23 * Permission to use, copy, modify, distribute and sell this software 24 * and its documentation for any purpose is hereby granted without fee, 25 * provided that the above copyright notice appear in all copies and 26 * that both that copyright notice and this permission notice appear 27 * in supporting documentation. Silicon Graphics makes no 28 * representations about the suitability of this software for any 29 * purpose. It is provided "as is" without express or implied warranty. 30 */ 31 32 /* NOTE: This is an internal header file, included by other STL headers. 33 * You should not attempt to use it directly. 34 */ 35 36 #ifndef __SGI_STL_INTERNAL_HEAP_H 37 #define __SGI_STL_INTERNAL_HEAP_H 38 39 __STL_BEGIN_NAMESPACE 40 41 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 42 #pragma set woff 1209 43 #endif 44 45 //// 46 // 注意: push_heap()操作前要保证新添加的元素已经加入到容器末尾!!! 47 //// 48 // 下面是使用默认比较函数的一个实例, XXX代表需要调整结点的位置 49 // 执行插入前, 元素已经追加到容器尾, 其值为450, 这里我们只 50 // 关注其位置, 不表示出其数值 51 // [500] 52 // | 53 // --------------------------------- 54 // | | 55 // [300] [400] 56 // | | 57 // ----------------------- ----------------------- 58 // | | | | 59 // [200] [270] [350] [240] 60 // | | 61 // ----------- ----------- 62 // | | | | 63 // [150] [130] [120] [XXX] 64 // 65 // first last 66 // ↓ ↓ 67 // -------------------------------------------------------------------------------------------- 68 // | Not Use | 500 | 300 | 400 | 200 | 270 | 350 | 240 | 150 | 130 | 120 | XXX | ...... | end | 69 // -------------------------------------------------------------------------------------------- 70 // 71 // 下面是移动步骤及内存变化 72 // [500] 73 // | 74 // --------------------------------- 75 // | | 76 // [300] [400] 77 // | | 78 // ----------------------- ----------------------- 79 // | | | | 80 // [200] [XXX]------- [350] [240] 81 // | | | 82 // ----------- ----------- | 83 // | | | | | 调整元素位置 84 // [150] [130] [120] [270]-- 85 // 86 // first last 87 // ↓ ↓ 88 // -------------------------------------------------------------------------------------------- 89 // | Not Use | 500 | 300 | 400 | 200 | XXX | 350 | 240 | 150 | 130 | 120 | 270 | ...... | end | 90 // -------------------------------------------------------------------------------------------- 91 // 92 // [500] 93 // | 94 // --------------------------------- 95 // | | 96 // [XXX]------------- 交换 [400] 97 // | | | 98 // ----------------------- | ----------------------- 99 // | | | | | 100 // [200] [300]-- [350] [240] 101 // | | 102 // ----------- ----------- 103 // | | | | 104 // [150] [130] [120] [270] 105 // 106 // first last 107 // ↓ ↓ 108 // -------------------------------------------------------------------------------------------- 109 // | Not Use | 500 | XXX | 400 | 200 | 300 | 350 | 240 | 150 | 130 | 120 | 270 | ...... | end | 110 // -------------------------------------------------------------------------------------------- 111 // 112 // 现在满足heap的要求了, 对[XXX]直接赋值即可 113 // 114 //// 115 116 template <class RandomAccessIterator, class Distance, class T> 117 void __push_heap(RandomAccessIterator first, Distance holeIndex, 118 Distance topIndex, T value) 119 { 120 // 首先找出待处理元素的父结点 121 Distance parent = (holeIndex - 1) / 2; 122 123 // 判断当前待处理结点是否优先级高于其父结点, 如果是则将其父结点向下移动 124 // 设置当前结点为父结点位置, 继续, 直到优先级小于父结点或者已经到达heap顶端 125 while (holeIndex > topIndex && *(first + parent) < value) { 126 *(first + holeIndex) = *(first + parent); 127 holeIndex = parent; 128 parent = (holeIndex - 1) / 2; 129 } 130 131 // 将找到的合适的位置设置成正确值 132 *(first + holeIndex) = value; 133 } 134 135 template <class RandomAccessIterator, class Distance, class T> 136 inline void __push_heap_aux(RandomAccessIterator first, 137 RandomAccessIterator last, Distance*, T*) 138 { 139 // 因为first所指的那个元素不是heap的组成元素, 所以计算距离要减去1 140 __push_heap(first, Distance((last - first) - 1), Distance(0), 141 T(*(last - 1))); 142 } 143 144 // 调用此函数前要先把待处理元素追加到容器末尾 145 template <class RandomAccessIterator> 146 inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) 147 { 148 __push_heap_aux(first, last, distance_type(first), value_type(first)); 149 } 150 151 template <class RandomAccessIterator, class Distance, class T, class Compare> 152 void __push_heap(RandomAccessIterator first, Distance holeIndex, 153 Distance topIndex, T value, Compare comp) 154 { 155 Distance parent = (holeIndex - 1) / 2; 156 while (holeIndex > topIndex && comp(*(first + parent), value)) { 157 *(first + holeIndex) = *(first + parent); 158 holeIndex = parent; 159 parent = (holeIndex - 1) / 2; 160 } 161 *(first + holeIndex) = value; 162 } 163 164 template <class RandomAccessIterator, class Compare, class Distance, class T> 165 inline void __push_heap_aux(RandomAccessIterator first, 166 RandomAccessIterator last, Compare comp, 167 Distance*, T*) 168 { 169 __push_heap(first, Distance((last - first) - 1), Distance(0), 170 T(*(last - 1)), comp); 171 } 172 173 // 这个除了用户自己指定优先级决策判别式外和默认的无区别 174 template <class RandomAccessIterator, class Compare> 175 inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, 176 Compare comp) 177 { 178 __push_heap_aux(first, last, comp, distance_type(first), value_type(first)); 179 } 180 181 //// 182 // 注意: pop_heap()操作, 执行完操作后要自己将容器尾元素弹出 183 //// 184 // 这里以默认的heap优先级决策来说 185 // STL采用的是先将待pop的元素复制到heap尾部, 然后将整个heap向上调整 186 // 这样就会将最后空出一个hole, 将原来最后的元素在这里进行push()操作 187 // 这就是两个shift_up的过程 188 // 个人感觉使用使用shift_down的算法更高效, 虽然时间复杂度一样, 但是shift_down 189 // 进行操作的元素会更少, 190 // 之所以用shift_up这可能也是STL设计理念的问题吧, 能复用就不写新的^_^ 191 //// 192 // 下面是使用默认比较函数的一个实例, 我们要弹出的是优先级最高的元素[500] 193 // 首先要把弹出的元素[500]复制到heap末尾 194 // 然后进行第一次shift_up, 完成后进行push()操作, 这个就是第二次shift_up了 195 // 196 // [500] 197 // | 198 // --------------------------------- 199 // | | 200 // [300] [400] 201 // | | 202 // ----------------------- ----------------------- 203 // | | | | 204 // [200] [270] [350] [240] 205 // | | 206 // ----------- ----------- 207 // | | | | 208 // [150] [130] [120] [100] 209 // 210 // first last 211 // ↓ ↓ 212 // -------------------------------------------------------------------------------------------- 213 // | Not Use | 500 | 300 | 400 | 200 | 270 | 350 | 240 | 150 | 130 | 120 | 100 | ...... | end | 214 // -------------------------------------------------------------------------------------------- 215 // 216 // 下面是移动步骤及内存变化 复制 217 // [500]---------------------------------- 218 // | | 219 // --------------------------------- | 220 // | | | 221 // [300] [400] | 222 // | | | 223 // ----------------------- ----------------------- | 224 // | | | | | 225 // [200] [270] [350] [240] | 226 // | | | 227 // ----------- ----------- | 228 // | | | | | 229 // [150] [130] [120] [500]---------------------------------- 230 // 231 // first last 232 // ↓ ↓ 233 // -------------------------------------------------------------------------------------------- 234 // | Not Use | 500 | 300 | 400 | 200 | 270 | 350 | 240 | 150 | 130 | 120 | 500 | ...... | end | 235 // -------------------------------------------------------------------------------------------- 236 // 237 // [400]----------------------- 238 // | | 239 // --------------------------------- | shift_up 240 // | | | 241 // [300] [400]------- 242 // | | 243 // ----------------------- ----------------------- 244 // | | | | 245 // [200] [270] [350] [240] 246 // | | 247 // ----------- ----------- 248 // | | | | 249 // [150] [130] [120] [500] 250 // 251 // first last 252 // ↓ ↓ 253 // -------------------------------------------------------------------------------------------- 254 // | Not Use | 400 | 300 | 400 | 200 | 270 | 350 | 240 | 150 | 130 | 120 | 500 | ...... | end | 255 // -------------------------------------------------------------------------------------------- 256 // 257 // [400] 258 // | 259 // --------------------------------- 260 // | | shift_up 261 // [300] [350]------------------- 262 // | | | 263 // ----------------------- ----------------------- | 264 // | | | | | 265 // [200] [270] [350] [240] | 266 // | | | | 267 // ----------- ----------- ---------------------------------- 268 // | | | | 269 // [150] [130] [120] [500] 270 // 271 // first last 272 // ↓ ↓ 273 // -------------------------------------------------------------------------------------------- 274 // | Not Use | 400 | 300 | 350 | 200 | 270 | 350 | 240 | 150 | 130 | 120 | 500 | ...... | end | 275 // -------------------------------------------------------------------------------------------- 276 // 277 // 接下来就是push()操作了, 参考前面的push() 278 //// 279 280 template <class RandomAccessIterator, class Distance, class T> 281 void __adjust_heap(RandomAccessIterator first, Distance holeIndex, 282 Distance len, T value) 283 { 284 Distance topIndex = holeIndex; 285 Distance secondChild = 2 * holeIndex + 2; // 弹出元素的有子孩 286 287 // 调整heap元素位置 288 while (secondChild < len) { 289 // 选择两个子孩中较大的进行操作, 使用secondChild表示其偏移 290 if (*(first + secondChild) < *(first + (secondChild - 1))) 291 secondChild--; 292 293 // 将较大元素向上填充, 并将整体偏移向下调整, 继续调整 294 *(first + holeIndex) = *(first + secondChild); 295 holeIndex = secondChild; 296 secondChild = 2 * (secondChild + 1); 297 } 298 299 if (secondChild == len) { 300 *(first + holeIndex) = *(first + (secondChild - 1)); 301 holeIndex = secondChild - 1; 302 } 303 304 // 这里就是shift_up过程了, 将最初的heap末尾元素向上调整 305 // 侯捷老师对这里的理解有误, :-), 人非圣贤, 孰能无过, ^_^ 306 __push_heap(first, holeIndex, topIndex, value); 307 } 308 309 template <class RandomAccessIterator, class T, class Distance> 310 inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, 311 RandomAccessIterator result, T value, Distance*) 312 { 313 // 将弹出的元素调整到heap末尾, 这个元素需要用户手动弹出 314 *result = *first; 315 316 // 去掉末尾哪个弹出的元素, 调整heap 317 __adjust_heap(first, Distance(0), Distance(last - first), value); 318 } 319 320 template <class RandomAccessIterator, class T> 321 inline void __pop_heap_aux(RandomAccessIterator first, 322 RandomAccessIterator last, T*) 323 { 324 __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first)); 325 } 326 327 template <class RandomAccessIterator> 328 inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) 329 { 330 __pop_heap_aux(first, last, value_type(first)); 331 } 332 333 template <class RandomAccessIterator, class Distance, class T, class Compare> 334 void __adjust_heap(RandomAccessIterator first, Distance holeIndex, 335 Distance len, T value, Compare comp) 336 { 337 Distance topIndex = holeIndex; 338 Distance secondChild = 2 * holeIndex + 2; 339 while (secondChild < len) { 340 if (comp(*(first + secondChild), *(first + (secondChild - 1)))) 341 secondChild--; 342 *(first + holeIndex) = *(first + secondChild); 343 holeIndex = secondChild; 344 secondChild = 2 * (secondChild + 1); 345 } 346 if (secondChild == len) { 347 *(first + holeIndex) = *(first + (secondChild - 1)); 348 holeIndex = secondChild - 1; 349 } 350 __push_heap(first, holeIndex, topIndex, value, comp); 351 } 352 353 template <class RandomAccessIterator, class T, class Compare, class Distance> 354 inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, 355 RandomAccessIterator result, T value, Compare comp, 356 Distance*) 357 { 358 *result = *first; 359 __adjust_heap(first, Distance(0), Distance(last - first), value, comp); 360 } 361 362 template <class RandomAccessIterator, class T, class Compare> 363 inline void __pop_heap_aux(RandomAccessIterator first, 364 RandomAccessIterator last, T*, Compare comp) 365 { 366 __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp, 367 distance_type(first)); 368 } 369 370 template <class RandomAccessIterator, class Compare> 371 inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, 372 Compare comp) 373 { 374 __pop_heap_aux(first, last, value_type(first), comp); 375 } 376 377 // 这个没设么好说的, 参考上面的分析吧 378 template <class RandomAccessIterator, class T, class Distance> 379 void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, 380 Distance*) 381 { 382 if (last - first < 2) return; 383 Distance len = last - first; 384 Distance parent = (len - 2)/2; 385 386 while (true) { 387 __adjust_heap(first, parent, len, T(*(first + parent))); 388 if (parent == 0) return; 389 parent--; 390 } 391 } 392 393 template <class RandomAccessIterator> 394 inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) 395 { 396 __make_heap(first, last, value_type(first), distance_type(first)); 397 } 398 399 template <class RandomAccessIterator, class Compare, class T, class Distance> 400 void __make_heap(RandomAccessIterator first, RandomAccessIterator last, 401 Compare comp, T*, Distance*) 402 { 403 if (last - first < 2) return; 404 Distance len = last - first; 405 Distance parent = (len - 2)/2; 406 407 while (true) { 408 __adjust_heap(first, parent, len, T(*(first + parent)), comp); 409 if (parent == 0) return; 410 parent--; 411 } 412 } 413 414 template <class RandomAccessIterator, class Compare> 415 inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, 416 Compare comp) 417 { 418 __make_heap(first, last, comp, value_type(first), distance_type(first)); 419 } 420 421 // 这个能保证heap有序, 其实个人感觉没啥必要, 这样还不如直接用平衡二叉树 422 template <class RandomAccessIterator> 423 void sort_heap(RandomAccessIterator first, RandomAccessIterator last) 424 { 425 while (last - first > 1) pop_heap(first, last--); 426 } 427 428 template <class RandomAccessIterator, class Compare> 429 void sort_heap(RandomAccessIterator first, RandomAccessIterator last, 430 Compare comp) 431 { 432 while (last - first > 1) pop_heap(first, last--, comp); 433 } 434 435 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 436 #pragma reset woff 1209 437 #endif 438 439 __STL_END_NAMESPACE 440 441 #endif /* __SGI_STL_INTERNAL_HEAP_H */ 442 443 // Local Variables: 444 // mode:C++ 445 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_tree.h 完整列表 2 /* 3 * 4 * Copyright (c) 1996,1997 5 * Silicon Graphics Computer Systems, Inc. 6 * 7 * Permission to use, copy, modify, distribute and sell this software 8 * and its documentation for any purpose is hereby granted without fee, 9 * provided that the above copyright notice appear in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation. Silicon Graphics makes no 12 * representations about the suitability of this software for any 13 * purpose. It is provided "as is" without express or implied warranty. 14 * 15 * 16 * Copyright (c) 1994 17 * Hewlett-Packard Company 18 * 19 * Permission to use, copy, modify, distribute and sell this software 20 * and its documentation for any purpose is hereby granted without fee, 21 * provided that the above copyright notice appear in all copies and 22 * that both that copyright notice and this permission notice appear 23 * in supporting documentation. Hewlett-Packard Company makes no 24 * representations about the suitability of this software for any 25 * purpose. It is provided "as is" without express or implied warranty. 26 * 27 * 28 */ 29 30 /* NOTE: This is an internal header file, included by other STL headers. 31 * You should not attempt to use it directly. 32 */ 33 34 #ifndef __SGI_STL_INTERNAL_TREE_H 35 #define __SGI_STL_INTERNAL_TREE_H 36 37 /* 38 本檔實作Red-black tree(紅-黑樹)class,用以實作 STL 關聯式容器(如set, 39 multiset, map, multimap)。所用之insertion 和deletion 演算法係以 40 Cormen, Leiserson 和 Rivest 所著之 Introduction to Algorithms 41 (MIT Press, 1990) 一書為基礎,唯以下兩點不同: 42 43 (1) header 不僅指向 root,也指向紅黑樹的最左節點,以便實作出常數時間之 44 begin();並且也指向紅黑樹的最右節點,以便set 相關泛型演算法(如set_union 45 等等)有線性時間之表現。 46 47 (2) 當一個即將被刪除之節點擁有兩個子節點時,它的successor node is 48 relinked into its place, rather than copied, 如此一來唯一失效(invalidated)的迭代器就只是那些referring to the deleted node. 49 */ 50 51 #include <stl_algobase.h> 52 #include <stl_alloc.h> 53 #include <stl_construct.h> 54 #include <stl_function.h> 55 56 __STL_BEGIN_NAMESPACE 57 58 typedef bool __rb_tree_color_type; 59 const __rb_tree_color_type __rb_tree_red = false; // 紅色為 0 60 const __rb_tree_color_type __rb_tree_black = true; // 黑色為 1 61 62 struct __rb_tree_node_base 63 { 64 typedef __rb_tree_color_type color_type; 65 typedef __rb_tree_node_base* base_ptr; 66 67 color_type color; // 節點顏色,非紅即黑。 68 base_ptr parent; // RB 樹的許多操作,必須知道父節點。 69 base_ptr left; // 指向左節點。 70 base_ptr right; // 指向右節點。 71 72 static base_ptr minimum(base_ptr x) 73 { 74 while (x->left != 0) x = x->left; // 一直向左走,就會找到最小值, 75 return x; // 這是二元搜尋樹的特性。 76 } 77 78 static base_ptr maximum(base_ptr x) 79 { 80 while (x->right != 0) x = x->right; // 一直向右走,就會找到最大值, 81 return x; // 這是二元搜尋樹的特性。 82 } 83 }; 84 85 template <class Value> 86 struct __rb_tree_node : public __rb_tree_node_base 87 { 88 typedef __rb_tree_node<Value>* link_type; 89 Value value_field; // 節點實值 90 }; 91 92 struct __rb_tree_base_iterator 93 { 94 typedef __rb_tree_node_base::base_ptr base_ptr; 95 typedef bidirectional_iterator_tag iterator_category; 96 typedef ptrdiff_t difference_type; 97 98 base_ptr node; // 它用來與容器之間產生一個連結關係(make a reference) 99 100 // 以下其實可實作於 operator++ 內,因為再無他處會呼叫此函式了。 101 void increment() 102 { 103 if (node->right != 0) { // 如果有右子節點。狀況(1) 104 node = node->right; // 就向右走 105 while (node->left != 0) // 然後一直往左子樹走到底 106 node = node->left; // 即是解答 107 } 108 else { // 沒有右子節點。狀況(2) 109 base_ptr y = node->parent; // 找出父節點 110 while (node == y->right) { // 如果現行節點本身是個右子節點, 111 node = y; // 就一直上溯,直到「不為右子節點」止。 112 y = y->parent; 113 } 114 if (node->right != y) // 「若此時的右子節點不等於此時的父節點」。 115 node = y; // 狀況(3) 此時的父節點即為解答。 116 // 否則此時的node 為解答。狀況(4) 117 } 118 // 注意,以上判斷「若此時的右子節點不等於此時的父節點」,是為了應付一種 119 // 特殊情況:我們欲尋找根節點的下一節點,而恰巧根節點無右子節點。 120 // 當然,以上特殊作法必須配合 RB-tree 根節點與特殊之header 之間的 121 // 特殊關係。 122 } 123 124 // 以下其實可實作於 operator-- 內,因為再無他處會呼叫此函式了。 125 void decrement() 126 { 127 if (node->color == __rb_tree_red && // 如果是紅節點,且 128 node->parent->parent == node) // 父節點的父節點等於自己, 129 node = node->right; // 狀況(1) 右子節點即為解答。 130 // 以上情況發生於node為header時(亦即 node 為 end() 時)。 131 // 注意,header 之右子節點即 mostright,指向整棵樹的 max 節點。 132 else if (node->left != 0) { // 如果有左子節點。狀況(2) 133 base_ptr y = node->left; // 令y指向左子節點 134 while (y->right != 0) // 當y有右子節點時 135 y = y->right; // 一直往右子節點走到底 136 node = y; // 最後即為答案 137 } 138 else { // 既非根節點,亦無左子節點。 139 base_ptr y = node->parent; // 狀況(3) 找出父節點 140 while (node == y->left) { // 當現行節點身為左子節點 141 node = y; // 一直交替往上走,直到現行節點 142 y = y->parent; // 不為左子節點 143 } 144 node = y; // 此時之父節點即為答案 145 } 146 } 147 }; 148 149 template <class Value, class Ref, class Ptr> 150 struct __rb_tree_iterator : public __rb_tree_base_iterator 151 { 152 typedef Value value_type; 153 typedef Ref reference; 154 typedef Ptr pointer; 155 typedef __rb_tree_iterator<Value, Value&, Value*> iterator; 156 typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator; 157 typedef __rb_tree_iterator<Value, Ref, Ptr> self; 158 typedef __rb_tree_node<Value>* link_type; 159 160 __rb_tree_iterator() {} 161 __rb_tree_iterator(link_type x) { node = x; } 162 __rb_tree_iterator(const iterator& it) { node = it.node; } 163 164 reference operator*() const { return link_type(node)->value_field; } 165 #ifndef __SGI_STL_NO_ARROW_OPERATOR 166 pointer operator->() const { return &(operator*()); } 167 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 168 169 self& operator++() { increment(); return *this; } 170 self operator++(int) { 171 self tmp = *this; 172 increment(); 173 return tmp; 174 } 175 176 self& operator--() { decrement(); return *this; } 177 self operator--(int) { 178 self tmp = *this; 179 decrement(); 180 return tmp; 181 } 182 }; 183 184 inline bool operator==(const __rb_tree_base_iterator& x, 185 const __rb_tree_base_iterator& y) { 186 return x.node == y.node; 187 // 兩個迭代器相等,意指其所指的節點相等。 188 } 189 190 inline bool operator!=(const __rb_tree_base_iterator& x, 191 const __rb_tree_base_iterator& y) { 192 return x.node != y.node; 193 // 兩個迭代器不等,意指其所指的節點不等。 194 } 195 196 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 197 198 inline bidirectional_iterator_tag 199 iterator_category(const __rb_tree_base_iterator&) { 200 return bidirectional_iterator_tag(); 201 } 202 203 inline __rb_tree_base_iterator::difference_type* 204 distance_type(const __rb_tree_base_iterator&) { 205 return (__rb_tree_base_iterator::difference_type*) 0; 206 } 207 208 template <class Value, class Ref, class Ptr> 209 inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) { 210 return (Value*) 0; 211 } 212 213 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 214 215 // 以下都是全域函式:__rb_tree_rotate_left(), __rb_tree_rotate_right(), 216 // __rb_tree_rebalance(), __rb_tree_rebalance_for_erase() 217 218 // 新節點必為紅節點。如果安插處之父節點亦為紅節點,就違反紅黑樹規則,此時必須 219 // 做樹形旋轉(及顏色改變,在程式它處)。 220 inline void 221 __rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root) 222 { 223 // x 為旋轉點 224 __rb_tree_node_base* y = x->right; // 令y 為旋轉點的右子節點 225 x->right = y->left; 226 if (y->left !=0) 227 y->left->parent = x; // 別忘了回馬槍設定父節點 228 y->parent = x->parent; 229 230 // 令 y 完全頂替 x 的地位(必須將 x 對其父節點的關係完全接收過來) 231 if (x == root) // x 為根節點 232 root = y; 233 else if (x == x->parent->left) // x 為其父節點的左子節點 234 x->parent->left = y; 235 else // x 為其父節點的右子節點 236 x->parent->right = y; 237 y->left = x; 238 x->parent = y; 239 } 240 241 // 新節點必為紅節點。如果安插處之父節點亦為紅節點,就違反紅黑樹規則,此時必須 242 // 做樹形旋轉(及顏色改變,在程式它處)。 243 inline void 244 __rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) 245 { 246 // x 為旋轉點 247 __rb_tree_node_base* y = x->left; // y 為旋轉點的左子節點 248 x->left = y->right; 249 if (y->right != 0) 250 y->right->parent = x; // 別忘了回馬槍設定父節點 251 y->parent = x->parent; 252 253 // 令 y 完全頂替 x 的地位(必須將 x 對其父節點的關係完全接收過來) 254 if (x == root) // x 為根節點 255 root = y; 256 else if (x == x->parent->right) // x 為其父節點的右子節點 257 x->parent->right = y; 258 else // x 為其父節點的左子節點 259 x->parent->left = y; 260 y->right = x; 261 x->parent = y; 262 } 263 264 // 重新令樹形平衡(改變顏色及旋轉樹形) 265 // 參數一為新增節點,參數二為 root 266 inline void 267 __rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) 268 { 269 x->color = __rb_tree_red; // 新節點必為紅 270 while (x != root && x->parent->color == __rb_tree_red) { // 父節點為紅 271 if (x->parent == x->parent->parent->left) { // 父節點為祖父節點之左子節點 272 __rb_tree_node_base* y = x->parent->parent->right; // 令y 為伯父節點 273 if (y && y->color == __rb_tree_red) { // 伯父節點存在,且為紅 274 x->parent->color = __rb_tree_black; // 更改父節點為黑 275 y->color = __rb_tree_black; // 更改伯父節點為黑 276 x->parent->parent->color = __rb_tree_red; // 更改祖父節點為紅 277 x = x->parent->parent; 278 } 279 else { // 無伯父節點,或伯父節點為黑 280 if (x == x->parent->right) { // 如果新節點為父節點之右子節點 281 x = x->parent; 282 __rb_tree_rotate_left(x, root); // 第一參數為左旋點 283 } 284 x->parent->color = __rb_tree_black; // 改變顏色 285 x->parent->parent->color = __rb_tree_red; 286 __rb_tree_rotate_right(x->parent->parent, root); // 第一參數為右旋點 287 } 288 } 289 else { // 父節點為祖父節點之右子節點 290 __rb_tree_node_base* y = x->parent->parent->left; // 令y 為伯父節點 291 if (y && y->color == __rb_tree_red) { // 有伯父節點,且為紅 292 x->parent->color = __rb_tree_black; // 更改父節點為黑 293 y->color = __rb_tree_black; // 更改伯父節點為黑 294 x->parent->parent->color = __rb_tree_red; // 更改祖父節點為紅 295 x = x->parent->parent; // 準備繼續往上層檢查... 296 } 297 else { // 無伯父節點,或伯父節點為黑 298 if (x == x->parent->left) { // 如果新節點為父節點之左子節點 299 x = x->parent; 300 __rb_tree_rotate_right(x, root); // 第一參數為右旋點 301 } 302 x->parent->color = __rb_tree_black; // 改變顏色 303 x->parent->parent->color = __rb_tree_red; 304 __rb_tree_rotate_left(x->parent->parent, root); // 第一參數為左旋點 305 } 306 } 307 } // while 結束 308 root->color = __rb_tree_black; // 根節點永遠為黑 309 } 310 311 inline __rb_tree_node_base* 312 __rb_tree_rebalance_for_erase(__rb_tree_node_base* z, 313 __rb_tree_node_base*& root, 314 __rb_tree_node_base*& leftmost, 315 __rb_tree_node_base*& rightmost) 316 { 317 __rb_tree_node_base* y = z; 318 __rb_tree_node_base* x = 0; 319 __rb_tree_node_base* x_parent = 0; 320 if (y->left == 0) // z has at most one non-null child. y == z. 321 x = y->right; // x might be null. 322 else 323 if (y->right == 0) // z has exactly one non-null child. y == z. 324 x = y->left; // x is not null. 325 else { // z has two non-null children. Set y to 326 y = y->right; // z's successor. x might be null. 327 while (y->left != 0) 328 y = y->left; 329 x = y->right; 330 } 331 if (y != z) { // relink y in place of z. y is z's successor 332 z->left->parent = y; 333 y->left = z->left; 334 if (y != z->right) { 335 x_parent = y->parent; 336 if (x) x->parent = y->parent; 337 y->parent->left = x; // y must be a left child 338 y->right = z->right; 339 z->right->parent = y; 340 } 341 else 342 x_parent = y; 343 if (root == z) 344 root = y; 345 else if (z->parent->left == z) 346 z->parent->left = y; 347 else 348 z->parent->right = y; 349 y->parent = z->parent; 350 __STD::swap(y->color, z->color); 351 y = z; 352 // y now points to node to be actually deleted 353 } 354 else { // y == z 355 x_parent = y->parent; 356 if (x) x->parent = y->parent; 357 if (root == z) 358 root = x; 359 else 360 if (z->parent->left == z) 361 z->parent->left = x; 362 else 363 z->parent->right = x; 364 if (leftmost == z) 365 if (z->right == 0) // z->left must be null also 366 leftmost = z->parent; 367 // makes leftmost == header if z == root 368 else 369 leftmost = __rb_tree_node_base::minimum(x); 370 if (rightmost == z) 371 if (z->left == 0) // z->right must be null also 372 rightmost = z->parent; 373 // makes rightmost == header if z == root 374 else // x == z->left 375 rightmost = __rb_tree_node_base::maximum(x); 376 } 377 if (y->color != __rb_tree_red) { 378 while (x != root && (x == 0 || x->color == __rb_tree_black)) 379 if (x == x_parent->left) { 380 __rb_tree_node_base* w = x_parent->right; 381 if (w->color == __rb_tree_red) { 382 w->color = __rb_tree_black; 383 x_parent->color = __rb_tree_red; 384 __rb_tree_rotate_left(x_parent, root); 385 w = x_parent->right; 386 } 387 if ((w->left == 0 || w->left->color == __rb_tree_black) && 388 (w->right == 0 || w->right->color == __rb_tree_black)) { 389 w->color = __rb_tree_red; 390 x = x_parent; 391 x_parent = x_parent->parent; 392 } else { 393 if (w->right == 0 || w->right->color == __rb_tree_black) { 394 if (w->left) w->left->color = __rb_tree_black; 395 w->color = __rb_tree_red; 396 __rb_tree_rotate_right(w, root); 397 w = x_parent->right; 398 } 399 w->color = x_parent->color; 400 x_parent->color = __rb_tree_black; 401 if (w->right) w->right->color = __rb_tree_black; 402 __rb_tree_rotate_left(x_parent, root); 403 break; 404 } 405 } else { // same as above, with right <-> left. 406 __rb_tree_node_base* w = x_parent->left; 407 if (w->color == __rb_tree_red) { 408 w->color = __rb_tree_black; 409 x_parent->color = __rb_tree_red; 410 __rb_tree_rotate_right(x_parent, root); 411 w = x_parent->left; 412 } 413 if ((w->right == 0 || w->right->color == __rb_tree_black) && 414 (w->left == 0 || w->left->color == __rb_tree_black)) { 415 w->color = __rb_tree_red; 416 x = x_parent; 417 x_parent = x_parent->parent; 418 } else { 419 if (w->left == 0 || w->left->color == __rb_tree_black) { 420 if (w->right) w->right->color = __rb_tree_black; 421 w->color = __rb_tree_red; 422 __rb_tree_rotate_left(w, root); 423 w = x_parent->left; 424 } 425 w->color = x_parent->color; 426 x_parent->color = __rb_tree_black; 427 if (w->left) w->left->color = __rb_tree_black; 428 __rb_tree_rotate_right(x_parent, root); 429 break; 430 } 431 } 432 if (x) x->color = __rb_tree_black; 433 } 434 return y; 435 } 436 437 template <class Key, class Value, class KeyOfValue, class Compare, 438 class Alloc = alloc> 439 class rb_tree { 440 protected: 441 typedef void* void_pointer; 442 typedef __rb_tree_node_base* base_ptr; 443 typedef __rb_tree_node<Value> rb_tree_node; 444 typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator; 445 typedef __rb_tree_color_type color_type; 446 public: 447 // 注意,沒有定義 iterator(喔,不,定義在後面) 448 typedef Key key_type; 449 typedef Value value_type; 450 typedef value_type* pointer; 451 typedef const value_type* const_pointer; 452 typedef value_type& reference; 453 typedef const value_type& const_reference; 454 typedef rb_tree_node* link_type; 455 typedef size_t size_type; 456 typedef ptrdiff_t difference_type; 457 protected: 458 link_type get_node() { return rb_tree_node_allocator::allocate(); } 459 void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } 460 461 link_type create_node(const value_type& x) { 462 link_type tmp = get_node(); // 配置空間 463 __STL_TRY { 464 construct(&tmp->value_field, x); // 建構內容 465 } 466 __STL_UNWIND(put_node(tmp)); 467 return tmp; 468 } 469 470 link_type clone_node(link_type x) { // 複製一個節點(的值和色) 471 link_type tmp = create_node(x->value_field); 472 tmp->color = x->color; 473 tmp->left = 0; 474 tmp->right = 0; 475 return tmp; 476 } 477 478 void destroy_node(link_type p) { 479 destroy(&p->value_field); // 解構內容 480 put_node(p); // 釋還記憶體 481 } 482 483 protected: 484 // RB-tree 只以三筆資料表現。 485 size_type node_count; // 追蹤記錄樹的大小(節點數量) 486 link_type header; 487 Compare key_compare; // 節點間的鍵值大小比較準則。應該會是個 function object。 488 489 // 以下三個函式用來方便取得 header 的成員 490 link_type& root() const { return (link_type&) header->parent; } 491 link_type& leftmost() const { return (link_type&) header->left; } 492 link_type& rightmost() const { return (link_type&) header->right; } 493 494 // 以下六個函式用來方便取得節點 x 的成員 495 static link_type& left(link_type x) { return (link_type&)(x->left); } 496 static link_type& right(link_type x) { return (link_type&)(x->right); } 497 static link_type& parent(link_type x) { return (link_type&)(x->parent); } 498 static reference value(link_type x) { return x->value_field; } 499 static const Key& key(link_type x) { return KeyOfValue()(value(x)); } 500 static color_type& color(link_type x) { return (color_type&)(x->color); } 501 502 // 以下六個函式用來方便取得節點 x 的成員 503 static link_type& left(base_ptr x) { return (link_type&)(x->left); } 504 static link_type& right(base_ptr x) { return (link_type&)(x->right); } 505 static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } 506 static reference value(base_ptr x) { return ((link_type)x)->value_field; } 507 static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} 508 static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } 509 510 // 求取極大值和極小值。node class 有實作此功能,交給它們完成即可。 511 static link_type minimum(link_type x) { 512 return (link_type) __rb_tree_node_base::minimum(x); 513 } 514 static link_type maximum(link_type x) { 515 return (link_type) __rb_tree_node_base::maximum(x); 516 } 517 518 public: 519 typedef __rb_tree_iterator<value_type, reference, pointer> iterator; 520 typedef __rb_tree_iterator<value_type, const_reference, const_pointer> 521 const_iterator; 522 523 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 524 typedef reverse_iterator<const_iterator> const_reverse_iterator; 525 typedef reverse_iterator<iterator> reverse_iterator; 526 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 527 typedef reverse_bidirectional_iterator<iterator, value_type, reference, 528 difference_type> 529 reverse_iterator; 530 typedef reverse_bidirectional_iterator<const_iterator, value_type, 531 const_reference, difference_type> 532 const_reverse_iterator; 533 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 534 private: 535 iterator __insert(base_ptr x, base_ptr y, const value_type& v); 536 link_type __copy(link_type x, link_type p); 537 void __erase(link_type x); 538 void init() { 539 header = get_node(); // 產生一個節點空間,令 header 指向它 540 color(header) = __rb_tree_red; // 令 header 為紅色,用來區分 header 541 // 和 root(在 iterator.operator++ 中) 542 root() = 0; 543 leftmost() = header; // 令 header 的左子節點為自己。 544 rightmost() = header; // 令 header 的右子節點為自己。 545 } 546 public: 547 // allocation/deallocation 548 rb_tree(const Compare& comp = Compare()) 549 : node_count(0), key_compare(comp) { init(); } 550 551 // 以另一個 rb_tree 物件 x 為初值 552 rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) 553 : node_count(0), key_compare(x.key_compare) 554 { 555 header = get_node(); // 產生一個節點空間,令 header 指向它 556 color(header) = __rb_tree_red; // 令 header 為紅色 557 if (x.root() == 0) { // 如果 x 是個空白樹 558 root() = 0; 559 leftmost() = header; // 令 header 的左子節點為自己。 560 rightmost() = header; // 令 header 的右子節點為自己。 561 } 562 else { // x 不是一個空白樹 563 __STL_TRY { 564 root() = __copy(x.root(), header); // ??? 565 } 566 __STL_UNWIND(put_node(header)); 567 leftmost() = minimum(root()); // 令 header 的左子節點為最小節點 568 rightmost() = maximum(root()); // 令 header 的右子節點為最大節點 569 } 570 node_count = x.node_count; 571 } 572 ~rb_tree() { 573 clear(); 574 put_node(header); 575 } 576 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 577 operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x); 578 579 public: 580 // accessors: 581 Compare key_comp() const { return key_compare; } 582 iterator begin() { return leftmost(); } // RB 樹的起頭為最左(最小)節點處 583 const_iterator begin() const { return leftmost(); } 584 iterator end() { return header; } // RB 樹的終點為 header所指處 585 const_iterator end() const { return header; } 586 reverse_iterator rbegin() { return reverse_iterator(end()); } 587 const_reverse_iterator rbegin() const { 588 return const_reverse_iterator(end()); 589 } 590 reverse_iterator rend() { return reverse_iterator(begin()); } 591 const_reverse_iterator rend() const { 592 return const_reverse_iterator(begin()); 593 } 594 bool empty() const { return node_count == 0; } 595 size_type size() const { return node_count; } 596 size_type max_size() const { return size_type(-1); } 597 598 void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) { 599 // RB-tree 只以三個資料成員表現。所以互換兩個 RB-trees時, 600 // 只需將這三個成員互換即可。 601 __STD::swap(header, t.header); 602 __STD::swap(node_count, t.node_count); 603 __STD::swap(key_compare, t.key_compare); 604 } 605 606 public: 607 // insert/erase 608 // 將 x 安插到 RB-tree 中(保持節點值獨一無二)。 609 pair<iterator,bool> insert_unique(const value_type& x); 610 // 將 x 安插到 RB-tree 中(允許節點值重複)。 611 iterator insert_equal(const value_type& x); 612 613 iterator insert_unique(iterator position, const value_type& x); 614 iterator insert_equal(iterator position, const value_type& x); 615 616 #ifdef __STL_MEMBER_TEMPLATES 617 template <class InputIterator> 618 void insert_unique(InputIterator first, InputIterator last); 619 template <class InputIterator> 620 void insert_equal(InputIterator first, InputIterator last); 621 #else /* __STL_MEMBER_TEMPLATES */ 622 void insert_unique(const_iterator first, const_iterator last); 623 void insert_unique(const value_type* first, const value_type* last); 624 void insert_equal(const_iterator first, const_iterator last); 625 void insert_equal(const value_type* first, const value_type* last); 626 #endif /* __STL_MEMBER_TEMPLATES */ 627 628 void erase(iterator position); 629 size_type erase(const key_type& x); 630 void erase(iterator first, iterator last); 631 void erase(const key_type* first, const key_type* last); 632 void clear() { 633 if (node_count != 0) { 634 __erase(root()); 635 leftmost() = header; 636 root() = 0; 637 rightmost() = header; 638 node_count = 0; 639 } 640 } 641 642 public: 643 // 集合(set)的各種操作行為: 644 iterator find(const key_type& x); 645 const_iterator find(const key_type& x) const; 646 size_type count(const key_type& x) const; 647 iterator lower_bound(const key_type& x); 648 const_iterator lower_bound(const key_type& x) const; 649 iterator upper_bound(const key_type& x); 650 const_iterator upper_bound(const key_type& x) const; 651 pair<iterator,iterator> equal_range(const key_type& x); 652 pair<const_iterator, const_iterator> equal_range(const key_type& x) const; 653 654 public: 655 // Debugging. 656 bool __rb_verify() const; 657 }; 658 659 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 660 inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 661 const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { 662 return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); 663 } 664 665 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 666 inline bool operator<(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 667 const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { 668 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); 669 } 670 671 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 672 673 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 674 inline void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 675 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { 676 x.swap(y); 677 } 678 679 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 680 681 682 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 683 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 684 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: 685 operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) { 686 if (this != &x) { 687 // Note that Key may be a constant type. 688 clear(); 689 node_count = 0; 690 key_compare = x.key_compare; 691 if (x.root() == 0) { 692 root() = 0; 693 leftmost() = header; 694 rightmost() = header; 695 } 696 else { 697 root() = __copy(x.root(), header); 698 leftmost() = minimum(root()); 699 rightmost() = maximum(root()); 700 node_count = x.node_count; 701 } 702 } 703 return *this; 704 } 705 706 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 707 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 708 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: 709 __insert(base_ptr x_, base_ptr y_, const Value& v) { 710 // 參數x_ 為新值安插點,參數y_ 為安插點之父節點,參數v 為新值。 711 link_type x = (link_type) x_; 712 link_type y = (link_type) y_; 713 link_type z; 714 715 // key_compare 是鍵值大小比較準則。應該會是個 function object。 716 if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) { 717 z = create_node(v); // 產生一個新節點 718 left(y) = z; // 這使得當 y 即為 header時,leftmost() = z 719 if (y == header) { 720 root() = z; 721 rightmost() = z; 722 } 723 else if (y == leftmost()) // 如果y為最左節點 724 leftmost() = z; // 維護leftmost(),使它永遠指向最左節點 725 } 726 else { 727 z = create_node(v); // 產生一個新節點 728 right(y) = z; // 令新節點成為安插點之父節點 y 的右子節點 729 if (y == rightmost()) 730 rightmost() = z; // 維護rightmost(),使它永遠指向最右節點 731 } 732 parent(z) = y; // 設定新節點的父節點 733 left(z) = 0; // 設定新節點的左子節點 734 right(z) = 0; // 設定新節點的右子節點 735 // 新節點的顏色將在 __rb_tree_rebalance() 設定(並調整) 736 __rb_tree_rebalance(z, header->parent); // 參數一為新增節點,參數二為 root 737 ++node_count; // 節點數累加 738 return iterator(z); // 傳回一個迭代器,指向新增節點 739 } 740 741 // 安插新值;節點鍵值允許重複。 742 // 注意,傳回值是一個 RB-tree 迭代器,指向新增節點 743 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 744 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 745 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v) 746 { 747 link_type y = header; 748 link_type x = root(); // 從根節點開始 749 while (x != 0) { // 從根節點開始,往下尋找適當的安插點 750 y = x; 751 x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x); 752 // 以上,遇「大」則往左,遇「小於或等於」則往右 753 } 754 return __insert(x, y, v); 755 } 756 757 // 安插新值;節點鍵值不允許重複,若重複則安插無效。 758 // 注意,傳回值是個pair,第一元素是個 RB-tree 迭代器,指向新增節點, 759 // 第二元素表示安插成功與否。 760 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 761 pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool> 762 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v) 763 { 764 link_type y = header; 765 link_type x = root(); // 從根節點開始 766 bool comp = true; 767 while (x != 0) { // 從根節點開始,往下尋找適當的安插點 768 y = x; 769 comp = key_compare(KeyOfValue()(v), key(x)); // v 鍵值小於目前節點之鍵值? 770 x = comp ? left(x) : right(x); // 遇「大」則往左,遇「小於或等於」則往右 771 } 772 // 離開 while 迴圈之後,y 所指即安插點之父節點(此時的它必為葉節點) 773 774 iterator j = iterator(y); // 令迭代器j指向安插點之父節點 y 775 if (comp) // 如果離開 while 迴圈時 comp 為真(表示遇「大」,將安插於左側) 776 if (j == begin()) // 如果安插點之父節點為最左節點 777 return pair<iterator,bool>(__insert(x, y, v), true); 778 // 以上,x 為安插點,y 為安插點之父節點,v 為新值。 779 else // 否則(安插點之父節點不為最左節點) 780 --j; // 調整 j,回頭準備測試... 781 if (key_compare(key(j.node), KeyOfValue()(v))) 782 // 小於新值(表示遇「小」,將安插於右側) 783 return pair<iterator,bool>(__insert(x, y, v), true); 784 785 // 進行至此,表示新值一定與樹中鍵值重複,那麼就不該插入新值。 786 return pair<iterator,bool>(j, false); 787 } 788 789 790 template <class Key, class Val, class KeyOfValue, class Compare, class Alloc> 791 typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 792 rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_unique(iterator position, 793 const Val& v) { 794 if (position.node == header->left) // begin() 795 if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) 796 return __insert(position.node, position.node, v); 797 // first argument just needs to be non-null 798 else 799 return insert_unique(v).first; 800 else if (position.node == header) // end() 801 if (key_compare(key(rightmost()), KeyOfValue()(v))) 802 return __insert(0, rightmost(), v); 803 else 804 return insert_unique(v).first; 805 else { 806 iterator before = position; 807 --before; 808 if (key_compare(key(before.node), KeyOfValue()(v)) 809 && key_compare(KeyOfValue()(v), key(position.node))) 810 if (right(before.node) == 0) 811 return __insert(0, before.node, v); 812 else 813 return __insert(position.node, position.node, v); 814 // first argument just needs to be non-null 815 else 816 return insert_unique(v).first; 817 } 818 } 819 820 template <class Key, class Val, class KeyOfValue, class Compare, class Alloc> 821 typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 822 rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_equal(iterator position, 823 const Val& v) { 824 if (position.node == header->left) // begin() 825 if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) 826 return __insert(position.node, position.node, v); 827 // first argument just needs to be non-null 828 else 829 return insert_equal(v); 830 else if (position.node == header) // end() 831 if (!key_compare(KeyOfValue()(v), key(rightmost()))) 832 return __insert(0, rightmost(), v); 833 else 834 return insert_equal(v); 835 else { 836 iterator before = position; 837 --before; 838 if (!key_compare(KeyOfValue()(v), key(before.node)) 839 && !key_compare(key(position.node), KeyOfValue()(v))) 840 if (right(before.node) == 0) 841 return __insert(0, before.node, v); 842 else 843 return __insert(position.node, position.node, v); 844 // first argument just needs to be non-null 845 else 846 return insert_equal(v); 847 } 848 } 849 850 #ifdef __STL_MEMBER_TEMPLATES 851 852 template <class K, class V, class KoV, class Cmp, class Al> template<class II> 853 void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) { 854 for ( ; first != last; ++first) 855 insert_equal(*first); 856 } 857 858 template <class K, class V, class KoV, class Cmp, class Al> template<class II> 859 void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) { 860 for ( ; first != last; ++first) 861 insert_unique(*first); 862 } 863 864 #else /* __STL_MEMBER_TEMPLATES */ 865 866 template <class K, class V, class KoV, class Cmp, class Al> 867 void 868 rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const V* first, const V* last) { 869 for ( ; first != last; ++first) 870 insert_equal(*first); 871 } 872 873 template <class K, class V, class KoV, class Cmp, class Al> 874 void 875 rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first, 876 const_iterator last) { 877 for ( ; first != last; ++first) 878 insert_equal(*first); 879 } 880 881 template <class K, class V, class KoV, class Cmp, class A> 882 void 883 rb_tree<K, V, KoV, Cmp, A>::insert_unique(const V* first, const V* last) { 884 for ( ; first != last; ++first) 885 insert_unique(*first); 886 } 887 888 template <class K, class V, class KoV, class Cmp, class A> 889 void 890 rb_tree<K, V, KoV, Cmp, A>::insert_unique(const_iterator first, 891 const_iterator last) { 892 for ( ; first != last; ++first) 893 insert_unique(*first); 894 } 895 896 #endif /* __STL_MEMBER_TEMPLATES */ 897 898 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 899 inline void 900 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) { 901 link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node, 902 header->parent, 903 header->left, 904 header->right); 905 destroy_node(y); 906 --node_count; 907 } 908 909 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 910 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 911 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key& x) { 912 pair<iterator,iterator> p = equal_range(x); 913 size_type n = 0; 914 distance(p.first, p.second, n); 915 erase(p.first, p.second); 916 return n; 917 } 918 919 template <class K, class V, class KeyOfValue, class Compare, class Alloc> 920 typename rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type 921 rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) { 922 // structural copy. x and p must be non-null. 923 link_type top = clone_node(x); 924 top->parent = p; 925 926 __STL_TRY { 927 if (x->right) 928 top->right = __copy(right(x), top); 929 p = top; 930 x = left(x); 931 932 while (x != 0) { 933 link_type y = clone_node(x); 934 p->left = y; 935 y->parent = p; 936 if (x->right) 937 y->right = __copy(right(x), y); 938 p = y; 939 x = left(x); 940 } 941 } 942 __STL_UNWIND(__erase(top)); 943 944 return top; 945 } 946 947 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 948 void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) { 949 // erase without rebalancing 950 while (x != 0) { 951 __erase(right(x)); 952 link_type y = left(x); 953 destroy_node(x); 954 x = y; 955 } 956 } 957 958 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 959 void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first, 960 iterator last) { 961 if (first == begin() && last == end()) 962 clear(); 963 else 964 while (first != last) erase(first++); 965 } 966 967 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 968 void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key* first, 969 const Key* last) { 970 while (first != last) erase(*first++); 971 } 972 973 // 尋找 RB 樹中是否有鍵值為 k 的節點 974 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 975 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 976 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) { 977 link_type y = header; // Last node which is not less than k. 978 link_type x = root(); // Current node. 979 980 while (x != 0) 981 // 以下,key_compare 是節點鍵值大小比較準則。應該會是個 function object。 982 if (!key_compare(key(x), k)) 983 // 進行到這裡,表示 x 鍵值大於 k。遇到大值就向左走。 984 y = x, x = left(x); // 注意語法! 985 else 986 // 進行到這裡,表示 x 鍵值小於 k。遇到小值就向右走。 987 x = right(x); 988 989 iterator j = iterator(y); 990 return (j == end() || key_compare(k, key(j.node))) ? end() : j; 991 } 992 993 // 尋找 RB 樹中是否有鍵值為 k 的節點 994 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 995 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 996 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) const { 997 link_type y = header; /* Last node which is not less than k. */ 998 link_type x = root(); /* Current node. */ 999 1000 while (x != 0) { 1001 // 以下,key_compare 是節點鍵值大小比較準則。應該會是個 function object。 1002 if (!key_compare(key(x), k)) 1003 // 進行到這裡,表示 x 鍵值大於 k。遇到大值就向左走。 1004 y = x, x = left(x); // 注意語法! 1005 else 1006 // 進行到這裡,表示 x 鍵值小於 k。遇到小值就向右走。 1007 x = right(x); 1008 } 1009 const_iterator j = const_iterator(y); 1010 return (j == end() || key_compare(k, key(j.node))) ? end() : j; 1011 } 1012 1013 // 計算 RB 樹中鍵值為 k 的節點個數 1014 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1015 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 1016 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const Key& k) const { 1017 pair<const_iterator, const_iterator> p = equal_range(k); 1018 size_type n = 0; 1019 distance(p.first, p.second, n); 1020 return n; 1021 } 1022 1023 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1024 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 1025 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) { 1026 link_type y = header; /* Last node which is not less than k. */ 1027 link_type x = root(); /* Current node. */ 1028 1029 while (x != 0) 1030 if (!key_compare(key(x), k)) 1031 y = x, x = left(x); 1032 else 1033 x = right(x); 1034 1035 return iterator(y); 1036 } 1037 1038 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1039 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 1040 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) const { 1041 link_type y = header; /* Last node which is not less than k. */ 1042 link_type x = root(); /* Current node. */ 1043 1044 while (x != 0) 1045 if (!key_compare(key(x), k)) 1046 y = x, x = left(x); 1047 else 1048 x = right(x); 1049 1050 return const_iterator(y); 1051 } 1052 1053 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1054 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 1055 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) { 1056 link_type y = header; /* Last node which is greater than k. */ 1057 link_type x = root(); /* Current node. */ 1058 1059 while (x != 0) 1060 if (key_compare(k, key(x))) 1061 y = x, x = left(x); 1062 else 1063 x = right(x); 1064 1065 return iterator(y); 1066 } 1067 1068 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1069 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 1070 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) const { 1071 link_type y = header; /* Last node which is greater than k. */ 1072 link_type x = root(); /* Current node. */ 1073 1074 while (x != 0) 1075 if (key_compare(k, key(x))) 1076 y = x, x = left(x); 1077 else 1078 x = right(x); 1079 1080 return const_iterator(y); 1081 } 1082 1083 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1084 inline pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, 1085 typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator> 1086 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) { 1087 return pair<iterator, iterator>(lower_bound(k), upper_bound(k)); 1088 } 1089 1090 template <class Key, class Value, class KoV, class Compare, class Alloc> 1091 inline pair<typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator, 1092 typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator> 1093 rb_tree<Key, Value, KoV, Compare, Alloc>::equal_range(const Key& k) const { 1094 return pair<const_iterator,const_iterator>(lower_bound(k), upper_bound(k)); 1095 } 1096 1097 // 計算從 node 至 root 路徑中的黑節點數量。 1098 inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root) 1099 { 1100 if (node == 0) 1101 return 0; 1102 else { 1103 int bc = node->color == __rb_tree_black ? 1 : 0; 1104 if (node == root) 1105 return bc; 1106 else 1107 return bc + __black_count(node->parent, root); // 累加 1108 } 1109 } 1110 1111 // 驗證己身這棵樹是否符合 RB 樹的條件 1112 template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> 1113 bool 1114 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const 1115 { 1116 // 空樹,符合RB樹標準 1117 if (node_count == 0 || begin() == end()) 1118 return node_count == 0 && begin() == end() && 1119 header->left == header && header->right == header; 1120 1121 // 最左(葉)節點至 root 路徑內的黑節點數 1122 int len = __black_count(leftmost(), root()); 1123 // 以下走訪整個RB樹,針對每個節點(從最小到最大)... 1124 for (const_iterator it = begin(); it != end(); ++it) { 1125 link_type x = (link_type) it.node; // __rb_tree_base_iterator::node 1126 link_type L = left(x); // 這是左子節點 1127 link_type R = right(x); // 這是右子節點 1128 1129 if (x->color == __rb_tree_red) 1130 if ((L && L->color == __rb_tree_red) || 1131 (R && R->color == __rb_tree_red)) 1132 return false; // 父子節點同為紅色,不符合 RB 樹的要求。 1133 1134 if (L && key_compare(key(x), key(L))) // 目前節點的鍵值小於左子節點鍵值 1135 return false; // 不符合二元搜尋樹的要求。 1136 if (R && key_compare(key(R), key(x))) // 目前節點的鍵值大於右子節點鍵值 1137 return false; // 不符合二元搜尋樹的要求。 1138 1139 // 「葉節點至 root」路徑內的黑節點數,與「最左節點至 root」路徑內的黑節點數不同。 1140 // 這不符合 RB 樹的要求。 1141 if (!L && !R && __black_count(x, root()) != len) 1142 return false; 1143 } 1144 1145 if (leftmost() != __rb_tree_node_base::minimum(root())) 1146 return false; // 最左節點不為最小節點,不符合二元搜尋樹的要求。 1147 if (rightmost() != __rb_tree_node_base::maximum(root())) 1148 return false; // 最右節點不為最大節點,不符合二元搜尋樹的要求。 1149 1150 return true; 1151 } 1152 1153 __STL_END_NAMESPACE 1154 1155 #endif /* __SGI_STL_INTERNAL_TREE_H */ 1156 1157 // Local Variables: 1158 // mode:C++ 1159 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_set.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_SET_H 38 #define __SGI_STL_INTERNAL_SET_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 47 // 那么就需要手工指定, 本实作set内部元素默认使用less进行比较 48 // 内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 49 // 注意: set内不允许重复元素的存在, 如果插入重复元素, 50 // 则会忽略插入操作 51 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 52 template <class Key, class Compare = less<Key>, class Alloc = alloc> 53 #else 54 template <class Key, class Compare, class Alloc = alloc> 55 #endif 56 class set 57 { 58 public: 59 // 在set中key就是value, value同时也是key 60 typedef Key key_type; 61 typedef Key value_type; 62 63 // 用于比较的函数 64 typedef Compare key_compare; 65 typedef Compare value_compare; 66 67 private: 68 // 内部采用红黑树为数据结构, 其实现在<stl_tree.h> 69 // 由于我剖析的版本没有侯捷老师的详细, 给出的是侯捷老师的版本 70 typedef rb_tree<key_type, value_type, 71 identity<value_type>, key_compare, Alloc> rep_type; 72 rep_type t; 73 74 public: 75 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 76 // 注意: 迭代器, 引用类型都设计为const, 这是由set的性质决定的, 77 // 如果用户自行更改其数值, 可能会导致内部的红黑树出现问题 78 typedef typename rep_type::const_pointer pointer; // STL标准强制要求 79 typedef typename rep_type::const_pointer const_pointer; 80 typedef typename rep_type::const_reference reference; // STL标准强制要求 81 typedef typename rep_type::const_reference const_reference; 82 typedef typename rep_type::const_iterator iterator; // STL标准强制要求 83 typedef typename rep_type::const_iterator const_iterator; 84 typedef typename rep_type::const_reverse_iterator reverse_iterator; 85 typedef typename rep_type::const_reverse_iterator const_reverse_iterator; 86 typedef typename rep_type::size_type size_type; 87 typedef typename rep_type::difference_type difference_type; // STL标准强制要求 88 89 set() : t(Compare()) {} 90 explicit set(const Compare& comp) : t(comp) {} 91 92 #ifdef __STL_MEMBER_TEMPLATES 93 template <class InputIterator> 94 set(InputIterator first, InputIterator last) 95 : t(Compare()) { t.insert_unique(first, last); } 96 97 template <class InputIterator> 98 set(InputIterator first, InputIterator last, const Compare& comp) 99 : t(comp) { t.insert_unique(first, last); } 100 #else 101 set(const value_type* first, const value_type* last) 102 : t(Compare()) { t.insert_unique(first, last); } 103 set(const value_type* first, const value_type* last, const Compare& comp) 104 : t(comp) { t.insert_unique(first, last); } 105 106 set(const_iterator first, const_iterator last) 107 : t(Compare()) { t.insert_unique(first, last); } 108 set(const_iterator first, const_iterator last, const Compare& comp) 109 : t(comp) { t.insert_unique(first, last); } 110 #endif /* __STL_MEMBER_TEMPLATES */ 111 112 set(const set<Key, Compare, Alloc>& x) : t(x.t) {} 113 114 set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) 115 { 116 t = x.t; 117 return *this; 118 } 119 120 // 返回用于key比较的函数 121 key_compare key_comp() const { return t.key_comp(); } 122 123 // 由于set的性质, value比较和key使用同一个比较函数 124 value_compare value_comp() const { return t.key_comp(); } 125 126 iterator begin() const { return t.begin(); } 127 iterator end() const { return t.end(); } 128 reverse_iterator rbegin() const { return t.rbegin(); } 129 reverse_iterator rend() const { return t.rend(); } 130 bool empty() const { return t.empty(); } 131 size_type size() const { return t.size(); } 132 size_type max_size() const { return t.max_size(); } 133 134 // 这里调用的是专用的swap, 不是全局的swap, 定于于<stl_tree.h> 135 void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); } 136 137 typedef pair<iterator, bool> pair_iterator_bool; 138 139 // 返回的pair.second用于告知用户insert操作是否执行 140 // 为true则表示真正进行插入, 为false则表示set中已存在待插入元素, 141 // 不会重复插入 142 pair<iterator,bool> insert(const value_type& x) 143 { 144 pair<typename rep_type::iterator, bool> p = t.insert_unique(x); 145 return pair<iterator, bool>(p.first, p.second); 146 } 147 148 // 在position处插入元素, 但是position仅仅是个提示, 如果给出的位置不能进行插入, 149 // STL会进行查找, 这会导致很差的效率 150 iterator insert(iterator position, const value_type& x) 151 { 152 typedef typename rep_type::iterator rep_iterator; 153 return t.insert_unique((rep_iterator&)position, x); 154 } 155 156 #ifdef __STL_MEMBER_TEMPLATES 157 template <class InputIterator> 158 void insert(InputIterator first, InputIterator last) 159 { 160 t.insert_unique(first, last); 161 } 162 #else 163 void insert(const_iterator first, const_iterator last) { 164 t.insert_unique(first, last); 165 } 166 void insert(const value_type* first, const value_type* last) { 167 t.insert_unique(first, last); 168 } 169 #endif /* __STL_MEMBER_TEMPLATES */ 170 171 // 擦除指定位置的元素, 会导致内部的红黑树重新排列 172 void erase(iterator position) 173 { 174 typedef typename rep_type::iterator rep_iterator; 175 t.erase((rep_iterator&)position); 176 } 177 178 // 会返回擦除元素的个数, 其实就是标识set内原来是否有指定的元素 179 size_type erase(const key_type& x) 180 { 181 return t.erase(x); 182 } 183 184 // 擦除指定区间的元素, 会导致红黑树有较大变化 185 void erase(iterator first, iterator last) 186 { 187 typedef typename rep_type::iterator rep_iterator; 188 t.erase((rep_iterator&)first, (rep_iterator&)last); 189 } 190 191 // 好吧, clear all, 再见吧红黑树 192 void clear() { t.clear(); } 193 194 // 查找指定的元素 195 iterator find(const key_type& x) const { return t.find(x); } 196 197 // 返回指定元素的个数, 其实就是测试元素是否在set中 198 size_type count(const key_type& x) const { return t.count(x); } 199 200 // 返回小于当前元素的第一个可插入的位置 201 iterator lower_bound(const key_type& x) const 202 { 203 return t.lower_bound(x); 204 } 205 206 // 返回大于当前元素的第一个可插入的位置 207 iterator upper_bound(const key_type& x) const 208 { 209 return t.upper_bound(x); 210 } 211 212 pair<iterator,iterator> equal_range(const key_type& x) const 213 { 214 return t.equal_range(x); 215 } 216 217 friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); 218 friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); 219 }; 220 221 // 比较两个set比较的是其内部的红黑树, 会触发红黑树的operator 222 223 template <class Key, class Compare, class Alloc> 224 inline bool operator==(const set<Key, Compare, Alloc>& x, 225 const set<Key, Compare, Alloc>& y) { 226 return x.t == y.t; 227 } 228 229 template <class Key, class Compare, class Alloc> 230 inline bool operator<(const set<Key, Compare, Alloc>& x, 231 const set<Key, Compare, Alloc>& y) { 232 return x.t < y.t; 233 } 234 235 // 如果编译器支持模板函数特化优先级 236 // 那么将全局的swap实现为使用set私有的swap以提高效率 237 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 238 239 template <class Key, class Compare, class Alloc> 240 inline void swap(set<Key, Compare, Alloc>& x, 241 set<Key, Compare, Alloc>& y) 242 { 243 x.swap(y); 244 } 245 246 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 247 248 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 249 #pragma reset woff 1174 250 #endif 251 252 __STL_END_NAMESPACE 253 254 #endif /* __SGI_STL_INTERNAL_SET_H */ 255 256 // Local Variables: 257 // mode:C++ 258 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_multiset.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_MULTISET_H 38 #define __SGI_STL_INTERNAL_MULTISET_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 47 // 那么就需要手工指定, 本实作multiset内部元素默认使用less进行比较 48 // 内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 49 // 注意: 与set不同, multiset允许有重复的元素 50 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 51 template <class Key, class Compare = less<Key>, class Alloc = alloc> 52 #else 53 template <class Key, class Compare, class Alloc = alloc> 54 #endif 55 class multiset 56 { 57 public: 58 // 这里和set定义相同, 见<stl_set.h> 59 typedef Key key_type; 60 typedef Key value_type; 61 typedef Compare key_compare; 62 typedef Compare value_compare; 63 64 private: 65 // 内部采用红黑树为数据结构, 其实现在<stl_tree.h> 66 typedef rb_tree<key_type, value_type, 67 identity<value_type>, key_compare, Alloc> rep_type; 68 rep_type t; // red-black tree representing multiset 69 70 public: 71 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 72 // 注意: 迭代器, 引用类型都设计为const, 这是由multiset的性质决定的, 73 // 如果用户自行更改其数值, 可能会导致内部的红黑树出现问题 74 typedef typename rep_type::const_pointer pointer; // STL标准强制要求 75 typedef typename rep_type::const_pointer const_pointer; 76 typedef typename rep_type::const_reference reference; // STL标准强制要求 77 typedef typename rep_type::const_reference const_reference; 78 typedef typename rep_type::const_iterator iterator; // STL标准强制要求 79 typedef typename rep_type::const_iterator const_iterator; 80 typedef typename rep_type::const_reverse_iterator reverse_iterator; 81 typedef typename rep_type::const_reverse_iterator const_reverse_iterator; 82 typedef typename rep_type::size_type size_type; 83 typedef typename rep_type::difference_type difference_type; // STL标准强制要求 84 85 multiset() : t(Compare()) {} 86 explicit multiset(const Compare& comp) : t(comp) {} 87 88 #ifdef __STL_MEMBER_TEMPLATES 89 template <class InputIterator> 90 multiset(InputIterator first, InputIterator last) 91 : t(Compare()) { t.insert_equal(first, last); } 92 template <class InputIterator> 93 multiset(InputIterator first, InputIterator last, const Compare& comp) 94 : t(comp) { t.insert_equal(first, last); } 95 #else 96 multiset(const value_type* first, const value_type* last) 97 : t(Compare()) { t.insert_equal(first, last); } 98 multiset(const value_type* first, const value_type* last, 99 const Compare& comp) 100 : t(comp) { t.insert_equal(first, last); } 101 102 multiset(const_iterator first, const_iterator last) 103 : t(Compare()) { t.insert_equal(first, last); } 104 multiset(const_iterator first, const_iterator last, const Compare& comp) 105 : t(comp) { t.insert_equal(first, last); } 106 #endif /* __STL_MEMBER_TEMPLATES */ 107 108 multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {} 109 multiset<Key, Compare, Alloc>& 110 operator=(const multiset<Key, Compare, Alloc>& x) 111 { 112 t = x.t; 113 return *this; 114 } 115 116 // 返回用于key比较的函数 117 key_compare key_comp() const { return t.key_comp(); } 118 119 // 由于multiset的性质, value比较和key使用同一个比较函数 120 value_compare value_comp() const { return t.key_comp(); } 121 122 iterator begin() const { return t.begin(); } 123 iterator end() const { return t.end(); } 124 reverse_iterator rbegin() const { return t.rbegin(); } 125 reverse_iterator rend() const { return t.rend(); } 126 bool empty() const { return t.empty(); } 127 size_type size() const { return t.size(); } 128 size_type max_size() const { return t.max_size(); } 129 130 // 这里调用的是专用的swap, 不是全局的swap, 定于于<stl_tree.h> 131 void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); } 132 133 // 插入元素, 注意, 插入的元素key允许重复 134 iterator insert(const value_type& x) 135 { 136 return t.insert_equal(x); 137 } 138 139 // 在position处插入元素, 但是position仅仅是个提示, 如果给出的位置不能进行插入, 140 // STL会进行查找, 这会导致很差的效率 141 iterator insert(iterator position, const value_type& x) 142 { 143 typedef typename rep_type::iterator rep_iterator; 144 return t.insert_equal((rep_iterator&)position, x); 145 } 146 147 #ifdef __STL_MEMBER_TEMPLATES 148 template <class InputIterator> 149 void insert(InputIterator first, InputIterator last) 150 { 151 t.insert_equal(first, last); 152 } 153 #else 154 void insert(const value_type* first, const value_type* last) { 155 t.insert_equal(first, last); 156 } 157 void insert(const_iterator first, const_iterator last) { 158 t.insert_equal(first, last); 159 } 160 #endif /* __STL_MEMBER_TEMPLATES */ 161 162 // 擦除指定位置的元素, 会导致内部的红黑树重新排列 163 void erase(iterator position) 164 { 165 typedef typename rep_type::iterator rep_iterator; 166 t.erase((rep_iterator&)position); 167 } 168 169 // 会返回擦除元素的个数 170 size_type erase(const key_type& x) 171 { 172 return t.erase(x); 173 } 174 175 // 擦除指定区间的元素, 会导致红黑树有较大变化 176 void erase(iterator first, iterator last) 177 { 178 typedef typename rep_type::iterator rep_iterator; 179 t.erase((rep_iterator&)first, (rep_iterator&)last); 180 } 181 182 // 好吧, clear all, 再见吧红黑树 183 void clear() { t.clear(); } 184 185 // 查找指定的元素 186 iterator find(const key_type& x) const { return t.find(x); } 187 188 // 返回指定元素的个数 189 size_type count(const key_type& x) const { return t.count(x); } 190 191 // 返回小于当前元素的第一个可插入的位置 192 iterator lower_bound(const key_type& x) const 193 { 194 return t.lower_bound(x); 195 } 196 197 // 返回大于当前元素的第一个可插入的位置 198 iterator upper_bound(const key_type& x) const 199 { 200 return t.upper_bound(x); 201 } 202 203 pair<iterator,iterator> equal_range(const key_type& x) const 204 { 205 return t.equal_range(x); 206 } 207 208 friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, 209 const multiset&); 210 friend bool operator< __STL_NULL_TMPL_ARGS (const multiset&, 211 const multiset&); 212 }; 213 214 // 比较两个multiset比较的是其内部的红黑树, 会触发红黑树的operator 215 216 template <class Key, class Compare, class Alloc> 217 inline bool operator==(const multiset<Key, Compare, Alloc>& x, 218 const multiset<Key, Compare, Alloc>& y) 219 { 220 return x.t == y.t; 221 } 222 223 template <class Key, class Compare, class Alloc> 224 inline bool operator<(const multiset<Key, Compare, Alloc>& x, 225 const multiset<Key, Compare, Alloc>& y) 226 { 227 return x.t < y.t; 228 } 229 230 // 如果编译器支持模板函数特化优先级 231 // 那么将全局的swap实现为使用multiset私有的swap以提高效率 232 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 233 234 template <class Key, class Compare, class Alloc> 235 inline void swap(multiset<Key, Compare, Alloc>& x, 236 multiset<Key, Compare, Alloc>& y) 237 { 238 x.swap(y); 239 } 240 241 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 242 243 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 244 #pragma reset woff 1174 245 #endif 246 247 __STL_END_NAMESPACE 248 249 #endif /* __SGI_STL_INTERNAL_MULTISET_H */ 250 251 // Local Variables: 252 // mode:C++ 253 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_map.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_MAP_H 38 #define __SGI_STL_INTERNAL_MAP_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 47 // 那么就需要手工指定, 本实作map内部元素默认使用less进行比较, 其排序以key作为参照 48 // 内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 49 // 注意: map内元素的key不可一重复, 但是value允许重复 50 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 51 template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> 52 #else 53 template <class Key, class T, class Compare, class Alloc = alloc> 54 #endif 55 class map { 56 public: 57 typedef Key key_type; // key类型 58 typedef T data_type; // value类型 59 typedef T mapped_type; 60 typedef pair<const Key, T> value_type; // 元素类型, 要保证key不被修改 61 typedef Compare key_compare; // 用于key比较的函数 62 63 // 关于为什么继承自binary_function见<stl_function.h>中的讲解 64 // 被嵌套类提供key的比较操作 65 class value_compare 66 : public binary_function<value_type, value_type, bool> 67 { 68 friend class map<Key, T, Compare, Alloc>; 69 protected : 70 Compare comp; 71 value_compare(Compare c) : comp(c) {} 72 public: 73 bool operator()(const value_type& x, const value_type& y) const { 74 return comp(x.first, y.first); 75 } 76 }; 77 78 private: 79 // 内部采用红黑树为数据结构, 其实现在<stl_tree.h> 80 // 由于我剖析的版本没有侯捷老师的详细, 给出的是侯捷老师的版本 81 typedef rb_tree<key_type, value_type, 82 select1st<value_type>, key_compare, Alloc> rep_type; 83 rep_type t; // red-black tree representing map 84 85 public: 86 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 87 // 注意: 迭代器, 引用类型都设计为const, 这是由map的性质决定的, 88 // 如果用户自行更改其数值, 可能会导致内部的红黑树出现问题 89 typedef typename rep_type::pointer pointer; // STL标准强制要求 90 typedef typename rep_type::const_pointer const_pointer; 91 typedef typename rep_type::reference reference; // STL标准强制要求 92 typedef typename rep_type::const_reference const_reference; 93 typedef typename rep_type::iterator iterator; // STL标准强制要求 94 typedef typename rep_type::const_iterator const_iterator; 95 typedef typename rep_type::reverse_iterator reverse_iterator; 96 typedef typename rep_type::const_reverse_iterator const_reverse_iterator; 97 typedef typename rep_type::size_type size_type; 98 typedef typename rep_type::difference_type difference_type; // STL标准强制要求 99 100 map() : t(Compare()) {} 101 explicit map(const Compare& comp) : t(comp) {} 102 103 #ifdef __STL_MEMBER_TEMPLATES 104 template <class InputIterator> 105 map(InputIterator first, InputIterator last) 106 : t(Compare()) { t.insert_unique(first, last); } 107 108 template <class InputIterator> 109 map(InputIterator first, InputIterator last, const Compare& comp) 110 : t(comp) { t.insert_unique(first, last); } 111 #else 112 map(const value_type* first, const value_type* last) 113 : t(Compare()) { t.insert_unique(first, last); } 114 map(const value_type* first, const value_type* last, const Compare& comp) 115 : t(comp) { t.insert_unique(first, last); } 116 117 map(const_iterator first, const_iterator last) 118 : t(Compare()) { t.insert_unique(first, last); } 119 map(const_iterator first, const_iterator last, const Compare& comp) 120 : t(comp) { t.insert_unique(first, last); } 121 #endif /* __STL_MEMBER_TEMPLATES */ 122 123 map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {} 124 125 map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x) 126 { 127 t = x.t; 128 return *this; 129 } 130 131 132 // 返回用于key比较的函数 133 key_compare key_comp() const { return t.key_comp(); } 134 135 // 由于map的性质, value和key使用同一个比较函数, 实际上我们并不使用value比较函数 136 value_compare value_comp() const { return value_compare(t.key_comp()); } 137 138 iterator begin() { return t.begin(); } 139 const_iterator begin() const { return t.begin(); } 140 iterator end() { return t.end(); } 141 const_iterator end() const { return t.end(); } 142 reverse_iterator rbegin() { return t.rbegin(); } 143 const_reverse_iterator rbegin() const { return t.rbegin(); } 144 reverse_iterator rend() { return t.rend(); } 145 const_reverse_iterator rend() const { return t.rend(); } 146 bool empty() const { return t.empty(); } 147 size_type size() const { return t.size(); } 148 size_type max_size() const { return t.max_size(); } 149 150 // 注意: 这里有一个常见的陷阱, 如果访问的key不存在, 会新建立一个 151 T& operator[](const key_type& k) 152 { 153 return (*((insert(value_type(k, T()))).first)).second; 154 } 155 156 // 返回的pair.second用于告知用户insert操作是否执行 157 // 为true则表示真正进行插入, 为false则表示set中已存在待插入元素, 158 // 不会重复插入 159 void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); } 160 161 // 对于相同的key, 只允许出现一次, bool标识 162 pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); } 163 164 // 在position处插入元素, 但是position仅仅是个提示, 如果给出的位置不能进行插入, 165 // STL会进行查找, 这会导致很差的效率 166 iterator insert(iterator position, const value_type& x) 167 { 168 return t.insert_unique(position, x); 169 } 170 171 #ifdef __STL_MEMBER_TEMPLATES 172 template <class InputIterator> 173 void insert(InputIterator first, InputIterator last) { 174 t.insert_unique(first, last); 175 } 176 #else 177 void insert(const value_type* first, const value_type* last) { 178 t.insert_unique(first, last); 179 } 180 void insert(const_iterator first, const_iterator last) { 181 t.insert_unique(first, last); 182 } 183 #endif /* __STL_MEMBER_TEMPLATES */ 184 185 // 擦除指定位置的元素, 会导致内部的红黑树重新排列 186 void erase(iterator position) { t.erase(position); } 187 188 // 会返回擦除元素的个数, 其实就是标识map内原来是否有指定的元素 189 size_type erase(const key_type& x) { return t.erase(x); } 190 void erase(iterator first, iterator last) { t.erase(first, last); } 191 192 // 好吧, clear all, 再见吧红黑树 193 void clear() { t.clear(); } 194 195 // 查找指定key的元素 196 iterator find(const key_type& x) { return t.find(x); } 197 const_iterator find(const key_type& x) const { return t.find(x); } 198 199 // 返回指定元素的个数, 其实就是测试元素是否在map中 200 size_type count(const key_type& x) const { return t.count(x); } 201 202 // 返回小于当前元素的第一个可插入的位置 203 iterator lower_bound(const key_type& x) {return t.lower_bound(x); } 204 const_iterator lower_bound(const key_type& x) const 205 { 206 return t.lower_bound(x); 207 } 208 209 // 返回大于当前元素的第一个可插入的位置 210 iterator upper_bound(const key_type& x) {return t.upper_bound(x); } 211 const_iterator upper_bound(const key_type& x) const 212 { 213 return t.upper_bound(x); 214 } 215 216 pair<iterator,iterator> equal_range(const key_type& x) 217 { 218 return t.equal_range(x); 219 } 220 pair<const_iterator,const_iterator> equal_range(const key_type& x) const 221 { 222 return t.equal_range(x); 223 } 224 225 friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); 226 friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); 227 }; 228 229 // 比较两个multiset比较的是其内部的红黑树, 会触发红黑树的operator 230 231 template <class Key, class T, class Compare, class Alloc> 232 inline bool operator==(const map<Key, T, Compare, Alloc>& x, 233 const map<Key, T, Compare, Alloc>& y) 234 { 235 return x.t == y.t; 236 } 237 238 template <class Key, class T, class Compare, class Alloc> 239 inline bool operator<(const map<Key, T, Compare, Alloc>& x, 240 const map<Key, T, Compare, Alloc>& y) 241 { 242 return x.t < y.t; 243 } 244 245 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 246 247 // 如果编译器支持模板函数特化优先级 248 // 那么将全局的swap实现为使用map私有的swap以提高效率 249 template <class Key, class T, class Compare, class Alloc> 250 inline void swap(map<Key, T, Compare, Alloc>& x, 251 map<Key, T, Compare, Alloc>& y) 252 { 253 x.swap(y); 254 } 255 256 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 257 258 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 259 #pragma reset woff 1174 260 #endif 261 262 __STL_END_NAMESPACE 263 264 #endif /* __SGI_STL_INTERNAL_MAP_H */ 265 266 // Local Variables: 267 // mode:C++ 268 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_multimap.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 /* 8 * 9 * Copyright (c) 1994 10 * Hewlett-Packard Company 11 * 12 * Permission to use, copy, modify, distribute and sell this software 13 * and its documentation for any purpose is hereby granted without fee, 14 * provided that the above copyright notice appear in all copies and 15 * that both that copyright notice and this permission notice appear 16 * in supporting documentation. Hewlett-Packard Company makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * 21 * Copyright (c) 1996,1997 22 * Silicon Graphics Computer Systems, Inc. 23 * 24 * Permission to use, copy, modify, distribute and sell this software 25 * and its documentation for any purpose is hereby granted without fee, 26 * provided that the above copyright notice appear in all copies and 27 * that both that copyright notice and this permission notice appear 28 * in supporting documentation. Silicon Graphics makes no 29 * representations about the suitability of this software for any 30 * purpose. It is provided "as is" without express or implied warranty. 31 */ 32 33 /* NOTE: This is an internal header file, included by other STL headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef __SGI_STL_INTERNAL_MULTIMAP_H 38 #define __SGI_STL_INTERNAL_MULTIMAP_H 39 40 __STL_BEGIN_NAMESPACE 41 42 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 43 #pragma set woff 1174 44 #endif 45 46 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 47 // 那么就需要手工指定, 本实作multimap内部元素默认使用less进行比较 48 // 内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 49 // 注意: 与map不同, multimap允许有重复的元素 50 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 51 template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> 52 #else 53 template <class Key, class T, class Compare, class Alloc = alloc> 54 #endif 55 class multimap 56 { 57 public: 58 // 这里和map定义相同, 见<setL_map.h> 59 typedef Key key_type; 60 typedef T data_type; 61 typedef T mapped_type; 62 typedef pair<const Key, T> value_type; 63 typedef Compare key_compare; 64 65 // 关于为什么继承自binary_function见<stl_function.h>中的讲解 66 // 被嵌套类提供key的比较操作 67 class value_compare : public binary_function<value_type, value_type, bool> 68 { 69 friend class multimap<Key, T, Compare, Alloc>; 70 protected: 71 Compare comp; 72 value_compare(Compare c) : comp(c) {} 73 public: 74 bool operator()(const value_type& x, const value_type& y) const { 75 return comp(x.first, y.first); 76 } 77 }; 78 79 private: 80 // 内部采用红黑树为数据结构, 其实现在<stl_tree.h> 81 typedef rb_tree<key_type, value_type, 82 select1st<value_type>, key_compare, Alloc> rep_type; 83 rep_type t; // red-black tree representing multimap 84 85 public: 86 // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 87 // 注意: 迭代器, 引用类型都设计为const, 这是由multimap的性质决定的, 88 // 如果用户自行更改其数值, 可能会导致内部的红黑树出现问题 89 typedef typename rep_type::pointer pointer; // STL标准强制要求 90 typedef typename rep_type::const_pointer const_pointer; 91 typedef typename rep_type::reference reference; // STL标准强制要求 92 typedef typename rep_type::const_reference const_reference; 93 typedef typename rep_type::iterator iterator; // STL标准强制要求 94 typedef typename rep_type::const_iterator const_iterator; 95 typedef typename rep_type::reverse_iterator reverse_iterator; 96 typedef typename rep_type::const_reverse_iterator const_reverse_iterator; 97 typedef typename rep_type::size_type size_type; 98 typedef typename rep_type::difference_type difference_type; // STL标准强制要求 99 100 multimap() : t(Compare()) { } 101 explicit multimap(const Compare& comp) : t(comp) { } 102 103 #ifdef __STL_MEMBER_TEMPLATES 104 template <class InputIterator> 105 multimap(InputIterator first, InputIterator last) 106 : t(Compare()) { t.insert_equal(first, last); } 107 108 template <class InputIterator> 109 multimap(InputIterator first, InputIterator last, const Compare& comp) 110 : t(comp) { t.insert_equal(first, last); } 111 #else 112 multimap(const value_type* first, const value_type* last) 113 : t(Compare()) { t.insert_equal(first, last); } 114 multimap(const value_type* first, const value_type* last, 115 const Compare& comp) 116 : t(comp) { t.insert_equal(first, last); } 117 118 multimap(const_iterator first, const_iterator last) 119 : t(Compare()) { t.insert_equal(first, last); } 120 multimap(const_iterator first, const_iterator last, const Compare& comp) 121 : t(comp) { t.insert_equal(first, last); } 122 #endif /* __STL_MEMBER_TEMPLATES */ 123 124 multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { } 125 126 multimap<Key, T, Compare, Alloc>& 127 operator=(const multimap<Key, T, Compare, Alloc>& x) 128 { 129 t = x.t; 130 return *this; 131 } 132 133 // 返回用于key比较的函数 134 key_compare key_comp() const { return t.key_comp(); } 135 136 // 由于multimap的性质, value比较和key使用同一个比较函数 137 value_compare value_comp() const { return value_compare(t.key_comp()); } 138 139 iterator begin() { return t.begin(); } 140 const_iterator begin() const { return t.begin(); } 141 iterator end() { return t.end(); } 142 const_iterator end() const { return t.end(); } 143 reverse_iterator rbegin() { return t.rbegin(); } 144 const_reverse_iterator rbegin() const { return t.rbegin(); } 145 reverse_iterator rend() { return t.rend(); } 146 const_reverse_iterator rend() const { return t.rend(); } 147 bool empty() const { return t.empty(); } 148 size_type size() const { return t.size(); } 149 size_type max_size() const { return t.max_size(); } 150 151 // 这里调用的是专用的swap, 不是全局的swap, 定于于<stl_tree.h> 152 void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); } 153 154 // 插入元素, 注意, 插入的元素key允许重复 155 iterator insert(const value_type& x) { return t.insert_equal(x); } 156 157 // 在position处插入元素, 但是position仅仅是个提示, 如果给出的位置不能进行插入, 158 // STL会进行查找, 这会导致很差的效率 159 iterator insert(iterator position, const value_type& x) 160 { 161 return t.insert_equal(position, x); 162 } 163 164 #ifdef __STL_MEMBER_TEMPLATES 165 template <class InputIterator> 166 void insert(InputIterator first, InputIterator last) 167 { 168 t.insert_equal(first, last); 169 } 170 #else 171 void insert(const value_type* first, const value_type* last) { 172 t.insert_equal(first, last); 173 } 174 void insert(const_iterator first, const_iterator last) { 175 t.insert_equal(first, last); 176 } 177 #endif /* __STL_MEMBER_TEMPLATES */ 178 179 // 擦除指定位置的元素, 会导致内部的红黑树重新排列 180 void erase(iterator position) { t.erase(position); } 181 182 // 会返回擦除元素的个数 183 size_type erase(const key_type& x) { return t.erase(x); } 184 185 // 擦除指定区间的元素, 会导致红黑树有较大变化 186 void erase(iterator first, iterator last) { t.erase(first, last); } 187 188 // 好吧, clear all, 再见吧红黑树 189 void clear() { t.clear(); } 190 191 // 查找指定的元素 192 iterator find(const key_type& x) { return t.find(x); } 193 const_iterator find(const key_type& x) const { return t.find(x); } 194 195 // 返回指定元素的个数 196 size_type count(const key_type& x) const { return t.count(x); } 197 198 // 返回小于当前元素的第一个可插入的位置 199 iterator lower_bound(const key_type& x) {return t.lower_bound(x); } 200 const_iterator lower_bound(const key_type& x) const 201 { 202 return t.lower_bound(x); 203 } 204 205 // 返回大于当前元素的第一个可插入的位置 206 iterator upper_bound(const key_type& x) {return t.upper_bound(x); } 207 const_iterator upper_bound(const key_type& x) const 208 { 209 return t.upper_bound(x); 210 } 211 212 pair<iterator,iterator> equal_range(const key_type& x) 213 { 214 return t.equal_range(x); 215 } 216 217 pair<const_iterator,const_iterator> equal_range(const key_type& x) const 218 { 219 return t.equal_range(x); 220 } 221 222 friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, 223 const multimap&); 224 friend bool operator< __STL_NULL_TMPL_ARGS (const multimap&, 225 const multimap&); 226 }; 227 228 // 比较两个multimap比较的是其内部的红黑树, 会触发红黑树的operator 229 230 template <class Key, class T, class Compare, class Alloc> 231 inline bool operator==(const multimap<Key, T, Compare, Alloc>& x, 232 const multimap<Key, T, Compare, Alloc>& y) 233 { 234 return x.t == y.t; 235 } 236 237 template <class Key, class T, class Compare, class Alloc> 238 inline bool operator<(const multimap<Key, T, Compare, Alloc>& x, 239 const multimap<Key, T, Compare, Alloc>& y) 240 { 241 return x.t < y.t; 242 } 243 244 // 如果编译器支持模板函数特化优先级 245 // 那么将全局的swap实现为使用multimap私有的swap以提高效率 246 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 247 248 template <class Key, class T, class Compare, class Alloc> 249 inline void swap(multimap<Key, T, Compare, Alloc>& x, 250 multimap<Key, T, Compare, Alloc>& y) 251 { 252 x.swap(y); 253 } 254 255 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 256 257 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 258 #pragma reset woff 1174 259 #endif 260 261 __STL_END_NAMESPACE 262 263 #endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ 264 265 // Local Variables: 266 // mode:C++ 267 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_hashtable.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 //// 8 // 本实作的hashtable采用的是开链法, 其内存布局如下 9 //// 10 // 对于产生哈希冲突的结点, 我们采取在其位置维护一个链表才处理之 11 // 12 // ------------------------------------------------------------------------ 13 // | | | | | | ..... | | | | | 14 // ------------------------------------------------------------------------ 15 // | | | 16 // ↓ ↓ ↓ 17 // -------- -------- -------- -------- -------- 18 // | next |->0 | next |->| next |->| next |->0 | next |->0 19 // -------- -------- -------- -------- -------- 20 // | data | | data | | data | | data | | data | 21 // -------- -------- -------- -------- -------- 22 //// 23 24 /* 25 * Copyright (c) 1996,1997 26 * Silicon Graphics Computer Systems, Inc. 27 * 28 * Permission to use, copy, modify, distribute and sell this software 29 * and its documentation for any purpose is hereby granted without fee, 30 * provided that the above copyright notice appear in all copies and 31 * that both that copyright notice and this permission notice appear 32 * in supporting documentation. Silicon Graphics makes no 33 * representations about the suitability of this software for any 34 * purpose. It is provided "as is" without express or implied warranty. 35 * 36 * 37 * Copyright (c) 1994 38 * Hewlett-Packard Company 39 * 40 * Permission to use, copy, modify, distribute and sell this software 41 * and its documentation for any purpose is hereby granted without fee, 42 * provided that the above copyright notice appear in all copies and 43 * that both that copyright notice and this permission notice appear 44 * in supporting documentation. Hewlett-Packard Company makes no 45 * representations about the suitability of this software for any 46 * purpose. It is provided "as is" without express or implied warranty. 47 * 48 */ 49 50 /* NOTE: This is an internal header file, included by other STL headers. 51 * You should not attempt to use it directly. 52 */ 53 54 #ifndef __SGI_STL_INTERNAL_HASHTABLE_H 55 #define __SGI_STL_INTERNAL_HASHTABLE_H 56 57 // hashtable类用于实现哈希关联容器hash_st, hash_map, hash_multiset和hash_multimap 58 59 #include <stl_algobase.h> 60 #include <stl_alloc.h> 61 #include <stl_construct.h> 62 #include <stl_tempbuf.h> 63 #include <stl_algo.h> 64 #include <stl_uninitialized.h> 65 #include <stl_function.h> 66 #include <stl_vector.h> 67 #include <stl_hash_fun.h> 68 69 __STL_BEGIN_NAMESPACE 70 71 // 这个是哈希表中维护的链表结点 72 template <class Value> 73 struct __hashtable_node 74 { 75 __hashtable_node* next; 76 Value val; 77 }; 78 79 // 这里使用前置声明, 否则后面的交叉引用会导致编译错误 80 template <class Value, class Key, class HashFcn, 81 class ExtractKey, class EqualKey, class Alloc = alloc> 82 class hashtable; 83 84 template <class Value, class Key, class HashFcn, 85 class ExtractKey, class EqualKey, class Alloc> 86 struct __hashtable_iterator; 87 88 template <class Value, class Key, class HashFcn, 89 class ExtractKey, class EqualKey, class Alloc> 90 struct __hashtable_const_iterator; 91 92 template <class Value, class Key, class HashFcn, 93 class ExtractKey, class EqualKey, class Alloc> 94 struct __hashtable_iterator 95 { 96 // 注意: hashtable不提供reverse iterator, 也不提供operator -- 97 typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> 98 hashtable; 99 typedef __hashtable_iterator<Value, Key, HashFcn, 100 ExtractKey, EqualKey, Alloc> 101 iterator; 102 typedef __hashtable_const_iterator<Value, Key, HashFcn, 103 ExtractKey, EqualKey, Alloc> 104 const_iterator; 105 typedef __hashtable_node<Value> node; 106 107 typedef forward_iterator_tag iterator_category; 108 typedef Value value_type; 109 typedef ptrdiff_t difference_type; 110 typedef size_t size_type; 111 typedef Value& reference; 112 typedef Value* pointer; 113 114 // 本实作中hasntable是由一个线性表作为hash表, 而表内的每一个被映射的 115 // 哈希结点内部维护这一个链表, 用于处理哈希冲突, 此即开链法 116 node* cur; // 当前的位置, 是线性表中的链表结点 117 hashtable* ht; // 线性表中的位置 118 119 __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {} 120 __hashtable_iterator() {} 121 122 reference operator*() const { return cur->val; } 123 124 #ifndef __SGI_STL_NO_ARROW_OPERATOR 125 // 如果编译器支持'->'则重载, 详细见我在<stl_list.h>中的剖析 126 pointer operator->() const { return &(operator*()); } 127 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 128 129 // 详细解析见实现部分 130 iterator& operator++(); 131 iterator operator++(int); 132 133 bool operator==(const iterator& it) const { return cur == it.cur; } 134 bool operator!=(const iterator& it) const { return cur != it.cur; } 135 }; 136 137 // const情况基本和上面一致 138 template <class Value, class Key, class HashFcn, 139 class ExtractKey, class EqualKey, class Alloc> 140 struct __hashtable_const_iterator 141 { 142 typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> 143 hashtable; 144 typedef __hashtable_iterator<Value, Key, HashFcn, 145 ExtractKey, EqualKey, Alloc> 146 iterator; 147 typedef __hashtable_const_iterator<Value, Key, HashFcn, 148 ExtractKey, EqualKey, Alloc> 149 const_iterator; 150 typedef __hashtable_node<Value> node; 151 152 typedef forward_iterator_tag iterator_category; 153 typedef Value value_type; 154 typedef ptrdiff_t difference_type; 155 typedef size_t size_type; 156 typedef const Value& reference; 157 typedef const Value* pointer; 158 159 const node* cur; 160 const hashtable* ht; 161 162 __hashtable_const_iterator(const node* n, const hashtable* tab) 163 : cur(n), ht(tab) {} 164 __hashtable_const_iterator() {} 165 __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {} 166 reference operator*() const { return cur->val; } 167 #ifndef __SGI_STL_NO_ARROW_OPERATOR 168 pointer operator->() const { return &(operator*()); } 169 #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 170 const_iterator& operator++(); 171 const_iterator operator++(int); 172 bool operator==(const const_iterator& it) const { return cur == it.cur; } 173 bool operator!=(const const_iterator& it) const { return cur != it.cur; } 174 }; 175 176 // 假设long至少为32-bits, 否则根据情况自己修改 177 static const int __stl_num_primes = 28; 178 static const unsigned long __stl_prime_list[__stl_num_primes] = 179 { 180 53, 97, 193, 389, 769, 181 1543, 3079, 6151, 12289, 24593, 182 49157, 98317, 196613, 393241, 786433, 183 1572869, 3145739, 6291469, 12582917, 25165843, 184 50331653, 100663319, 201326611, 402653189, 805306457, 185 1610612741, 3221225473ul, 4294967291ul 186 }; 187 188 // 返回大于n的最小素数 189 inline unsigned long __stl_next_prime(unsigned long n) 190 { 191 const unsigned long* first = __stl_prime_list; 192 const unsigned long* last = __stl_prime_list + __stl_num_primes; 193 const unsigned long* pos = lower_bound(first, last, n); 194 return pos == last ? *(last - 1) : *pos; 195 } 196 197 // Value: 结点的valule类型 198 // Key: 结点的key类型 199 // HashFcn: hash function 200 // ExtractKey: 从结点中取出键值的方法 201 // EqualKey: 判断键值是否相同的方法 202 // Alloc: allocator, 默认alloc 203 template <class Value, class Key, class HashFcn, 204 class ExtractKey, class EqualKey, 205 class Alloc> 206 class hashtable 207 { 208 public: 209 typedef Key key_type; 210 typedef Value value_type; 211 typedef HashFcn hasher; 212 typedef EqualKey key_equal; 213 214 typedef size_t size_type; 215 typedef ptrdiff_t difference_type; 216 typedef value_type* pointer; 217 typedef const value_type* const_pointer; 218 typedef value_type& reference; 219 typedef const value_type& const_reference; 220 221 // 获取hash相关的函数 222 hasher hash_funct() const { return hash; } 223 key_equal key_eq() const { return equals; } 224 225 private: 226 // 详细剖析参考<stl_fun_fun.h> 227 hasher hash; 228 key_equal equals; 229 ExtractKey get_key; 230 231 typedef __hashtable_node<Value> node; 232 typedef simple_alloc<node, Alloc> node_allocator; 233 234 vector<node*,Alloc> buckets; // 线性表以vector实作 235 size_type num_elements; 236 237 public: 238 typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, 239 Alloc> 240 iterator; 241 242 typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, 243 Alloc> 244 const_iterator; 245 246 friend struct 247 __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; 248 friend struct 249 __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; 250 251 public: 252 // 下面这些函数STL容器的表现基本一致, 253 // 不做说明, 可以参看<stl_vector.h>, <stl_list.h>中的解析 254 hashtable(size_type n, 255 const HashFcn& hf, 256 const EqualKey& eql, 257 const ExtractKey& ext) 258 : hash(hf), equals(eql), get_key(ext), num_elements(0) 259 { 260 initialize_buckets(n); 261 } 262 263 hashtable(size_type n, 264 const HashFcn& hf, 265 const EqualKey& eql) 266 : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0) 267 { 268 initialize_buckets(n); 269 } 270 271 hashtable(const hashtable& ht) 272 : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0) 273 { 274 copy_from(ht); 275 } 276 277 hashtable& operator= (const hashtable& ht) 278 { 279 if (&ht != this) { 280 clear(); 281 hash = ht.hash; 282 equals = ht.equals; 283 get_key = ht.get_key; 284 copy_from(ht); 285 } 286 return *this; 287 } 288 289 ~hashtable() { clear(); } 290 291 size_type size() const { return num_elements; } 292 size_type max_size() const { return size_type(-1); } 293 bool empty() const { return size() == 0; } 294 295 void swap(hashtable& ht) 296 { 297 __STD::swap(hash, ht.hash); 298 __STD::swap(equals, ht.equals); 299 __STD::swap(get_key, ht.get_key); 300 buckets.swap(ht.buckets); 301 __STD::swap(num_elements, ht.num_elements); 302 } 303 304 iterator begin() 305 { 306 for (size_type n = 0; n < buckets.size(); ++n) 307 if (buckets[n]) 308 return iterator(buckets[n], this); 309 return end(); 310 } 311 312 iterator end() { return iterator(0, this); } 313 314 const_iterator begin() const 315 { 316 for (size_type n = 0; n < buckets.size(); ++n) 317 if (buckets[n]) 318 return const_iterator(buckets[n], this); 319 return end(); 320 } 321 322 const_iterator end() const { return const_iterator(0, this); } 323 324 friend bool 325 operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); 326 327 public: 328 // 线性表中的结点数 329 size_type bucket_count() const { return buckets.size(); } 330 331 // 线性表最多能分配的结点数 332 size_type max_bucket_count() const 333 { return __stl_prime_list[__stl_num_primes - 1]; } 334 335 // 返回指定key映射了多少value 336 size_type elems_in_bucket(size_type bucket) const 337 { 338 size_type result = 0; 339 for (node* cur = buckets[bucket]; cur; cur = cur->next) 340 result += 1; 341 return result; 342 } 343 344 // 插入操作, 不允许重复 345 pair<iterator, bool> insert_unique(const value_type& obj) 346 { 347 // 首先判断容量是否够用, 否则就重新配置 348 resize(num_elements + 1); 349 return insert_unique_noresize(obj); 350 } 351 352 // 插入操作, 允许重复 353 iterator insert_equal(const value_type& obj) 354 { 355 resize(num_elements + 1); 356 return insert_equal_noresize(obj); 357 } 358 359 pair<iterator, bool> insert_unique_noresize(const value_type& obj); 360 iterator insert_equal_noresize(const value_type& obj); 361 362 #ifdef __STL_MEMBER_TEMPLATES 363 template <class InputIterator> 364 void insert_unique(InputIterator f, InputIterator l) 365 { 366 insert_unique(f, l, iterator_category(f)); 367 } 368 369 template <class InputIterator> 370 void insert_equal(InputIterator f, InputIterator l) 371 { 372 insert_equal(f, l, iterator_category(f)); 373 } 374 375 template <class InputIterator> 376 void insert_unique(InputIterator f, InputIterator l, 377 input_iterator_tag) 378 { 379 for ( ; f != l; ++f) 380 insert_unique(*f); 381 } 382 383 template <class InputIterator> 384 void insert_equal(InputIterator f, InputIterator l, 385 input_iterator_tag) 386 { 387 for ( ; f != l; ++f) 388 insert_equal(*f); 389 } 390 391 template <class ForwardIterator> 392 void insert_unique(ForwardIterator f, ForwardIterator l, 393 forward_iterator_tag) 394 { 395 size_type n = 0; 396 distance(f, l, n); 397 resize(num_elements + n); 398 for ( ; n > 0; --n, ++f) 399 insert_unique_noresize(*f); 400 } 401 402 template <class ForwardIterator> 403 void insert_equal(ForwardIterator f, ForwardIterator l, 404 forward_iterator_tag) 405 { 406 size_type n = 0; 407 distance(f, l, n); 408 resize(num_elements + n); 409 for ( ; n > 0; --n, ++f) 410 insert_equal_noresize(*f); 411 } 412 413 #else /* __STL_MEMBER_TEMPLATES */ 414 void insert_unique(const value_type* f, const value_type* l) 415 { 416 size_type n = l - f; 417 resize(num_elements + n); 418 for ( ; n > 0; --n, ++f) 419 insert_unique_noresize(*f); 420 } 421 422 void insert_equal(const value_type* f, const value_type* l) 423 { 424 size_type n = l - f; 425 resize(num_elements + n); 426 for ( ; n > 0; --n, ++f) 427 insert_equal_noresize(*f); 428 } 429 430 void insert_unique(const_iterator f, const_iterator l) 431 { 432 size_type n = 0; 433 distance(f, l, n); 434 resize(num_elements + n); 435 for ( ; n > 0; --n, ++f) 436 insert_unique_noresize(*f); 437 } 438 439 void insert_equal(const_iterator f, const_iterator l) 440 { 441 size_type n = 0; 442 distance(f, l, n); 443 resize(num_elements + n); 444 for ( ; n > 0; --n, ++f) 445 insert_equal_noresize(*f); 446 } 447 #endif /*__STL_MEMBER_TEMPLATES */ 448 449 reference find_or_insert(const value_type& obj); 450 451 // 查找指定key 452 iterator find(const key_type& key) 453 { 454 size_type n = bkt_num_key(key); 455 node* first; 456 for ( first = buckets[n]; 457 first && !equals(get_key(first->val), key); 458 first = first->next) 459 {} 460 return iterator(first, this); 461 } 462 463 const_iterator find(const key_type& key) const 464 { 465 size_type n = bkt_num_key(key); 466 const node* first; 467 for ( first = buckets[n]; 468 first && !equals(get_key(first->val), key); 469 first = first->next) 470 {} 471 return const_iterator(first, this); 472 } 473 474 // 返回key元素的个数 475 size_type count(const key_type& key) const 476 { 477 const size_type n = bkt_num_key(key); 478 size_type result = 0; 479 480 for (const node* cur = buckets[n]; cur; cur = cur->next) 481 if (equals(get_key(cur->val), key)) 482 ++result; 483 return result; 484 } 485 486 pair<iterator, iterator> equal_range(const key_type& key); 487 pair<const_iterator, const_iterator> equal_range(const key_type& key) const; 488 489 // 擦除元素 490 size_type erase(const key_type& key); 491 void erase(const iterator& it); 492 void erase(iterator first, iterator last); 493 494 void erase(const const_iterator& it); 495 void erase(const_iterator first, const_iterator last); 496 497 void resize(size_type num_elements_hint); 498 void clear(); 499 500 private: 501 size_type next_size(size_type n) const { return __stl_next_prime(n); } 502 503 // 预留空间, 并进行初始化 504 void initialize_buckets(size_type n) 505 { 506 const size_type n_buckets = next_size(n); 507 buckets.reserve(n_buckets); 508 buckets.insert(buckets.end(), n_buckets, (node*) 0); 509 num_elements = 0; 510 } 511 512 size_type bkt_num_key(const key_type& key) const 513 { 514 return bkt_num_key(key, buckets.size()); 515 } 516 517 // 获取obj映射位置, 要经过一个mod过程 518 size_type bkt_num(const value_type& obj) const 519 { 520 return bkt_num_key(get_key(obj)); 521 } 522 523 size_type bkt_num_key(const key_type& key, size_t n) const 524 { 525 return hash(key) % n; 526 } 527 528 size_type bkt_num(const value_type& obj, size_t n) const 529 { 530 return bkt_num_key(get_key(obj), n); 531 } 532 533 // 分配空间并进行构造 534 node* new_node(const value_type& obj) 535 { 536 node* n = node_allocator::allocate(); 537 n->next = 0; 538 __STL_TRY { 539 construct(&n->val, obj); 540 return n; 541 } 542 __STL_UNWIND(node_allocator::deallocate(n)); 543 } 544 545 // 析构并释放空间 546 void delete_node(node* n) 547 { 548 destroy(&n->val); 549 node_allocator::deallocate(n); 550 } 551 552 // 解析见实现部分 553 void erase_bucket(const size_type n, node* first, node* last); 554 void erase_bucket(const size_type n, node* last); 555 556 void copy_from(const hashtable& ht); 557 }; 558 559 560 template <class V, class K, class HF, class ExK, class EqK, class A> 561 __hashtable_iterator<V, K, HF, ExK, EqK, A>& 562 __hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++() 563 { 564 const node* old = cur; 565 cur = cur->next; // 当前链表结点的下一个结点, 如果不为0 566 // 那么它就是我们要的 567 568 // 链表结点恰好是最后一个结点, 我们要在线性表的下一个表格的链表中查找 569 if (!cur) 570 { 571 size_type bucket = ht->bkt_num(old->val); 572 while (!cur && ++bucket < ht->buckets.size()) 573 cur = ht->buckets[bucket]; 574 } 575 576 return *this; 577 } 578 579 template <class V, class K, class HF, class ExK, class EqK, class A> 580 inline __hashtable_iterator<V, K, HF, ExK, EqK, A> 581 __hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int) 582 { 583 iterator tmp = *this; 584 ++*this; // 触发operator ++() 585 return tmp; 586 } 587 588 // const情况同上 589 template <class V, class K, class HF, class ExK, class EqK, class A> 590 __hashtable_const_iterator<V, K, HF, ExK, EqK, A>& 591 __hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++() 592 { 593 const node* old = cur; 594 cur = cur->next; 595 if (!cur) { 596 size_type bucket = ht->bkt_num(old->val); 597 while (!cur && ++bucket < ht->buckets.size()) 598 cur = ht->buckets[bucket]; 599 } 600 return *this; 601 } 602 603 template <class V, class K, class HF, class ExK, class EqK, class A> 604 inline __hashtable_const_iterator<V, K, HF, ExK, EqK, A> 605 __hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int) 606 { 607 const_iterator tmp = *this; 608 ++*this; 609 return tmp; 610 } 611 612 // 对于不支持偏特化的编译器提供traits支持 613 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION 614 615 template <class V, class K, class HF, class ExK, class EqK, class All> 616 inline forward_iterator_tag 617 iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) 618 { 619 return forward_iterator_tag(); 620 } 621 622 template <class V, class K, class HF, class ExK, class EqK, class All> 623 inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) 624 { 625 return (V*) 0; 626 } 627 628 template <class V, class K, class HF, class ExK, class EqK, class All> 629 inline hashtable<V, K, HF, ExK, EqK, All>::difference_type* 630 distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) 631 { 632 return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; 633 } 634 635 template <class V, class K, class HF, class ExK, class EqK, class All> 636 inline forward_iterator_tag 637 iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) 638 { 639 return forward_iterator_tag(); 640 } 641 642 template <class V, class K, class HF, class ExK, class EqK, class All> 643 inline V* 644 value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) 645 { 646 return (V*) 0; 647 } 648 649 template <class V, class K, class HF, class ExK, class EqK, class All> 650 inline hashtable<V, K, HF, ExK, EqK, All>::difference_type* 651 distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) 652 { 653 return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; 654 } 655 656 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 657 658 template <class V, class K, class HF, class Ex, class Eq, class A> 659 bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1, 660 const hashtable<V, K, HF, Ex, Eq, A>& ht2) 661 { 662 typedef typename hashtable<V, K, HF, Ex, Eq, A>::node node; 663 if (ht1.buckets.size() != ht2.buckets.size()) 664 return false; 665 for (int n = 0; n < ht1.buckets.size(); ++n) { 666 node* cur1 = ht1.buckets[n]; 667 node* cur2 = ht2.buckets[n]; 668 for ( ; cur1 && cur2 && cur1->val == cur2->val; 669 cur1 = cur1->next, cur2 = cur2->next) 670 {} 671 if (cur1 || cur2) 672 return false; 673 } 674 return true; 675 } 676 677 // 如果编译器支持模板函数特化优先级 678 // 那么将全局的swap实现为使用hashtable私有的swap以提高效率 679 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 680 681 template <class Val, class Key, class HF, class Extract, class EqKey, class A> 682 inline void swap(hashtable<Val, Key, HF, Extract, EqKey, A>& ht1, 683 hashtable<Val, Key, HF, Extract, EqKey, A>& ht2) { 684 ht1.swap(ht2); 685 } 686 687 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 688 689 690 // 在不需要重新调整容量的情况下插入元素, key不可以重复 691 template <class V, class K, class HF, class Ex, class Eq, class A> 692 pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> 693 hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj) 694 { 695 // 获取待插入元素在hashtable中的索引 696 const size_type n = bkt_num(obj); 697 698 node* first = buckets[n]; 699 700 for (node* cur = first; cur; cur = cur->next) 701 // 如果keu重复, 在不进行插入, 并告知用户插入失败 702 if (equals(get_key(cur->val), get_key(obj))) 703 return pair<iterator, bool>(iterator(cur, this), false); 704 705 // 插入结点 706 node* tmp = new_node(obj); 707 tmp->next = first; 708 buckets[n] = tmp; 709 ++num_elements; 710 return pair<iterator, bool>(iterator(tmp, this), true); 711 } 712 713 // 在不需要重新调整容量的情况下插入元素, key可以重复 714 template <class V, class K, class HF, class Ex, class Eq, class A> 715 typename hashtable<V, K, HF, Ex, Eq, A>::iterator 716 hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj) 717 { 718 const size_type n = bkt_num(obj); 719 node* first = buckets[n]; 720 721 for (node* cur = first; cur; cur = cur->next) 722 if (equals(get_key(cur->val), get_key(obj))) { 723 node* tmp = new_node(obj); 724 tmp->next = cur->next; 725 cur->next = tmp; 726 ++num_elements; 727 return iterator(tmp, this); 728 } 729 730 node* tmp = new_node(obj); 731 tmp->next = first; 732 buckets[n] = tmp; 733 ++num_elements; 734 return iterator(tmp, this); 735 } 736 737 // 这个用于支持hash_map操作 738 template <class V, class K, class HF, class Ex, class Eq, class A> 739 typename hashtable<V, K, HF, Ex, Eq, A>::reference 740 hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj) 741 { 742 resize(num_elements + 1); 743 744 size_type n = bkt_num(obj); 745 node* first = buckets[n]; 746 747 for (node* cur = first; cur; cur = cur->next) 748 if (equals(get_key(cur->val), get_key(obj))) 749 return cur->val; 750 751 node* tmp = new_node(obj); 752 tmp->next = first; 753 buckets[n] = tmp; 754 ++num_elements; 755 return tmp->val; 756 } 757 758 // 查找满足key的区间 759 template <class V, class K, class HF, class Ex, class Eq, class A> 760 pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, 761 typename hashtabfind_or_insertle<V, K, HF, Ex, Eq, A>::iterator> 762 hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) 763 { 764 typedef pair<iterator, iterator> pii; 765 const size_type n = bkt_num_key(key); 766 767 for (node* first = buckets[n]; first; first = first->next) { 768 if (equals(get_key(first->val), key)) { 769 for (node* cur = first->next; cur; cur = cur->next) 770 if (!equals(get_key(cur->val), key)) 771 return pii(iterator(first, this), iterator(cur, this)); 772 for (size_type m = n + 1; m < buckets.size(); ++m) 773 if (buckets[m]) 774 return pii(iterator(first, this), 775 iterator(buckets[m], this)); 776 return pii(iterator(first, this), end()); 777 } 778 } 779 return pii(end(), end()); 780 } 781 782 template <class V, class K, class HF, class Ex, class Eq, class A> 783 pair<typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator, 784 typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator> 785 hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const 786 { 787 typedef pair<const_iterator, const_iterator> pii; 788 const size_type n = bkt_num_key(key); 789 790 for (const node* first = buckets[n] ; first; first = first->next) { 791 if (equals(get_key(first->val), key)) { 792 for (const node* cur = first->next; cur; cur = cur->next) 793 if (!equals(get_key(cur->val), key)) 794 return pii(const_iterator(first, this), 795 const_iterator(cur, this)); 796 for (size_type m = n + 1; m < buckets.size(); ++m) 797 if (buckets[m]) 798 return pii(const_iterator(first, this), 799 const_iterator(buckets[m], this)); 800 return pii(const_iterator(first, this), end()); 801 } 802 } 803 return pii(end(), end()); 804 } 805 806 // 擦除指定元素 807 template <class V, class K, class HF, class Ex, class Eq, class A> 808 typename hashtable<V, K, HF, Ex, Eq, A>::size_type 809 hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key) 810 { 811 // 计算映射位置 812 const size_type n = bkt_num_key(key); 813 node* first = buckets[n]; 814 size_type erased = 0; 815 816 // 开始查找并删除 817 if (first) { 818 node* cur = first; 819 node* next = cur->next; 820 while (next) { 821 if (equals(get_key(next->val), key)) { 822 cur->next = next->next; 823 delete_node(next); 824 next = cur->next; 825 ++erased; 826 --num_elements; 827 } 828 else { 829 cur = next; 830 next = cur->next; 831 } 832 } 833 if (equals(get_key(first->val), key)) { 834 buckets[n] = first->next; 835 delete_node(first); 836 ++erased; 837 --num_elements; 838 } 839 } 840 return erased; 841 } 842 843 template <class V, class K, class HF, class Ex, class Eq, class A> 844 void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it) 845 { 846 if (node* const p = it.cur) { 847 const size_type n = bkt_num(p->val); 848 node* cur = buckets[n]; 849 850 if (cur == p) { 851 buckets[n] = cur->next; 852 delete_node(cur); 853 --num_elements; 854 } 855 else { 856 node* next = cur->next; 857 while (next) { 858 if (next == p) { 859 cur->next = next->next; 860 delete_node(next); 861 --num_elements; 862 break; 863 } 864 else { 865 cur = next; 866 next = cur->next; 867 } 868 } 869 } 870 } 871 } 872 873 // 擦除指定区间的元素 874 template <class V, class K, class HF, class Ex, class Eq, class A> 875 void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last) 876 { 877 size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size(); 878 size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size(); 879 880 if (first.cur == last.cur) 881 return; 882 else if (f_bucket == l_bucket) 883 erase_bucket(f_bucket, first.cur, last.cur); 884 else { 885 erase_bucket(f_bucket, first.cur, 0); 886 for (size_type n = f_bucket + 1; n < l_bucket; ++n) 887 erase_bucket(n, 0); 888 if (l_bucket != buckets.size()) 889 erase_bucket(l_bucket, last.cur); 890 } 891 } 892 893 template <class V, class K, class HF, class Ex, class Eq, class A> 894 inline void 895 hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first, 896 const_iterator last) 897 { 898 erase(iterator(const_cast<node*>(first.cur), 899 const_cast<hashtable*>(first.ht)), 900 iterator(const_cast<node*>(last.cur), 901 const_cast<hashtable*>(last.ht))); 902 } 903 904 template <class V, class K, class HF, class Ex, class Eq, class A> 905 inline void 906 hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it) 907 { 908 erase(iterator(const_cast<node*>(it.cur), 909 const_cast<hashtable*>(it.ht))); 910 } 911 912 // 调整hashtable的容量 913 template <class V, class K, class HF, class Ex, class Eq, class A> 914 void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint) 915 { 916 const size_type old_n = buckets.size(); 917 918 // 如果新调整的大小小于当前大小, 不进行更改 919 if (num_elements_hint > old_n) { 920 const size_type n = next_size(num_elements_hint); 921 922 // 如果已经到达hashtable的容量的极限, 那么也不进行更改 923 if (n > old_n) { 924 // 建立新的线性表来扩充容量 925 vector<node*, A> tmp(n, (node*) 0); 926 __STL_TRY { 927 // 先面开始copy 928 for (size_type bucket = 0; bucket < old_n; ++bucket) { 929 node* first = buckets[bucket]; 930 while (first) { 931 size_type new_bucket = bkt_num(first->val, n); 932 buckets[bucket] = first->next; 933 first->next = tmp[new_bucket]; 934 tmp[new_bucket] = first; 935 first = buckets[bucket]; 936 } 937 } 938 buckets.swap(tmp); 939 } 940 # ifdef __STL_USE_EXCEPTIONS 941 catch(...) { 942 for (size_type bucket = 0; bucket < tmp.size(); ++bucket) { 943 while (tmp[bucket]) { 944 node* next = tmp[bucket]->next; 945 delete_node(tmp[bucket]); 946 tmp[bucket] = next; 947 } 948 } 949 throw; 950 } 951 # endif /* __STL_USE_EXCEPTIONS */ 952 } 953 } 954 } 955 956 // 擦除指定映射位置的所有元素 957 template <class V, class K, class HF, class Ex, class Eq, class A> 958 void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, 959 node* first, node* last) 960 { 961 node* cur = buckets[n]; 962 if (cur == first) 963 erase_bucket(n, last); 964 else { 965 node* next; 966 for (next = cur->next; next != first; cur = next, next = cur->next) 967 ; 968 while (next) { 969 cur->next = next->next; 970 delete_node(next); 971 next = cur->next; 972 --num_elements; 973 } 974 } 975 } 976 977 template <class V, class K, class HF, class Ex, class Eq, class A> 978 void 979 hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last) 980 { 981 node* cur = buckets[n]; 982 while (cur != last) { 983 node* next = cur->next; 984 delete_node(cur); 985 cur = next; 986 buckets[n] = cur; 987 --num_elements; 988 } 989 } 990 991 // 清空hashtable, 但是不释放vector的内存 992 template <class V, class K, class HF, class Ex, class Eq, class A> 993 void hashtable<V, K, HF, Ex, Eq, A>::clear() 994 { 995 for (size_type i = 0; i < buckets.size(); ++i) { 996 node* cur = buckets[i]; 997 while (cur != 0) { 998 node* next = cur->next; 999 delete_node(cur); 1000 cur = next; 1001 } 1002 buckets[i] = 0; 1003 } 1004 num_elements = 0; 1005 } 1006 1007 // 复制另一个hashtable给当前hashtable 1008 template <class V, class K, class HF, class Ex, class Eq, class A> 1009 void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht) 1010 { 1011 // 首先清空当前hashtable 1012 buckets.clear(); 1013 // 预留足够容量 1014 buckets.reserve(ht.buckets.size()); 1015 // 完成初始化操作, 这是hashtable的先验条件 1016 buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); 1017 __STL_TRY { 1018 // 开始copy操作 1019 for (size_type i = 0; i < ht.buckets.size(); ++i) { 1020 if (const node* cur = ht.buckets[i]) { 1021 node* copy = new_node(cur->val); 1022 buckets[i] = copy; 1023 1024 for (node* next = cur->next; next; cur = next, next = cur->next) { 1025 copy->next = new_node(next->val); 1026 copy = copy->next; 1027 } 1028 } 1029 } 1030 num_elements = ht.num_elements; 1031 } 1032 __STL_UNWIND(clear()); 1033 } 1034 1035 __STL_END_NAMESPACE 1036 1037 #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ 1038 1039 // Local Variables: 1040 // mode:C++ 1041 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_hash_set.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // hash_set和hash_multiset是对hashtable的简单包装, 很容易理解 8 9 /* 10 * Copyright (c) 1996 11 * Silicon Graphics Computer Systems, Inc. 12 * 13 * Permission to use, copy, modify, distribute and sell this software 14 * and its documentation for any purpose is hereby granted without fee, 15 * provided that the above copyright notice appear in all copies and 16 * that both that copyright notice and this permission notice appear 17 * in supporting documentation. Silicon Graphics makes no 18 * representations about the suitability of this software for any 19 * purpose. It is provided "as is" without express or implied warranty. 20 * 21 * 22 * Copyright (c) 1994 23 * Hewlett-Packard Company 24 * 25 * Permission to use, copy, modify, distribute and sell this software 26 * and its documentation for any purpose is hereby granted without fee, 27 * provided that the above copyright notice appear in all copies and 28 * that both that copyright notice and this permission notice appear 29 * in supporting documentation. Hewlett-Packard Company makes no 30 * representations about the suitability of this software for any 31 * purpose. It is provided "as is" without express or implied warranty. 32 * 33 */ 34 35 /* NOTE: This is an internal header file, included by other STL headers. 36 * You should not attempt to use it directly. 37 */ 38 39 #ifndef __SGI_STL_INTERNAL_HASH_SET_H 40 #define __SGI_STL_INTERNAL_HASH_SET_H 41 42 __STL_BEGIN_NAMESPACE 43 44 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 45 #pragma set woff 1174 46 #endif 47 48 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 49 // 那么就需要手工指定, 并且对于基本的数据类型, 在<stl_hash_fun.h> 50 // 中都提供hash函数 51 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 52 template <class Value, class HashFcn = hash<Value>, 53 class EqualKey = equal_to<Value>, 54 class Alloc = alloc> 55 #else 56 template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> 57 #endif 58 class hash_set 59 { 60 private: 61 // identity<Value>用于析出Value 62 typedef hashtable<Value, Value, HashFcn, identity<Value>, 63 EqualKey, Alloc> ht; 64 ht rep; // 其实hash_set就是hashtable的简单封装 65 66 public: 67 typedef typename ht::key_type key_type; 68 typedef typename ht::value_type value_type; 69 typedef typename ht::hasher hasher; 70 typedef typename ht::key_equal key_equal; 71 72 // 注意: reference, pointer, iterator都为const, 因为不能修改hashtable 73 // 内部的元素, 否则会导致hashtable失效 74 typedef typename ht::size_type size_type; 75 typedef typename ht::difference_type difference_type; 76 typedef typename ht::const_pointer pointer; 77 typedef typename ht::const_pointer const_pointer; 78 typedef typename ht::const_reference reference; 79 typedef typename ht::const_reference const_reference; 80 81 typedef typename ht::const_iterator iterator; 82 typedef typename ht::const_iterator const_iterator; 83 84 // 返回hash相关函数 85 hasher hash_funct() const { return rep.hash_funct(); } 86 key_equal key_eq() const { return rep.key_eq(); } 87 88 public: 89 hash_set() : rep(100, hasher(), key_equal()) {} 90 explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {} 91 hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} 92 hash_set(size_type n, const hasher& hf, const key_equal& eql) 93 : rep(n, hf, eql) {} 94 95 #ifdef __STL_MEMBER_TEMPLATES 96 template <class InputIterator> 97 hash_set(InputIterator f, InputIterator l) 98 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 99 template <class InputIterator> 100 hash_set(InputIterator f, InputIterator l, size_type n) 101 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 102 template <class InputIterator> 103 hash_set(InputIterator f, InputIterator l, size_type n, 104 const hasher& hf) 105 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 106 template <class InputIterator> 107 hash_set(InputIterator f, InputIterator l, size_type n, 108 const hasher& hf, const key_equal& eql) 109 : rep(n, hf, eql) { rep.insert_unique(f, l); } 110 #else 111 112 hash_set(const value_type* f, const value_type* l) 113 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 114 hash_set(const value_type* f, const value_type* l, size_type n) 115 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 116 hash_set(const value_type* f, const value_type* l, size_type n, 117 const hasher& hf) 118 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 119 hash_set(const value_type* f, const value_type* l, size_type n, 120 const hasher& hf, const key_equal& eql) 121 : rep(n, hf, eql) { rep.insert_unique(f, l); } 122 123 hash_set(const_iterator f, const_iterator l) 124 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 125 hash_set(const_iterator f, const_iterator l, size_type n) 126 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 127 hash_set(const_iterator f, const_iterator l, size_type n, 128 const hasher& hf) 129 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 130 hash_set(const_iterator f, const_iterator l, size_type n, 131 const hasher& hf, const key_equal& eql) 132 : rep(n, hf, eql) { rep.insert_unique(f, l); } 133 #endif /*__STL_MEMBER_TEMPLATES */ 134 135 public: 136 // 下面都是对hashtable的简单封装, 见<stl_hashtable.h> 137 size_type size() const { return rep.size(); } 138 size_type max_size() const { return rep.max_size(); } 139 bool empty() const { return rep.empty(); } 140 void swap(hash_set& hs) { rep.swap(hs.rep); } 141 142 friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, 143 const hash_set&); 144 iterator begin() const { return rep.begin(); } 145 iterator end() const { return rep.end(); } 146 147 public: 148 pair<iterator, bool> insert(const value_type& obj) 149 { 150 pair<typename ht::iterator, bool> p = rep.insert_unique(obj); 151 r 152 eturn pair<iterator, bool>(p.first, p.second); 153 } 154 #ifdef __STL_MEMBER_TEMPLATES 155 template <class InputIterator> 156 void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } 157 #else 158 void insert(const value_type* f, const value_type* l) { 159 rep.insert_unique(f,l); 160 } 161 void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); } 162 #endif /*__STL_MEMBER_TEMPLATES */ 163 164 // hash_set和set一样, 都不允许key重复 165 pair<iterator, bool> insert_noresize(const value_type& obj) 166 { 167 pair<typename ht::iterator, bool> p = rep.insert_unique_noresize(obj); 168 return pair<iterator, bool>(p.first, p.second); 169 } 170 171 iterator find(const key_type& key) const { return rep.find(key); } 172 173 size_type count(const key_type& key) const { return rep.count(key); } 174 175 pair<iterator, iterator> equal_range(const key_type& key) const 176 { return rep.equal_range(key); } 177 178 size_type erase(const key_type& key) {return rep.erase(key); } 179 void erase(iterator it) { rep.erase(it); } 180 void erase(iterator f, iterator l) { rep.erase(f, l); } 181 void clear() { rep.clear(); } 182 183 public: 184 void resize(size_type hint) { rep.resize(hint); } 185 size_type bucket_count() const { return rep.bucket_count(); } 186 size_type max_bucket_count() const { return rep.max_bucket_count(); } 187 size_type elems_in_bucket(size_type n) const 188 { return rep.elems_in_bucket(n); } 189 }; 190 191 template <class Value, class HashFcn, class EqualKey, class Alloc> 192 inline bool operator==(const hash_set<Value, HashFcn, EqualKey, Alloc>& hs1, 193 const hash_set<Value, HashFcn, EqualKey, Alloc>& hs2) 194 { 195 return hs1.rep == hs2.rep; 196 } 197 198 // 如果编译器支持模板函数特化优先级 199 // 那么将全局的swap实现为使用hash_set私有的swap以提高效率 200 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 201 202 template <class Val, class HashFcn, class EqualKey, class Alloc> 203 inline void swap(hash_set<Val, HashFcn, EqualKey, Alloc>& hs1, 204 hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) 205 { 206 hs1.swap(hs2); 207 } 208 209 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 210 211 // hash_multiset和hash_set除去允许key重复外, 其余性质一致 212 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 213 template <class Value, class HashFcn = hash<Value>, 214 class EqualKey = equal_to<Value>, 215 class Alloc = alloc> 216 #else 217 template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> 218 #endif 219 class hash_multiset 220 { 221 private: 222 typedef hashtable<Value, Value, HashFcn, identity<Value>, 223 EqualKey, Alloc> ht; 224 ht rep; 225 226 public: 227 typedef typename ht::key_type key_type; 228 typedef typename ht::value_type value_type; 229 typedef typename ht::hasher hasher; 230 typedef typename ht::key_equal key_equal; 231 232 typedef typename ht::size_type size_type; 233 typedef typename ht::difference_type difference_type; 234 typedef typename ht::const_pointer pointer; 235 typedef typename ht::const_pointer const_pointer; 236 typedef typename ht::const_reference reference; 237 typedef typename ht::const_reference const_reference; 238 239 typedef typename ht::const_iterator iterator; 240 typedef typename ht::const_iterator const_iterator; 241 242 hasher hash_funct() const { return rep.hash_funct(); } 243 key_equal key_eq() const { return rep.key_eq(); } 244 245 public: 246 hash_multiset() : rep(100, hasher(), key_equal()) {} 247 explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {} 248 hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} 249 hash_multiset(size_type n, const hasher& hf, const key_equal& eql) 250 : rep(n, hf, eql) {} 251 252 #ifdef __STL_MEMBER_TEMPLATES 253 template <class InputIterator> 254 hash_multiset(InputIterator f, InputIterator l) 255 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 256 template <class InputIterator> 257 hash_multiset(InputIterator f, InputIterator l, size_type n) 258 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 259 template <class InputIterator> 260 hash_multiset(InputIterator f, InputIterator l, size_type n, 261 const hasher& hf) 262 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 263 template <class InputIterator> 264 hash_multiset(InputIterator f, InputIterator l, size_type n, 265 const hasher& hf, const key_equal& eql) 266 : rep(n, hf, eql) { rep.insert_equal(f, l); } 267 #else 268 269 hash_multiset(const value_type* f, const value_type* l) 270 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 271 hash_multiset(const value_type* f, const value_type* l, size_type n) 272 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 273 hash_multiset(const value_type* f, const value_type* l, size_type n, 274 const hasher& hf) 275 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 276 hash_multiset(const value_type* f, const value_type* l, size_type n, 277 const hasher& hf, const key_equal& eql) 278 : rep(n, hf, eql) { rep.insert_equal(f, l); } 279 280 hash_multiset(const_iterator f, const_iterator l) 281 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 282 hash_multiset(const_iterator f, const_iterator l, size_type n) 283 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 284 hash_multiset(const_iterator f, const_iterator l, size_type n, 285 const hasher& hf) 286 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 287 hash_multiset(const_iterator f, const_iterator l, size_type n, 288 const hasher& hf, const key_equal& eql) 289 : rep(n, hf, eql) { rep.insert_equal(f, l); } 290 #endif /*__STL_MEMBER_TEMPLATES */ 291 292 public: 293 size_type size() const { return rep.size(); } 294 size_type max_size() const { return rep.max_size(); } 295 bool empty() const { return rep.empty(); } 296 void swap(hash_multiset& hs) { rep.swap(hs.rep); } 297 friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, 298 const hash_multiset&); 299 300 iterator begin() const { return rep.begin(); } 301 iterator end() const { return rep.end(); } 302 303 public: 304 iterator insert(const value_type& obj) { return rep.insert_equal(obj); } 305 #ifdef __STL_MEMBER_TEMPLATES 306 template <class InputIterator> 307 void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } 308 #else 309 void insert(const value_type* f, const value_type* l) { 310 rep.insert_equal(f,l); 311 } 312 void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } 313 #endif /*__STL_MEMBER_TEMPLATES */ 314 iterator insert_noresize(const value_type& obj) 315 { return rep.insert_equal_noresize(obj); } 316 317 iterator find(const key_type& key) const { return rep.find(key); } 318 319 size_type count(const key_type& key) const { return rep.count(key); } 320 321 pair<iterator, iterator> equal_range(const key_type& key) const 322 { return rep.equal_range(key); } 323 324 size_type erase(const key_type& key) {return rep.erase(key); } 325 void erase(iterator it) { rep.erase(it); } 326 void erase(iterator f, iterator l) { rep.erase(f, l); } 327 void clear() { rep.clear(); } 328 329 public: 330 void resize(size_type hint) { rep.resize(hint); } 331 size_type bucket_count() const { return rep.bucket_count(); } 332 size_type max_bucket_count() const { return rep.max_bucket_count(); } 333 size_type elems_in_bucket(size_type n) const 334 { return rep.elems_in_bucket(n); } 335 }; 336 337 template <class Val, class HashFcn, class EqualKey, class Alloc> 338 inline bool operator==(const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1, 339 const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2) 340 { 341 return hs1.rep == hs2.rep; 342 } 343 344 // 如果编译器支持模板函数特化优先级 345 // 那么将全局的swap实现为使用hash_multiset私有的swap以提高效率 346 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 347 348 template <class Val, class HashFcn, class EqualKey, class Alloc> 349 inline void swap(hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1, 350 hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2) 351 { 352 hs1.swap(hs2); 353 } 354 355 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 356 357 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 358 #pragma reset woff 1174 359 #endif 360 361 __STL_END_NAMESPACE 362 363 #endif /* __SGI_STL_INTERNAL_HASH_SET_H */ 364 365 // Local Variables: 366 // mode:C++ 367 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_hash_map.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // hash_map和hash_multimap是对hashtable的简单包装, 很容易理解 8 9 /* 10 * Copyright (c) 1996 11 * Silicon Graphics Computer Systems, Inc. 12 * 13 * Permission to use, copy, modify, distribute and sell this software 14 * and its documentation for any purpose is hereby granted without fee, 15 * provided that the above copyright notice appear in all copies and 16 * that both that copyright notice and this permission notice appear 17 * in supporting documentation. Silicon Graphics makes no 18 * representations about the suitability of this software for any 19 * purpose. It is provided "as is" without express or implied warranty. 20 * 21 * 22 * Copyright (c) 1994 23 * Hewlett-Packard Company 24 * 25 * Permission to use, copy, modify, distribute and sell this software 26 * and its documentation for any purpose is hereby granted without fee, 27 * provided that the above copyright notice appear in all copies and 28 * that both that copyright notice and this permission notice appear 29 * in supporting documentation. Hewlett-Packard Company makes no 30 * representations about the suitability of this software for any 31 * purpose. It is provided "as is" without express or implied warranty. 32 * 33 */ 34 35 /* NOTE: This is an internal header file, included by other STL headers. 36 * You should not attempt to use it directly. 37 */ 38 39 #ifndef __SGI_STL_INTERNAL_HASH_MAP_H 40 #define __SGI_STL_INTERNAL_HASH_MAP_H 41 42 __STL_BEGIN_NAMESPACE 43 44 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 45 #pragma set woff 1174 46 #endif 47 48 // 如果编译器不能根据前面模板参数推导出后面使用的默认参数类型, 49 // 那么就需要手工指定, 并且对于基本的数据类型, 在<stl_hash_fun.h> 50 // 中都提供hash函数 51 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 52 template <class Key, class T, class HashFcn = hash<Key>, 53 class EqualKey = equal_to<Key>, 54 class Alloc = alloc> 55 #else 56 template <class Key, class T, class HashFcn, class EqualKey, 57 class Alloc = alloc> 58 #endif 59 class hash_map 60 { 61 private: 62 typedef hashtable<pair<const Key, T>, Key, HashFcn, 63 select1st<pair<const Key, T> >, EqualKey, Alloc> ht; 64 ht rep; 65 66 public: 67 // 注意: reference, pointer, iterator都为const, 因为不能修改hashtable 68 // 内部的元素, 否则会导致hashtable失效 69 typedef typename ht::key_type key_type; 70 typedef T data_type; 71 typedef T mapped_type; 72 typedef typename ht::value_type value_type; 73 typedef typename ht::hasher hasher; 74 typedef typename ht::key_equal key_equal; 75 76 typedef typename ht::size_type size_type; 77 typedef typename ht::difference_type difference_type; 78 typedef typename ht::pointer pointer; 79 typedef typename ht::const_pointer const_pointer; 80 typedef typename ht::reference reference; 81 typedef typename ht::const_reference const_reference; 82 83 typedef typename ht::iterator iterator; 84 typedef typename ht::const_iterator const_iterator; 85 86 // 返回hash相关函数 87 hasher hash_funct() const { return rep.hash_funct(); } 88 key_equal key_eq() const { return rep.key_eq(); } 89 90 public: 91 hash_map() : rep(100, hasher(), key_equal()) {} 92 explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {} 93 hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} 94 hash_map(size_type n, const hasher& hf, const key_equal& eql) 95 : rep(n, hf, eql) {} 96 97 #ifdef __STL_MEMBER_TEMPLATES 98 template <class InputIterator> 99 hash_map(InputIterator f, InputIterator l) 100 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 101 template <class InputIterator> 102 hash_map(InputIterator f, InputIterator l, size_type n) 103 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 104 template <class InputIterator> 105 hash_map(InputIterator f, InputIterator l, size_type n, 106 const hasher& hf) 107 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 108 template <class InputIterator> 109 hash_map(InputIterator f, InputIterator l, size_type n, 110 const hasher& hf, const key_equal& eql) 111 : rep(n, hf, eql) { rep.insert_unique(f, l); } 112 113 #else 114 hash_map(const value_type* f, const value_type* l) 115 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 116 hash_map(const value_type* f, const value_type* l, size_type n) 117 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 118 hash_map(const value_type* f, const value_type* l, size_type n, 119 const hasher& hf) 120 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 121 hash_map(const value_type* f, const value_type* l, size_type n, 122 const hasher& hf, const key_equal& eql) 123 : rep(n, hf, eql) { rep.insert_unique(f, l); } 124 125 hash_map(const_iterator f, const_iterator l) 126 : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } 127 hash_map(const_iterator f, const_iterator l, size_type n) 128 : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } 129 hash_map(const_iterator f, const_iterator l, size_type n, 130 const hasher& hf) 131 : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } 132 hash_map(const_iterator f, const_iterator l, size_type n, 133 const hasher& hf, const key_equal& eql) 134 : rep(n, hf, eql) { rep.insert_unique(f, l); } 135 #endif /*__STL_MEMBER_TEMPLATES */ 136 137 public: 138 // 下面都是对hashtable的简单封装, 见<stl_hashtable.h> 139 size_type size() const { return rep.size(); } 140 size_type max_size() const { return rep.max_size(); } 141 bool empty() const { return rep.empty(); } 142 void swap(hash_map& hs) { rep.swap(hs.rep); } 143 friend bool 144 operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); 145 146 iterator begin() { return rep.begin(); } 147 iterator end() { return rep.end(); } 148 const_iterator begin() const { return rep.begin(); } 149 const_iterator end() const { return rep.end(); } 150 151 public: 152 // 不允许插入key相同的元素 153 pair<iterator, bool> insert(const value_type& obj) 154 { return rep.insert_unique(obj); } 155 156 #ifdef __STL_MEMBER_TEMPLATES 157 template <class InputIterator> 158 void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } 159 #else 160 void insert(const value_type* f, const value_type* l) { 161 rep.insert_unique(f,l); 162 } 163 void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); } 164 #endif /*__STL_MEMBER_TEMPLATES */ 165 166 pair<iterator, bool> insert_noresize(const value_type& obj) 167 { return rep.insert_unique_noresize(obj); } 168 169 iterator find(const key_type& key) { return rep.find(key); } 170 const_iterator find(const key_type& key) const { return rep.find(key); } 171 172 // 如果key存在则返回对应的元素, 否则新建一个key 173 T& operator[](const key_type& key) 174 { 175 return rep.find_or_insert(value_type(key, T())).second; 176 } 177 178 // 下面封装见<stl_hashtable.h> 179 size_type count(const key_type& key) const { return rep.count(key); } 180 181 pair<iterator, iterator> equal_range(const key_type& key) 182 { return rep.equal_range(key); } 183 pair<const_iterator, const_iterator> equal_range(const key_type& key) const 184 { return rep.equal_range(key); } 185 186 size_type erase(const key_type& key) {return rep.erase(key); } 187 void erase(iterator it) { rep.erase(it); } 188 void erase(iterator f, iterator l) { rep.erase(f, l); } 189 void clear() { rep.clear(); } 190 191 public: 192 void resize(size_type hint) { rep.resize(hint); } 193 size_type bucket_count() const { return rep.bucket_count(); } 194 size_type max_bucket_count() const { return rep.max_bucket_count(); } 195 size_type elems_in_bucket(size_type n) const 196 { return rep.elems_in_bucket(n); } 197 }; 198 199 template <class Key, class T, class HashFcn, class EqualKey, class Alloc> 200 inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1, 201 const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) 202 { 203 return hm1.rep == hm2.rep; 204 } 205 206 // 如果编译器支持模板函数特化优先级 207 // 那么将全局的swap实现为使用hash_map私有的swap以提高效率 208 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 209 210 template <class Key, class T, class HashFcn, class EqualKey, class Alloc> 211 inline void swap(hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1, 212 hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) 213 { 214 hm1.swap(hm2); 215 } 216 217 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 218 219 // hash_multimap和hash_map除去允许key重复外, 其余性质一致 220 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES 221 template <class Key, class T, class HashFcn = hash<Key>, 222 class EqualKey = equal_to<Key>, 223 class Alloc = alloc> 224 #else 225 template <class Key, class T, class HashFcn, class EqualKey, 226 class Alloc = alloc> 227 #endif 228 class hash_multimap 229 { 230 private: 231 typedef hashtable<pair<const Key, T>, Key, HashFcn, 232 select1st<pair<const Key, T> >, EqualKey, Alloc> ht; 233 ht rep; 234 235 public: 236 typedef typename ht::key_type key_type; 237 typedef T data_type; 238 typedef T mapped_type; 239 typedef typename ht::value_type value_type; 240 typedef typename ht::hasher hasher; 241 typedef typename ht::key_equal key_equal; 242 243 typedef typename ht::size_type size_type; 244 typedef typename ht::difference_type difference_type; 245 typedef typename ht::pointer pointer; 246 typedef typename ht::const_pointer const_pointer; 247 typedef typename ht::reference reference; 248 typedef typename ht::const_reference const_reference; 249 250 typedef typename ht::iterator iterator; 251 typedef typename ht::const_iterator const_iterator; 252 253 hasher hash_funct() const { return rep.hash_funct(); } 254 key_equal key_eq() const { return rep.key_eq(); } 255 256 public: 257 hash_multimap() : rep(100, hasher(), key_equal()) {} 258 explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {} 259 hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} 260 hash_multimap(size_type n, const hasher& hf, const key_equal& eql) 261 : rep(n, hf, eql) {} 262 263 #ifdef __STL_MEMBER_TEMPLATES 264 template <class InputIterator> 265 hash_multimap(InputIterator f, InputIterator l) 266 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 267 template <class InputIterator> 268 hash_multimap(InputIterator f, InputIterator l, size_type n) 269 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 270 template <class InputIterator> 271 hash_multimap(InputIterator f, InputIterator l, size_type n, 272 const hasher& hf) 273 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 274 template <class InputIterator> 275 hash_multimap(InputIterator f, InputIterator l, size_type n, 276 const hasher& hf, const key_equal& eql) 277 : rep(n, hf, eql) { rep.insert_equal(f, l); } 278 279 #else 280 hash_multimap(const value_type* f, const value_type* l) 281 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 282 hash_multimap(const value_type* f, const value_type* l, size_type n) 283 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 284 hash_multimap(const value_type* f, const value_type* l, size_type n, 285 const hasher& hf) 286 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 287 hash_multimap(const value_type* f, const value_type* l, size_type n, 288 const hasher& hf, const key_equal& eql) 289 : rep(n, hf, eql) { rep.insert_equal(f, l); } 290 291 hash_multimap(const_iterator f, const_iterator l) 292 : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } 293 hash_multimap(const_iterator f, const_iterator l, size_type n) 294 : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } 295 hash_multimap(const_iterator f, const_iterator l, size_type n, 296 const hasher& hf) 297 : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } 298 hash_multimap(const_iterator f, const_iterator l, size_type n, 299 const hasher& hf, const key_equal& eql) 300 : rep(n, hf, eql) { rep.insert_equal(f, l); } 301 #endif /*__STL_MEMBER_TEMPLATES */ 302 303 public: 304 size_type size() const { return rep.size(); } 305 size_type max_size() const { return rep.max_size(); } 306 bool empty() const { return rep.empty(); } 307 void swap(hash_multimap& hs) { rep.swap(hs.rep); } 308 friend bool 309 operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); 310 311 iterator begin() { return rep.begin(); } 312 iterator end() { return rep.end(); } 313 const_iterator begin() const { return rep.begin(); } 314 const_iterator end() const { return rep.end(); } 315 316 public: 317 iterator insert(const value_type& obj) { return rep.insert_equal(obj); } 318 #ifdef __STL_MEMBER_TEMPLATES 319 template <class InputIterator> 320 void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } 321 #else 322 void insert(const value_type* f, const value_type* l) { 323 rep.insert_equal(f,l); 324 } 325 void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } 326 #endif /*__STL_MEMBER_TEMPLATES */ 327 iterator insert_noresize(const value_type& obj) 328 { return rep.insert_equal_noresize(obj); } 329 330 iterator find(const key_type& key) { return rep.find(key); } 331 const_iterator find(const key_type& key) const { return rep.find(key); } 332 333 size_type count(const key_type& key) const { return rep.count(key); } 334 335 pair<iterator, iterator> equal_range(const key_type& key) 336 { return rep.equal_range(key); } 337 pair<const_iterator, const_iterator> equal_range(const key_type& key) const 338 { return rep.equal_range(key); } 339 340 size_type erase(const key_type& key) {return rep.erase(key); } 341 void erase(iterator it) { rep.erase(it); } 342 void erase(iterator f, iterator l) { rep.erase(f, l); } 343 void clear() { rep.clear(); } 344 345 public: 346 void resize(size_type hint) { rep.resize(hint); } 347 size_type bucket_count() const { return rep.bucket_count(); } 348 size_type max_bucket_count() const { return rep.max_bucket_count(); } 349 size_type elems_in_bucket(size_type n) const 350 { return rep.elems_in_bucket(n); } 351 }; 352 353 template <class Key, class T, class HF, class EqKey, class Alloc> 354 inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1, 355 const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2) 356 { 357 return hm1.rep == hm2.rep; 358 } 359 360 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 361 362 template <class Key, class T, class HashFcn, class EqualKey, class Alloc> 363 inline void swap(hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm1, 364 hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm2) 365 { 366 hm1.swap(hm2); 367 } 368 369 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 370 371 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) 372 #pragma reset woff 1174 373 #endif 374 375 __STL_END_NAMESPACE 376 377 #endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ 378 379 // Local Variables: 380 // mode:C++ 381 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_algobase.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // 这个文件中定义的都是一些最常用的算法, 我仅仅给出一个思路, 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_ALGOBASE_H 43 #define __SGI_STL_INTERNAL_ALGOBASE_H 44 45 #ifndef __STL_CONFIG_H 46 #include <stl_config.h> 47 #endif 48 #ifndef __SGI_STL_INTERNAL_RELOPS 49 #include <stl_relops.h> 50 #endif 51 #ifndef __SGI_STL_INTERNAL_PAIR_H 52 #include <stl_pair.h> 53 #endif 54 #ifndef __TYPE_TRAITS_H_ 55 #include <type_traits.h> 56 #endif 57 58 #include <string.h> 59 #include <limits.h> 60 #include <stdlib.h> 61 #include <stddef.h> 62 #include <new.h> 63 #include <iostream.h> 64 65 #ifndef __SGI_STL_INTERNAL_ITERATOR_H 66 #include <stl_iterator.h> 67 #endif 68 69 __STL_BEGIN_NAMESPACE 70 71 // 第三个参数为什么为指针参见<stl_iterator.h> 72 template <class ForwardIterator1, class ForwardIterator2, class T> 73 inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) 74 { 75 // 这里交换的其实是内部对象 76 T tmp = *a; 77 *a = *b; 78 *b = tmp; 79 } 80 81 template <class ForwardIterator1, class ForwardIterator2> 82 inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) 83 { 84 // 型别以第一个为准 85 __iter_swap(a, b, value_type(a)); 86 } 87 88 // 进行交换操作, 使用的是operator =() 89 template <class T> 90 inline void swap(T& a, T& b) 91 { 92 T tmp = a; 93 a = b; 94 b = tmp; 95 } 96 97 #ifndef __BORLANDC__ 98 99 #undef min 100 #undef max 101 102 // max和min非常简单了, 由于返回的是引用, 因此可以嵌套使用 103 template <class T> 104 inline const T& min(const T& a, const T& b) 105 { 106 return b < a ? b : a; 107 } 108 109 template <class T> 110 inline const T& max(const T& a, const T& b) 111 { 112 return a < b ? b : a; 113 } 114 115 #endif /* __BORLANDC__ */ 116 117 template <class T, class Compare> 118 inline const T& min(const T& a, const T& b, Compare comp) 119 { 120 return comp(b, a) ? b : a; 121 } 122 123 template <class T, class Compare> 124 inline const T& max(const T& a, const T& b, Compare comp) 125 { 126 return comp(a, b) ? b : a; 127 } 128 129 // 这是不支持随机访问的情况 130 template <class InputIterator, class OutputIterator> 131 inline OutputIterator __copy(InputIterator first, InputIterator last, 132 OutputIterator result, input_iterator_tag) 133 { 134 // first != last导致要进行迭代器的比较, 效率低 135 for ( ; first != last; ++result, ++first) 136 *result = *first; 137 return result; 138 } 139 140 template <class RandomAccessIterator, class OutputIterator, class Distance> 141 inline OutputIterator 142 __copy_d(RandomAccessIterator first, RandomAccessIterator last, 143 OutputIterator result, Distance*) 144 { 145 // 不进行迭代器间的比较, 直接指定循环次数, 高效 146 for (Distance n = last - first; n > 0; --n, ++result, ++first) 147 *result = *first; 148 return result; 149 } 150 151 // 这是支持随机访问的情况 152 template <class RandomAccessIterator, class OutputIterator> 153 inline OutputIterator 154 __copy(RandomAccessIterator first, RandomAccessIterator last, 155 OutputIterator result, random_access_iterator_tag) 156 { 157 return __copy_d(first, last, result, distance_type(first)); 158 } 159 160 template <class InputIterator, class OutputIterator> 161 struct __copy_dispatch 162 { 163 // 这里是一个仿函数. 再次派发 164 OutputIterator operator()(InputIterator first, InputIterator last, 165 OutputIterator result) { 166 return __copy(first, last, result, iterator_category(first)); 167 } 168 }; 169 170 // 提供兼容 171 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 172 173 // 可以直接移动, 不需要额外操作 174 template <class T> 175 inline T* __copy_t(const T* first, const T* last, T* result, __true_type) 176 { 177 memmove(result, first, sizeof(T) * (last - first)); 178 return result + (last - first); 179 } 180 181 // 需要进行一些处理, 保证对象复制的正确性 182 template <class T> 183 inline T* __copy_t(const T* first, const T* last, T* result, __false_type) 184 { 185 return __copy_d(first, last, result, (ptrdiff_t*) 0); 186 } 187 188 // 对指针提供特化 189 template <class T> 190 struct __copy_dispatch<T*, T*> 191 { 192 T* operator()(T* first, T* last, T* result) 193 { 194 // 判断其内部是否具有trivial_assignment_operator, 以进行派发 195 typedef typename __type_traits<T>::has_trivial_assignment_operator t; 196 return __copy_t(first, last, result, t()); 197 } 198 }; 199 200 template <class T> 201 struct __copy_dispatch<const T*, T*> 202 { 203 T* operator()(const T* first, const T* last, T* result) { 204 typedef typename __type_traits<T>::has_trivial_assignment_operator t; 205 return __copy_t(first, last, result, t()); 206 } 207 }; 208 209 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 210 211 // 将[first, last)拷贝到result处 212 template <class InputIterator, class OutputIterator> 213 inline OutputIterator copy(InputIterator first, InputIterator last, 214 OutputIterator result) 215 { 216 // 此处进行函数派发操作 217 return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result); 218 } 219 220 // 针对char字符串的特化, 效率至上, C++的设计理念 221 inline char* copy(const char* first, const char* last, char* result) 222 { 223 memmove(result, first, last - first); 224 return result + (last - first); 225 } 226 227 // 针对wchar_t字符串的特化, 效率至上, C++的设计理念 228 inline wchar_t* copy(const wchar_t* first, const wchar_t* last, 229 wchar_t* result) { 230 memmove(result, first, sizeof(wchar_t) * (last - first)); 231 return result + (last - first); 232 } 233 234 235 template <class BidirectionalIterator1, class BidirectionalIterator2> 236 inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, 237 BidirectionalIterator1 last, 238 BidirectionalIterator2 result) 239 { 240 while (first != last) *--result = *--last; 241 return result; 242 } 243 244 245 template <class BidirectionalIterator1, class BidirectionalIterator2> 246 struct __copy_backward_dispatch 247 { 248 BidirectionalIterator2 operator()(BidirectionalIterator1 first, 249 BidirectionalIterator1 last, 250 BidirectionalIterator2 result) 251 { 252 return __copy_backward(first, last, result); 253 } 254 }; 255 256 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 257 258 template <class T> 259 inline T* __copy_backward_t(const T* first, const T* last, T* result, 260 __true_type) 261 { 262 const ptrdiff_t N = last - first; 263 memmove(result - N, first, sizeof(T) * N); 264 return result - N; 265 } 266 267 template <class T> 268 inline T* __copy_backward_t(const T* first, const T* last, T* result, 269 __false_type) 270 { 271 return __copy_backward(first, last, result); 272 } 273 274 template <class T> 275 struct __copy_backward_dispatch<T*, T*> 276 { 277 T* operator()(T* first, T* last, T* result) 278 { 279 typedef typename __type_traits<T>::has_trivial_assignment_operator t; 280 return __copy_backward_t(first, last, result, t()); 281 } 282 }; 283 284 template <class T> 285 struct __copy_backward_dispatch<const T*, T*> 286 { 287 T* operator()(const T* first, const T* last, T* result) 288 { 289 typedef typename __type_traits<T>::has_trivial_assignment_operator t; 290 return __copy_backward_t(first, last, result, t()); 291 } 292 }; 293 294 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 295 296 // 将[first, last)的元素反向拷贝到(..., last)处, 其机制和copy非常接近, 不做说明 297 template <class BidirectionalIterator1, class BidirectionalIterator2> 298 inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, 299 BidirectionalIterator1 last, 300 BidirectionalIterator2 result) 301 { 302 return __copy_backward_dispatch<BidirectionalIterator1, 303 BidirectionalIterator2>()(first, last, 304 result); 305 } 306 307 308 template <class InputIterator, class Size, class OutputIterator> 309 pair<InputIterator, OutputIterator> __copy_n(InputIterator first, Size count, 310 OutputIterator result, 311 input_iterator_tag) 312 { 313 for ( ; count > 0; --count, ++first, ++result) 314 *result = *first; 315 return pair<InputIterator, OutputIterator>(first, result); 316 } 317 318 template <class RandomAccessIterator, class Size, class OutputIterator> 319 inline pair<RandomAccessIterator, OutputIterator> 320 __copy_n(RandomAccessIterator first, Size count, 321 OutputIterator result, 322 random_access_iterator_tag) 323 { 324 // 使用copy()以选择最高效的拷贝算法 325 RandomAccessIterator last = first + count; 326 return pair<RandomAccessIterator, OutputIterator>(last, 327 copy(first, last, result)); 328 } 329 330 // 从first拷贝n个值到result处 331 template <class InputIterator, class Size, class OutputIterator> 332 inline pair<InputIterator, OutputIterator> 333 copy_n(InputIterator first, Size count, 334 OutputIterator result) 335 { 336 // 进行函数派发, 选咋高效版本 337 return __copy_n(first, count, result, iterator_category(first)); 338 } 339 340 // 使用value填充[first, last)区间 341 template <class ForwardIterator, class T> 342 void fill(ForwardIterator first, ForwardIterator last, const T& value) 343 { 344 for ( ; first != last; ++first) 345 *first = value; // 调用的是operator =(), 这个要特别注意 346 } 347 348 // 用value填充[first, first + n)的区间 349 // 为了防止越界, 可以使用下面实例的技巧 350 // vector<int> vec(); 351 // for (int i = 0; i < 10; ++i) 352 // vec.push_back(i); 353 // fill_n(inserter(iv, iv.begin()), 100, 10); // 这就可以使容器动态扩展 354 template <class OutputIterator, class Size, class T> 355 OutputIterator fill_n(OutputIterator first, Size n, const T& value) 356 { 357 for ( ; n > 0; --n, ++first) 358 *first = value; 359 return first; 360 } 361 362 // 找到两个序列第一个失配的地方, 结果以pair返回 363 template <class InputIterator1, class InputIterator2> 364 pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, 365 InputIterator1 last1, 366 InputIterator2 first2) 367 { 368 // 遍历区间, 寻找失配点 369 while (first1 != last1 && *first1 == *first2) { 370 ++first1; 371 ++first2; 372 } 373 return pair<InputIterator1, InputIterator2>(first1, first2); 374 } 375 376 // 提供用户自定义的二元判别式, 其余同上 377 template <class InputIterator1, class InputIterator2, class BinaryPredicate> 378 pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, 379 InputIterator1 last1, 380 InputIterator2 first2, 381 BinaryPredicate binary_pred) 382 { 383 while (first1 != last1 && binary_pred(*first1, *first2)) { 384 ++first1; 385 ++first2; 386 } 387 return pair<InputIterator1, InputIterator2>(first1, first2); 388 } 389 390 // 如果序列在[first, last)内相等, 则返回true, 如果第二个序列有多余的元素, 391 // 则不进行比较, 直接忽略. 如果第二个序列元素不足, 会导致未定义行为 392 template <class InputIterator1, class InputIterator2> 393 inline bool equal(InputIterator1 first1, InputIterator1 last1, 394 InputIterator2 first2) 395 { 396 for ( ; first1 != last1; ++first1, ++first2) 397 if (*first1 != *first2) // 只要有一个不相等就判定为false 398 return false; 399 return true; 400 } 401 402 // 进行比较的操作改为用户指定的二元判别式, 其余同上 403 template <class InputIterator1, class InputIterator2, class BinaryPredicate> 404 inline bool equal(InputIterator1 first1, InputIterator1 last1, 405 InputIterator2 first2, BinaryPredicate binary_pred) 406 { 407 for ( ; first1 != last1; ++first1, ++first2) 408 if (!binary_pred(*first1, *first2)) 409 return false; 410 return true; 411 } 412 413 // 字典序比较, 非常类似字符串的比较 414 // 具体比较方式参见STL文档, 另外strcmp()也可以参考 415 template <class InputIterator1, class InputIterator2> 416 bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, 417 InputIterator2 first2, InputIterator2 last2) 418 { 419 for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { 420 if (*first1 < *first2) 421 return true; 422 if (*first2 < *first1) 423 return false; 424 } 425 return first1 == last1 && first2 != last2; 426 } 427 428 // 二元判别式自己指定, 其余同上 429 template <class InputIterator1, class InputIterator2, class Compare> 430 bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, 431 InputIterator2 first2, InputIterator2 last2, 432 Compare comp) { 433 for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) 434 { 435 if (comp(*first1, *first2)) 436 return true; 437 if (comp(*first2, *first1)) 438 return false; 439 } 440 return first1 == last1 && first2 != last2; 441 } 442 443 // 针对字符串的特化, 效率至上 444 inline bool 445 lexicographical_compare(const unsigned char* first1, 446 const unsigned char* last1, 447 const unsigned char* first2, 448 const unsigned char* last2) 449 { 450 const size_t len1 = last1 - first1; 451 const size_t len2 = last2 - first2; 452 const int result = memcmp(first1, first2, min(len1, len2)); 453 return result != 0 ? result < 0 : len1 < len2; 454 } 455 456 // 针对字符串的特化, 效率至上 457 inline bool lexicographical_compare(const char* first1, const char* last1, 458 const char* first2, const char* last2) 459 { 460 #if CHAR_MAX == SCHAR_MAX 461 return lexicographical_compare((const signed char*) first1, 462 (const signed char*) last1, 463 (const signed char*) first2, 464 (const signed char*) last2); 465 #else 466 return lexicographical_compare((const unsigned char*) first1, 467 (const unsigned char*) last1, 468 (const unsigned char*) first2, 469 (const unsigned char*) last2); 470 #endif 471 } 472 473 // 一句话概括, 这个是strcmp()的泛化版本 474 template <class InputIterator1, class InputIterator2> 475 int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1, 476 InputIterator2 first2, InputIterator2 last2) 477 { 478 while (first1 != last1 && first2 != last2) { 479 if (*first1 < *first2) return -1; 480 if (*first2 < *first1) return 1; 481 ++first1; ++first2; 482 } 483 if (first2 == last2) { 484 return !(first1 == last1); 485 } else { 486 return -1; 487 } 488 } 489 490 // 特换版本, 效率决定一切 491 inline int 492 lexicographical_compare_3way(const unsigned char* first1, 493 const unsigned char* last1, 494 const unsigned char* first2, 495 const unsigned char* last2) 496 { 497 const ptrdiff_t len1 = last1 - first1; 498 const ptrdiff_t len2 = last2 - first2; 499 const int result = memcmp(first1, first2, min(len1, len2)); 500 return result != 0 ? result : (len1 == len2 ? 0 : (len1 < len2 ? -1 : 1)); 501 } 502 503 inline int lexicographical_compare_3way(const char* first1, const char* last1, 504 const char* first2, const char* last2) 505 { 506 #if CHAR_MAX == SCHAR_MAX 507 return lexicographical_compare_3way( 508 (const signed char*) first1, 509 (const signed char*) last1, 510 (const signed char*) first2, 511 (const signed char*) last2); 512 #else 513 return lexicographical_compare_3way((const unsigned char*) first1, 514 (const unsigned char*) last1, 515 (const unsigned char*) first2, 516 (const unsigned char*) last2); 517 #endif 518 } 519 520 __STL_END_NAMESPACE 521 522 #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ 523 524 // Local Variables: 525 // mode:C++ 526 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
1 // Filename: stl_relops.h 2 3 // Comment By: 凝霜 4 // E-mail: mdl2009@vip.qq.com 5 // Blog: http://blog.csdn.net/mdl13412 6 7 // 这个文件非常简单, 提供比较运算符的重载, 任何全局的比较运算符如果需要重载 8 // 只需要自己提供operator <和==即可 9 10 /* 11 * 12 * Copyright (c) 1994 13 * Hewlett-Packard Company 14 * 15 * Permission to use, copy, modify, distribute and sell this software 16 * and its documentation for any purpose is hereby granted without fee, 17 * provided that the above copyright notice appear in all copies and 18 * that both that copyright notice and this permission notice appear 19 * in supporting documentation. Hewlett-Packard Company makes no 20 * representations about the suitability of this software for any 21 * purpose. It is provided "as is" without express or implied warranty. 22 * 23 * Copyright (c) 1996,1997 24 * Silicon Graphics 25 * 26 * Permission to use, copy, modify, distribute and sell this software 27 * and its documentation for any purpose is hereby granted without fee, 28 * provided that the above copyright notice appear in all copies and 29 * that both that copyright notice and this permission notice appear 30 * in supporting documentation. Silicon Graphics makes no 31 * representations about the suitability of this software for any 32 * purpose. It is provided "as is" without express or implied warranty. 33 * 34 */ 35 36 /* NOTE: This is an internal header file, included by other STL headers. 37 * You should not attempt to use it directly. 38 */ 39 40 #ifndef __SGI_STL_INTERNAL_RELOPS 41 #define __SGI_STL_INTERNAL_RELOPS 42 43 __STL_BEGIN_RELOPS_NAMESPACE 44 45 template <class T> 46 inline bool operator!=(const T& x, const T& y) 47 { 48 return !(x == y); 49 } 50 51 template <class T> 52 inline bool operator>(const T& x, const T& y) 53 { 54 return y < x; 55 } 56 57 template <class T> 58 inline bool operator<=(const T& x, const T& y) 59 { 60 return !(y < x); 61 } 62 63 template <class T> 64 inline bool operator>=(const T& x, const T& y) 65 { 66 return !(x < y); 67 } 68 69 __STL_END_RELOPS_NAMESPACE 70 71 #endif /* __SGI_STL_INTERNAL_RELOPS */ 72 73 // Local Variables: 74 // mode:C++ 75 // End:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)