///////////////////////////////////////////////////////////////////////////
// FILE: memory (Utilities for manipulating memory)
//
//                          Open Watcom Project
//
//    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
//
//    This file is automatically generated. Do not edit directly.
//
// =========================================================================
//
// Description: This header is part of the C++ standard library. It
//              defines a number of helper templates to simplify the
//              handling of raw memory.
///////////////////////////////////////////////////////////////////////////
#ifndef _MEMORY_INCLUDED
#define _MEMORY_INCLUDED

#if !defined(_ENABLE_AUTODEPEND)
  #pragma read_only_file;
#endif


#ifndef __cplusplus
#error The header memory requires C++
#endif

#ifndef _CSTDDEF_INCLUDED
  #include <cstddef>
#endif

#ifndef _ITERATOR_INCLUDED
  #include <iterator>
#endif

#ifndef _NEW_INCLUDED
  #include <new>
#endif

#ifndef _WC_EXCEPTION_MACROS_
  #define _WC_EXCEPTION_MACROS_
  #ifdef _CPPUNWIND
    #define _WCTHROWS( __t )  throw( __t ) // Use for exception specifications.
    #define _WCTHROW( __t )   throw( __t ) // Use for throw statements.
    #define _WCTRY            try
    #define _WCHANDLERS       1
  #else
    #define _WCTHROWS( __t )
    #define _WCTHROW( __t )
    #define _WCTRY
  #endif
#endif

template< class Iterator, class Type >
inline void _RawConstruct( Iterator ptr, const Type &value )
{
    typedef typename std::iterator_traits< Iterator >::value_type value_type;
    new ( static_cast< void * >( &*ptr ) ) value_type( value );
}

template< class Iterator >
inline void _RawDestroy( Iterator ptr )
{
    typedef typename std::iterator_traits< Iterator >::value_type value_type;
    ( *ptr ).~value_type( );
}

namespace std {

  template< class Type > class allocator;

  // Allocator specialization for void
  // *********************************

  template< >
  class allocator< void > {
  public:
    typedef void       *pointer;
    typedef const void *const_pointer;
    typedef void        value_type;

    template< class Type2 >
    struct rebind { typedef allocator< Type2 > other; };
  };

  // Default allocator template
  // **************************

  template< class Type >
  class allocator {
  public:
    typedef       std::size_t    size_type;
    typedef       std::ptrdiff_t difference_type;
    typedef       Type          *pointer;
    typedef const Type          *const_pointer;
    typedef       Type          &reference;
    typedef const Type          &const_reference;
    typedef       Type           value_type;

    template< class Type2 >
    struct rebind { typedef allocator< Type2 > other; };

    allocator( )
      { }

    allocator( const allocator & )
      { }

    template< class Type2 >
    allocator( const allocator< Type2 > & )
      { }

   ~allocator( )
      { }

    pointer address( reference r ) const
      { return( &r ); }

    const_pointer address( const_reference r ) const
      { return( &r ); }

    pointer allocate( size_type n, allocator< void >::const_pointer = 0 )
      { return( reinterpret_cast< Type * >(
                  new unsigned char[ n * sizeof( Type ) ] ) ); }

    void deallocate( pointer p, size_type )
      { delete [] reinterpret_cast< unsigned char * >( p ); }

    size_type max_size( ) const
      { return 0; }  // FIX ME

    void construct( pointer p, const Type &value )
      { new ( ( void * )p ) Type( value ); }

    void destroy( pointer p )
      { ( ( Type * )p )->~Type( ); }
  };

  // Raw storage iterator
  // ********************

  template< class OutputIterator, class Type >
  class raw_storage_iterator
    : public iterator< output_iterator_tag, void, void, void, void > {
  public:
    explicit raw_storage_iterator( OutputIterator it ) : ptr( it )
      { }
    raw_storage_iterator &operator*( )
      { return( *this ); }
    raw_storage_iterator &operator=( const Type & incoming )
      { _RawConstruct( ptr, incoming ); return( *this ); }
    raw_storage_iterator &operator++( )
      { ++ptr; return( *this ); }
    raw_storage_iterator  operator++( int )
      { raw_storage_iterator temp( *this ); ++ptr; return( temp ); }
  private:
    OutputIterator ptr;
  };


  // Temporary Buffers
  // *****************

  // Need compiler support for explicit function template arguments.

  // Templates for initializing blocks of uninitialized memory
  // *********************************************************

  template< class ForwardIterator, class Type >
  void uninitialized_fill(
      ForwardIterator first,
      ForwardIterator last,
      const Type &value )
  {
      typedef
        typename iterator_traits< ForwardIterator >::value_type value_type;
      ForwardIterator bookmark( first );

      _WCTRY {
          // Construct copies of value in the raw storage.
          while( first != last ) {
              _RawConstruct( first, value );
              ++first;
          }
      }
      #ifdef _WCHANDLERS
      // If an exception occurs, destroy copies that were made successfully.
      catch( ... ) {
          while( bookmark != first ) {
              _RawDestroy( bookmark );
              ++bookmark;
          }
          throw;
      }
      #endif
  }


  template< class ForwardIterator, class Size, class Type >
  void uninitialized_fill_n(
      ForwardIterator first,
      Size n,
      const Type &value )
  {
      typedef
        typename iterator_traits< ForwardIterator >::value_type value_type;
      ForwardIterator bookmark( first );

      _WCTRY {
          // Construct n copies of value in raw storage.
          while( n-- ) {
              _RawConstruct( first, value );
              ++first;
          }
      }
      #ifdef _WCHANDLERS
      // If an exception occurs, destroy copies that were made successfully.
      catch( ... ) {
          while( bookmark != first ) {
              _RawDestroy( bookmark );
              ++bookmark;
          }
          throw;
      }
      #endif
  }


  template< class InputIterator, class ForwardIterator >
  ForwardIterator uninitialized_copy(
      InputIterator first,
      InputIterator last,
      ForwardIterator dest )
  {
      typedef
        typename iterator_traits< ForwardIterator >::value_type value_type;
      ForwardIterator bookmark( dest );

      _WCTRY {
          // Copy objects from input sequence to raw storage.
          while( first != last ) {
              _RawConstruct( dest, *first );
              ++first;
              ++dest;
          }
          return( dest );
      }
      #ifdef _WCHANDLERS
      // If an exception occurs, destroy copies that were made successfully.
      catch( ... ) {
          while( bookmark != dest ) {
              _RawDestroy( bookmark );
              ++bookmark;
          }
          throw;
      }
      #endif
  }


  // auto_ptr template
  // *****************

  template< class Type >
  struct auto_ptr_ref {
    auto_ptr< Type > &ref;
    auto_ptr_ref( auto_ptr< Type > &r ) : ref( r ) { }
  };

  template< class Type >
  class auto_ptr {
  public:
    typedef Type element_type;

    explicit auto_ptr( Type *p = 0 ) : ptr( p )
      { }

    auto_ptr( auto_ptr &other ) : ptr( other.release( ) )
      { }

    template< class Type2 >
    auto_ptr( auto_ptr< Type2 > &other ) :
      ptr( static_cast< Type * >( other.release( ) ) )
      { }

    auto_ptr &operator=( auto_ptr &other )
      { reset( other.release( ) ); return( *this ); }

    template< class Type2 >
    auto_ptr &operator=( auto_ptr< Type2 > &other )
      { reset( static_cast< Type * >( other.release( ) ) ); return ( *this ); }

   ~auto_ptr( ) _WCTHROWS( )
      { delete ptr; }

    Type &operator*( ) const
      { return( *ptr ); }

    Type *operator->( ) const
      { return( ptr ); }

    Type *get( ) const
      { return( ptr ); }

    Type *release( )
      { Type *tmp = ptr; ptr = 0; return( tmp ); }

    void reset( Type *p = 0 ) _WCTHROWS( )
      { if ( ptr != p ) delete ptr; ptr = p; }

    auto_ptr( auto_ptr_ref< Type > r ) : ptr( r.ref.release( ) )
      { }

    // template< class Type2 > 
    // operator auto_ptr_ref< Type2 >( )
    //   { return( auto_ptr_ref< Type2 >( *this ); }

    // template< class Type2 >
    // operator auto_ptr< Type2 >( )
    //   { }

  private:
    Type *ptr;
  };

} // namespace std.

#endif
