home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / borland / cb / setup / cbuilder / data.z / MEMORY.H < prev    next >
C/C++ Source or Header  |  1997-02-28  |  14KB  |  508 lines

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