// Memory extensions -*- C++ -*-

// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file ext/memory
 *  This file is a GNU extension to the Standard C++ Library (possibly
 *  containing extensions from the HP/SGI STL subset).
 */

#ifndef _EXT_MEMORY
#define _EXT_MEMORY 1

#pragma GCC system_header

#include <memory>
#include <bits/stl_tempbuf.h>

_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

  using std::ptrdiff_t;
  using std::pair;
  using std::__iterator_category;
  using std::_Temporary_buffer;

  template<typename _InputIter, typename _Size, typename _ForwardIter>
    pair<_InputIter, _ForwardIter>
    __uninitialized_copy_n(_InputIter __first, _Size __count,
			   _ForwardIter __result, std::input_iterator_tag)
    {
      _ForwardIter __cur = __result;
      __try
	{
	  for (; __count > 0 ; --__count, ++__first, ++__cur)
	    std::_Construct(&*__cur, *__first);
	  return pair<_InputIter, _ForwardIter>(__first, __cur);
	}
      __catch(...)
	{
	  std::_Destroy(__result, __cur);
	  __throw_exception_again;
	}
    }

  template<typename _RandomAccessIter, typename _Size, typename _ForwardIter>
    inline pair<_RandomAccessIter, _ForwardIter>
    __uninitialized_copy_n(_RandomAccessIter __first, _Size __count,
			   _ForwardIter __result,
			   std::random_access_iterator_tag)
    {
      _RandomAccessIter __last = __first + __count;
      return (pair<_RandomAccessIter, _ForwardIter>
	      (__last, std::uninitialized_copy(__first, __last, __result)));
    }

  template<typename _InputIter, typename _Size, typename _ForwardIter>
    inline pair<_InputIter, _ForwardIter>
    __uninitialized_copy_n(_InputIter __first, _Size __count,
			 _ForwardIter __result)
    { return __uninitialized_copy_n(__first, __count, __result,
				    __iterator_category(__first)); }

  /**
   *  @brief Copies the range [first,last) into result.
   *  @param  first  An input iterator.
   *  @param  last   An input iterator.
   *  @param  result An output iterator.
   *  @return   result + (first - last)
   *  @ingroup SGIextensions
   *
   *  Like copy(), but does not require an initialized output range.
  */
  template<typename _InputIter, typename _Size, typename _ForwardIter>
    inline pair<_InputIter, _ForwardIter>
    uninitialized_copy_n(_InputIter __first, _Size __count,
			 _ForwardIter __result)
    { return __uninitialized_copy_n(__first, __count, __result,
				    __iterator_category(__first)); }


  // An alternative version of uninitialized_copy_n that constructs
  // and destroys objects with a user-provided allocator.
  template<typename _InputIter, typename _Size, typename _ForwardIter,
           typename _Allocator>
    pair<_InputIter, _ForwardIter>
    __uninitialized_copy_n_a(_InputIter __first, _Size __count,
			     _ForwardIter __result,
			     _Allocator __alloc)
    {
      _ForwardIter __cur = __result;
      __try
	{
	  for (; __count > 0 ; --__count, ++__first, ++__cur)
	    __alloc.construct(&*__cur, *__first);
	  return pair<_InputIter, _ForwardIter>(__first, __cur);
	}
      __catch(...)
	{
	  std::_Destroy(__result, __cur, __alloc);
	  __throw_exception_again;
	}
    }

  template<typename _InputIter, typename _Size, typename _ForwardIter,
           typename _Tp>
    inline pair<_InputIter, _ForwardIter>
    __uninitialized_copy_n_a(_InputIter __first, _Size __count,
			     _ForwardIter __result,
			     std::allocator<_Tp>)
    {
      return uninitialized_copy_n(__first, __count, __result);
    }

  /**
   *  This class provides similar behavior and semantics of the standard
   *  functions get_temporary_buffer() and return_temporary_buffer(), but
   *  encapsulated in a type vaguely resembling a standard container.
   *
   *  By default, a temporary_buffer<Iter> stores space for objects of
   *  whatever type the Iter iterator points to.  It is constructed from a
   *  typical [first,last) range, and provides the begin(), end(), size()
   *  functions, as well as requested_size().  For non-trivial types, copies
   *  of *first will be used to initialize the storage.
   *
   *  @c malloc is used to obtain underlying storage.
   *
   *  Like get_temporary_buffer(), not all the requested memory may be
   *  available.  Ideally, the created buffer will be large enough to hold a
   *  copy of [first,last), but if size() is less than requested_size(),
   *  then this didn't happen.
   *
   *  @ingroup SGIextensions
  */
  template <class _ForwardIterator, class _Tp
	    = typename std::iterator_traits<_ForwardIterator>::value_type >
    struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp>
    {
      /// Requests storage large enough to hold a copy of [first,last).
      temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
      : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { }
      
      /// Destroys objects and frees storage.
      ~temporary_buffer() { }
    };

_GLIBCXX_END_NAMESPACE

#endif

