home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / progs / CB / DATA.Z / MEMORY.H < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-18  |  13.6 KB  |  502 lines

  1. /*  memory.h
  2.  
  3.     Memory manipulation functions
  4.  
  5. */
  6.  
  7. /* $Copyright: 1991$ */
  8. /* $Revision:   8.1  $ */
  9.  
  10. #if !defined(__USING_STD_NAMES__)
  11.  
  12. #include <mem.h>
  13.  
  14. #else   /* __USING_STD_NAMES__ */
  15.  
  16. #ifndef __STD_MEMORY
  17. #define __STD_MEMORY
  18.  
  19. /***************************************************************************
  20.  *
  21.  * memory - declarations for the Standard Library memory implementation
  22.  *
  23.  * $Id: memory,v 1.38 1995/09/14 02:50:59 smithey Exp $
  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.  ***************************************************************************
  40.  *
  41.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  42.  * ALL RIGHTS RESERVED
  43.  *
  44.  * The software and information contained herein are proprietary to, and
  45.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  46.  * intends to preserve as trade secrets such software and information.
  47.  * This software is furnished pursuant to a written license agreement and
  48.  * may be used, copied, transmitted, and stored only in accordance with
  49.  * the terms of such license and with the inclusion of the above copyright
  50.  * notice.  This software and information or any other copies thereof may
  51.  * not be provided or otherwise made available to any other person.
  52.  *
  53.  * Notwithstanding any other lease or license that may pertain to, or
  54.  * accompany the delivery of, this computer software and information, the
  55.  * rights of the Government regarding its use, reproduction and disclosure
  56.  * are as set forth in Section 52.227-19 of the FARS Computer
  57.  * Software-Restricted Rights clause.
  58.  *
  59.  * Use, duplication, or disclosure by the Government is subject to
  60.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  61.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  62.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  63.  * P.O. Box 2328, Corvallis, Oregon 97339.
  64.  *
  65.  * This computer software and information is distributed with "restricted
  66.  * rights."  Use, duplication or disclosure is subject to restrictions as
  67.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  68.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  69.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  70.  * then the "Alternate III" clause applies.
  71.  *
  72.  **************************************************************************/
  73.  
  74. #include <stdcomp.h>
  75.  
  76. #ifndef RWSTD_NO_NEW_HEADER
  77. #include <cstddef>
  78. #include <cstdlib>
  79. #include <new>
  80. #else
  81. #include <new.h>
  82. #include <stddef.h>
  83. #include <stdlib.h>
  84. #endif
  85.  
  86. #include <limits>
  87.  
  88. #ifdef RW_STD_IOSTREAM
  89. #include <iostream>
  90. #else
  91. #include <iostream.h>
  92. #endif
  93.  
  94. #include <iterator>
  95. #include <utility>
  96.  
  97. #ifdef RWSTD_MULTI_THREAD
  98. #include <stdmutex.h>
  99. #endif
  100.  
  101. #ifndef RWSTD_NO_NAMESPACE
  102. namespace std {
  103. #endif
  104.  
  105. #ifdef RWSTD_NO_NEW_DECL
  106. inline void* operator new (size_t, void* p) { return p; }
  107. #endif
  108.  
  109. //
  110. // Raw storage iterator.
  111. //
  112.  
  113. template <class OutputIterator, class T>
  114. class raw_storage_iterator : public output_iterator
  115. {
  116.   protected:
  117.     OutputIterator iter;
  118.   public:
  119.     explicit raw_storage_iterator (OutputIterator x) : iter(x) {}
  120.     raw_storage_iterator<OutputIterator, T>& operator* () { return *this; }
  121.     raw_storage_iterator<OutputIterator, T>& operator= (const T& element)
  122.     {
  123.         construct(iter, element); return *this;
  124.     }
  125.     raw_storage_iterator<OutputIterator, T>& operator++ ()
  126.     {
  127.         ++iter; return *this;
  128.     }
  129.     raw_storage_iterator<OutputIterator, T> operator++ (int)
  130.     {
  131.         raw_storage_iterator<OutputIterator, T> tmp = *this;
  132.         ++iter;
  133.         return tmp;
  134.     }
  135. };
  136.  
  137. //
  138. // Memory handling primitives.
  139. //
  140.  
  141. template <class T>
  142. inline T* allocate (int size, T*)
  143. {
  144. #ifndef RWSTD_NO_NAMESPACE
  145.     T* tmp = (T*)(std::operator new((unsigned int)(size * sizeof(T))));
  146. #else
  147.     T* tmp = (T*)(::operator new((unsigned int)(size * sizeof(T))));
  148. #endif
  149.     if (tmp == 0)
  150.     {
  151.         cerr << "out of memory" << endl;
  152.         exit(1);
  153.     }
  154.     return tmp;
  155. }
  156.  
  157. #ifndef RWSTD_NO_ARG_MATCH
  158. template <class T>
  159. inline T* allocate (long size, T*)
  160. {
  161. #ifndef RWSTD_NO_NAMESPACE
  162.     T* tmp = (T*)(std::operator new((unsigned long)(size * sizeof(T))));
  163. #else
  164.     T* tmp = (T*)(::operator new((unsigned long)(size * sizeof(T))));
  165. #endif
  166.     if (tmp == 0)
  167.     {
  168.         cerr << "out of memory" << endl;
  169.         exit(1);
  170.     }
  171.     return tmp;
  172. }
  173. #endif
  174.  
  175. template <class T>
  176. inline void deallocate (T* buffer)
  177. {
  178. #ifndef RWSTD_NO_NAMESPACE
  179.     std::operator delete(buffer);
  180. #else
  181.     ::operator delete(buffer);
  182. #endif
  183. }
  184.  
  185. template <class T1, class T2>
  186. inline void construct (T1* p, const T2& value)
  187. {
  188.     new (p) T1(value);
  189. }
  190.  
  191. #if defined(RWSTD_NO_DESTROY_NONBUILTIN)
  192. template <class T> struct __FS : public T
  193. {
  194.     //
  195.     // Calls destructor, but does not free the space.
  196.     //
  197.     void operator delete (void*) {;}
  198. };
  199. #endif
  200.  
  201. template <class T>
  202. inline void destroy (T* pointer)
  203. {
  204. #if defined(RWSTD_NO_DESTROY_NONBUILTIN)
  205.     delete (__FS<T>*) (pointer);
  206. #else
  207.     pointer->~T();
  208. #endif
  209. }
  210.  
  211. template <class Pointer>
  212. void destroy (Pointer first, Pointer last)
  213. {
  214.     while (first != last)
  215.     {
  216.         destroy(first);
  217.         ++first;
  218.     }
  219. }
  220.  
  221. #ifdef RWSTD_FAST_TEMP_BUF
  222.  
  223. #ifndef __stl_buffer_size
  224. #define __stl_buffer_size 16384  /* 16k */
  225. #endif
  226.  
  227. extern char __stl_temp_buffer[__stl_buffer_size];
  228.  
  229. #ifdef RWSTD_MULTI_THREAD
  230. extern RWSTDMutex __stl_temp_buffer_mutex;
  231. extern bool       __stl_temp_buffer_being_used;
  232. #endif
  233.  
  234. template <class T>
  235. pair<T*, int> get_temporary_buffer (int len, T*)
  236. {
  237.     while (len > __stl_buffer_size / sizeof(T))
  238.     {
  239. #ifndef RWSTD_NO_NAMESPACE
  240.         T* tmp = (T*)(std::operator new((unsigned int)len * sizeof(T)));
  241. #else
  242.         T* tmp = (T*)(   ::operator new((unsigned int)len * sizeof(T)));
  243. #endif
  244.         if (tmp)
  245.         {
  246.             pair<T*, int> result(tmp, len);
  247.             return result;
  248.         }
  249.         len = len / 2;
  250.     }
  251.  
  252. #ifdef RWSTD_MULTI_THREAD
  253.     RWSTDGuard guard(__stl_temp_buffer_mutex);
  254.  
  255.     if (__stl_temp_buffer_being_used)
  256.     {
  257. #ifndef RWSTD_NO_NAMESPACE
  258.         T* tmp = (T*)(std::operator new((unsigned int)len * sizeof(T)));
  259. #else
  260.         T* tmp = (T*)(   ::operator new((unsigned int)len * sizeof(T)));
  261. #endif
  262.         pair<T*,int> result(tmp, len);
  263.         return result;
  264.     }
  265.     else
  266.     {
  267.         __stl_temp_buffer_being_used = true;
  268.         pair<T*, int> result((T*) __stl_temp_buffer,
  269.                              (int) (__stl_buffer_size / sizeof(T)));
  270.         return result;
  271.     }
  272. #else
  273.     pair<T*, int> result((T*) __stl_temp_buffer,
  274.                          (int) (__stl_buffer_size / sizeof(T)));
  275.     return result;
  276. #endif /*RWSTD_MULTI_THREAD*/
  277. }
  278.  
  279. template <class T>
  280. inline void return_temporary_buffer (T* p)
  281. {
  282. #ifdef RWSTD_MULTI_THREAD
  283.     RWSTDGuard guard(__stl_temp_buffer_mutex);
  284.  
  285.     if ((char*)(p) != __stl_temp_buffer)
  286.         deallocate(p);
  287.     else
  288.         __stl_temp_buffer_being_used = false;
  289. #else
  290.     if ((char*)(p) != __stl_temp_buffer)
  291.         deallocate(p);
  292. #endif /*RWSTD_MULTI_THREAD*/
  293. }
  294.  
  295. #else
  296.  
  297. template <class T>
  298. pair<T*, int> get_temporary_buffer (int len, T*)
  299. {
  300. #ifndef RWSTD_NO_NAMESPACE
  301.     T* tmp = (T*)(std::operator new((unsigned int)len * sizeof(T)));
  302. #else
  303.     T* tmp = (T*)(   ::operator new((unsigned int)len * sizeof(T)));
  304. #endif
  305.     pair<T*,int> result(tmp, len);
  306.     return result;
  307. }
  308.  
  309. template <class T>
  310. inline void return_temporary_buffer (T* p)
  311. {
  312.     deallocate(p);
  313. }
  314.  
  315. #endif /*RWSTD_FAST_TEMP_BUF*/
  316.  
  317. #ifndef RWSTD_NO_ARG_MATCH
  318. template <class T>
  319. pair<T*, long> get_temporary_buffer (long len, T* p)
  320. {
  321.     if (len > INT_MAX/sizeof(T))
  322.         len = INT_MAX/sizeof(T);
  323.     pair<T*, int> tmp = get_temporary_buffer((int)len, p);
  324.     return pair<T*, long>(tmp.first, (long)(tmp.second));
  325. }
  326. #endif
  327.  
  328. #if defined(RWSTD_NO_DESTROY_BUILTIN) || defined(RWSTD_NO_DESTROY_NONBUILTIN)
  329. //
  330. // Some specializations of STL destroy for builtin types.
  331. //
  332. inline void destroy (void*)             {;}
  333. inline void destroy (char*)             {;}
  334. inline void destroy (unsigned char*)    {;}
  335. inline void destroy (short*)            {;}
  336. inline void destroy (unsigned short*)   {;}
  337. inline void destroy (int*)              {;}
  338. inline void destroy (unsigned int*)     {;}
  339. inline void destroy (long*)             {;}
  340. inline void destroy (unsigned long*)    {;}
  341. inline void destroy (float*)            {;}
  342. inline void destroy (double*)           {;}
  343. inline void destroy (long double*)      {;}
  344. inline void destroy (void**)            {;}
  345. inline void destroy (char**)            {;}
  346. inline void destroy (unsigned char**)   {;}
  347. inline void destroy (short**)           {;}
  348. inline void destroy (unsigned short**)  {;}
  349. inline void destroy (int**)             {;}
  350. inline void destroy (unsigned int**)    {;}
  351. inline void destroy (long**)            {;}
  352. inline void destroy (unsigned long**)   {;}
  353. inline void destroy (float**)           {;}
  354. inline void destroy (double**)          {;}
  355. inline void destroy (long double**)     {;}
  356. inline void destroy (void***)           {;}
  357. inline void destroy (char***)           {;}
  358. inline void destroy (unsigned char***)  {;}
  359. inline void destroy (short***)          {;}
  360. inline void destroy (unsigned short***) {;}
  361. inline void destroy (int***)            {;}
  362. inline void destroy (unsigned int***)   {;}
  363. inline void destroy (long***)           {;}
  364. inline void destroy (unsigned long***)  {;}
  365. inline void destroy (float***)          {;}
  366. inline void destroy (double***)         {;}
  367. inline void destroy (long double***)    {;}
  368. #ifndef RWSTD_NO_BOOL
  369. inline void destroy (bool*)             {;}
  370. inline void destroy (bool**)            {;}
  371. inline void destroy (bool***)           {;}
  372. #endif
  373. #ifndef RWSTD_NO_OVERLOAD_WCHAR
  374. inline void destroy (wchar_t*)          {;}
  375. inline void destroy (wchar_t**)         {;}
  376. inline void destroy (wchar_t***)        {;}
  377. #endif
  378. #endif /*RWSTD_NO_DESTROY_BUILTIN || RWSTD_NO_DESTROY_NONBUILTIN*/
  379.  
  380. //
  381. // The default allocator.
  382. //
  383. // Note that this is the old allocator, not the one defined in the
  384. // 28 April 1995 WP.  There aren't any compilers that implement member
  385. // class templates, that we're aware of, yet.
  386. //
  387.  
  388. template <class T>
  389. class allocator
  390. {
  391.   public:
  392.     typedef T         value_type;
  393.     typedef T*        pointer;
  394.     typedef const T*  const_pointer;
  395.     typedef T&        reference;
  396.     typedef const T&  const_reference;
  397.     typedef size_t    size_type;
  398.     typedef ptrdiff_t difference_type;
  399.  
  400.     pointer allocate (size_type n = 0)
  401.     {
  402. #ifndef RWSTD_NO_NAMESPACE
  403.         return std::allocate((difference_type)n, (pointer)0);
  404. #else
  405.         return ::allocate((difference_type)n, (pointer)0);
  406. #endif
  407.     }
  408. #ifndef RWSTD_NO_NAMESPACE
  409.     void deallocate (pointer p) { std::deallocate(p); }
  410. #else
  411.     void deallocate (pointer p) { ::deallocate(p); }
  412. #endif
  413.     pointer address (reference x) { return (pointer)&x; }
  414.     const_pointer const_address (const_reference x)
  415.     {
  416.         return (const_pointer)&x;
  417.     }
  418.     size_type init_page_size ()
  419.     {
  420.         return max(size_type(1), size_type(4096/sizeof(T)));
  421.     }
  422.     size_type max_size () const
  423.     {
  424.         return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
  425.     }
  426. };
  427.  
  428. //
  429. // A specialization.
  430. //
  431.  
  432. class allocator<void>
  433. {
  434. public:
  435.     typedef void* pointer;
  436. };
  437.  
  438. //
  439. // Specialized algorithms.
  440. //
  441.  
  442. template <class InputIterator, class ForwardIterator>
  443. ForwardIterator uninitialized_copy (InputIterator first, InputIterator last,
  444.                                     ForwardIterator result)
  445. {
  446.     while (first != last) construct(&*result++, *first++);
  447.     return result;
  448. }
  449.  
  450. template <class ForwardIterator, class T>
  451. void uninitialized_fill (ForwardIterator first, ForwardIterator last,
  452.                          const T& x)
  453. {
  454.     while (first != last) construct(&*first++, x);
  455. }
  456.  
  457. template <class ForwardIterator, class Size, class T>
  458. ForwardIterator uninitialized_fill_n (ForwardIterator first, Size n, const T& x)
  459. {
  460.     while (n--) construct(&*first++, x);
  461.     return first;
  462. }
  463.  
  464. //
  465. // Template auto_ptr holds onto a pointer obtained via new and deletes that
  466. // object when it itself is destroyed (such as when leaving block scope).
  467. //
  468. // It can be used to make calls to new() exception safe.
  469. //
  470.  
  471. template<class X> class auto_ptr
  472. {
  473.   public:
  474.     //
  475.     // construct/copy/destroy
  476.     //
  477.     explicit auto_ptr (X* p = 0) : the_p(p)           {}
  478.     auto_ptr (auto_ptr<X>& a)    : the_p(a.release()) {}
  479.     void operator= (auto_ptr<X>& rhs) { reset(rhs.release()); }
  480.     ~auto_ptr () { delete the_p; }
  481.     //
  482.     // members
  483.     //
  484.     X& operator*  ()        const { return *the_p;   }
  485.     X* operator-> ()        const { return the_p;    }
  486.     X* get        ()        const { return the_p;    }
  487.     X* release    ()              { return reset(0); }
  488.     X* reset      (X* p = 0)      { X* tmp = the_p; the_p = p; return tmp; }
  489.  
  490. private:
  491.  
  492.     X* the_p;
  493. };
  494.  
  495. #ifndef RWSTD_NO_NAMESPACE
  496. }
  497. #endif
  498.  
  499. #endif /*__STD_MEMORY*/
  500.  
  501. #endif /* __USING_STD_NAMES__ */
  502.