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