xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/stl_uninitialized.h (revision 63ce0b47aeb8b4c6792d02a0de9ecf8182e299ac)
1 // Raw memory manipulators -*- C++ -*-
2 
3 // Copyright (C) 2001-2016 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
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.  Hewlett-Packard Company 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  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
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.  Silicon Graphics 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 /** @file bits/stl_uninitialized.h
52  *  This is an internal header file, included by other library headers.
53  *  Do not attempt to use it directly. @headername{memory}
54  */
55 
56 #ifndef _STL_UNINITIALIZED_H
57 #define _STL_UNINITIALIZED_H 1
58 
59 namespace std _GLIBCXX_VISIBILITY(default)
60 {
61 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 
63   template<bool _TrivialValueTypes>
64     struct __uninitialized_copy
65     {
66       template<typename _InputIterator, typename _ForwardIterator>
67         static _ForwardIterator
68         __uninit_copy(_InputIterator __first, _InputIterator __last,
69 		      _ForwardIterator __result)
70         {
71 	  _ForwardIterator __cur = __result;
72 	  __try
73 	    {
74 	      for (; __first != __last; ++__first, (void)++__cur)
75 		std::_Construct(std::__addressof(*__cur), *__first);
76 	      return __cur;
77 	    }
78 	  __catch(...)
79 	    {
80 	      std::_Destroy(__result, __cur);
81 	      __throw_exception_again;
82 	    }
83 	}
84     };
85 
86   template<>
87     struct __uninitialized_copy<true>
88     {
89       template<typename _InputIterator, typename _ForwardIterator>
90         static _ForwardIterator
91         __uninit_copy(_InputIterator __first, _InputIterator __last,
92 		      _ForwardIterator __result)
93         { return std::copy(__first, __last, __result); }
94     };
95 
96   /**
97    *  @brief Copies the range [first,last) into result.
98    *  @param  __first  An input iterator.
99    *  @param  __last   An input iterator.
100    *  @param  __result An output iterator.
101    *  @return   __result + (__first - __last)
102    *
103    *  Like copy(), but does not require an initialized output range.
104   */
105   template<typename _InputIterator, typename _ForwardIterator>
106     inline _ForwardIterator
107     uninitialized_copy(_InputIterator __first, _InputIterator __last,
108 		       _ForwardIterator __result)
109     {
110       typedef typename iterator_traits<_InputIterator>::value_type
111 	_ValueType1;
112       typedef typename iterator_traits<_ForwardIterator>::value_type
113 	_ValueType2;
114 #if __cplusplus < 201103L
115       const bool __assignable = true;
116 #else
117       // trivial types can have deleted assignment
118       typedef typename iterator_traits<_InputIterator>::reference _RefType1;
119       typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
120       const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
121 #endif
122 
123       return std::__uninitialized_copy<__is_trivial(_ValueType1)
124 				       && __is_trivial(_ValueType2)
125 				       && __assignable>::
126 	__uninit_copy(__first, __last, __result);
127     }
128 
129 
130   template<bool _TrivialValueType>
131     struct __uninitialized_fill
132     {
133       template<typename _ForwardIterator, typename _Tp>
134         static void
135         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
136 		      const _Tp& __x)
137         {
138 	  _ForwardIterator __cur = __first;
139 	  __try
140 	    {
141 	      for (; __cur != __last; ++__cur)
142 		std::_Construct(std::__addressof(*__cur), __x);
143 	    }
144 	  __catch(...)
145 	    {
146 	      std::_Destroy(__first, __cur);
147 	      __throw_exception_again;
148 	    }
149 	}
150     };
151 
152   template<>
153     struct __uninitialized_fill<true>
154     {
155       template<typename _ForwardIterator, typename _Tp>
156         static void
157         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
158 		      const _Tp& __x)
159         { std::fill(__first, __last, __x); }
160     };
161 
162   /**
163    *  @brief Copies the value x into the range [first,last).
164    *  @param  __first  An input iterator.
165    *  @param  __last   An input iterator.
166    *  @param  __x      The source value.
167    *  @return   Nothing.
168    *
169    *  Like fill(), but does not require an initialized output range.
170   */
171   template<typename _ForwardIterator, typename _Tp>
172     inline void
173     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
174 		       const _Tp& __x)
175     {
176       typedef typename iterator_traits<_ForwardIterator>::value_type
177 	_ValueType;
178 #if __cplusplus < 201103L
179       const bool __assignable = true;
180 #else
181       // trivial types can have deleted assignment
182       const bool __assignable = is_copy_assignable<_ValueType>::value;
183 #endif
184 
185       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
186 	__uninit_fill(__first, __last, __x);
187     }
188 
189 
190   template<bool _TrivialValueType>
191     struct __uninitialized_fill_n
192     {
193       template<typename _ForwardIterator, typename _Size, typename _Tp>
194         static _ForwardIterator
195         __uninit_fill_n(_ForwardIterator __first, _Size __n,
196 			const _Tp& __x)
197         {
198 	  _ForwardIterator __cur = __first;
199 	  __try
200 	    {
201 	      for (; __n > 0; --__n, ++__cur)
202 		std::_Construct(std::__addressof(*__cur), __x);
203 	      return __cur;
204 	    }
205 	  __catch(...)
206 	    {
207 	      std::_Destroy(__first, __cur);
208 	      __throw_exception_again;
209 	    }
210 	}
211     };
212 
213   template<>
214     struct __uninitialized_fill_n<true>
215     {
216       template<typename _ForwardIterator, typename _Size, typename _Tp>
217         static _ForwardIterator
218         __uninit_fill_n(_ForwardIterator __first, _Size __n,
219 			const _Tp& __x)
220         { return std::fill_n(__first, __n, __x); }
221     };
222 
223    // _GLIBCXX_RESOLVE_LIB_DEFECTS
224    // DR 1339. uninitialized_fill_n should return the end of its range
225   /**
226    *  @brief Copies the value x into the range [first,first+n).
227    *  @param  __first  An input iterator.
228    *  @param  __n      The number of copies to make.
229    *  @param  __x      The source value.
230    *  @return   Nothing.
231    *
232    *  Like fill_n(), but does not require an initialized output range.
233   */
234   template<typename _ForwardIterator, typename _Size, typename _Tp>
235     inline _ForwardIterator
236     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
237     {
238       typedef typename iterator_traits<_ForwardIterator>::value_type
239 	_ValueType;
240 #if __cplusplus < 201103L
241       const bool __assignable = true;
242 #else
243       // trivial types can have deleted assignment
244       const bool __assignable = is_copy_assignable<_ValueType>::value;
245 #endif
246       return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
247 	__uninit_fill_n(__first, __n, __x);
248     }
249 
250   // Extensions: versions of uninitialized_copy, uninitialized_fill,
251   //  and uninitialized_fill_n that take an allocator parameter.
252   //  We dispatch back to the standard versions when we're given the
253   //  default allocator.  For nondefault allocators we do not use
254   //  any of the POD optimizations.
255 
256   template<typename _InputIterator, typename _ForwardIterator,
257 	   typename _Allocator>
258     _ForwardIterator
259     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
260 			   _ForwardIterator __result, _Allocator& __alloc)
261     {
262       _ForwardIterator __cur = __result;
263       __try
264 	{
265 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
266 	  for (; __first != __last; ++__first, (void)++__cur)
267 	    __traits::construct(__alloc, std::__addressof(*__cur), *__first);
268 	  return __cur;
269 	}
270       __catch(...)
271 	{
272 	  std::_Destroy(__result, __cur, __alloc);
273 	  __throw_exception_again;
274 	}
275     }
276 
277   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
278     inline _ForwardIterator
279     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
280 			   _ForwardIterator __result, allocator<_Tp>&)
281     { return std::uninitialized_copy(__first, __last, __result); }
282 
283   template<typename _InputIterator, typename _ForwardIterator,
284 	   typename _Allocator>
285     inline _ForwardIterator
286     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
287 			   _ForwardIterator __result, _Allocator& __alloc)
288     {
289       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
290 					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
291 					 __result, __alloc);
292     }
293 
294   template<typename _InputIterator, typename _ForwardIterator,
295 	   typename _Allocator>
296     inline _ForwardIterator
297     __uninitialized_move_if_noexcept_a(_InputIterator __first,
298 				       _InputIterator __last,
299 				       _ForwardIterator __result,
300 				       _Allocator& __alloc)
301     {
302       return std::__uninitialized_copy_a
303 	(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
304 	 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
305     }
306 
307   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
308     void
309     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
310 			   const _Tp& __x, _Allocator& __alloc)
311     {
312       _ForwardIterator __cur = __first;
313       __try
314 	{
315 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
316 	  for (; __cur != __last; ++__cur)
317 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
318 	}
319       __catch(...)
320 	{
321 	  std::_Destroy(__first, __cur, __alloc);
322 	  __throw_exception_again;
323 	}
324     }
325 
326   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
327     inline void
328     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
329 			   const _Tp& __x, allocator<_Tp2>&)
330     { std::uninitialized_fill(__first, __last, __x); }
331 
332   template<typename _ForwardIterator, typename _Size, typename _Tp,
333 	   typename _Allocator>
334     _ForwardIterator
335     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
336 			     const _Tp& __x, _Allocator& __alloc)
337     {
338       _ForwardIterator __cur = __first;
339       __try
340 	{
341 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
342 	  for (; __n > 0; --__n, ++__cur)
343 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
344 	  return __cur;
345 	}
346       __catch(...)
347 	{
348 	  std::_Destroy(__first, __cur, __alloc);
349 	  __throw_exception_again;
350 	}
351     }
352 
353   template<typename _ForwardIterator, typename _Size, typename _Tp,
354 	   typename _Tp2>
355     inline _ForwardIterator
356     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
357 			     const _Tp& __x, allocator<_Tp2>&)
358     { return std::uninitialized_fill_n(__first, __n, __x); }
359 
360 
361   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
362   // __uninitialized_fill_move, __uninitialized_move_fill.
363   // All of these algorithms take a user-supplied allocator, which is used
364   // for construction and destruction.
365 
366   // __uninitialized_copy_move
367   // Copies [first1, last1) into [result, result + (last1 - first1)), and
368   //  move [first2, last2) into
369   //  [result, result + (last1 - first1) + (last2 - first2)).
370   template<typename _InputIterator1, typename _InputIterator2,
371 	   typename _ForwardIterator, typename _Allocator>
372     inline _ForwardIterator
373     __uninitialized_copy_move(_InputIterator1 __first1,
374 			      _InputIterator1 __last1,
375 			      _InputIterator2 __first2,
376 			      _InputIterator2 __last2,
377 			      _ForwardIterator __result,
378 			      _Allocator& __alloc)
379     {
380       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
381 							   __result,
382 							   __alloc);
383       __try
384 	{
385 	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
386 	}
387       __catch(...)
388 	{
389 	  std::_Destroy(__result, __mid, __alloc);
390 	  __throw_exception_again;
391 	}
392     }
393 
394   // __uninitialized_move_copy
395   // Moves [first1, last1) into [result, result + (last1 - first1)), and
396   //  copies [first2, last2) into
397   //  [result, result + (last1 - first1) + (last2 - first2)).
398   template<typename _InputIterator1, typename _InputIterator2,
399 	   typename _ForwardIterator, typename _Allocator>
400     inline _ForwardIterator
401     __uninitialized_move_copy(_InputIterator1 __first1,
402 			      _InputIterator1 __last1,
403 			      _InputIterator2 __first2,
404 			      _InputIterator2 __last2,
405 			      _ForwardIterator __result,
406 			      _Allocator& __alloc)
407     {
408       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
409 							   __result,
410 							   __alloc);
411       __try
412 	{
413 	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
414 	}
415       __catch(...)
416 	{
417 	  std::_Destroy(__result, __mid, __alloc);
418 	  __throw_exception_again;
419 	}
420     }
421 
422   // __uninitialized_fill_move
423   // Fills [result, mid) with x, and moves [first, last) into
424   //  [mid, mid + (last - first)).
425   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
426 	   typename _Allocator>
427     inline _ForwardIterator
428     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
429 			      const _Tp& __x, _InputIterator __first,
430 			      _InputIterator __last, _Allocator& __alloc)
431     {
432       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
433       __try
434 	{
435 	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
436 	}
437       __catch(...)
438 	{
439 	  std::_Destroy(__result, __mid, __alloc);
440 	  __throw_exception_again;
441 	}
442     }
443 
444   // __uninitialized_move_fill
445   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
446   //  fills [first2 + (last1 - first1), last2) with x.
447   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
448 	   typename _Allocator>
449     inline void
450     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
451 			      _ForwardIterator __first2,
452 			      _ForwardIterator __last2, const _Tp& __x,
453 			      _Allocator& __alloc)
454     {
455       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
456 							    __first2,
457 							    __alloc);
458       __try
459 	{
460 	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
461 	}
462       __catch(...)
463 	{
464 	  std::_Destroy(__first2, __mid2, __alloc);
465 	  __throw_exception_again;
466 	}
467     }
468 
469 #if __cplusplus >= 201103L
470   // Extensions: __uninitialized_default, __uninitialized_default_n,
471   // __uninitialized_default_a, __uninitialized_default_n_a.
472 
473   template<bool _TrivialValueType>
474     struct __uninitialized_default_1
475     {
476       template<typename _ForwardIterator>
477         static void
478         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
479         {
480 	  _ForwardIterator __cur = __first;
481 	  __try
482 	    {
483 	      for (; __cur != __last; ++__cur)
484 		std::_Construct(std::__addressof(*__cur));
485 	    }
486 	  __catch(...)
487 	    {
488 	      std::_Destroy(__first, __cur);
489 	      __throw_exception_again;
490 	    }
491 	}
492     };
493 
494   template<>
495     struct __uninitialized_default_1<true>
496     {
497       template<typename _ForwardIterator>
498         static void
499         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
500         {
501 	  typedef typename iterator_traits<_ForwardIterator>::value_type
502 	    _ValueType;
503 
504 	  std::fill(__first, __last, _ValueType());
505 	}
506     };
507 
508   template<bool _TrivialValueType>
509     struct __uninitialized_default_n_1
510     {
511       template<typename _ForwardIterator, typename _Size>
512         static _ForwardIterator
513         __uninit_default_n(_ForwardIterator __first, _Size __n)
514         {
515 	  _ForwardIterator __cur = __first;
516 	  __try
517 	    {
518 	      for (; __n > 0; --__n, ++__cur)
519 		std::_Construct(std::__addressof(*__cur));
520 	      return __cur;
521 	    }
522 	  __catch(...)
523 	    {
524 	      std::_Destroy(__first, __cur);
525 	      __throw_exception_again;
526 	    }
527 	}
528     };
529 
530   template<>
531     struct __uninitialized_default_n_1<true>
532     {
533       template<typename _ForwardIterator, typename _Size>
534         static _ForwardIterator
535         __uninit_default_n(_ForwardIterator __first, _Size __n)
536         {
537 	  typedef typename iterator_traits<_ForwardIterator>::value_type
538 	    _ValueType;
539 
540 	  return std::fill_n(__first, __n, _ValueType());
541 	}
542     };
543 
544   // __uninitialized_default
545   // Fills [first, last) with std::distance(first, last) default
546   // constructed value_types(s).
547   template<typename _ForwardIterator>
548     inline void
549     __uninitialized_default(_ForwardIterator __first,
550 			    _ForwardIterator __last)
551     {
552       typedef typename iterator_traits<_ForwardIterator>::value_type
553 	_ValueType;
554       // trivial types can have deleted assignment
555       const bool __assignable = is_copy_assignable<_ValueType>::value;
556 
557       std::__uninitialized_default_1<__is_trivial(_ValueType)
558 				     && __assignable>::
559 	__uninit_default(__first, __last);
560     }
561 
562   // __uninitialized_default_n
563   // Fills [first, first + n) with n default constructed value_type(s).
564   template<typename _ForwardIterator, typename _Size>
565     inline _ForwardIterator
566     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
567     {
568       typedef typename iterator_traits<_ForwardIterator>::value_type
569 	_ValueType;
570       // trivial types can have deleted assignment
571       const bool __assignable = is_copy_assignable<_ValueType>::value;
572 
573       return __uninitialized_default_n_1<__is_trivial(_ValueType)
574 				       && __assignable>::
575 	__uninit_default_n(__first, __n);
576     }
577 
578 
579   // __uninitialized_default_a
580   // Fills [first, last) with std::distance(first, last) default
581   // constructed value_types(s), constructed with the allocator alloc.
582   template<typename _ForwardIterator, typename _Allocator>
583     void
584     __uninitialized_default_a(_ForwardIterator __first,
585 			      _ForwardIterator __last,
586 			      _Allocator& __alloc)
587     {
588       _ForwardIterator __cur = __first;
589       __try
590 	{
591 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
592 	  for (; __cur != __last; ++__cur)
593 	    __traits::construct(__alloc, std::__addressof(*__cur));
594 	}
595       __catch(...)
596 	{
597 	  std::_Destroy(__first, __cur, __alloc);
598 	  __throw_exception_again;
599 	}
600     }
601 
602   template<typename _ForwardIterator, typename _Tp>
603     inline void
604     __uninitialized_default_a(_ForwardIterator __first,
605 			      _ForwardIterator __last,
606 			      allocator<_Tp>&)
607     { std::__uninitialized_default(__first, __last); }
608 
609 
610   // __uninitialized_default_n_a
611   // Fills [first, first + n) with n default constructed value_types(s),
612   // constructed with the allocator alloc.
613   template<typename _ForwardIterator, typename _Size, typename _Allocator>
614     _ForwardIterator
615     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
616 				_Allocator& __alloc)
617     {
618       _ForwardIterator __cur = __first;
619       __try
620 	{
621 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
622 	  for (; __n > 0; --__n, ++__cur)
623 	    __traits::construct(__alloc, std::__addressof(*__cur));
624 	  return __cur;
625 	}
626       __catch(...)
627 	{
628 	  std::_Destroy(__first, __cur, __alloc);
629 	  __throw_exception_again;
630 	}
631     }
632 
633   template<typename _ForwardIterator, typename _Size, typename _Tp>
634     inline _ForwardIterator
635     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
636 				allocator<_Tp>&)
637     { return std::__uninitialized_default_n(__first, __n); }
638 
639 
640   template<typename _InputIterator, typename _Size,
641 	   typename _ForwardIterator>
642     _ForwardIterator
643     __uninitialized_copy_n(_InputIterator __first, _Size __n,
644 			   _ForwardIterator __result, input_iterator_tag)
645     {
646       _ForwardIterator __cur = __result;
647       __try
648 	{
649 	  for (; __n > 0; --__n, ++__first, ++__cur)
650 	    std::_Construct(std::__addressof(*__cur), *__first);
651 	  return __cur;
652 	}
653       __catch(...)
654 	{
655 	  std::_Destroy(__result, __cur);
656 	  __throw_exception_again;
657 	}
658     }
659 
660   template<typename _RandomAccessIterator, typename _Size,
661 	   typename _ForwardIterator>
662     inline _ForwardIterator
663     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
664 			   _ForwardIterator __result,
665 			   random_access_iterator_tag)
666     { return std::uninitialized_copy(__first, __first + __n, __result); }
667 
668   /**
669    *  @brief Copies the range [first,first+n) into result.
670    *  @param  __first  An input iterator.
671    *  @param  __n      The number of elements to copy.
672    *  @param  __result An output iterator.
673    *  @return  __result + __n
674    *
675    *  Like copy_n(), but does not require an initialized output range.
676   */
677   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
678     inline _ForwardIterator
679     uninitialized_copy_n(_InputIterator __first, _Size __n,
680 			 _ForwardIterator __result)
681     { return std::__uninitialized_copy_n(__first, __n, __result,
682 					 std::__iterator_category(__first)); }
683 #endif
684 
685 _GLIBCXX_END_NAMESPACE_VERSION
686 } // namespace
687 
688 #endif /* _STL_UNINITIALIZED_H */
689