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 51template <class _InputIter, class _OutputIter, class _Distance> 52inline _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 64template <class _InputIter, class _OutputIter, class _Distance> 65inline _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) 70template <class _InputIter, class _OutputIter, class _Distance> 71inline _OutputIter __ucopy(_InputIter __first, _InputIter __last, 72 _OutputIter __result, const forward_iterator_tag &, _Distance* __d) 73{ return __ucopy(__first, __last, __result, __d); } 74 75template <class _InputIter, class _OutputIter, class _Distance> 76inline _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 81template <class _RandomAccessIter, class _OutputIter, class _Distance> 82inline _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 98template <class _RandomAccessIter, class _OutputIter> 99inline _OutputIter __ucopy(_RandomAccessIter __first, _RandomAccessIter __last, _OutputIter __result) 100{ return __ucopy(__first, __last, __result, random_access_iterator_tag(), (ptrdiff_t*)0); } 101 102inline 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 110template <class _InputIter, class _OutputIter> 111inline _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 115template <class _InputIter, class _OutputIter> 116inline _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 123template <class _InputIter, class _OutputIter> 124inline _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 131template <class _InputIter, class _OutputIter> 132inline _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 141template <class _InputIter, class _ForwardIter> 142inline _ForwardIter 143uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result) 144{ return _STLP_PRIV __ucopy_aux(__first, __last, __result, _BothPtrType< _InputIter, _ForwardIter>::_Answer()); } 145 146inline char* 147uninitialized_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 151inline wchar_t* 152uninitialized_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 159template <class _InputIter, class _Size, class _ForwardIter> 160_STLP_INLINE_LOOP 161pair<_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) 175template <class _InputIter, class _Size, class _ForwardIterator> 176inline 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 182template <class _InputIter, class _Size, class _ForwardIterator> 183inline 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 190template <class _RandomAccessIter, class _Size, class _ForwardIter> 191inline 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. 199template <class _InputIter, class _Size, class _ForwardIter> 200inline 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 208template <class _InputIter, class _Size, class _ForwardIter> 209inline pair<_InputIter, _ForwardIter> 210uninitialized_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 217template <class _ForwardIter, class _Tp, class _Distance> 218inline 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 227template <class _ForwardIter, class _Tp, class _Distance> 228inline 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) 233template <class _ForwardIter, class _Tp, class _Distance> 234inline void __ufill(_ForwardIter __first, _ForwardIter __last, 235 const _Tp& __x, const forward_iterator_tag &, _Distance* __d) 236{ __ufill(__first, __last, __x, __d); } 237 238template <class _ForwardIter, class _Tp, class _Distance> 239inline 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 244template <class _ForwardIter, class _Tp, class _Distance> 245inline 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 257template <class _ForwardIter, class _Tp> 258inline 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. 265inline 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) 271inline 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 277inline 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 284template <class _ForwardIter, class _Size, class _Tp> 285inline _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 295template <class _ForwardIter, class _Size, class _Tp> 296inline _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) 301template <class _ForwardIter, class _Size, class _Tp> 302inline _ForwardIter __ufill_n(_ForwardIter __first, _Size __n, const _Tp& __x, 303 const forward_iterator_tag &) 304{ return __ufill_n(__first, __n, __x); } 305 306template <class _ForwardIter, class _Size, class _Tp> 307inline _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 312template <class _ForwardIter, class _Size, class _Tp> 313inline _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 319template <class _ForwardIter, class _Size, class _Tp> 320inline _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 */ 328template <class _ForwardIter, class _Size, class _Tp> 329inline _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 333template <class _ForwardIter, class _Size, class _Tp> 334inline _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 340template <class _ForwardIter, class _Size, class _Tp> 341inline _ForwardIter __uinit_aux(_ForwardIter __first, _Size __n, const _Tp&, 342 const __true_type& /*_TrivialInit*/) 343{ return __first + __n; } 344 345template <class _ForwardIter, class _Size, class _Tp> 346inline _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 350template <class _ForwardIter, class _Size, class _Tp> 351inline _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 356template <class _ForwardIter, class _Size, class _Tp> 357inline void 358uninitialized_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 371template <class _InputIter1, class _InputIter2, class _ForwardIter> 372inline _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)). 387template <class _ForwardIter, class _Tp, class _InputIter> 388inline _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. 402template <class _Iter, class _Tp> 403inline 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 */ 416template <class _InputIter, class _ForwardIter, class _TrivialUCpy> 417inline _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 422template <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