1 1. // Filename: stl_config.h 2 2. 3 3. // Comment By: 凝霜 4 4. // E-mail: [email protected] 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:
1 1. // Filename: defalloc.h 2 2. 3 3. // Comment By: 凝霜 4 4. // E-mail: [email protected] 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
1 # // Comment By: 凝霜 2 # // E-mail: [email protected] 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:
1 # // Filename: memory 2 # 3 # // Comment By: 凝霜 4 # // E-mail: [email protected] 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:
1 // Filename: stl_construct.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_uninitialized.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_iterator.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: type_traits.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_vector.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_pair.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_list.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_deque.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_stack.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_queue.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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:
1 // Filename: stl_slist.h 2 3 // Comment By: 凝霜 4 // E-mail: [email protected] 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 //