home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / memory.stl < prev    next >
Encoding:
Text File  |  2000-01-31  |  25.1 KB  |  881 lines

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