Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
/*
2
 * Copyright (c) 1997-1998
3
 * Silicon Graphics Computer Systems, Inc.
4
 *
5
 * Permission to use, copy, modify, distribute and sell this software
6
 * and its documentation for any purpose is hereby granted without fee,
7
 * provided that the above copyright notice appear in all copies and
8
 * that both that copyright notice and this permission notice appear
9
 * in supporting documentation.  Silicon Graphics makes no
10
 * representations about the suitability of this software for any
11
 * purpose.  It is provided "as is" without express or implied warranty.
12
 */
13
 
14
/* NOTE: This is an internal header file, included by other STL headers.
15
 *   You should not attempt to use it directly.
16
 */
17
 
18
// rope<_CharT,_Alloc> is a sequence of _CharT.
19
// Ropes appear to be mutable, but update operations
20
// really copy enough of the data structure to leave the original
21
// valid.  Thus ropes can be logically copied by just copying
22
// a pointer value.
23
 
24
#ifndef __SGI_STL_INTERNAL_ROPE_H
25
# define __SGI_STL_INTERNAL_ROPE_H
26
 
27
# ifdef __GC
28
#   define __GC_CONST const
29
# else
30
#   include 
31
#   define __GC_CONST   // constant except for deallocation
32
# endif
33
# ifdef __STL_SGI_THREADS
34
#    include 
35
# endif
36
 
37
namespace std
38
{
39
 
40
// The _S_eos function is used for those functions that
41
// convert to/from C-like strings to detect the end of the string.
42
 
43
// The end-of-C-string character.
44
// This is what the draft standard says it should be.
45
template 
46
inline _CharT _S_eos(_CharT*) { return _CharT(); }
47
 
48
// Test for basic character types.
49
// For basic character types leaves having a trailing eos.
50
template 
51
inline bool _S_is_basic_char_type(_CharT*) { return false; }
52
template 
53
inline bool _S_is_one_byte_char_type(_CharT*) { return false; }
54
 
55
inline bool _S_is_basic_char_type(char*) { return true; }
56
inline bool _S_is_one_byte_char_type(char*) { return true; }
57
inline bool _S_is_basic_char_type(wchar_t*) { return true; }
58
 
59
// Store an eos iff _CharT is a basic character type.
60
// Do not reference _S_eos if it isn't.
61
template 
62
inline void _S_cond_store_eos(_CharT&) {}
63
 
64
inline void _S_cond_store_eos(char& __c) { __c = 0; }
65
inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; }
66
 
67
// char_producers are logically functions that generate a section of
68
// a string.  These can be convereted to ropes.  The resulting rope
69
// invokes the char_producer on demand.  This allows, for example,
70
// files to be viewed as ropes without reading the entire file.
71
template 
72
class char_producer {
73
    public:
74
        virtual ~char_producer() {};
75
        virtual void operator()(size_t __start_pos, size_t __len,
76
                                _CharT* __buffer) = 0;
77
        // Buffer should really be an arbitrary output iterator.
78
        // That way we could flatten directly into an ostream, etc.
79
        // This is thoroughly impossible, since iterator types don't
80
        // have runtime descriptions.
81
};
82
 
83
// Sequence buffers:
84
//
85
// Sequence must provide an append operation that appends an
86
// array to the sequence.  Sequence buffers are useful only if
87
// appending an entire array is cheaper than appending element by element.
88
// This is true for many string representations.
89
// This should  perhaps inherit from ostream
90
// and be implemented correspondingly, so that they can be used
91
// for formatted.  For the sake of portability, we don't do this yet.
92
//
93
// For now, sequence buffers behave as output iterators.  But they also
94
// behave a little like basic_ostringstream and a
95
// little like containers.
96
 
97
template
98
class sequence_buffer : public output_iterator {
99
    public:
100
        typedef typename _Sequence::value_type value_type;
101
    protected:
102
        _Sequence* _M_prefix;
103
        value_type _M_buffer[_Buf_sz];
104
        size_t     _M_buf_count;
105
    public:
106
        void flush() {
107
            _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count);
108
            _M_buf_count = 0;
109
        }
110
        ~sequence_buffer() { flush(); }
111
        sequence_buffer() : _M_prefix(0), _M_buf_count(0) {}
112
        sequence_buffer(const sequence_buffer& __x) {
113
            _M_prefix = __x._M_prefix;
114
            _M_buf_count = __x._M_buf_count;
115
            copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
116
        }
117
        sequence_buffer(sequence_buffer& __x) {
118
            __x.flush();
119
            _M_prefix = __x._M_prefix;
120
            _M_buf_count = 0;
121
        }
122
        sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {}
123
        sequence_buffer& operator= (sequence_buffer& __x) {
124
            __x.flush();
125
            _M_prefix = __x._M_prefix;
126
            _M_buf_count = 0;
127
            return *this;
128
        }
129
        sequence_buffer& operator= (const sequence_buffer& __x) {
130
            _M_prefix = __x._M_prefix;
131
            _M_buf_count = __x._M_buf_count;
132
            copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
133
            return *this;
134
        }
135
        void push_back(value_type __x)
136
        {
137
            if (_M_buf_count < _Buf_sz) {
138
                _M_buffer[_M_buf_count] = __x;
139
                ++_M_buf_count;
140
            } else {
141
                flush();
142
                _M_buffer[0] = __x;
143
                _M_buf_count = 1;
144
            }
145
        }
146
        void append(value_type* __s, size_t __len)
147
        {
148
            if (__len + _M_buf_count <= _Buf_sz) {
149
                size_t __i = _M_buf_count;
150
                size_t __j = 0;
151
                for (; __j < __len; __i++, __j++) {
152
                    _M_buffer[__i] = __s[__j];
153
                }
154
                _M_buf_count += __len;
155
            } else if (0 == _M_buf_count) {
156
                _M_prefix->append(__s, __s + __len);
157
            } else {
158
                flush();
159
                append(__s, __len);
160
            }
161
        }
162
        sequence_buffer& write(value_type* __s, size_t __len)
163
        {
164
            append(__s, __len);
165
            return *this;
166
        }
167
        sequence_buffer& put(value_type __x)
168
        {
169
            push_back(__x);
170
            return *this;
171
        }
172
        sequence_buffer& operator=(const value_type& __rhs)
173
        {
174
            push_back(__rhs);
175
            return *this;
176
        }
177
        sequence_buffer& operator*() { return *this; }
178
        sequence_buffer& operator++() { return *this; }
179
        sequence_buffer& operator++(int) { return *this; }
180
};
181
 
182
// The following should be treated as private, at least for now.
183
template
184
class _Rope_char_consumer {
185
    public:
186
        // If we had member templates, these should not be virtual.
187
        // For now we need to use run-time parametrization where
188
        // compile-time would do.  Hence this should all be private
189
        // for now.
190
        // The symmetry with char_producer is accidental and temporary.
191
        virtual ~_Rope_char_consumer() {};
192
        virtual bool operator()(const _CharT* __buffer, size_t __len) = 0;
193
};
194
 
195
// First a lot of forward declarations.  The standard seems to require
196
// much stricter "declaration before use" than many of the implementations
197
// that preceded it.
198
template > class rope;
199
template struct _Rope_RopeConcatenation;
200
template struct _Rope_RopeLeaf;
201
template struct _Rope_RopeFunction;
202
template struct _Rope_RopeSubstring;
203
template class _Rope_iterator;
204
template class _Rope_const_iterator;
205
template class _Rope_char_ref_proxy;
206
template class _Rope_char_ptr_proxy;
207
 
208
template
209
bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x,
210
                 const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y);
211
 
212
template
213
_Rope_const_iterator<_CharT,_Alloc> operator-
214
        (const _Rope_const_iterator<_CharT,_Alloc>& __x,
215
         ptrdiff_t __n);
216
 
217
template
218
_Rope_const_iterator<_CharT,_Alloc> operator+
219
        (const _Rope_const_iterator<_CharT,_Alloc>& __x,
220
         ptrdiff_t __n);
221
 
222
template
223
_Rope_const_iterator<_CharT,_Alloc> operator+
224
        (ptrdiff_t __n,
225
         const _Rope_const_iterator<_CharT,_Alloc>& __x);
226
 
227
template
228
bool operator==
229
        (const _Rope_const_iterator<_CharT,_Alloc>& __x,
230
         const _Rope_const_iterator<_CharT,_Alloc>& __y);
231
 
232
template
233
bool operator<
234
        (const _Rope_const_iterator<_CharT,_Alloc>& __x,
235
         const _Rope_const_iterator<_CharT,_Alloc>& __y);
236
 
237
template
238
ptrdiff_t operator-
239
        (const _Rope_const_iterator<_CharT,_Alloc>& __x,
240
         const _Rope_const_iterator<_CharT,_Alloc>& __y);
241
 
242
template
243
_Rope_iterator<_CharT,_Alloc> operator-
244
        (const _Rope_iterator<_CharT,_Alloc>& __x,
245
         ptrdiff_t __n);
246
 
247
template
248
_Rope_iterator<_CharT,_Alloc> operator+
249
        (const _Rope_iterator<_CharT,_Alloc>& __x,
250
         ptrdiff_t __n);
251
 
252
template
253
_Rope_iterator<_CharT,_Alloc> operator+
254
        (ptrdiff_t __n,
255
         const _Rope_iterator<_CharT,_Alloc>& __x);
256
 
257
template
258
bool operator==
259
        (const _Rope_iterator<_CharT,_Alloc>& __x,
260
         const _Rope_iterator<_CharT,_Alloc>& __y);
261