home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 May / PCFMay2001.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / Rw / string_r.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  10.2 KB  |  315 lines

  1. #ifndef __STRING_R_H
  2. #define __STRING_R_H
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. // -*- C++ -*-
  5. /***************************************************************************
  6.  *
  7.  * string_ref - Declarations for the Standard Library string_ref classes
  8.  *
  9.  ***************************************************************************
  10.  *
  11.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  12.  *
  13.  * This computer software is owned by Rogue Wave Software, Inc. and is
  14.  * protected by U.S. copyright laws and other laws and by international
  15.  * treaties.  This computer software is furnished by Rogue Wave Software,
  16.  * Inc. pursuant to a written license agreement and may be used, copied,
  17.  * transmitted, and stored only in accordance with the terms of such
  18.  * license and with the inclusion of the above copyright notice.  This
  19.  * computer software or any other copies thereof may not be provided or
  20.  * otherwise made available to any other person.
  21.  *
  22.  * U.S. Government Restricted Rights.  This computer software is provided
  23.  * with Restricted Rights.  Use, duplication, or disclosure by the
  24.  * Government is subject to restrictions as set forth in subparagraph (c)
  25.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  26.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  27.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  28.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  29.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  30.  *
  31.  **************************************************************************/
  32.  
  33. #ifndef __STD_STRING_REF
  34. #define __STD_STRING_REF
  35.  
  36. #include <stdcomp.h>
  37. #include <rw/stddefs.h> 
  38. #include <memory>     // For allocator.
  39. #include <rw/traits>
  40.  
  41. #ifndef _RWSTD_NO_NAMESPACE
  42. namespace std {
  43. #endif
  44.  
  45. //
  46. // Class & Structure Declarations
  47. //
  48.   template< class charT, class traits _RWSTD_COMPLEX_DEFAULT(char_traits<charT>), 
  49.   class Allocator _RWSTD_COMPLEX_DEFAULT(allocator<charT>) >
  50.   class basic_string;
  51.  
  52. #ifndef _RWSTD_NO_NAMESPACE
  53. } namespace __rwstd {
  54. #endif
  55.  
  56.   //
  57.   // __string_noref_rep and __string_noref are used to implement a 
  58.   // non-reference counted string.  Use this implementation when the 
  59.   // overhead from the reference counting (including mutex locking) 
  60.   // overwhelms the advantages.  One example of such a situation would 
  61.   // be in an application that infrequently copies short strings and 
  62.   // only very rarely copies long ones.  Another example would be an 
  63.   // application that makes heavy use of iterators from basic_string, 
  64.   // since any outstanding refernece into the string data nullifies 
  65.   // the advantages of reference counting.
  66.   //
  67.  
  68.   template <class Allocator>
  69.   class _RWSTDExportTemplate __string_noref_rep
  70.   {
  71.   public:
  72.      _EXPLICIT __string_noref_rep(long refs = 0)
  73.       : __refs_((bool)refs), __capacity_(0), __nchars_(0)  {;}
  74.     __string_noref_rep(const __string_noref_rep& r)
  75.       : __refs_((bool)r.__refs_), __capacity_(0), __nchars_(0)  {;}
  76.   
  77.     typedef Allocator                        allocator_type;
  78.     typedef _TYPENAME _RWSTD_ALLOC_SIZE_TYPE size_type;
  79.  
  80.   protected:
  81.  
  82.     bool            __refs_;      // true if null ref, else false
  83.     size_type       __capacity_;  // Size of allocated memory
  84.     size_type       __nchars_;    // Number of actual data values stored
  85.   };
  86.  
  87.   template <class charT, class traits , class Allocator>
  88.   class _RWSTDExportTemplate __string_noref
  89.    : public __string_noref_rep<Allocator>
  90.   {
  91.   public:
  92.     typedef __string_noref_rep<Allocator> __string_ref_rep_type;
  93.     typedef _TYPENAME __string_noref_rep<Allocator>::size_type size_type;
  94.   
  95.     _EXPLICIT __string_noref (long=0) 
  96.     { ; }
  97.  
  98.   private:
  99.     long __references () const
  100.     { 
  101.       return (long)__string_noref_rep<Allocator>::__refs_; 
  102.     }
  103.     void __setRefCount (long r)
  104.     { ; }
  105.     void __addReference ()
  106.     { ; }
  107.     long  __removeReference ()
  108.     { 
  109.       return (long)__string_noref_rep<Allocator>::__refs_;
  110.     }
  111.     size_type length () const
  112.     { 
  113.       return __string_noref_rep<Allocator>::__nchars_; 
  114.     }
  115.     size_type __getCapac () const
  116.     { 
  117.       return __string_noref_rep<Allocator>::__capacity_;
  118.     }
  119.     charT*    data () const
  120.     {
  121.       return (charT*)(this+1);
  122.     }
  123.     charT&   operator[]     (size_type i)      
  124.     { 
  125.       return (_RWSTD_REINTERPRET_CAST(charT*,(this+1)))[i]; 
  126.     }
  127.     const charT&  operator[]     (size_type i) const
  128.     {
  129.       return ((charT*)(this+1))[i];
  130.     }
  131. #ifndef _RWSTD_NO_NAMESPACE
  132.     friend class std::basic_string<charT, traits, Allocator>;
  133. #else
  134.     friend class basic_string<charT, traits, Allocator>;
  135. #endif
  136.   };
  137.   //
  138.   // __string_ref_rep and __string_ref are used to implement a 
  139.   // reference counted string.  Using this class  basic_string 
  140.   // optimizes copying by sharing data whenever possible.  Copies 
  141.   // are only made when absolutely necessary.
  142.   //
  143. #if defined (_RWSTD_MULTI_THREAD) && defined(_RWSTD_ONE_STRING_MUTEX) && defined(_RWSTD_NO_TEST_AND_SET)
  144.   extern  _RWSTDMutex _RWSTDExport __rw_string_mutex;
  145. #endif /* _RWSTD_MULTI_THREAD */
  146.  
  147.   template <class Allocator>
  148.   class _RWSTDExportTemplate __string_ref_rep
  149.   {
  150.   public:
  151.     //  the __refs_ are initialized to 1 because of a problem
  152.     //  where the destructor was being called when it
  153.     //  should not be.
  154.   
  155.     __string_ref_rep()
  156.       : __refs_(0), __capacity_(0), __nchars_(0) {;}
  157.     __string_ref_rep(long x)
  158.       : __refs_(x), __capacity_(0), __nchars_(0) {;}
  159.     __string_ref_rep(const __string_ref_rep& r)
  160.       : __refs_(r.__refs_), __capacity_(0), __nchars_(0)  {;}
  161.   
  162.     typedef Allocator                        allocator_type;
  163.     typedef _TYPENAME _RWSTD_ALLOC_SIZE_TYPE size_type;
  164.  
  165.   protected:
  166.  
  167. #if defined (_RWSTD_MULTI_THREAD) && !defined(_RWSTD_ONE_STRING_MUTEX) && defined(_RWSTD_NO_TEST_AND_SET)
  168.     _RWSTDMutex __mutex_;
  169. #endif /* _RWSTD_MULTI_THREAD */  
  170.  
  171.     long   __refs_;               // (1 less than) number of references
  172.                                   // (-2 if reference counting disabled)
  173.     size_type       __capacity_;  // Size of allocated memory
  174.     size_type       __nchars_;    // Number of actual data values stored
  175.   };
  176.   template <class charT, class traits , class Allocator >
  177.   class _RWSTDExportTemplate __string_ref : public __string_ref_rep<Allocator>
  178.   {
  179.   public:
  180.     typedef __string_ref_rep<Allocator> __string_ref_rep_type;
  181.     typedef _TYPENAME __string_ref_rep<Allocator>::size_type size_type;
  182.   
  183.     _EXPLICIT __string_ref (long initRef = 0) 
  184.       :  __string_ref_rep<Allocator>(initRef - 1)
  185.     { ; }
  186.  
  187.     __string_ref (const __string_ref<charT,traits,Allocator>& ref)
  188.       : __string_ref_rep<Allocator>(ref.__refs_)
  189.     { ; }
  190.  
  191.   private:
  192.     long __references () const 
  193.     { 
  194.       return __string_ref_rep<Allocator>::__refs_+1; 
  195.     }
  196.  
  197.     void __setRefCount (long r)       
  198.     { 
  199.       if (this != _RW_STD::basic_string<charT,traits,Allocator>::__getNullRep())
  200.       {
  201. #ifdef _RWSTD_NO_TEST_AND_SET
  202. #ifdef _RWSTD_MULTI_THREAD
  203. #ifdef _RWSTD_ONE_STRING_MUTEX
  204.          _RWSTDGuard guard(__rw_string_mutex);
  205. #else
  206.          _RWSTDGuard guard(this->__mutex_);
  207. #endif
  208. #endif /* _RWSTD_MULTI_THREAD */
  209. #endif /* _RWSTD_NO_TEST_AND_SET */
  210.         _RWSTD_MT_SET(this->__refs_,r-1);
  211.       }
  212.     }
  213.  
  214.     void __addReference ()
  215.     { 
  216.       if (this != _RW_STD::basic_string<charT,traits,Allocator>::__getNullRep())
  217.       {
  218. #ifdef _RWSTD_NO_TEST_AND_SET
  219. #ifdef _RWSTD_MULTI_THREAD
  220. #ifdef _RWSTD_ONE_STRING_MUTEX
  221.          _RWSTDGuard guard(__rw_string_mutex);
  222. #else
  223.          _RWSTDGuard guard(this->__mutex_);
  224. #endif
  225. #endif /* _RWSTD_MULTI_THREAD */
  226. #endif /* _RWSTD_NO_TEST_AND_SET */
  227.         _RWSTD_MT_INCREMENT(this->__refs_);
  228.       }
  229.     }
  230.     long  __removeReference ()                
  231.     {
  232.       if (this != _RW_STD::basic_string<charT,traits,Allocator>::__getNullRep())
  233.       {
  234. #ifdef _RWSTD_NO_TEST_AND_SET
  235. #ifdef _RWSTD_MULTI_THREAD
  236. #ifdef _RWSTD_ONE_STRING_MUTEX
  237.          _RWSTDGuard guard(__rw_string_mutex);
  238. #else
  239.          _RWSTDGuard guard(this->__mutex_);
  240. #endif
  241. #endif /* _RWSTD_MULTI_THREAD */
  242. #endif /* _RWSTD_NO_TEST_AND_SET */
  243.         return __unSafeRemoveReference();
  244.       }
  245.       else
  246.         return 1;
  247.     }
  248.     long  __unSafeRemoveReference ()                
  249.     {
  250.       if (this != _RW_STD::basic_string<charT,traits,Allocator>::__getNullRep())
  251.       {
  252.         _RWSTD_MT_DECREMENT(this->__refs_);
  253.         return this->__refs_+1;
  254.       }
  255.       else
  256.         return 1;
  257.     }
  258.  
  259.     size_type length () const
  260.     { return __string_ref_rep<Allocator>::__nchars_; }
  261.     size_type __getCapac () const
  262.     { return __string_ref_rep<Allocator>::__capacity_;}
  263.  
  264.     charT*    data () const
  265.     {
  266.       return (charT*)(this+1);
  267.     }
  268.     charT&   operator[]     (size_type i)      
  269.     { 
  270.       return (_RWSTD_REINTERPRET_CAST(charT*,(this+1)))[i]; 
  271.     }
  272.     const charT&  operator[]     (size_type i) const
  273.     {
  274.       return ((charT*)(this+1))[i];
  275.     }
  276. #ifndef _RWSTD_NO_NAMESPACE
  277.     friend class std::basic_string<charT, traits, Allocator>;
  278. #else
  279.     friend class basic_string<charT, traits, Allocator>;
  280. #endif
  281.   };
  282.   //
  283.   // __null_string_ref_rep is used to provide a single empty
  284.   // string reference for all instances of empty strings.
  285.   // This makes empty strings much smaller and avoids unecessary
  286.   // allocations of reference objects.
  287.   //
  288.  
  289.   template <class charT, class traits , class Allocator, 
  290.             class stringRef _RWSTD_COMPLEX_DEFAULT(__string_ref_rep<Allocator>) >
  291.   struct _RWSTDExportTemplate __null_string_ref_rep
  292.   {
  293.     //
  294.     // __ref_hdr_ has to be immediately followed by __eos_char_ !
  295.     //
  296.     stringRef      __ref_hdr_;
  297.     charT          __eos_char_; 
  298.  
  299.     __null_string_ref_rep ()
  300.       : __ref_hdr_(1), __eos_char_(charT(0)) {;}
  301.     __null_string_ref_rep (const __null_string_ref_rep<charT,traits, 
  302.                                                        Allocator,stringRef>& r)
  303.       : __ref_hdr_(r.__ref_hdr_), __eos_char_(charT(0)) {;}
  304.  
  305.   };
  306.  
  307. #ifndef _RWSTD_NO_NAMESPACE
  308. } // End of __rwstd 
  309. #endif
  310.  
  311. #endif // __STD_STRING_REF
  312.  
  313. #pragma option pop
  314. #endif /* __STRING_R_H */
  315.