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

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  CSTRING.H                                                             */
  4. /*                                                                        */
  5. /*                                                                        */
  6. /*------------------------------------------------------------------------*/
  7.  
  8. /* $Copyright: 1993$ */
  9. /* $Revision:   8.1  $ */
  10.  
  11. #ifndef __cplusplus
  12. #error Must use C++ for CSTRING.H
  13. #endif
  14.  
  15. #ifndef __CSTRING_H
  16. #define __CSTRING_H
  17.  
  18. /*------------------------------------------------------------------------*/
  19. /*                                                                        */
  20. /*  This class uses a technique called "copy-on-write".                   */
  21. /*  Multiple instances of a string can refer to the same piece of data    */
  22. /*  so long as it is in a "readonly" situation.  If a string writes to    */
  23. /*  the data, then a copy is automatically made if more than one string   */
  24. /*  is referring to it.                                                   */
  25. /*                                                                        */
  26. /*------------------------------------------------------------------------*/
  27.  
  28. #define STRICT
  29.  
  30. #if !defined(__STRING_H)
  31. #include <string.h>
  32. #endif
  33.  
  34. #if !defined(__REF_H)
  35. #include <ref.h>
  36. #endif
  37.  
  38. #if !defined(__CTYPE_H)
  39. #include <ctype.h>
  40. #endif
  41.  
  42. #if !defined(__STDDEF_H)
  43. #include <stddef.h>
  44. #endif
  45.  
  46. #if !defined(__EXCEPT_H)
  47. #include <except.h>
  48. #endif
  49.  
  50. #if defined(_Windows) && !defined(__WINDOWS_H)
  51. #include <windows.h>
  52. #endif
  53.  
  54.  
  55. #if !defined(RC_INVOKED)
  56.  
  57. #pragma pack(push, 1)
  58.  
  59. #if defined(__BCOPT__)
  60. #if !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
  61. #pragma option -po-     // disable Object data calling convention
  62. #endif
  63. #endif
  64.  
  65. #if !defined(__TINY__)
  66. #pragma option -RT
  67. #endif
  68.  
  69. #pragma option -Vo-     // set standard C++ options
  70.  
  71. #if defined(__STDC__)
  72. #pragma warn -nak
  73. #endif
  74.  
  75. #endif  /* !RC_INVOKED */
  76.  
  77.  
  78. class _EXPCLASS string;
  79. class _EXPCLASS TRegexp;
  80. class _EXPCLASS TSubString;
  81. class _EXPCLASS TStringRef;
  82. class _EXPCLASS istream;
  83. class _EXPCLASS ostream;
  84.  
  85. /*------------------------------------------------------------------------*/
  86. /*                                                                        */
  87. /*  Since inline functions that use throw specifiers                      */
  88. /*  currently end up rather large, we don't use throw                     */
  89. /*  specifiers on them unless you #define USE_THROW_SPECIFIERS.           */
  90. /*                                                                        */
  91. /*------------------------------------------------------------------------*/
  92.  
  93. #if defined( USE_THROW_SPECIFIERS )
  94. #define THROW_NONE                  throw()
  95. #define THROW_XALLOC                throw(xalloc)
  96. #define THROW_OUTOFRANGE            throw( string::outofrange )
  97. #define THROW_XALLOC_LENGTHERROR    throw( xalloc, string::lengtherror )
  98. #define THROW_XALLOC_OUTOFRANGE     throw( xalloc, string::outofrange )
  99. #define THROW_XALLOC_RANGE_LENGTH   \
  100.         throw( xalloc, string::lengtherror, string::outofrange )
  101. #else
  102. #define THROW_NONE
  103. #define THROW_XALLOC
  104. #define THROW_OUTOFRANGE
  105. #define THROW_XALLOC_LENGTHERROR
  106. #define THROW_XALLOC_OUTOFRANGE
  107. #define THROW_XALLOC_RANGE_LENGTH
  108. #endif
  109.  
  110.  
  111. /*------------------------------------------------------------------------*/
  112. /*                                                                        */
  113. /*  string                                                                */
  114. /*                                                                        */
  115. /*------------------------------------------------------------------------*/
  116.  
  117. const size_t NPOS = size_t(-1);
  118.  
  119. class _EXPCLASS string
  120. {
  121.  
  122. public:
  123.  
  124.     //
  125.     // Exceptions
  126.     //
  127.     class outofrange : public xmsg
  128.     {
  129.     public:
  130.         _RTLENTRY outofrange();
  131.     };
  132.  
  133.     class lengtherror : public xmsg
  134.     {
  135.     public:
  136.         _RTLENTRY lengtherror();
  137.     };
  138.  
  139.     //
  140.     // Constructors
  141.     //
  142.  
  143.     _RTLENTRY string() throw( xalloc );
  144.  
  145.     _RTLENTRY string( const string _FAR &s ) throw( xalloc );
  146.     _RTLENTRY string( const string _FAR &s, size_t orig, size_t n = NPOS )
  147.         throw( xalloc );
  148.  
  149.     _RTLENTRY string( const char _FAR *cp ) throw( xalloc, lengtherror );
  150.     _RTLENTRY string( const char _FAR *cp, size_t orig, size_t n = NPOS )
  151.         throw( xalloc, lengtherror );
  152.  
  153.     _RTLENTRY string( char c ) throw (xalloc, string::lengtherror);
  154.     _RTLENTRY string( char c, size_t n ) throw (xalloc, string::lengtherror);
  155.  
  156.     _RTLENTRY string( signed char c ) throw (xalloc, string::lengtherror);
  157.     _RTLENTRY string( signed char c, size_t n ) throw (xalloc, string::lengtherror);
  158.  
  159.     _RTLENTRY string( unsigned char c ) throw (xalloc, string::lengtherror);
  160.     _RTLENTRY string( unsigned char c, size_t n ) throw (xalloc, string::lengtherror);
  161.  
  162.     // non-standard constructors
  163.     _RTLENTRY string( const TSubString _FAR &ss ) throw( xalloc );
  164.  
  165.     // Special far string ctors for small & medium model
  166.     #if (defined( __TINY__ ) || defined( __SMALL__ ) || defined( __MEDIUM__ )) && !defined( __DLL__ )
  167.     _RTLENTRY string( const char __far *cp ) throw (xalloc, string::lengtherror);
  168.     _RTLENTRY string( const char __far *cp, size_t orig, size_t n = NPOS )
  169.         throw( xalloc, lengtherror );
  170.     #endif
  171.  
  172.     // Ctor to make a string from a resource
  173.     #if defined( _Windows )
  174.     _RTLENTRY string( HINSTANCE instance, UINT id, int len = 255 )
  175.         throw( xalloc, lengtherror );
  176.     #endif
  177.  
  178.     //
  179.     // Destructor
  180.     //
  181.     _RTLENTRY ~string() throw();
  182.  
  183.     //
  184.     // Assignment
  185.     //
  186.     string _FAR & _RTLENTRY operator = ( const string _FAR &s ) THROW_XALLOC;
  187.     string _FAR & _RTLENTRY assign( const string _FAR &s ) THROW_XALLOC;
  188.     string _FAR & _RTLENTRY assign( const string _FAR &s,
  189.                                     size_t orig,
  190.                                     size_t n = NPOS ) throw( xalloc );
  191.  
  192.     //
  193.     // Concatenation
  194.     //
  195.     string _FAR & _RTLENTRY operator += ( const string _FAR &s )
  196.         THROW_XALLOC_LENGTHERROR;
  197.     string _FAR & _RTLENTRY append( const string _FAR &s )
  198.         THROW_XALLOC_LENGTHERROR;
  199.     string _FAR & _RTLENTRY append( const string _FAR &s,
  200.                                     size_t orig,
  201.                                     size_t n = NPOS ) throw( xalloc, lengtherror );
  202.  
  203.     string _FAR & _RTLENTRY operator += ( const char _FAR *cp )
  204.         THROW_XALLOC_LENGTHERROR;
  205.     friend string _RTLENTRY _FARFUNC operator + ( const string _FAR &s,
  206.                                                const char _FAR *cp )
  207.         THROW_XALLOC_LENGTHERROR;
  208.     string _FAR & _RTLENTRY append( const char _FAR *cp )
  209.         throw( xalloc, lengtherror );
  210.     string _FAR & _RTLENTRY append( const char _FAR *cp,
  211.                                     size_t orig,
  212.                                     size_t n = NPOS ) throw( xalloc, lengtherror );
  213.  
  214.     string _FAR & _RTLENTRY prepend( const string _FAR &s )
  215.         THROW_XALLOC_LENGTHERROR;
  216.     string _FAR & _RTLENTRY prepend( const string _FAR &s,
  217.                                      size_t orig,
  218.                                      size_t n = NPOS ) THROW_XALLOC_LENGTHERROR;
  219.     string _FAR & _RTLENTRY prepend( const char _FAR *cp )
  220.         THROW_XALLOC_LENGTHERROR;
  221.     string _FAR & _RTLENTRY prepend( const char _FAR *cp,
  222.                                      size_t orig,
  223.                                      size_t n = NPOS ) throw( xalloc, lengtherror );
  224.  
  225.     //
  226.     // Comparison
  227.     //
  228.     int _RTLENTRY compare(const string _FAR &s) const throw();
  229.     int _RTLENTRY compare(const string _FAR &s,
  230.                           size_t orig,
  231.                           size_t n = NPOS ) const throw();
  232.  
  233.     friend int _RTLENTRY operator == ( const string _FAR &s1, const string _FAR &s2 )
  234.         THROW_NONE;
  235.  
  236.     friend int _RTLENTRY operator != ( const string _FAR &s1, const string _FAR &s2 )
  237.         THROW_NONE;
  238.  
  239.     friend int _RTLENTRY operator == ( const string _FAR &s, const char _FAR *cp )
  240.         THROW_NONE;
  241.     friend int _RTLENTRY operator == ( const char _FAR *cp, const string _FAR &s )
  242.         THROW_NONE;
  243.  
  244.     friend int _RTLENTRY operator != ( const string _FAR &s, const char _FAR *cp )
  245.         THROW_NONE;
  246.     friend int _RTLENTRY operator != ( const char _FAR *cp, const string _FAR &s )
  247.         THROW_NONE;
  248.  
  249.     friend int _RTLENTRY operator <  ( const string _FAR &s1, const string _FAR &s2 )
  250.         THROW_NONE;
  251.     friend int _RTLENTRY operator <  ( const string _FAR &s, const char _FAR *cp )
  252.         THROW_NONE;
  253.     friend int _RTLENTRY operator <  ( const char _FAR *cp, const string _FAR &s )
  254.         THROW_NONE;
  255.  
  256.     friend int _RTLENTRY operator <= ( const string _FAR &s1, const string _FAR &s2 )
  257.         THROW_NONE;
  258.     friend int _RTLENTRY operator <= ( const string _FAR &s, const char _FAR *cp )
  259.         THROW_NONE;
  260.     friend int _RTLENTRY operator <= ( const char _FAR *cp, const string _FAR &s )
  261.         THROW_NONE;
  262.  
  263.     friend int _RTLENTRY operator >  ( const string _FAR &s1, const string _FAR &s2 )
  264.         THROW_NONE;
  265.     friend int _RTLENTRY operator >  ( const string _FAR &s, const char _FAR *cp )
  266.         THROW_NONE;
  267.     friend int _RTLENTRY operator >  ( const char _FAR *cp, const string _FAR &s )
  268.         THROW_NONE;
  269.  
  270.     friend int _RTLENTRY operator >= ( const string _FAR &s1, const string _FAR &s2 )
  271.         THROW_NONE;
  272.     friend int _RTLENTRY operator >= ( const string _FAR &s, const char _FAR *cp )
  273.         THROW_NONE;
  274.     friend int _RTLENTRY operator >= ( const char _FAR *cp, const string _FAR &s )
  275.         THROW_NONE;
  276.  
  277.     //
  278.     // Insertion at some position
  279.     //
  280.     string _FAR & _RTLENTRY insert( size_t pos, const string _FAR &s )
  281.         throw( xalloc, outofrange, lengtherror );
  282.     string _FAR & _RTLENTRY insert( size_t pos,
  283.                                     const string _FAR &s,
  284.                                     size_t orig,
  285.                                     size_t n = NPOS ) throw( xalloc, outofrange, lengtherror );
  286.  
  287.     //
  288.     // Removal
  289.     //
  290.     string _FAR & _RTLENTRY remove( size_t pos ) THROW_XALLOC_OUTOFRANGE;
  291.     string _FAR & _RTLENTRY remove( size_t pos, size_t n )
  292.         throw( xalloc, outofrange );
  293.  
  294.     //
  295.     // Replacement at some position
  296.     //
  297.     string _FAR & _RTLENTRY replace( size_t pos, size_t n, const string _FAR &s )
  298.         THROW_XALLOC_RANGE_LENGTH;
  299.     string _FAR & _RTLENTRY replace( size_t pos,
  300.                                      size_t n1,
  301.                                      const string _FAR &s,
  302.                                      size_t orig,
  303.                                      size_t n2 = NPOS ) throw( xalloc, outofrange, lengtherror );
  304.  
  305.     //
  306.     // Subscripting
  307.     //
  308.     char _RTLENTRY get_at( size_t pos ) const THROW_OUTOFRANGE;
  309.     void _RTLENTRY put_at( size_t pos, char c ) THROW_OUTOFRANGE;
  310.  
  311.     char _FAR & _RTLENTRY operator[]( size_t pos ) THROW_OUTOFRANGE;
  312.     char _FAR & _RTLENTRY operator()( size_t pos ) throw( outofrange );
  313.     TSubString _RTLENTRY operator()( size_t start, size_t len ) THROW_NONE;
  314.     TSubString _RTLENTRY operator()( const TRegexp _FAR &re ) THROW_NONE;
  315.     TSubString _RTLENTRY operator()( const TRegexp _FAR &re, size_t start ) throw();
  316.  
  317.     char _RTLENTRY operator[]( size_t pos ) const THROW_OUTOFRANGE;
  318.     char _RTLENTRY operator()( size_t pos ) const THROW_OUTOFRANGE;
  319.     const TSubString _RTLENTRY operator()( size_t start, size_t len ) const throw();
  320.     const TSubString _RTLENTRY operator()( const TRegexp _FAR &pat ) const THROW_NONE;
  321.     const TSubString _RTLENTRY operator()( const TRegexp _FAR &pat, size_t start )
  322.         const throw();
  323.  
  324.     //
  325.     // Searching
  326.     //
  327.     size_t _RTLENTRY find( const string _FAR &s ) const THROW_NONE;
  328.     size_t _RTLENTRY find( const string _FAR &s, size_t pos ) const throw();
  329.     size_t _RTLENTRY rfind( const string _FAR &s ) const THROW_NONE;
  330.     size_t _RTLENTRY rfind( const string _FAR &s, size_t pos ) const throw();
  331.  
  332.     int _RTLENTRY contains( const char _FAR *pat ) const throw();
  333.     int _RTLENTRY contains(const string _FAR &s) const THROW_NONE;
  334.     size_t _RTLENTRY find( const TRegexp _FAR &pat, size_t i = 0 ) const throw();
  335.     size_t _RTLENTRY find( const TRegexp _FAR &pat, size_t _FAR *ext, size_t i = 0 )
  336.         const throw();
  337.  
  338.     //
  339.     // Substring
  340.     //
  341.     string _RTLENTRY substr( size_t pos ) const
  342.         throw( xalloc, outofrange );
  343.     string _RTLENTRY substr( size_t pos, size_t n ) const
  344.         throw( xalloc, outofrange );
  345.  
  346.     TSubString _RTLENTRY substring( const char _FAR *cp ) THROW_NONE;
  347.     const TSubString _RTLENTRY substring( const char _FAR *cp )
  348.         const THROW_NONE;
  349.     TSubString _RTLENTRY substring( const char _FAR *cp, size_t start ) throw();
  350.     const TSubString _RTLENTRY substring( const char _FAR *cp, size_t start )
  351.         const throw();
  352.  
  353.     //
  354.     // Character set searching
  355.     //
  356.     size_t _RTLENTRY find_first_of( const string _FAR &s ) const THROW_NONE;
  357.     size_t _RTLENTRY find_first_of( const string _FAR &s, size_t pos ) const throw();
  358.     size_t _RTLENTRY find_first_not_of( const string _FAR &s ) const THROW_NONE;
  359.     size_t _RTLENTRY find_first_not_of( const string _FAR &s, size_t pos )
  360.         const throw();
  361.     size_t _RTLENTRY find_last_of( const string _FAR &s ) const THROW_NONE;
  362.     size_t _RTLENTRY find_last_of( const string _FAR &s, size_t pos ) const throw();
  363.     size_t _RTLENTRY find_last_not_of( const string _FAR &s ) const THROW_NONE;
  364.     size_t _RTLENTRY find_last_not_of( const string _FAR &s, size_t pos )
  365.         const throw();
  366.  
  367.     //
  368.     // Miscellaneous
  369.     //
  370.     size_t _RTLENTRY length() const THROW_NONE;
  371.     size_t _RTLENTRY copy( char _FAR *cb, size_t n ) throw( outofrange );
  372.     size_t _RTLENTRY copy( char _FAR *cb, size_t n, size_t pos ) throw( outofrange );
  373.     const char _FAR * _RTLENTRY c_str() const THROW_NONE;
  374.     size_t _RTLENTRY reserve() const THROW_NONE;
  375.     void _RTLENTRY reserve( size_t ic ) throw( xalloc, outofrange );
  376.  
  377.     string _RTLENTRY copy() const throw( xalloc );    // Distinct copy of self.
  378.  
  379.  
  380.     // Static member functions:
  381.     static int _RTLENTRY set_case_sensitive( int tf = 1 );
  382.     static int _RTLENTRY set_paranoid_check( int ck = 1 );
  383.     static int _RTLENTRY skip_whitespace( int sk = 1 );
  384.     static size_t _RTLENTRY initial_capacity( size_t ic = 63 );
  385.     static size_t _RTLENTRY resize_increment( size_t ri = 64 );
  386.     static size_t _RTLENTRY max_waste( size_t mw = 63 );
  387.  
  388.     static int _RTLENTRY get_case_sensitive_flag();
  389.     static int _RTLENTRY get_paranoid_check_flag();
  390.     static int _RTLENTRY get_skip_whitespace_flag();
  391.     static size_t _RTLENTRY get_initial_capacity();
  392.     static size_t _RTLENTRY get_resize_increment();
  393.     static size_t _RTLENTRY get_max_waste();
  394.  
  395.     enum StripType { Leading, Trailing, Both };
  396.  
  397.     // Non-static member functions:
  398.     unsigned _RTLENTRY hash() const;
  399.     int      _RTLENTRY is_null() const;
  400.     istream _FAR & _RTLENTRY read_file( istream _FAR &is );
  401.     istream _FAR & _RTLENTRY read_string( istream _FAR &is );
  402.     istream _FAR & _RTLENTRY read_line( istream _FAR &is );
  403.     istream _FAR & _RTLENTRY read_to_delim( istream _FAR &is, char delim = '\n' );
  404.     istream _FAR & _RTLENTRY read_token( istream _FAR &is );
  405.     void       _RTLENTRY resize( size_t m );
  406.     TSubString _RTLENTRY strip( StripType s = Trailing, char c = ' ' );
  407.     void       _RTLENTRY to_lower();
  408.     void       _RTLENTRY to_upper();
  409.  
  410.     #if defined( _Windows )
  411.     void _RTLENTRY ansi_to_oem() THROW_NONE;
  412.     void _RTLENTRY oem_to_ansi() THROW_NONE;
  413.     #endif
  414.  
  415. protected:
  416.  
  417.     int  _RTLENTRY valid_element( size_t pos ) const THROW_NONE;
  418.     int  _RTLENTRY valid_index( size_t pos ) const THROW_NONE;
  419.  
  420.     void _RTLENTRY assert_element( size_t pos ) const throw( outofrange );
  421.     void _RTLENTRY assert_index( size_t pos ) const throw( outofrange );
  422.  
  423.     _RTLENTRY string( const string _FAR &s, const char _FAR *cb );
  424.     void _RTLENTRY cow();
  425.  
  426. private:
  427.  
  428.     TStringRef _FAR *p;
  429.  
  430.     static int case_sensitive;
  431.     static int paranoid_check;
  432.     static int skip_white;
  433.     static size_t initial_capac;
  434.     static size_t resize_inc;
  435.     static size_t freeboard;
  436.  
  437. private:
  438.  
  439.     friend class _EXPCLASS TSubString;
  440.     friend class _EXPCLASS TStringRef;
  441.  
  442.     void _RTLENTRY clone();
  443.     size_t _RTLENTRY find_case_index( const char _FAR *cb,
  444.                             size_t start,
  445.                             size_t _FAR &patl) const;
  446.     size_t _RTLENTRY rfind_case_index( const char _FAR *cb,
  447.                              size_t start,
  448.                              size_t _FAR &patl) const;
  449.     size_t _RTLENTRY find_index(const char _FAR *,
  450.                       size_t start,
  451.                       size_t _FAR & patl) const;
  452.     size_t _RTLENTRY rfind_index(const char _FAR *,
  453.                        size_t start,
  454.                        size_t _FAR & patl) const;
  455.     unsigned _RTLENTRY hash_case() const;
  456.  
  457. };
  458.  
  459. #if defined( BI_OLDNAMES )
  460. #define BI_String string
  461. #endif
  462.  
  463. /*------------------------------------------------------------------------*/
  464. /*                                                                        */
  465. /*  Related global functions                                              */
  466. /*                                                                        */
  467. /*------------------------------------------------------------------------*/
  468.  
  469. istream _FAR &
  470. _RTLENTRY _FARFUNC operator >> ( istream _FAR &is, string _FAR &s );
  471.  
  472. ostream _FAR &
  473. _RTLENTRY _FARFUNC operator << ( ostream _FAR &os, const string _FAR &s );
  474.  
  475. istream _FAR &
  476. _RTLENTRY _FARFUNC getline( istream _FAR &is, string _FAR &s );
  477.  
  478. istream _FAR &
  479. _RTLENTRY _FARFUNC getline( istream _FAR &is, string _FAR &s, char c );
  480.  
  481. string _RTLENTRY _FARFUNC to_lower( const string _FAR &s ) throw();
  482. string _RTLENTRY _FARFUNC to_upper( const string _FAR &s ) throw();
  483. string _RTLENTRY _FARFUNC operator + ( const char _FAR *cp,
  484.                                     const string _FAR & s)
  485.                                     throw( xalloc, string::lengtherror );
  486. string _RTLENTRY _FARFUNC operator + ( const string _FAR &s1,
  487.                                     const string _FAR &s2 )
  488.                                     THROW_XALLOC_LENGTHERROR;
  489.  
  490. /*------------------------------------------------------------------------*/
  491. /*                                                                        */
  492. /*  TStringRef                                                            */
  493. /*                                                                        */
  494. /*  This is the dynamically allocated part of a string.                   */
  495. /*  It maintains a reference count.                                       */
  496. /*  There are no public member functions.                                 */
  497. /*                                                                        */
  498. /*------------------------------------------------------------------------*/
  499.  
  500. class _EXPCLASS TStringRef : public TReference
  501. {
  502.  
  503.     friend class _EXPCLASS string;
  504.     friend class _EXPCLASS TSubString;
  505.  
  506.     //
  507.     // Data
  508.     //
  509.     char _FAR *array;
  510.     size_t nchars;
  511.     size_t capacity;
  512.  
  513.     //
  514.     // State flags
  515.     //
  516.     enum {
  517.         MemReserved = 1     // indicates that reserve() has been
  518.                             // called on this string
  519.         };
  520.     unsigned flags;
  521.  
  522.     //
  523.     // Constructors
  524.     //
  525.     _RTLENTRY TStringRef( char c, size_t n );
  526.     _RTLENTRY TStringRef( const char _FAR *str1, size_t count1,
  527.                 const char _FAR *str2, size_t count2,
  528.                 size_t extra );
  529.  
  530.     // Special far TStringRef ctor for small data models
  531.     #if (defined( __TINY__ ) || defined( __SMALL__ ) || defined( __MEDIUM__ )) && !defined( __DLL__ )
  532.     _RTLENTRY TStringRef( const char __far*, size_t n = NPOS );
  533.     #endif
  534.  
  535.     //
  536.     // Ctor to make a TStringRef from a resource
  537.     //
  538.     #if defined( _Windows )
  539.     _RTLENTRY TStringRef( HINSTANCE instance, UINT id, int len = 255 )
  540.          throw( xalloc, string::lengtherror );
  541.     #endif
  542.  
  543.     //
  544.     // Destructor
  545.     //
  546.     _RTLENTRY ~TStringRef() throw();
  547.  
  548.     //
  549.     // Miscellaneous
  550.     //
  551.     void _RTLENTRY reserve( size_t ic ) throw( xalloc, string::outofrange );
  552.     void _RTLENTRY check_freeboard() throw();
  553.     void _RTLENTRY grow_to( size_t n ) throw( xalloc, string::lengtherror );
  554.     void _RTLENTRY read_to_delim( istream _FAR &is, char delim ) throw( xalloc );
  555.     void _RTLENTRY read_token( istream _FAR &is ) throw( xalloc );
  556.     static size_t _RTLENTRY round_capacity( size_t cap ) throw();
  557.     void _RTLENTRY splice( size_t start, size_t extent,
  558.                  const char _FAR *cp, size_t n )
  559.         throw( xalloc, string::lengtherror );
  560.  
  561. };
  562.  
  563. #if defined( BI_OLDNAMES )
  564. #define BI_StringRef TStringRef
  565. #endif
  566.  
  567. /*------------------------------------------------------------------------*/
  568. /*                                                                        */
  569. /*  TSubString                                                            */
  570. /*                                                                        */
  571. /*  The TSubString class allows selected elements to be addressed.        */
  572. /*  There are no public constructors.                                     */
  573. /*                                                                        */
  574. /*------------------------------------------------------------------------*/
  575.  
  576. class _EXPCLASS TSubString
  577. {
  578.  
  579. public:
  580.  
  581.     //
  582.     // Assignment
  583.     //
  584.     TSubString _FAR & _RTLENTRY operator = ( const string _FAR &s ) throw();
  585.  
  586.     //
  587.     // Comparison
  588.     //
  589.     int _RTLENTRY operator == ( const char _FAR *cp ) const throw();
  590.     int _RTLENTRY operator == ( const string _FAR &s ) const THROW_NONE;
  591.     int _RTLENTRY operator != ( const char _FAR *cp ) const THROW_NONE;
  592.     int _RTLENTRY operator != ( const string _FAR & str ) const THROW_NONE;
  593.  
  594.     //
  595.     // Subscripting
  596.     //
  597.     char _RTLENTRY get_at( size_t pos ) const THROW_OUTOFRANGE;
  598.     void _RTLENTRY put_at( size_t pos, char c ) THROW_OUTOFRANGE;
  599.  
  600.     char _FAR & _RTLENTRY operator[]( size_t pos ) THROW_OUTOFRANGE;
  601.     char _FAR & _RTLENTRY operator()( size_t pos ) throw( string::outofrange );
  602.     char _RTLENTRY operator[]( size_t pos ) const THROW_OUTOFRANGE;
  603.     char _RTLENTRY operator()( size_t pos ) const THROW_OUTOFRANGE;
  604.     size_t _RTLENTRY length() const THROW_NONE;
  605.     int _RTLENTRY start() const THROW_NONE;
  606.     void _RTLENTRY to_lower() throw();
  607.     void _RTLENTRY to_upper() throw();
  608.  
  609.     //
  610.     // Detecting empty strings
  611.     //
  612.     int _RTLENTRY is_null() const THROW_NONE;
  613.     int _RTLENTRY operator!() const THROW_NONE;
  614.  
  615. protected:
  616.  
  617.     void _RTLENTRY assert_element( size_t pos ) const throw( string::outofrange );
  618.     int _RTLENTRY valid_element( size_t pos ) const;
  619.  
  620. private:
  621.  
  622.     friend class _EXPCLASS string;
  623.  
  624.     //
  625.     // Data
  626.     //
  627.     string _FAR *s;
  628.     size_t begin;
  629.     size_t extent;
  630.  
  631.     //
  632.     // Constructor
  633.     //
  634.     _RTLENTRY TSubString( const string _FAR *cp, size_t start, size_t len );
  635.  
  636. };
  637.  
  638. #if defined( BI_OLDNAMES )
  639. #define BI_SubString TSubString
  640. #endif
  641.  
  642. /*------------------------------------------------------------------------*/
  643. /*                                                                        */
  644. /*  string inlines                                                        */
  645. /*                                                                        */
  646. /*------------------------------------------------------------------------*/
  647.  
  648. inline _RTLENTRY string::outofrange::outofrange() :
  649.     xmsg( "String reference out of range" )
  650. {
  651. }
  652.  
  653. inline _RTLENTRY string::lengtherror::lengtherror() :
  654.     xmsg( "String length error" )
  655. {
  656. }
  657.  
  658. inline string _FAR & _RTLENTRY string::operator = ( const string _FAR &s )
  659.     THROW_NONE
  660. {
  661.     return assign( s, 0, NPOS );
  662. }
  663.  
  664. inline string _FAR & _RTLENTRY string::assign( const string _FAR &s )
  665.     THROW_NONE
  666. {
  667.     return assign( s, 0, NPOS );
  668. }
  669.  
  670. inline string _FAR & _RTLENTRY string::operator += ( const string _FAR &s )
  671.     THROW_XALLOC_LENGTHERROR
  672. {
  673.     return append( s, 0, NPOS );
  674. }
  675.  
  676. inline string _FAR & _RTLENTRY string::append( const string _FAR &s )
  677.     THROW_XALLOC_LENGTHERROR
  678. {
  679.     return append(s, 0, NPOS);
  680. }
  681.  
  682. inline string _FAR & _RTLENTRY string::prepend( const char _FAR *cp )
  683.     THROW_XALLOC_LENGTHERROR
  684. {
  685.     return prepend( cp, 0, strlen(cp) );
  686. }
  687.  
  688. inline int _RTLENTRY operator == ( const string _FAR &s1, const string _FAR &s2 )
  689.     THROW_NONE
  690. {
  691.     return s1.compare( s2 ) == 0;
  692. }
  693.  
  694. inline int _RTLENTRY operator != ( const string _FAR &s1, const string _FAR &s2 )
  695.     THROW_NONE
  696. {
  697.     return !(s1==s2);
  698. }
  699.  
  700. inline string _FAR & _RTLENTRY string::remove( size_t pos )
  701.     THROW_XALLOC_OUTOFRANGE
  702. {
  703.     return remove( pos, length() );
  704. }
  705.  
  706. inline string _FAR & _RTLENTRY string::replace( size_t pos,
  707.                                      size_t n,
  708.                                      const string _FAR &s )
  709.     THROW_XALLOC_RANGE_LENGTH
  710. {
  711.     return replace( pos, n, s, 0, NPOS );
  712. }
  713.  
  714. inline char _RTLENTRY string::get_at( size_t pos ) const THROW_OUTOFRANGE
  715. {
  716.     return (*this)[pos];
  717. }
  718.  
  719. inline void _RTLENTRY string::put_at( size_t pos, char c ) THROW_OUTOFRANGE
  720. {
  721.     (*this)[pos] = c;
  722. }
  723.  
  724. inline char _FAR & _RTLENTRY string::operator[]( size_t pos ) THROW_OUTOFRANGE
  725. {
  726.     return (*this)(pos);    // use operator()
  727. }
  728.  
  729. inline TSubString _RTLENTRY string::operator()( size_t start, size_t len ) THROW_NONE
  730. {
  731.     return TSubString( this, start, len );
  732. }
  733.  
  734. inline size_t _RTLENTRY string::find( const string _FAR &s ) const THROW_NONE
  735. {
  736.     return find( s, 0 );
  737. }
  738.  
  739. inline size_t _RTLENTRY string::rfind( const string _FAR &s ) const THROW_NONE
  740. {
  741.     return rfind( s, length() );
  742. }
  743.  
  744. inline size_t _RTLENTRY string::length() const THROW_NONE
  745. {
  746.     return p->nchars;
  747. }
  748.  
  749. inline const char _FAR * _RTLENTRY string::c_str() const THROW_NONE
  750. {
  751.     return p->array;
  752. }
  753.  
  754. inline size_t _RTLENTRY string::reserve() const THROW_NONE
  755. {
  756.     return p->capacity;
  757. }
  758.  
  759. inline void _RTLENTRY string::cow()
  760. {
  761.     if( p->References() > 1 )
  762.         clone();
  763. }
  764.  
  765. inline string _FAR & _RTLENTRY string::operator += ( const char _FAR *cp )
  766.     THROW_XALLOC_LENGTHERROR
  767. {
  768.     return append( cp, 0, strlen(cp) );
  769. }
  770.  
  771. inline string _FAR & _RTLENTRY string::prepend( const string _FAR &s )
  772.     THROW_XALLOC_LENGTHERROR
  773. {
  774.     return prepend( s.c_str() );
  775. }
  776.  
  777. inline string _FAR & _RTLENTRY string::prepend( const string _FAR &s,
  778.                                                 size_t orig,
  779.                                                 size_t n ) THROW_XALLOC_LENGTHERROR
  780. {
  781.     return prepend( s.c_str(), orig, n );
  782. }
  783.  
  784. inline int _RTLENTRY operator == ( const string _FAR &s1, const char _FAR *s2 ) THROW_NONE
  785. {
  786.     return s1.compare(s2) == 0;
  787. }
  788.  
  789. inline int _RTLENTRY operator == ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  790. {
  791.     return string(cp).compare(s) == 0;
  792. }
  793.  
  794. inline int _RTLENTRY operator != ( const string _FAR &s, const char _FAR *cp ) THROW_NONE
  795. {
  796.     return !(s==cp);
  797. }
  798.  
  799. inline int _RTLENTRY operator != ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  800. {
  801.     return !(cp==s);
  802. }
  803.  
  804. inline int _RTLENTRY operator <  ( const string _FAR &s1, const string _FAR &s2 )
  805.     THROW_NONE
  806. {
  807.     return s1.compare(s2) < 0;
  808. }
  809.  
  810. inline int _RTLENTRY operator <  ( const string _FAR &s1, const char _FAR *s2 ) THROW_NONE
  811. {
  812.     return s1.compare(s2) < 0;
  813. }
  814.  
  815. inline int _RTLENTRY operator <  ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  816. {
  817.     return string(cp).compare(s) < 0;
  818. }
  819.  
  820. inline int _RTLENTRY operator <= ( const string _FAR &s1, const string _FAR &s2 )
  821.     THROW_NONE
  822. {
  823.     return s1.compare(s2) <= 0;
  824. }
  825.  
  826. inline int _RTLENTRY operator <= ( const string _FAR &s, const char _FAR *cp ) THROW_NONE
  827. {
  828.     return s.compare(string(cp)) <= 0;
  829. }
  830.  
  831. inline int _RTLENTRY operator <= ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  832. {
  833.     return string(cp).compare(s) <= 0;
  834. }
  835.  
  836. inline int _RTLENTRY operator >  ( const string _FAR &s1, const string _FAR &s2 )
  837.     THROW_NONE
  838. {
  839.     return s1.compare(s2) > 0;
  840. }
  841.  
  842. inline int _RTLENTRY operator >  ( const string _FAR &s, const char _FAR *cp ) THROW_NONE
  843. {
  844.     return s.compare(cp) > 0;
  845. }
  846.  
  847. inline int _RTLENTRY operator >  ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  848. {
  849.     return string(cp).compare(s) > 0;
  850. }
  851.  
  852. inline int _RTLENTRY operator >= ( const string _FAR &s1, const string _FAR &s2 )
  853.     THROW_NONE
  854. {
  855.     return s1.compare(s2) >= 0;
  856. }
  857.  
  858. inline int _RTLENTRY operator >= ( const string _FAR &s, const char _FAR *cp ) THROW_NONE
  859. {
  860.     return s.compare(cp) >= 0;
  861. }
  862.  
  863. inline int _RTLENTRY operator >= ( const char _FAR *cp, const string _FAR &s ) THROW_NONE
  864. {
  865.     return string(cp).compare(s) >= 0;
  866. }
  867.  
  868. inline char _RTLENTRY string::operator[]( size_t pos ) const THROW_OUTOFRANGE
  869. {
  870.     assert_element(pos);
  871.     return p->array[pos];
  872. }
  873.  
  874. inline char _RTLENTRY string::operator()( size_t pos ) const THROW_OUTOFRANGE
  875. {
  876. #if defined( BOUNDS_CHECK )
  877.     assert_element(pos);
  878. #endif
  879.     return p->array[pos];
  880. }
  881.  
  882. inline int _RTLENTRY string::contains( const string _FAR &s ) const THROW_NONE
  883. {
  884.     return contains( s.c_str() );
  885. }
  886.  
  887. inline TSubString _RTLENTRY string::substring( const char _FAR *cp ) THROW_NONE
  888. {
  889.     return substring( cp, 0 );
  890. }
  891.  
  892. inline const TSubString _RTLENTRY string::substring( const char _FAR *cp ) const
  893.     THROW_NONE
  894. {
  895.     return substring( cp, 0 );
  896. }
  897.  
  898. inline size_t _RTLENTRY string::find_first_of( const string _FAR &s ) const THROW_NONE
  899. {
  900.     return find_first_of( s, 0 );
  901. }
  902.  
  903. inline size_t _RTLENTRY string::find_first_not_of( const string _FAR &s ) const THROW_NONE
  904. {
  905.     return find_first_not_of( s, 0 );
  906. }
  907.  
  908. inline size_t _RTLENTRY string::find_last_of( const string _FAR &s ) const THROW_NONE
  909. {
  910.     return find_last_of( s, NPOS );
  911. }
  912.  
  913. inline size_t _RTLENTRY string::find_last_not_of( const string _FAR &s ) const THROW_NONE
  914. {
  915.     return find_last_not_of( s, NPOS );
  916. }
  917.  
  918. inline int _RTLENTRY string::get_case_sensitive_flag()
  919. {
  920.     return case_sensitive;
  921. }
  922.  
  923. inline int _RTLENTRY string::get_paranoid_check_flag()
  924. {
  925.     return paranoid_check;
  926. }
  927.  
  928. inline int _RTLENTRY string::get_skip_whitespace_flag()
  929. {
  930.     return skip_white;
  931. }
  932.  
  933. inline size_t _RTLENTRY string::get_initial_capacity()
  934. {
  935.     return initial_capac;
  936. }
  937.  
  938. inline size_t _RTLENTRY string::get_resize_increment()
  939. {
  940.     return resize_inc;
  941. }
  942.  
  943. inline size_t _RTLENTRY string::get_max_waste()
  944. {
  945.     return freeboard;
  946. }
  947.  
  948. inline int _RTLENTRY string::is_null() const
  949. {
  950.     return *p->array==0;
  951. }
  952.  
  953. #if defined( _Windows )
  954. inline void _RTLENTRY string::ansi_to_oem() THROW_NONE
  955. {
  956.     ::AnsiToOem( p->array, p->array );
  957. }
  958.  
  959. inline void _RTLENTRY string::oem_to_ansi() THROW_NONE
  960. {
  961.     ::OemToAnsi( p->array, p->array );
  962. }
  963. #endif
  964.  
  965. // Check to make sure a string index refers to a valid element
  966. inline int _RTLENTRY string::valid_element( size_t n ) const THROW_NONE
  967. {
  968.     return n < length();
  969. }
  970.  
  971. // Check to make sure a string index is in range
  972. inline int _RTLENTRY string::valid_index( size_t n ) const THROW_NONE
  973. {
  974.     return n <= length();
  975. }
  976.  
  977. // Constructor for internal use only
  978. inline _RTLENTRY string::string( const string _FAR &s, const char _FAR *cp )
  979. {
  980.     p = new TStringRef( s.c_str(), s.length(), cp, cp?strlen(cp):0, 0 );
  981. }
  982.  
  983. inline string _RTLENTRY operator + ( const string _FAR &s,
  984.                                   const char _FAR *cp )
  985.     THROW_XALLOC_LENGTHERROR
  986. {
  987.     return string(s,cp);
  988. }
  989.  
  990. inline string _RTLENTRY operator + ( const string _FAR &s1,
  991.                                   const string _FAR &s2 )
  992.     THROW_XALLOC_LENGTHERROR
  993. {
  994.     return s1 + s2.c_str();
  995. }
  996.  
  997. /*------------------------------------------------------------------------*/
  998. /*                                                                        */
  999. /*  TSubString inlines                                                    */
  1000. /*                                                                        */
  1001. /*------------------------------------------------------------------------*/
  1002.  
  1003. inline int _RTLENTRY TSubString::operator == ( const string _FAR &s ) const THROW_NONE
  1004. {
  1005.     return operator==(s.c_str());
  1006. }
  1007.  
  1008. inline int _RTLENTRY TSubString::operator != ( const char _FAR *cp ) const THROW_NONE
  1009. {
  1010.     return !operator==(cp);
  1011. }
  1012.  
  1013. inline int _RTLENTRY TSubString::operator != ( const string _FAR &s ) const THROW_NONE
  1014. {
  1015.     return !operator==(s.c_str());
  1016. }
  1017.  
  1018. inline char _RTLENTRY TSubString::get_at( size_t pos ) const THROW_OUTOFRANGE
  1019. {
  1020.     return (*this)[pos];
  1021. }
  1022.  
  1023. inline void _RTLENTRY TSubString::put_at( size_t pos, char c ) THROW_OUTOFRANGE
  1024. {
  1025.     (*this)[pos] = c;
  1026. }
  1027.  
  1028. inline char _FAR & _RTLENTRY TSubString::operator[]( size_t pos ) THROW_OUTOFRANGE
  1029. {
  1030.     return (*this)(pos);    // use operator()
  1031. }
  1032.  
  1033. inline char _RTLENTRY TSubString::operator[]( size_t pos ) const
  1034.     THROW_OUTOFRANGE
  1035. {
  1036.     assert_element(pos);
  1037.     return s->p->array[begin+pos];
  1038. }
  1039.  
  1040. inline char _RTLENTRY TSubString::operator()( size_t pos ) const
  1041.     THROW_OUTOFRANGE
  1042. {
  1043. #if defined( BOUNDS_CHECK )
  1044.     assert_element(pos);
  1045. #endif
  1046.     return s->p->array[begin+pos];
  1047. }
  1048.  
  1049. inline size_t _RTLENTRY TSubString::length() const THROW_NONE
  1050. {
  1051.     return extent;
  1052. }
  1053.  
  1054. inline int _RTLENTRY TSubString::start() const THROW_NONE
  1055. {
  1056.     return begin;
  1057. }
  1058.  
  1059. inline int _RTLENTRY TSubString::is_null() const THROW_NONE
  1060. {
  1061.     return begin == NPOS;
  1062. }
  1063.  
  1064. inline int _RTLENTRY TSubString::operator!() const THROW_NONE
  1065. {
  1066.     return begin == NPOS;
  1067. }
  1068.  
  1069. inline int _RTLENTRY TSubString::valid_element( size_t n ) const THROW_NONE
  1070. {
  1071.     return n < length();
  1072. }
  1073.  
  1074. // Private constructor
  1075. inline _RTLENTRY TSubString::TSubString(const string _FAR *sp,
  1076.                               size_t start,
  1077.                               size_t len ) :
  1078.     begin(start),
  1079.     extent(len),
  1080.     s((string _FAR *)sp)
  1081. {
  1082. }
  1083.  
  1084. inline TSubString _RTLENTRY string::operator()( const TRegexp _FAR & r ) THROW_NONE
  1085. {
  1086.     return (*this)(r,0);
  1087. }
  1088.  
  1089. inline const TSubString _RTLENTRY string::operator()( const TRegexp _FAR &r ) const THROW_NONE
  1090. {
  1091.     return (*this)(r,0);
  1092. }
  1093.  
  1094.  
  1095. #if !defined(RC_INVOKED)
  1096.  
  1097. #if defined(__STDC__)
  1098. #pragma warn .nak
  1099. #endif
  1100.  
  1101. #pragma option -Vo.     // restore user C++ options
  1102.  
  1103. #if !defined(__TINY__)
  1104. #pragma option -RT.
  1105. #endif
  1106.  
  1107. #if defined(__BCOPT__)
  1108. #if !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
  1109. #pragma option -po.     // restore Object data calling convention
  1110. #endif
  1111. #endif
  1112.  
  1113. /* restore default packing */
  1114. #pragma pack(pop)
  1115.  
  1116. #endif  /* !RC_INVOKED */
  1117.  
  1118.  
  1119. #endif  // __CSTRING_H
  1120.  
  1121.