Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/wave/util/macro_helpers.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*============================================================================= | |
2 Boost.Wave: A Standard compliant C++ preprocessor library | |
3 | |
4 http://www.boost.org/ | |
5 | |
6 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost | |
7 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 #if !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED) | |
12 #define MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED | |
13 | |
14 #include <vector> | |
15 | |
16 #include <boost/assert.hpp> | |
17 #include <boost/wave/wave_config.hpp> | |
18 #include <boost/wave/token_ids.hpp> | |
19 #include <boost/wave/cpplexer/validate_universal_char.hpp> | |
20 #include <boost/wave/util/unput_queue_iterator.hpp> | |
21 | |
22 // this must occur after all of the includes and before any code appears | |
23 #ifdef BOOST_HAS_ABI_HEADERS | |
24 #include BOOST_ABI_PREFIX | |
25 #endif | |
26 | |
27 /////////////////////////////////////////////////////////////////////////////// | |
28 namespace boost { | |
29 namespace wave { | |
30 namespace util { | |
31 | |
32 namespace impl { | |
33 | |
34 // escape a string literal (insert '\\' before every '\"', '?' and '\\') | |
35 template <typename StringT> | |
36 inline StringT | |
37 escape_lit(StringT const &value) | |
38 { | |
39 StringT result; | |
40 typename StringT::size_type pos = 0; | |
41 typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0); | |
42 if (StringT::npos != pos1) { | |
43 do { | |
44 result += value.substr(pos, pos1-pos) | |
45 + StringT("\\") | |
46 + StringT(1, value[pos1]); | |
47 pos1 = value.find_first_of ("\"\\?", pos = pos1+1); | |
48 } while (StringT::npos != pos1); | |
49 result += value.substr(pos); | |
50 } | |
51 else { | |
52 result = value; | |
53 } | |
54 return result; | |
55 } | |
56 | |
57 // un-escape a string literal (remove '\\' just before '\\', '\"' or '?') | |
58 template <typename StringT> | |
59 inline StringT | |
60 unescape_lit(StringT const &value) | |
61 { | |
62 StringT result; | |
63 typename StringT::size_type pos = 0; | |
64 typename StringT::size_type pos1 = value.find_first_of ("\\", 0); | |
65 if (StringT::npos != pos1) { | |
66 do { | |
67 switch (value[pos1+1]) { | |
68 case '\\': | |
69 case '\"': | |
70 case '?': | |
71 result = result + value.substr(pos, pos1-pos); | |
72 pos1 = value.find_first_of ("\\", (pos = pos1+1)+1); | |
73 break; | |
74 | |
75 case 'n': | |
76 result = result + value.substr(pos, pos1-pos) + "\n"; | |
77 pos1 = value.find_first_of ("\\", pos = pos1+1); | |
78 ++pos; | |
79 break; | |
80 | |
81 default: | |
82 result = result + value.substr(pos, pos1-pos+1); | |
83 pos1 = value.find_first_of ("\\", pos = pos1+1); | |
84 } | |
85 | |
86 } while (pos1 != StringT::npos); | |
87 result = result + value.substr(pos); | |
88 } | |
89 else { | |
90 // the string doesn't contain any escaped character sequences | |
91 result = value; | |
92 } | |
93 return result; | |
94 } | |
95 | |
96 // return the string representation of a token sequence | |
97 template <typename ContainerT, typename PositionT> | |
98 inline typename ContainerT::value_type::string_type | |
99 as_stringlit (ContainerT const &token_sequence, PositionT const &pos) | |
100 { | |
101 using namespace boost::wave; | |
102 typedef typename ContainerT::value_type::string_type string_type; | |
103 | |
104 string_type result("\""); | |
105 bool was_whitespace = false; | |
106 typename ContainerT::const_iterator end = token_sequence.end(); | |
107 for (typename ContainerT::const_iterator it = token_sequence.begin(); | |
108 it != end; ++it) | |
109 { | |
110 token_id id = token_id(*it); | |
111 | |
112 if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) { | |
113 if (!was_whitespace) { | |
114 // C++ standard 16.3.2.2 [cpp.stringize] | |
115 // Each occurrence of white space between the argument's | |
116 // preprocessing tokens becomes a single space character in the | |
117 // character string literal. | |
118 result += " "; | |
119 was_whitespace = true; | |
120 } | |
121 } | |
122 else if (T_STRINGLIT == id || T_CHARLIT == id) { | |
123 // string literals and character literals have to be escaped | |
124 result += impl::escape_lit((*it).get_value()); | |
125 was_whitespace = false; | |
126 } | |
127 else | |
128 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 | |
129 if (T_PLACEMARKER != id) | |
130 #endif | |
131 { | |
132 // now append this token to the string | |
133 result += (*it).get_value(); | |
134 was_whitespace = false; | |
135 } | |
136 } | |
137 result += "\""; | |
138 | |
139 // validate the resulting literal to contain no invalid universal character | |
140 // value (throws if invalid chars found) | |
141 boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(), | |
142 pos.get_column(), pos.get_file()); | |
143 return result; | |
144 } | |
145 | |
146 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 | |
147 // return the string representation of a token sequence | |
148 template <typename ContainerT, typename PositionT> | |
149 inline typename ContainerT::value_type::string_type | |
150 as_stringlit (std::vector<ContainerT> const &arguments, | |
151 typename std::vector<ContainerT>::size_type i, PositionT const &pos) | |
152 { | |
153 using namespace boost::wave; | |
154 typedef typename ContainerT::value_type::string_type string_type; | |
155 | |
156 BOOST_ASSERT(i < arguments.size()); | |
157 | |
158 string_type result("\""); | |
159 bool was_whitespace = false; | |
160 | |
161 for (/**/; i < arguments.size(); ++i) { | |
162 // stringize all remaining arguments | |
163 typename ContainerT::const_iterator end = arguments[i].end(); | |
164 for (typename ContainerT::const_iterator it = arguments[i].begin(); | |
165 it != end; ++it) | |
166 { | |
167 token_id id = token_id(*it); | |
168 | |
169 if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) { | |
170 if (!was_whitespace) { | |
171 // C++ standard 16.3.2.2 [cpp.stringize] | |
172 // Each occurrence of white space between the argument's | |
173 // preprocessing tokens becomes a single space character in the | |
174 // character string literal. | |
175 result += " "; | |
176 was_whitespace = true; | |
177 } | |
178 } | |
179 else if (T_STRINGLIT == id || T_CHARLIT == id) { | |
180 // string literals and character literals have to be escaped | |
181 result += impl::escape_lit((*it).get_value()); | |
182 was_whitespace = false; | |
183 } | |
184 else if (T_PLACEMARKER != id) { | |
185 // now append this token to the string | |
186 result += (*it).get_value(); | |
187 was_whitespace = false; | |
188 } | |
189 } | |
190 | |
191 // append comma, if not last argument | |
192 if (i < arguments.size()-1) { | |
193 result += ","; | |
194 was_whitespace = false; | |
195 } | |
196 } | |
197 result += "\""; | |
198 | |
199 // validate the resulting literal to contain no invalid universal character | |
200 // value (throws if invalid chars found) | |
201 boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(), | |
202 pos.get_column(), pos.get_file()); | |
203 return result; | |
204 } | |
205 #endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 | |
206 | |
207 // return the string representation of a token sequence | |
208 template <typename StringT, typename IteratorT> | |
209 inline StringT | |
210 as_string(IteratorT it, IteratorT const& end) | |
211 { | |
212 StringT result; | |
213 for (/**/; it != end; ++it) | |
214 { | |
215 result += (*it).get_value(); | |
216 } | |
217 return result; | |
218 } | |
219 | |
220 // return the string representation of a token sequence | |
221 template <typename ContainerT> | |
222 inline typename ContainerT::value_type::string_type | |
223 as_string (ContainerT const &token_sequence) | |
224 { | |
225 typedef typename ContainerT::value_type::string_type string_type; | |
226 return as_string<string_type>(token_sequence.begin(), | |
227 token_sequence.end()); | |
228 } | |
229 | |
230 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 | |
231 /////////////////////////////////////////////////////////////////////////// | |
232 // | |
233 // Copies all arguments beginning with the given index to the output | |
234 // sequence. The arguments are separated by commas. | |
235 // | |
236 template <typename ContainerT, typename PositionT> | |
237 void replace_ellipsis (std::vector<ContainerT> const &arguments, | |
238 typename ContainerT::size_type index, | |
239 ContainerT &expanded, PositionT const &pos) | |
240 { | |
241 using namespace cpplexer; | |
242 typedef typename ContainerT::value_type token_type; | |
243 | |
244 token_type comma(T_COMMA, ",", pos); | |
245 for (/**/; index < arguments.size(); ++index) { | |
246 ContainerT const &arg = arguments[index]; | |
247 | |
248 std::copy(arg.begin(), arg.end(), | |
249 std::inserter(expanded, expanded.end())); | |
250 | |
251 if (index < arguments.size()-1) | |
252 expanded.push_back(comma); | |
253 } | |
254 } | |
255 #endif | |
256 | |
257 // Skip all whitespace characters and queue the skipped characters into the | |
258 // given container | |
259 template <typename IteratorT> | |
260 inline boost::wave::token_id | |
261 skip_whitespace(IteratorT &first, IteratorT const &last) | |
262 { | |
263 token_id id = util::impl::next_token<IteratorT>::peek(first, last, false); | |
264 if (IS_CATEGORY(id, WhiteSpaceTokenType)) { | |
265 do { | |
266 ++first; | |
267 id = util::impl::next_token<IteratorT>::peek(first, last, false); | |
268 } while (IS_CATEGORY(id, WhiteSpaceTokenType)); | |
269 } | |
270 ++first; | |
271 return id; | |
272 } | |
273 | |
274 template <typename IteratorT, typename ContainerT> | |
275 inline boost::wave::token_id | |
276 skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue) | |
277 { | |
278 queue.push_back (*first); // queue up the current token | |
279 | |
280 token_id id = util::impl::next_token<IteratorT>::peek(first, last, false); | |
281 if (IS_CATEGORY(id, WhiteSpaceTokenType)) { | |
282 do { | |
283 queue.push_back(*++first); // queue up the next whitespace | |
284 id = util::impl::next_token<IteratorT>::peek(first, last, false); | |
285 } while (IS_CATEGORY(id, WhiteSpaceTokenType)); | |
286 } | |
287 ++first; | |
288 return id; | |
289 } | |
290 | |
291 } // namespace impl | |
292 | |
293 /////////////////////////////////////////////////////////////////////////////// | |
294 } // namespace util | |
295 } // namespace wave | |
296 } // namespace boost | |
297 | |
298 // the suffix header occurs after all of the code | |
299 #ifdef BOOST_HAS_ABI_HEADERS | |
300 #include BOOST_ABI_SUFFIX | |
301 #endif | |
302 | |
303 #endif // !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED) |