1 /* 2 * 3 * Copyright (c) 1994 4 * Hewlett-Packard Company 5 * 6 * Copyright (c) 1996,1997 7 * Silicon Graphics Computer Systems, Inc. 8 * 9 * Copyright (c) 1997 10 * Moscow Center for SPARC Technology 11 * 12 * Copyright (c) 1999 13 * Boris Fomitchev 14 * 15 * This material is provided "as is", with absolutely no warranty expressed 16 * or implied. Any use is at your own risk. 17 * 18 * Permission to use or copy this software for any purpose is hereby granted 19 * without fee, provided the above notices are retained on all copies. 20 * Permission to modify the code and to distribute modified code is granted, 21 * provided the above notices are retained, and a notice that the code was 22 * modified is included with the above copyright notice. 23 * 24 */ 25 26 /* NOTE: This is an internal header file, included by other STL headers. 27 * You should not attempt to use it directly. 28 */ 29 30 #ifndef _STLP_INTERNAL_UNINITIALIZED_H 31 #define _STLP_INTERNAL_UNINITIALIZED_H 32 33 #ifndef _STLP_INTERNAL_CSTRING 34 # include <stl/_cstring.h> 35 #endif 36 37 #ifndef _STLP_INTERNAL_ALGOBASE_H 38 # include <stl/_algobase.h> 39 #endif 40 41 #ifndef _STLP_INTERNAL_CONSTRUCT_H 42 # include <stl/_construct.h> 43 #endif 44 45 _STLP_BEGIN_NAMESPACE 46 47 _STLP_MOVE_TO_PRIV_NAMESPACE 48 49 // uninitialized_copy 50 51 template <class _InputIter, class _OutputIter, class _Distance> 52 inline _OutputIter __ucopy(_InputIter __first, _InputIter __last, 53 _OutputIter __result, _Distance*) { 54 _OutputIter __cur = __result; 55 _STLP_TRY { 56 for ( ; __first != __last; ++__first, ++__cur) 57 _Param_Construct(&*__cur, *__first); 58 return __cur; 59 } 60 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__result, __cur)) 61 _STLP_RET_AFTER_THROW(__cur) 62 } 63 64 template <class _InputIter, class _OutputIter, class _Distance> 65 inline _OutputIter __ucopy(_InputIter __first, _InputIter __last, 66 _OutputIter __result, const input_iterator_tag &, _Distance* __d) 67 { return __ucopy(__first, __last, __result, __d); } 68 69 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 70 template <class _InputIter, class _OutputIter, class _Distance> 71 inline _OutputIter __ucopy(_InputIter __first, _InputIter __last, 72 _OutputIter __result, const forward_iterator_tag &, _Distance* __d) 73 { return __ucopy(__first, __last, __result, __d); } 74 75 template <class _InputIter, class _OutputIter, class _Distance> 76 inline _OutputIter __ucopy(_InputIter __first, _InputIter __last, 77 _OutputIter __result, const bidirectional_iterator_tag &, _Distance* __d) 78 { return __ucopy(__first, __last, __result, __d); } 79 #endif 80 81 template <class _RandomAccessIter, class _OutputIter, class _Distance> 82 inline _OutputIter __ucopy(_RandomAccessIter __first, _RandomAccessIter __last, 83 _OutputIter __result, const random_access_iterator_tag &, _Distance*) { 84 _OutputIter __cur = __result; 85 _STLP_TRY { 86 for (_Distance __n = __last - __first; __n > 0; --__n) { 87 _Param_Construct(&*__cur, *__first); 88 ++__first; 89 ++__cur; 90 } 91 return __cur; 92 } 93 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__result, __cur)) 94 _STLP_RET_AFTER_THROW(__cur) 95 } 96 97 //Used internaly 98 template <class _RandomAccessIter, class _OutputIter> 99 inline _OutputIter __ucopy(_RandomAccessIter __first, _RandomAccessIter __last, _OutputIter __result) 100 { return __ucopy(__first, __last, __result, random_access_iterator_tag(), (ptrdiff_t*)0); } 101 102 inline void* 103 __ucopy_trivial(const void* __first, const void* __last, void* __result) { 104 //dums: this version can use memcpy (__copy_trivial can't) 105 return (__last == __first) ? __result : 106 ((char*)memcpy(__result, __first, ((const char*)__last - (const char*)__first))) + 107 ((const char*)__last - (const char*)__first); 108 } 109 110 template <class _InputIter, class _OutputIter> 111 inline _OutputIter __ucopy_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, 112 const __false_type& /*TrivialUCopy*/) 113 { return __ucopy(__first, __last, __result, random_access_iterator_tag(), (ptrdiff_t*)0); } 114 115 template <class _InputIter, class _OutputIter> 116 inline _OutputIter __ucopy_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, 117 const __true_type& /*TrivialUCopy*/) { 118 // we know they all pointers, so this cast is OK 119 // return (_OutputIter)__copy_trivial(&(*__first), &(*__last), &(*__result)); 120 return (_OutputIter)__ucopy_trivial(__first, __last, __result); 121 } 122 123 template <class _InputIter, class _OutputIter> 124 inline _OutputIter __ucopy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, 125 const __true_type& /*BothPtrType*/) { 126 return __ucopy_ptrs(__first, __last, __result, 127 _UseTrivialUCopy(_STLP_VALUE_TYPE(__first, _InputIter), 128 _STLP_VALUE_TYPE(__result, _OutputIter))._Answer()); 129 } 130 131 template <class _InputIter, class _OutputIter> 132 inline _OutputIter __ucopy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, 133 const __false_type& /*BothPtrType*/) { 134 return __ucopy(__first, __last, __result, 135 _STLP_ITERATOR_CATEGORY(__first, _InputIter), 136 _STLP_DISTANCE_TYPE(__first, _InputIter)); 137 } 138 139 _STLP_MOVE_TO_STD_NAMESPACE 140 141 template <class _InputIter, class _ForwardIter> 142 inline _ForwardIter 143 uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result) 144 { return _STLP_PRIV __ucopy_aux(__first, __last, __result, _BothPtrType< _InputIter, _ForwardIter>::_Answer()); } 145 146 inline char* 147 uninitialized_copy(const char* __first, const char* __last, char* __result) 148 { return (char*)_STLP_PRIV __ucopy_trivial(__first, __last, __result); } 149 150 # if defined (_STLP_HAS_WCHAR_T) // dwa 8/15/97 151 inline wchar_t* 152 uninitialized_copy(const wchar_t* __first, const wchar_t* __last, wchar_t* __result) 153 { return (wchar_t*)_STLP_PRIV __ucopy_trivial (__first, __last, __result); } 154 # endif 155 156 // uninitialized_copy_n (not part of the C++ standard) 157 _STLP_MOVE_TO_PRIV_NAMESPACE 158 159 template <class _InputIter, class _Size, class _ForwardIter> 160 _STLP_INLINE_LOOP 161 pair<_InputIter, _ForwardIter> 162 __ucopy_n(_InputIter __first, _Size __count, _ForwardIter __result, 163 const input_iterator_tag &) { 164 _ForwardIter __cur = __result; 165 _STLP_TRY { 166 for ( ; __count > 0 ; --__count, ++__first, ++__cur) 167 _Param_Construct(&*__cur, *__first); 168 return pair<_InputIter, _ForwardIter>(__first, __cur); 169 } 170 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__result, __cur)) 171 _STLP_RET_AFTER_THROW((pair<_InputIter, _ForwardIter>(__first, __cur))) 172 } 173 174 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 175 template <class _InputIter, class _Size, class _ForwardIterator> 176 inline pair<_InputIter, _ForwardIterator> 177 __ucopy_n(_InputIter __first, _Size __count, 178 _ForwardIterator __result, 179 const forward_iterator_tag &) 180 { return __ucopy_n(__first, __count, __result, input_iterator_tag()); } 181 182 template <class _InputIter, class _Size, class _ForwardIterator> 183 inline pair<_InputIter, _ForwardIterator> 184 __ucopy_n(_InputIter __first, _Size __count, 185 _ForwardIterator __result, 186 const bidirectional_iterator_tag &) 187 { return __ucopy_n(__first, __count, __result, input_iterator_tag()); } 188 # endif 189 190 template <class _RandomAccessIter, class _Size, class _ForwardIter> 191 inline pair<_RandomAccessIter, _ForwardIter> 192 __ucopy_n(_RandomAccessIter __first, _Size __count, _ForwardIter __result, 193 const random_access_iterator_tag &) { 194 _RandomAccessIter __last = __first + __count; 195 return pair<_RandomAccessIter, _ForwardIter>(__last, uninitialized_copy(__first, __last, __result)); 196 } 197 198 // This is used internally in <rope> , which is extension itself. 199 template <class _InputIter, class _Size, class _ForwardIter> 200 inline pair<_InputIter, _ForwardIter> 201 __ucopy_n(_InputIter __first, _Size __count, _ForwardIter __result) 202 { return _STLP_PRIV __ucopy_n(__first, __count, __result, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); } 203 204 #if !defined (_STLP_NO_EXTENSIONS) 205 206 _STLP_MOVE_TO_STD_NAMESPACE 207 208 template <class _InputIter, class _Size, class _ForwardIter> 209 inline pair<_InputIter, _ForwardIter> 210 uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) 211 { return _STLP_PRIV __ucopy_n(__first, __count, __result); } 212 213 _STLP_MOVE_TO_PRIV_NAMESPACE 214 215 #endif 216 217 template <class _ForwardIter, class _Tp, class _Distance> 218 inline void __ufill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, _Distance*) { 219 _ForwardIter __cur = __first; 220 _STLP_TRY { 221 for ( ; __cur != __last; ++__cur) 222 _Param_Construct(&*__cur, __x); 223 } 224 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__first, __cur)) 225 } 226 227 template <class _ForwardIter, class _Tp, class _Distance> 228 inline void __ufill(_ForwardIter __first, _ForwardIter __last, 229 const _Tp& __x, const input_iterator_tag &, _Distance* __d) 230 { __ufill(__first, __last, __x, __d); } 231 232 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 233 template <class _ForwardIter, class _Tp, class _Distance> 234 inline void __ufill(_ForwardIter __first, _ForwardIter __last, 235 const _Tp& __x, const forward_iterator_tag &, _Distance* __d) 236 { __ufill(__first, __last, __x, __d); } 237 238 template <class _ForwardIter, class _Tp, class _Distance> 239 inline void __ufill(_ForwardIter __first, _ForwardIter __last, 240 const _Tp& __x, const bidirectional_iterator_tag &, _Distance* __d) 241 { __ufill(__first, __last, __x, __d); } 242 #endif 243 244 template <class _ForwardIter, class _Tp, class _Distance> 245 inline void __ufill(_ForwardIter __first, _ForwardIter __last, 246 const _Tp& __x, const random_access_iterator_tag &, _Distance*) { 247 _ForwardIter __cur = __first; 248 _STLP_TRY { 249 for (_Distance __n = __last - __first; __n > 0; --__n, ++__cur) 250 _Param_Construct(&*__cur, __x); 251 } 252 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__first, __cur)) 253 } 254 255 _STLP_MOVE_TO_STD_NAMESPACE 256 257 template <class _ForwardIter, class _Tp> 258 inline void uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x) { 259 _STLP_PRIV __ufill(__first, __last, __x, 260 _STLP_ITERATOR_CATEGORY(__first, _ForwardIter), 261 _STLP_DISTANCE_TYPE(__first, _ForwardIter)); 262 } 263 264 // Specialization: for one-byte types we can use memset. 265 inline void uninitialized_fill(unsigned char* __first, unsigned char* __last, 266 const unsigned char& __val) { 267 unsigned char __tmp = __val; 268 memset(__first, __tmp, __last - __first); 269 } 270 #if !defined (_STLP_NO_SIGNED_BUILTINS) 271 inline void uninitialized_fill(signed char* __first, signed char* __last, 272 const signed char& __val) { 273 signed char __tmp = __val; 274 memset(__first, __STATIC_CAST(unsigned char,__tmp), __last - __first); 275 } 276 #endif 277 inline void uninitialized_fill(char* __first, char* __last, const char& __val) { 278 char __tmp = __val; 279 memset(__first, __STATIC_CAST(unsigned char,__tmp), __last - __first); 280 } 281 282 _STLP_MOVE_TO_PRIV_NAMESPACE 283 284 template <class _ForwardIter, class _Size, class _Tp> 285 inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x) { 286 _ForwardIter __cur = __first; 287 _STLP_TRY { 288 for ( ; __n > 0; --__n, ++__cur) 289 _Param_Construct(&*__cur, __x); 290 } 291 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__first, __cur)) 292 return __cur; 293 } 294 295 template <class _ForwardIter, class _Size, class _Tp> 296 inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x, 297 const input_iterator_tag &) 298 { return __ufill_n(__first, __n, __x); } 299 300 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 301 template <class _ForwardIter, class _Size, class _Tp> 302 inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x, 303 const forward_iterator_tag &) 304 { return __ufill_n(__first, __n, __x); } 305 306 template <class _ForwardIter, class _Size, class _Tp> 307 inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x, 308 const bidirectional_iterator_tag &) 309 { return __ufill_n(__first, __n, __x); } 310 #endif 311 312 template <class _ForwardIter, class _Size, class _Tp> 313 inline _ForwardIter __uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) { 314 _ForwardIter __last = __first + __n; 315 __ufill(__first, __last, __x, random_access_iterator_tag(), (ptrdiff_t*)0); 316 return __last; 317 } 318 319 template <class _ForwardIter, class _Size, class _Tp> 320 inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x, 321 const random_access_iterator_tag &) 322 { return __uninitialized_fill_n(__first, __n, __x); } 323 324 /* __uninitialized_init is an internal algo to init a range with a value 325 * built using default constructor. It is only called with pointer as 326 * iterator. 327 */ 328 template <class _ForwardIter, class _Size, class _Tp> 329 inline _ForwardIter __uinit_aux_aux(_ForwardIter __first, _Size __n, const _Tp& __val, 330 const __false_type& /*_HasDefaultZero*/) 331 { return __uninitialized_fill_n(__first, __n, __val); } 332 333 template <class _ForwardIter, class _Size, class _Tp> 334 inline _ForwardIter __uinit_aux_aux(_ForwardIter __first, _Size __n, const _Tp& /* __val */, 335 const __true_type& /*_HasDefaultZero*/) { 336 memset((unsigned char*)__first, 0, __n * sizeof(_Tp)); 337 return __first + __n; 338 } 339 340 template <class _ForwardIter, class _Size, class _Tp> 341 inline _ForwardIter __uinit_aux(_ForwardIter __first, _Size __n, const _Tp&, 342 const __true_type& /*_TrivialInit*/) 343 { return __first + __n; } 344 345 template <class _ForwardIter, class _Size, class _Tp> 346 inline _ForwardIter __uinit_aux(_ForwardIter __first, _Size __n, const _Tp& __val, 347 const __false_type& /*_TrivialInit*/) 348 { return __uinit_aux_aux(__first, __n, __val, _HasDefaultZeroValue(__first)._Answer()); } 349 350 template <class _ForwardIter, class _Size, class _Tp> 351 inline _ForwardIter __uninitialized_init(_ForwardIter __first, _Size __n, const _Tp& __val) 352 { return __uinit_aux(__first, __n, __val, _UseTrivialInit(__first)._Answer()); } 353 354 _STLP_MOVE_TO_STD_NAMESPACE 355 356 template <class _ForwardIter, class _Size, class _Tp> 357 inline void 358 uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) 359 { _STLP_PRIV __ufill_n(__first, __n, __x, _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); } 360 361 // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, 362 // __uninitialized_fill_copy. 363 364 // __uninitialized_copy_copy 365 // Copies [first1, last1) into [result, result + (last1 - first1)), and 366 // copies [first2, last2) into 367 // [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)). 368 369 _STLP_MOVE_TO_PRIV_NAMESPACE 370 371 template <class _InputIter1, class _InputIter2, class _ForwardIter> 372 inline _ForwardIter 373 __uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, 374 _InputIter2 __first2, _InputIter2 __last2, 375 _ForwardIter __result) { 376 _ForwardIter __new_result = uninitialized_copy(__first1, __last1, __result); 377 _STLP_TRY { 378 return uninitialized_copy(__first2, __last2, __new_result); 379 } 380 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__result, __new_result)) 381 _STLP_RET_AFTER_THROW(__result) 382 } 383 384 // __uninitialized_fill_copy 385 // Fills [result, mid) with x, and copies [first, last) into 386 // [mid, mid + (last - first)). 387 template <class _ForwardIter, class _Tp, class _InputIter> 388 inline _ForwardIter 389 __uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, const _Tp& __x, 390 _InputIter __first, _InputIter __last) { 391 uninitialized_fill(__result, __mid, __x); 392 _STLP_TRY { 393 return uninitialized_copy(__first, __last, __mid); 394 } 395 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__result, __mid)) 396 _STLP_RET_AFTER_THROW(__result) 397 } 398 399 // __uninitialized_copy_fill 400 // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and 401 // fills [first2 + (last1 - first1), last2) with x. 402 template <class _Iter, class _Tp> 403 inline void 404 __uninitialized_copy_fill(_Iter __first1, _Iter __last1, _Iter __first2, _Iter __last2, 405 const _Tp& __x) { 406 _Iter __mid2 = uninitialized_copy(__first1, __last1, __first2); 407 _STLP_TRY { 408 uninitialized_fill(__mid2, __last2, __x); 409 } 410 _STLP_UNWIND(_STLP_STD::_Destroy_Range(__first2, __mid2)) 411 } 412 413 /* __uninitialized_move: 414 * This function is used internaly and only with pointers as iterators. 415 */ 416 template <class _InputIter, class _ForwardIter, class _TrivialUCpy> 417 inline _ForwardIter 418 __uninitialized_move(_InputIter __first, _InputIter __last, _ForwardIter __result, 419 _TrivialUCpy __trivial_ucpy, const __false_type& /*_Movable*/) 420 { return __ucopy_ptrs(__first, __last, __result, __trivial_ucpy); } 421 422 template <class _InputIter, class _ForwardIter, class _TrivialUCpy> 423 _STLP_INLINE_LOOP 424 _ForwardIter 425 __uninitialized_move(_InputIter __first, _InputIter __last, _ForwardIter __result, 426 _TrivialUCpy , const __true_type& /*_Movable*/) { 427 //Move constructor should not throw so we do not need to take care of exceptions here. 428 for (ptrdiff_t __n = __last - __first ; __n > 0; --__n) { 429 _Move_Construct(&*__result, *__first); 430 ++__first; ++__result; 431 } 432 return __result; 433 } 434 435 _STLP_MOVE_TO_STD_NAMESPACE 436 437 _STLP_END_NAMESPACE 438 439 #endif /* _STLP_INTERNAL_UNINITIALIZED_H */ 440 441 // Local Variables: 442 // mode:C++ 443 // End: 444