1 /*
2 *
3 * Copyright (c) 1998-2002
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE regex_raw_buffer.hpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Raw character buffer for regex code.
17 * Note this is an internal header file included
18 * by regex.hpp, do not include on its own.
19 */
20
21 #ifndef BOOST_REGEX_RAW_BUFFER_HPP
22 #define BOOST_REGEX_RAW_BUFFER_HPP
23
24 #ifndef BOOST_REGEX_CONFIG_HPP
25 #include <boost/regex/config.hpp>
26 #endif
27
28 #include <algorithm>
29 #include <cstddef>
30
31 namespace boost{
32 namespace BOOST_REGEX_DETAIL_NS{
33
34 struct empty_padding{};
35
36 union padding
37 {
38 void* p;
39 unsigned int i;
40 };
41
42 template <int N>
43 struct padding3
44 {
45 enum{
46 padding_size = 8,
47 padding_mask = 7
48 };
49 };
50
51 template<>
52 struct padding3<2>
53 {
54 enum{
55 padding_size = 2,
56 padding_mask = 1
57 };
58 };
59
60 template<>
61 struct padding3<4>
62 {
63 enum{
64 padding_size = 4,
65 padding_mask = 3
66 };
67 };
68
69 template<>
70 struct padding3<8>
71 {
72 enum{
73 padding_size = 8,
74 padding_mask = 7
75 };
76 };
77
78 template<>
79 struct padding3<16>
80 {
81 enum{
82 padding_size = 16,
83 padding_mask = 15
84 };
85 };
86
87 enum{
88 padding_size = padding3<sizeof(padding)>::padding_size,
89 padding_mask = padding3<sizeof(padding)>::padding_mask
90 };
91
92 //
93 // class raw_storage
94 // basically this is a simplified vector<unsigned char>
95 // this is used by basic_regex for expression storage
96 //
97
98 class raw_storage
99 {
100 public:
101 typedef std::size_t size_type;
102 typedef unsigned char* pointer;
103 private:
104 pointer last, start, end;
105 public:
106
107 raw_storage();
108 raw_storage(size_type n);
109
~raw_storage()110 ~raw_storage()
111 {
112 ::operator delete(start);
113 }
114
resize(size_type n)115 void resize(size_type n)
116 {
117 size_type newsize = start ? last - start : 1024;
118 while (newsize < n)
119 newsize *= 2;
120 size_type datasize = end - start;
121 // extend newsize to WORD/DWORD boundary:
122 newsize = (newsize + padding_mask) & ~(padding_mask);
123
124 // allocate and copy data:
125 pointer ptr = static_cast<pointer>(::operator new(newsize));
126 BOOST_REGEX_NOEH_ASSERT(ptr)
127 if (start)
128 std::memcpy(ptr, start, datasize);
129
130 // get rid of old buffer:
131 ::operator delete(start);
132
133 // and set up pointers:
134 start = ptr;
135 end = ptr + datasize;
136 last = ptr + newsize;
137 }
138
extend(size_type n)139 void* extend(size_type n)
140 {
141 if(size_type(last - end) < n)
142 resize(n + (end - start));
143 pointer result = end;
144 end += n;
145 return result;
146 }
147
insert(size_type pos,size_type n)148 void* insert(size_type pos, size_type n)
149 {
150 BOOST_REGEX_ASSERT(pos <= size_type(end - start));
151 if (size_type(last - end) < n)
152 resize(n + (end - start));
153 void* result = start + pos;
154 std::memmove(start + pos + n, start + pos, (end - start) - pos);
155 end += n;
156 return result;
157 }
158
size()159 size_type size()
160 {
161 return size_type(end - start);
162 }
163
capacity()164 size_type capacity()
165 {
166 return size_type(last - start);
167 }
168
data() const169 void* data()const
170 {
171 return start;
172 }
173
index(void * ptr)174 size_type index(void* ptr)
175 {
176 return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
177 }
178
clear()179 void clear()
180 {
181 end = start;
182 }
183
align()184 void align()
185 {
186 // move end up to a boundary:
187 end = start + (((end - start) + padding_mask) & ~padding_mask);
188 }
swap(raw_storage & that)189 void swap(raw_storage& that)
190 {
191 std::swap(start, that.start);
192 std::swap(end, that.end);
193 std::swap(last, that.last);
194 }
195 };
196
raw_storage()197 inline raw_storage::raw_storage()
198 {
199 last = start = end = 0;
200 }
201
raw_storage(size_type n)202 inline raw_storage::raw_storage(size_type n)
203 {
204 start = end = static_cast<pointer>(::operator new(n));
205 BOOST_REGEX_NOEH_ASSERT(start)
206 last = start + n;
207 }
208
209 } // namespace BOOST_REGEX_DETAIL_NS
210 } // namespace boost
211
212 #endif
213
214