]> git.lyx.org Git - lyx.git/blob - boost/boost/re_detail/regex_raw_buffer.hpp
cvsignore ++
[lyx.git] / boost / boost / re_detail / regex_raw_buffer.hpp
1 /*
2  *
3  * Copyright (c) 1998-2000
4  * Dr John Maddock
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Dr John Maddock makes no representations
11  * about the suitability of this software for any purpose.
12  * It is provided "as is" without express or implied warranty.
13  *
14  */
15
16  /*
17   *   LOCATION:    see http://www.boost.org for most recent version.
18   *   FILE         regex_raw_buffer.hpp
19   *   VERSION      3.03
20   *   DESCRIPTION: Raw character buffer for regex code.
21   *                Note this is an internal header file included
22   *                by regex.hpp, do not include on its own.
23   */
24
25 #ifndef BOOST_REGEX_RAW_BUFFER_HPP
26 #define BOOST_REGEX_RAW_BUFFER_HPP
27
28 #ifndef BOOST_REGEX_CONFIG_HPP
29 #include <boost/re_detail/regex_config.hpp>
30 #endif
31
32 namespace boost{
33    namespace re_detail{
34
35 #ifdef __BORLANDC__
36    #if __BORLANDC__ == 0x530
37     #pragma option push -a4 -b -Ve
38    #elif __BORLANDC__ > 0x530
39     #pragma option push -a8 -b -Ve
40    #endif
41 #endif
42
43 struct empty_padding{};
44
45 union padding
46 {
47    void* p;
48    unsigned int i;
49 };
50
51 template <int N>
52 struct padding3
53 {
54    enum{
55       padding_size = 8,
56       padding_mask = 7
57    };
58 };
59
60 template<>
61 struct padding3<2>
62 {
63    enum{
64       padding_size = 2,
65       padding_mask = 1
66    };
67 };
68
69 template<>
70 struct padding3<4>
71 {
72    enum{
73       padding_size = 4,
74       padding_mask = 3
75    };
76 };
77
78 template<>
79 struct padding3<8>
80 {
81    enum{
82       padding_size = 8,
83       padding_mask = 7
84    };
85 };
86
87 template<>
88 struct padding3<16>
89 {
90    enum{
91       padding_size = 16,
92       padding_mask = 15
93    };
94 };
95
96 enum{
97    padding_size = padding3<sizeof(padding)>::padding_size,
98    padding_mask = padding3<sizeof(padding)>::padding_mask
99 };
100
101 //
102 // class raw_storage
103 // basically this is a simplified vector<unsigned char>
104 // this is used by reg_expression for expression storage
105 //
106
107 template <class Allocator>
108 class raw_storage
109 {
110 public:
111    typedef Allocator allocator_type;
112    typedef typename REBIND_TYPE(unsigned char, allocator_type)::size_type size_type;
113    typedef BOOST_RE_MAYBE_TYPENAME REBIND_TYPE(unsigned char, allocator_type) alloc_inst_type;
114    typedef typename REBIND_TYPE(unsigned char, allocator_type)::pointer pointer;
115 private:
116    //
117    // empty member optimisation:
118    struct alloc_data : public alloc_inst_type
119    {
120       typename alloc_inst_type::pointer last;
121       alloc_data(const Allocator& a) : alloc_inst_type(a){}
122    } alloc_inst;
123    pointer start, end;
124 public:
125
126    raw_storage(const Allocator& a = Allocator());
127    raw_storage(size_type n, const Allocator& a = Allocator());
128
129    ~raw_storage()
130    {
131       alloc_inst.deallocate(start, (alloc_inst.last - start));
132    }
133
134    void BOOST_RE_CALL resize(size_type n);
135    
136    void* BOOST_RE_CALL extend(size_type n)
137    {
138       if(size_type(alloc_inst.last - end) < n)
139          resize(n + (end - start));
140       register void* result = end;
141       end += n;
142       return result;
143    }
144
145    void* BOOST_RE_CALL insert(size_type pos, size_type n);
146
147    size_type BOOST_RE_CALL size()
148    {
149       return end - start;
150    }
151
152    size_type BOOST_RE_CALL capacity()
153    {
154       return alloc_inst.last - start;
155    }
156
157    void* BOOST_RE_CALL data()const
158    {
159       return start;
160    }
161
162    size_type BOOST_RE_CALL index(void* ptr)
163    {
164       return (unsigned char*)ptr - (unsigned char*)data();
165    }
166
167    void BOOST_RE_CALL clear()
168    {
169       end = start;
170    }
171
172    void BOOST_RE_CALL align()
173    {
174       // move end up to a boundary:
175       end = (unsigned char*)start + ((((unsigned char*)end - (unsigned char*)start) + padding_mask) & ~padding_mask);
176    }
177
178    Allocator BOOST_RE_CALL allocator()const;
179 };
180
181 template <class Allocator>
182 CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(const Allocator& a)
183   : alloc_inst(a)
184 {
185   start = end = alloc_inst.allocate(1024);
186   alloc_inst.last = start + 1024;
187 }
188
189 template <class Allocator>
190 CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a)
191   : alloc_inst(a)
192 {
193   start = end = alloc_inst.allocate(n);
194   alloc_inst.last = start + n;
195 }
196
197 template <class Allocator>
198 Allocator BOOST_RE_CALL raw_storage<Allocator>::allocator()const
199 {
200   return alloc_inst;
201 }
202
203 template <class Allocator>
204 void BOOST_RE_CALL raw_storage<Allocator>::resize(size_type n)
205 {
206    register size_type newsize = (alloc_inst.last - start) * 2;
207    register size_type datasize = end - start;
208    if(newsize < n)
209       newsize = n;
210    // extend newsize to WORD/DWORD boundary:
211    newsize = (newsize + padding_mask) & ~(padding_mask);
212
213    // allocate and copy data:
214    register unsigned char* ptr = alloc_inst.allocate(newsize);
215    std::memcpy(ptr, start, datasize);
216
217    // get rid of old buffer:
218    alloc_inst.deallocate(start, (alloc_inst.last - start));
219
220    // and set up pointers:
221    start = ptr;
222    end = ptr + datasize;
223    alloc_inst.last = ptr + newsize;
224 }
225
226 template <class Allocator>
227 void* BOOST_RE_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
228 {
229    jm_assert(pos <= size_type(end - start));
230    if(size_type(alloc_inst.last - end) < n)
231       resize(n + (end - start));
232    register void* result = start + pos;
233    std::memmove(start + pos + n, start + pos, (end - start) - pos);
234    end += n;
235    return result;
236 }
237
238 #ifdef __BORLANDC__
239  #if __BORLANDC__ > 0x520
240   #pragma option pop
241  #endif
242 #endif
243
244 } // namespace re_detail
245 } // namespace boost
246
247 #endif
248
249
250
251