home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Include / MEMORY.H < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-26  |  26.3 KB  |  914 lines

  1. #if !defined(__USING_STD_NAMES__)
  2. #  if !defined(__MEM_H)
  3. #    include <mem.h>
  4. #  endif /* __MEM_H */
  5. #else /* __USING_STD_NAMES__ */
  6.  
  7. #ifndef __MEMORY_H
  8. #define __MEMORY_H
  9. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  10. // -*- C++ -*-
  11. #ifndef __STD_MEMORY 
  12. #define __STD_MEMORY
  13.  
  14. /***************************************************************************
  15.  *
  16.  * memory - declarations for the Standard Library memory implementation
  17.  *
  18.  ***************************************************************************
  19.  *
  20.  * Copyright (c) 1994
  21.  * Hewlett-Packard Company
  22.  *
  23.  * Permission to use, copy, modify, distribute and sell this software
  24.  * and its documentation for any purpose is hereby granted without fee,
  25.  * provided that the above copyright notice appear in all copies and
  26.  * that both that copyright notice and this permission notice appear
  27.  * in supporting documentation.  Hewlett-Packard Company makes no
  28.  * representations about the suitability of this software for any
  29.  * purpose.  It is provided "as is" without express or implied warranty.
  30.  *
  31.  *
  32.  ***************************************************************************
  33.  *
  34.  * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
  35.  * ALL RIGHTS RESERVED
  36.  *
  37.  * The software and information contained herein are proprietary to, and
  38.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  39.  * intends to preserve as trade secrets such software and information.
  40.  * This software is furnished pursuant to a written license agreement and
  41.  * may be used, copied, transmitted, and stored only in accordance with
  42.  * the terms of such license and with the inclusion of the above copyright
  43.  * notice.  This software and information or any other copies thereof may
  44.  * not be provided or otherwise made available to any other person.
  45.  *
  46.  * Notwithstanding any other lease or license that may pertain to, or
  47.  * accompany the delivery of, this computer software and information, the
  48.  * rights of the Government regarding its use, reproduction and disclosure
  49.  * are as set forth in Section 52.227-19 of the FARS Computer
  50.  * Software-Restricted Rights clause.
  51.  * 
  52.  * Use, duplication, or disclosure by the Government is subject to
  53.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  54.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  55.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  56.  * P.O. Box 2328, Corvallis, Oregon 97339.
  57.  *
  58.  * This computer software and information is distributed with "restricted
  59.  * rights."  Use, duplication or disclosure is subject to restrictions as
  60.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  61.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  62.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  63.  * then the "Alternate III" clause applies.
  64.  *
  65.  **************************************************************************/ 
  66.  
  67. #include <stdcomp.h>
  68.  
  69. #ifndef _RWSTD_NO_NEW_HEADER
  70. #include <cstddef>
  71. #include <cstdlib>
  72. #include <cstdio>
  73. #include <climits>
  74. #else
  75. #include <stddef.h>
  76. #include <stdlib.h>
  77. #include <stdio.h>
  78. #include <limits.h>
  79.  
  80. #endif //_RWSTD_NO_NEW_HEADER
  81.  
  82. #include <new>
  83. #include <iterator>
  84. #include <utility>
  85. #include <rw/rwstderr.h>
  86.  
  87. #ifdef _RWSTD_MULTI_THREAD
  88. #include <rw/stdmutex.h>
  89. #endif
  90.  
  91. //
  92. // Turn off the warnings under the MSVC compiler that
  93. // say 'bool reserved for future use' and turn off warnings
  94. // that say 'debug information truncated to 256 characters'
  95. //
  96. #ifdef _RWSTD_MSVC_BOOL_WARNING
  97. #pragma warning ( disable : 4237 )
  98. #endif
  99. #if defined(_MSC_VER) && !defined(__BORLANDC__)
  100. #pragma warning ( disable : 4786 )
  101. #endif
  102.  
  103. #ifdef _RWSTD_NO_NEW_DECL
  104. extern void _RWSTDExportFunc(*) operator new(size_t size, void* ptr);
  105. #endif
  106.  
  107. #ifdef _RWSTD_NO_NEW_HEADER
  108. #include <exception>
  109. #endif
  110.  
  111. #ifndef _RWSTD_NO_NAMESPACE
  112. namespace __rwstd {
  113. #endif
  114.  
  115. //
  116. // Template used for empty base optimization
  117. //
  118.   template <class T , class __Base> // __BORLANDC__ bug: Class name cannot be the same as the base name
  119.   class __rw_basis : public __Base
  120.   {
  121.     T __data_;
  122.   public:
  123.     __rw_basis(const __rw_basis& b) : __data_(b.__data_) {;}
  124.     __rw_basis(const T& t, const __Base& b) : __Base(b), __data_(t) {;}
  125.     __rw_basis(int t, const __Base& b) : __Base(b), __data_((T)t) {;}   // TEMP
  126.     __rw_basis operator=(const T& t) { __data_ = t; return *this; }
  127.     __rw_basis operator=(int t) { __data_ = (T)t; return *this; }   // TEMP
  128.     __rw_basis operator=(const __rw_basis& r)
  129.     { __data_ = r.__data_; return *this; }
  130.     __rw_basis operator=(const __Base& b)
  131.     { *this = __rw_basis<T,__Base>(__data_,b); return *this; }
  132.     operator T() { return __data_; }
  133.     T data() const { return __data_; }
  134.   };
  135.  
  136. // Default buffer size for containers.    
  137. #ifndef _RWSTD_CONTAINER_BUFFER_SIZE 
  138. #define _RWSTD_CONTAINER_BUFFER_SIZE 1024
  139. #endif
  140.  
  141. #ifndef _RWSTD_VECTOR_CONST_ENLARGE
  142.   // Double buffer size every time new space is needed
  143.   // This is the standard compliant method, resulting
  144.   // in a linear increase in execution time for
  145.   // individual additions to a container.
  146.   // if __n is zero then  get initial buffer size from
  147.   // _RWSTD_CONTAINER_BUFFER_SIZE.  Only vector calls 
  148.   // this function with a non-zero value for cursize.  
  149.   // Return new buffer size in bytes.
  150.   // Third parameter not used.
  151.   template <class T, class size>
  152.   inline size __rw_allocation_size(T*,size cursize, size)
  153.   {
  154.     if (cursize) 
  155.       return cursize*2;
  156.     else
  157.       return _RWSTD_CONTAINER_BUFFER_SIZE / sizeof(T); // RW_BUG fix for bts-41790
  158.   }
  159. #else
  160.   // Increment the buffer size by a set amount
  161.   // indicated by __delta (if __delta is 0 then
  162.   // get delta size from _RWSTD_CONTAINER_BUFFER_SIZE 
  163.   // if __n is zero then  get initial buffer size from
  164.   // _RWSTD_CONTAINER_BUFFER_SIZE.  Only vector calls 
  165.   // this function with a non-zero value for cursize.  
  166.   // Return new buffer size in bytes.
  167.   template <class T, class size>
  168.   inline size __rw_allocation_size(T*,size __n, size __delta)
  169.   {
  170.     if (__n) 
  171.       return __n + (__delta ? 
  172.              __delta : _RWSTD_CONTAINER_BUFFER_SIZE / sizeof(T)); // RW_BUG fix for bts-41790
  173.     else
  174.       return _RWSTD_CONTAINER_BUFFER_SIZE / sizeof(T); // RW_BUG fix for bts-41790
  175.   }
  176. #endif // _RWSTD_CONTAINER_CONST_ENLARGE
  177.  
  178. #if defined(_RWSTD_NO_DESTROY_NONBUILTIN)
  179.   template <class __T> struct __FS : public __T // __BORLANDC__ bug: Class name cannot be the same as the base name
  180.   {
  181.     __FS() { ; }
  182.     //
  183.     // Calls destructor, but does not free the space.
  184.     //
  185.     void operator delete (void*) {;}
  186.   };
  187. #endif // _RWSTD_NO_DESTROY_NONBUILTIN
  188. #ifdef __TURBOC__
  189. #pragma option -w-inl
  190. #pragma option -w-par
  191. #endif
  192.  
  193.   template <class T>
  194.   inline void __destroy (T* pointer)
  195.   {
  196. #if defined(_RWSTD_NO_DESTROY_NONBUILTIN)
  197.     delete (__FS<T>*) (pointer);
  198. #else
  199. #if defined(_RWSTD_EXPLICIT_SCOPE_DESTROY)
  200.     pointer->T::~T();
  201. #else
  202.     pointer->~T();
  203. #endif // _RWSTD_EXPLICIT_SCOPE_DESTROY
  204. #endif // _RWSTD_NO_DESTROY_NONBUILTIN
  205.   }
  206.   template <class T1, class T2>
  207.   inline void __construct (T1* p, const T2& value)
  208.   {
  209.     new (p) T1(value);
  210.   }
  211.  
  212.   template <class ForwardIterator> 
  213.   _RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last)
  214.   {
  215.     while (first != last)
  216.       ++first;
  217.   }
  218. #if defined(_RWSTD_NO_DESTROY_BUILTIN) || defined(_RWSTD_NO_DESTROY_NONBUILTIN)
  219. //
  220. // Some specializations of STL destroy for builtin types.f
  221. //
  222.   inline void __destroy (void*)             {;}
  223.   inline void __destroy (char*)             {;}
  224.   inline void __destroy (unsigned char*)    {;}
  225.   inline void __destroy (short*)            {;}
  226.   inline void __destroy (unsigned short*)   {;}
  227.   inline void __destroy (int*)              {;}
  228.   inline void __destroy (unsigned int*)     {;}
  229.   inline void __destroy (long*)             {;}
  230.   inline void __destroy (unsigned long*)    {;}
  231.   inline void __destroy (float*)            {;}
  232.   inline void __destroy (double*)           {;}
  233.   inline void __destroy (void**)            {;}
  234.   inline void __destroy (char**)            {;}
  235.   inline void __destroy (unsigned char**)   {;}
  236.   inline void __destroy (short**)           {;}
  237.   inline void __destroy (unsigned short**)  {;}
  238.   inline void __destroy (int**)             {;}
  239.   inline void __destroy (unsigned int**)    {;}
  240.   inline void __destroy (long**)            {;}
  241.   inline void __destroy (unsigned long**)   {;}
  242.   inline void __destroy (float**)           {;}
  243.   inline void __destroy (double**)          {;}
  244.   inline void __destroy (void***)           {;}
  245.   inline void __destroy (char***)           {;}
  246.   inline void __destroy (unsigned char***)  {;}
  247.   inline void __destroy (short***)          {;}
  248.   inline void __destroy (unsigned short***) {;}
  249.   inline void __destroy (int***)            {;}
  250.   inline void __destroy (unsigned int***)   {;}
  251.   inline void __destroy (long***)           {;}
  252.   inline void __destroy (unsigned long***)  {;}
  253.   inline void __destroy (float***)          {;}
  254.   inline void __destroy (double***)         {;}
  255. #ifndef _RWSTD_NO_BOOL
  256.   inline void __destroy (bool*)             {;}
  257.   inline void __destroy (bool**)            {;}
  258.   inline void __destroy (bool***)           {;}
  259. #endif
  260. #ifndef _RWSTD_NO_LONGDOUBLE
  261.   inline void __destroy (long double*)      {;}
  262.   inline void __destroy (long double**)     {;}
  263.   inline void __destroy (long double***)    {;}
  264. #endif 
  265. #ifndef _RWSTD_NO_OVERLOAD_WCHAR
  266.   inline void __destroy (wchar_t*)          {;}
  267.   inline void __destroy (wchar_t**)         {;}
  268.   inline void __destroy (wchar_t***)        {;}
  269. #endif
  270. #endif /*_RWSTD_NO_DESTROY_BUILTIN || _RWSTD_NO_DESTROY_NONBUILTIN*/
  271.  
  272. #ifdef _RWSTD_LOCALIZED_ERRORS
  273.   extern const unsigned int _RWSTDExport rwse_OutOfRange;
  274. #else
  275.   extern const char _RWSTDExportFunc(*) rwse_OutOfRange;
  276. #endif // _RWSTD_LOCALIZED_ERRORS
  277.  
  278. #ifndef _RWSTD_NO_NAMESPACE
  279. } // __rwstd namespace
  280.  
  281. namespace std {
  282. #endif
  283.  
  284. //
  285. // The default allocator.
  286. //
  287. #ifdef _RWSTD_ALLOCATOR
  288.  
  289.   template <class T> class allocator;
  290.  
  291. //
  292. // void specialization of allocator
  293. //
  294.   _RWSTD_TEMPLATE
  295.   class allocator<void> {  
  296.   public:
  297.     typedef void*       pointer;
  298.     typedef const void* const_pointer;
  299.     typedef void        value_type;
  300.    
  301.     template <class U> 
  302.     struct rebind { typedef allocator<U> other; };
  303.     
  304. #ifndef _RWSTD_NO_MULTI_DIM_ARRAY
  305.     ~allocator()  _RWSTD_THROW_SPEC_NULL
  306.     { ; }
  307. #endif
  308.  
  309.   };
  310.   template <class T>
  311.   class allocator
  312.   {
  313.   public:
  314.     typedef size_t     size_type;
  315.     typedef ptrdiff_t  difference_type;
  316.     typedef T*         pointer;
  317.     typedef const T*   const_pointer;
  318.     typedef T&         reference;
  319.     typedef const T&   const_reference;
  320.     typedef T          value_type;
  321.  
  322.     template <class U> struct rebind
  323.     { typedef allocator<U> other; };
  324.  
  325.     allocator()  _RWSTD_THROW_SPEC_NULL
  326.     { ; }
  327.  
  328.     allocator(const allocator&)  _RWSTD_THROW_SPEC_NULL
  329.     { ; }
  330.  
  331.     template <class U>
  332.     allocator(const allocator<U>&)  _RWSTD_THROW_SPEC_NULL
  333.     { ; }
  334.  
  335.     template <class U>
  336.     allocator<T>& operator=(const allocator<U>& a)  _RWSTD_THROW_SPEC_NULL
  337.     { return *this; }
  338.     
  339. #ifndef _RWSTD_NO_MULTI_DIM_ARRAY
  340.     ~allocator()  _RWSTD_THROW_SPEC_NULL
  341.     { ; }
  342. #endif
  343.  
  344.     pointer address(reference x) const
  345.     { 
  346.       return _RWSTD_STATIC_CAST(pointer,&x); 
  347.     }
  348.     const_pointer address(const_reference x) const
  349.     { 
  350.       return _RWSTD_STATIC_CAST(const_pointer,&x); 
  351.     }
  352.     pointer allocate(size_type n, allocator<void>::const_pointer hint = 0)
  353.     { 
  354.       pointer tmp =
  355.       _RWSTD_STATIC_CAST(pointer,(::operator 
  356.                                   new(_RWSTD_STATIC_CAST(size_t,(n * sizeof(value_type))))));
  357.       _RWSTD_THROW_NO_MSG(tmp == 0, bad_alloc);
  358.       return tmp;
  359.     }
  360.  
  361.     void deallocate(pointer p, size_type)
  362.     {
  363.       ::operator delete(p);
  364.     }
  365.     size_type max_size() const  _RWSTD_THROW_SPEC_NULL
  366.     {
  367.       return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
  368.     }
  369.     inline void construct(pointer p, const T& val);
  370.  
  371.     inline void destroy(T* p);
  372.  
  373.   };
  374.  
  375.   template <class T>
  376.   inline void allocator<T>::construct(pointer p, const T& val) // RW_BUG not marked as inline
  377.   {
  378.     __RWSTD::__construct(p,val);
  379.   }
  380.  
  381.   template <class T>
  382.   inline void allocator<T>::destroy(T* p) // RW_BUG not marked as inline
  383.   {
  384.      __RWSTD::__destroy(p);
  385.   }
  386.  
  387. #else
  388.  
  389. //
  390. // Alternate allocator uses an interface class (allocator_interface)
  391. // to get type safety.
  392. //
  393.   template <class T>
  394.   class allocator
  395.   { 
  396.   public:
  397.    
  398.     typedef size_t    size_type;
  399.     typedef ptrdiff_t difference_type;
  400.     typedef T*         pointer;
  401.     typedef const T*   const_pointer;
  402.     typedef T&         reference;
  403.     typedef const T&   const_reference;
  404.     typedef T          value_type;
  405.  
  406.     allocator()  _RWSTD_THROW_SPEC_NULL { ; }
  407.     allocator(const allocator<T>&)  _RWSTD_THROW_SPEC_NULL
  408.     { ; }
  409.     allocator<T>& operator=(const allocator<T>&)  _RWSTD_THROW_SPEC_NULL
  410.     { return *this; }
  411.  
  412. #ifndef _RWSTD_NO_MULTI_DIM_ARRAY
  413.     ~allocator()  _RWSTD_THROW_SPEC_NULL { ; }
  414. #endif
  415.  
  416.     void * allocate (size_type n, void *  = 0)
  417.     { 
  418.       void * tmp = _RWSTD_STATIC_CAST(void*,(::operator new(_RWSTD_STATIC_CAST(size_t,(n)))));
  419.       _RWSTD_THROW_NO_MSG(tmp == 0, bad_alloc);
  420.       return tmp;
  421.     }
  422.     
  423.     void deallocate (void* p, size_type) 
  424.     { 
  425.       ::operator delete(p);
  426.     }
  427.     size_type max_size (size_type size) const
  428.     { 
  429.       return 1 > UINT_MAX/size ? size_type(1) : size_type(UINT_MAX/size);
  430.     }
  431.   };
  432.  
  433.   _RWSTD_TEMPLATE
  434.   class allocator<void>
  435.   { 
  436.   public:
  437.    
  438.     typedef size_t    size_type;
  439.     typedef ptrdiff_t difference_type;
  440.     typedef void*         pointer;
  441.     typedef const void*   const_pointer;
  442.     typedef void          value_type;
  443.  
  444.     allocator() _RWSTD_THROW_SPEC_NULL { ; }
  445.     allocator(const allocator<void>&)  _RWSTD_THROW_SPEC_NULL
  446.     { ; }
  447.     allocator<void>& operator=(const allocator<void>&)  _RWSTD_THROW_SPEC_NULL
  448.     { return *this; }
  449. #ifndef _RWSTD_NO_MULTI_DIM_ARRAY
  450.     ~allocator() _RWSTD_THROW_SPEC_NULL { ; }
  451. #endif
  452.  
  453.     void * allocate (size_type n, void *  = 0)
  454.     { 
  455.       void * tmp = _RWSTD_STATIC_CAST(void*,(::operator new(_RWSTD_STATIC_CAST(size_t,(n)))));
  456.       _RWSTD_THROW_NO_MSG(tmp == 0, bad_alloc);
  457.       return tmp;
  458.     }
  459.     
  460.     void deallocate (void* p, size_type) 
  461.     { 
  462.       ::operator delete(p);
  463.     }
  464.     size_type max_size (size_type size) const
  465.     { 
  466.       return 1 > UINT_MAX/size ? size_type(1) : size_type(UINT_MAX/size);
  467.     }
  468.   };
  469.  
  470. //
  471. // allocator_interface provides all types and typed functions.  Memory
  472. // allocated as raw bytes using the class provided by the Allocator
  473. // template parameter.  allocator_interface casts appropriately.
  474. //
  475. // Multiple allocator_interface objects can attach to a single 
  476. // allocator, thus allowing one allocator to allocate all storage
  477. // for a container, regardless of how many types are involved.
  478. //
  479. // The only real restriction is that pointer and reference are
  480. // hard coded as T* and T&.  Partial specialization would 
  481. // get around this.
  482. //
  483.   template <class Allocator,class T>
  484.   class allocator_interface 
  485.   {
  486.   public:
  487.     typedef Allocator allocator_type;
  488.     typedef T*         pointer;
  489.     typedef const T*   const_pointer;      
  490.     typedef T&         reference;
  491.     typedef const T&   const_reference;
  492.     typedef T          value_type;
  493.     typedef _TYPENAME _RWSTD_ALLOC_SIZE_TYPE             size_type;
  494.     typedef _TYPENAME _RWSTD_ALLOC_DIFF_TYPE             difference_type;
  495.     typedef void*      void_pointer;
  496.     typedef const void* const_void_pointer;
  497.  
  498.   protected:
  499.     allocator_type         alloc_;
  500.  
  501.   public:
  502.     allocator_interface()  _RWSTD_THROW_SPEC_NULL  { ; }
  503.     allocator_interface(const Allocator& a)  _RWSTD_THROW_SPEC_NULL
  504.     : alloc_(a) { ; }
  505.  
  506.     pointer address (T& x) 
  507.     { 
  508.       return _RWSTD_STATIC_CAST(pointer,&x); 
  509.     }
  510.   
  511.     size_type max_size ()  const
  512.     { 
  513.       return alloc_.max_size(sizeof(T));
  514.     }
  515.  
  516.     pointer allocate(size_type n, pointer p  = 0)
  517.     {
  518.       return _RWSTD_STATIC_CAST(pointer,alloc_.allocate(n*sizeof(T),p));
  519.     }
  520.  
  521.     void deallocate(pointer p, size_type n)
  522.     {
  523.       alloc_.deallocate(p,n);
  524.     }
  525.  
  526.     inline void construct(pointer p, const T& val);
  527.  
  528.     inline void destroy(T* p);
  529.  
  530.   };
  531.   template <class Allocator, class T>
  532.   inline void 
  533.   allocator_interface<Allocator,T>::construct(pointer p, const T& val)
  534.   {
  535.      __RWSTD::__construct(p,val);
  536.   }
  537.  
  538.   template <class Allocator, class T>
  539.   inline void allocator_interface<Allocator,T>::destroy(T* p)
  540.   {
  541.      __RWSTD::__destroy(p);
  542.   }
  543.  
  544.   _RWSTD_TEMPLATE
  545.   class allocator_interface<allocator<void>,void> 
  546.   {
  547.   public:
  548.     typedef allocator<void> allocator_type;
  549.     typedef void*         pointer;
  550.     typedef const void*   const_pointer;      
  551.     typedef void          value_type;
  552.     typedef allocator<void>::size_type       size_type;
  553.     typedef allocator<void>::difference_type difference_type;
  554.  
  555.   protected:
  556.     allocator_type         alloc_;
  557.  
  558.   public:
  559.     allocator_interface()  _RWSTD_THROW_SPEC_NULL { ; }
  560.     allocator_interface(const allocator<void>& a) _RWSTD_THROW_SPEC_NULL
  561.     : alloc_(a) { ; }
  562.  
  563.     size_type max_size ()  const
  564.     { 
  565.       return alloc_.max_size(1);
  566.     }
  567.  
  568.     pointer allocate(size_type n, pointer  = 0)
  569.     {
  570.       return _RWSTD_STATIC_CAST(pointer,alloc_.allocate(n));
  571.     }
  572.  
  573.     void deallocate(pointer p, size_type n)
  574.     {
  575.       alloc_.deallocate(p,n);
  576.     }      
  577.   };
  578.  
  579. #endif  // _RWSTD_ALLOCATOR
  580.  
  581. // 
  582. // Allocator globals
  583. //
  584.   template <class T, class U>
  585.   inline bool operator==(const allocator<T>&, const allocator<U>&)  _RWSTD_THROW_SPEC_NULL
  586.   {
  587.     return true;
  588.   }
  589.  
  590. #ifndef _RWSTD_NO_NAMESPACE
  591.   template <class T, class U>
  592.   inline bool operator!=(const allocator<T>&, const allocator<U>&)  _RWSTD_THROW_SPEC_NULL
  593.   {
  594.     return false;
  595.   }
  596. #endif
  597.  
  598. //
  599. // Raw storage iterator.
  600. //
  601.  
  602.   template <class OutputIterator, class T>
  603.   class raw_storage_iterator
  604.     : public iterator<output_iterator_tag,T,ptrdiff_t,T*,T&>
  605.   {
  606.   protected:
  607.     OutputIterator iter;
  608.  
  609.   public:
  610.     typedef OutputIterator iterator_type;
  611.     typedef T element_type;
  612.  
  613.     _EXPLICIT raw_storage_iterator (OutputIterator x) : iter(x) {}
  614.     raw_storage_iterator<OutputIterator, T>& operator* () { return *this; }
  615.     raw_storage_iterator<OutputIterator, T>& operator= (const T& element)
  616.     {
  617.       new ((void *) &*iter) T (element);  // RW_BUG - jjp
  618.       return *this;
  619.     }
  620.     raw_storage_iterator<OutputIterator, T>& operator++ ()
  621.     {
  622.       ++iter; return *this;
  623.     }
  624.     raw_storage_iterator<OutputIterator, T> operator++ (int)
  625.     {
  626.       raw_storage_iterator<OutputIterator, T> tmp = *this;
  627.       ++iter;
  628.       return tmp;
  629.     }
  630.   };
  631. //
  632. // Temporary buffers
  633. //
  634.  
  635. #ifdef _RWSTD_FAST_TEMP_BUF
  636.  
  637. #if defined(_RWSTD_SHARED_LIB) && !defined (_RWSTD_MULTI_THREAD)
  638. #error Cannot use fast temporary buffer in this configuration
  639. #endif
  640. #if defined(_RWSTDDLL) && defined (__WIN16__)
  641. #error Cannot use fast temporary buffer in this configuration
  642. #endif
  643.  
  644. #ifndef __stl_buffer_size
  645. #define __stl_buffer_size 16384  /* 16k */
  646. #endif
  647.  
  648. #ifndef _RWSTD_NO_NAMESPACE
  649. }
  650.  
  651. namespace __rwstd {
  652. #endif
  653.  
  654.   extern char _RWSTDExport stl_temp_buffer[__stl_buffer_size];
  655.  
  656. #ifdef _RWSTD_MULTI_THREAD
  657.   extern _RWSTDMutex _RWSTDExport stl_temp_buffer_mutex;
  658.   extern bool       _RWSTDExport stl_temp_buffer_being_used;
  659. #endif
  660.  
  661. #ifndef _RWSTD_NO_NAMESPACE
  662. } // End of __rwstd namespace
  663.  
  664. namespace std {
  665. #endif
  666.  
  667.   template <class T>
  668. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  669.   inline pair<T*, ptrdiff_t> get_temporary_buffer (ptrdiff_t len)
  670. #else
  671.   inline pair<T*, ptrdiff_t> get_temporary_buffer (ptrdiff_t len, T*)
  672. #endif
  673.   {
  674.     while (len > __stl_buffer_size / sizeof(T))
  675.     {
  676.       T* tmp = _RWSTD_STATIC_CAST(T*,( ::operator new(_RWSTD_STATIC_CAST(unsigned int,len) * sizeof(T))));
  677.       if (tmp)
  678.       {
  679.         pair<T*, ptrdiff_t> result(tmp, len);
  680.         return result;
  681.       }
  682.       len = len / 2;
  683.     }
  684.     
  685. #ifdef _RWSTD_MULTI_THREAD
  686.     _RWSTDGuard guard(__RWSTD::stl_temp_buffer_mutex);
  687.  
  688.     if (__RWSTD::stl_temp_buffer_being_used)
  689.     {
  690.       T* tmp = _RWSTD_STATIC_CAST(T*,(   ::operator new(_RWSTD_STATIC_CAST(unsigned int,len) * sizeof(T))));
  691.       pair<T*,ptrdiff_t> result(tmp, len);
  692.       return result;
  693.     }
  694.     else
  695.     {
  696.       __RWSTD::stl_temp_buffer_being_used = true;
  697.       pair<T*, ptrdiff_t> result(_RWSTD_STATIC_CAST(T*,
  698.                                  _RWSTD_STATIC_CAST(void*,__RWSTD::stl_temp_buffer)), 
  699.                                  _RWSTD_STATIC_CAST(ptrdiff_t,(__stl_buffer_size / sizeof(T))));
  700.       return result;
  701.     }
  702. #else
  703.     pair<T*, ptrdiff_t> result(_RWSTD_STATIC_CAST(T*,
  704.                                _RWSTD_STATIC_CAST(void*,__RWSTD::stl_temp_buffer)), 
  705.                                _RWSTD_STATIC_CAST(ptrdiff_t,(__stl_buffer_size / sizeof(T))));
  706.     return result;
  707. #endif /*_RWSTD_MULTI_THREAD*/
  708.   }
  709.  
  710.   template <class T>
  711.   inline void return_temporary_buffer (T* p)
  712.   {
  713. #ifdef _RWSTD_MULTI_THREAD
  714.     _RWSTDGuard guard(__RWSTD::stl_temp_buffer_mutex);
  715.  
  716.     if (_RWSTD_STATIC_CAST(char*,
  717.                            _RWSTD_STATIC_CAST(void*,p)) != __RWSTD::stl_temp_buffer) 
  718.       ::operator delete(p);
  719.     else
  720.       __RWSTD::stl_temp_buffer_being_used = false;
  721. #else
  722.     if (_RWSTD_STATIC_CAST(char*,
  723.                            _RWSTD_STATIC_CAST(void*,p)) != __RWSTD::stl_temp_buffer) 
  724.       ::operator delete(p);
  725. #endif /*_RWSTD_MULTI_THREAD*/
  726.   }
  727.  
  728. #else
  729.  
  730.   template <class T>
  731. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  732.   inline pair<T*, ptrdiff_t> get_temporary_buffer (ptrdiff_t len)
  733. #else
  734.   inline pair<T*, ptrdiff_t> get_temporary_buffer (ptrdiff_t len, T*)
  735. #endif
  736.   {
  737.     T* tmp = _RWSTD_STATIC_CAST(T*,(   ::operator new(len * sizeof(T))));
  738.     pair<T*,ptrdiff_t> result(tmp, len);
  739.     return result;
  740.   }
  741.  
  742.   template <class T>
  743.   inline void return_temporary_buffer (T* p)
  744.   {
  745.     ::operator delete(p);
  746.   }
  747.  
  748. #endif /*_RWSTD_FAST_TEMP_BUF*/
  749. //
  750. // Specialized algorithms.
  751. //
  752.  
  753.   template <class InputIterator, class ForwardIterator>
  754.   _RWSTD_TRICKY_INLINE ForwardIterator uninitialized_copy (InputIterator first, InputIterator last,
  755.                                                            ForwardIterator result)
  756.   {
  757.     ForwardIterator start = result;
  758. #ifndef _RWSTD_NO_EXCEPTIONS
  759.     try {
  760.       while (first != last) 
  761.          __RWSTD::__construct(result++, *first++);
  762.     } catch(...) {
  763.        __RWSTD::__destroy(start,result);
  764.       throw;
  765.     }
  766. #else
  767.     while (first != last) 
  768.        __RWSTD::__construct(result++, *first++);
  769. #endif // _RWSTD_NO_EXCEPTIONS
  770.  
  771.     return result;
  772.   }
  773.  
  774.   template <class ForwardIterator, class T>
  775.   _RWSTD_TRICKY_INLINE void uninitialized_fill (ForwardIterator first, ForwardIterator last,
  776.                                                 const T& x)
  777.   {
  778.     ForwardIterator start = first;
  779. #ifndef _RWSTD_NO_EXCEPTIONS
  780.     try {
  781.       while (first != last) 
  782.          __RWSTD::__construct(first++, x);
  783.     } catch(...) {
  784.        __RWSTD::__destroy(start,first);
  785.       throw;
  786.     }
  787. #else
  788.     while (first != last) 
  789.        __RWSTD::__construct(first++, x);
  790. #endif // _RWSTD_NO_EXCEPTIONS
  791.   }
  792.  
  793.   template <class ForwardIterator, class Size, class T>
  794.   _RWSTD_TRICKY_INLINE void uninitialized_fill_n (ForwardIterator first, Size n, const T& x)
  795.   {
  796.     ForwardIterator start = first;
  797. #ifndef _RWSTD_NO_EXCEPTIONS
  798.     try {
  799.       while (n--) 
  800.          __RWSTD::__construct(first++, x);
  801.     } catch(...) {
  802.        __RWSTD::__destroy(start,first);
  803.       throw;
  804.     }
  805. #else
  806.     while (n--) 
  807.        __RWSTD::__construct(first++, x);
  808. #endif // _RWSTD_NO_EXCEPTIONS
  809.   }
  810. //
  811. // Template auto_ptr holds onto a pointer obtained via new and deletes that
  812. // object when it itself is destroyed (such as when leaving block scope).
  813. //
  814. // It can be used to make calls to new() exception safe.
  815. //
  816.  
  817.   template<class X> class auto_ptr
  818.   {
  819. #ifndef _RWSTD_NO_MEM_CLASS_TEMPLATES
  820.     template <class Y> class auto_ptr_ref 
  821.     {
  822.     public:
  823.       const auto_ptr<Y>& p;
  824.       auto_ptr_ref(const auto_ptr<Y>& a) { p = a; }
  825.     };
  826. #endif    
  827.  
  828.   public:
  829.     typedef X element_type;
  830.  
  831.     //
  832.     // construct/copy/destroy
  833.     //
  834.     _EXPLICIT auto_ptr (X* p = 0)  _RWSTD_THROW_SPEC_NULL
  835.      : the_p(p)
  836.     { ; }
  837.  
  838.     auto_ptr (auto_ptr<X>& a)  _RWSTD_THROW_SPEC_NULL
  839.      :  the_p((_RWSTD_CONST_CAST(auto_ptr<X>&,a)).release()) 
  840.     { ; }
  841.  
  842.     auto_ptr<X>& operator= (auto_ptr<X>& rhs)  _RWSTD_THROW_SPEC_NULL
  843.     { 
  844.       reset(rhs.release());
  845.       return *this;
  846.     }
  847. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  848.     template <class Y>
  849.     auto_ptr (auto_ptr<Y>& a)  _RWSTD_THROW_SPEC_NULL
  850.      : the_p((_RWSTD_CONST_CAST(auto_ptr<Y>&,a)).release()) 
  851.     { ; }
  852.  
  853.     template <class Y>
  854.     auto_ptr<X>& operator= (auto_ptr<Y>& rhs)  _RWSTD_THROW_SPEC_NULL
  855.     { 
  856.       reset(rhs.release());
  857.       return *this;
  858.     }
  859. #endif
  860.  
  861.     ~auto_ptr () { delete the_p; }
  862.     //
  863.     // members
  864.     //
  865.     X& operator*  ()  const _RWSTD_THROW_SPEC_NULL { return *the_p;   }
  866.     X* operator-> ()  const _RWSTD_THROW_SPEC_NULL { return the_p;    }
  867.     X* get        ()  const _RWSTD_THROW_SPEC_NULL { return the_p;    }
  868.  
  869.     X* release    ()  _RWSTD_THROW_SPEC_NULL
  870.     { 
  871.       X* tmp = the_p;
  872.       the_p = 0; 
  873.       return tmp; 
  874.     }
  875.  
  876.     void reset (X* p = 0) _RWSTD_THROW_SPEC_NULL
  877.     { 
  878.       if (the_p != p)
  879.       {
  880.         delete the_p;
  881.         the_p = p;
  882.       }
  883.     }
  884.  
  885. #ifndef _RWSTD_NO_MEM_CLASS_TEMPLATES
  886.     auto_ptr(auto_ptr_ref<X> r) _RWSTD_THROW_SPEC_NULL
  887.     {
  888.       reset(r.p.release());
  889.     }
  890. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  891.     template <class Y> operator auto_ptr_ref<Y>() _RWSTD_THROW_SPEC_NULL
  892.     {
  893.       return auto_ptr_ref<Y>(*this);
  894.     }
  895.     template <class Y> operator auto_ptr<Y>() _RWSTD_THROW_SPEC_NULL
  896.     {  
  897.       auto_ptr<Y> tmp;
  898.       tmp.reset(release());
  899.       return tmp;
  900.     }
  901. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  902. #endif // _RWSTD_NO_MEM_CLASS_TEMPLATES
  903.  
  904.   private:
  905.     X* the_p;
  906.   };
  907. #ifndef _RWSTD_NO_NAMESPACE
  908. }
  909. #endif
  910.  
  911. #endif /*__STD_MEMORY*/
  912. #pragma option pop
  913. #endif /* __MEMORY_H */
  914. #endif /* __USING_STD_NAMES__ */