File indexing completed on 2025-01-18 09:53:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #if !defined(BOOST_CPP_MACROMAP_UTIL_HPP_HK041119)
0014 #define BOOST_CPP_MACROMAP_UTIL_HPP_HK041119
0015
0016 #include <boost/assert.hpp>
0017
0018 #include <boost/wave/wave_config.hpp>
0019 #include <boost/wave/token_ids.hpp>
0020 #include <boost/wave/util/unput_queue_iterator.hpp>
0021 #include <boost/wave/language_support.hpp>
0022
0023
0024 #ifdef BOOST_HAS_ABI_HEADERS
0025 #include BOOST_ABI_PREFIX
0026 #endif
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 namespace boost {
0037 namespace wave {
0038 namespace util {
0039
0040
0041 namespace on_exit {
0042
0043
0044
0045
0046
0047
0048 template <typename ContainerT>
0049 class pop_front {
0050 public:
0051 pop_front(ContainerT &list_) : list(list_) {}
0052 ~pop_front() { list.pop_front(); }
0053
0054 private:
0055 ContainerT &list;
0056 };
0057
0058
0059
0060
0061
0062
0063
0064 template <typename ContainerT>
0065 class splice_pop_front {
0066 public:
0067 splice_pop_front(ContainerT &list_, ContainerT &queue)
0068 : list(list_)
0069 {
0070 list.splice(list.end(), queue);
0071 }
0072 ~splice_pop_front() { list.pop_front(); }
0073
0074 private:
0075 ContainerT &list;
0076 };
0077
0078
0079
0080
0081
0082
0083 template <typename TypeT>
0084 class reset {
0085 public:
0086 reset(TypeT &target_value_, TypeT new_value)
0087 : target_value(target_value_), old_value(target_value_)
0088 {
0089 target_value_ = new_value;
0090 }
0091 ~reset() { target_value = old_value; }
0092
0093 private:
0094 TypeT &target_value;
0095 TypeT old_value;
0096 };
0097
0098
0099
0100
0101
0102
0103 template <typename IteratorT, typename UnputIteratorT>
0104 class assign
0105 {
0106 public:
0107 assign(IteratorT &it_, UnputIteratorT const &uit_)
0108 : it(it_), uit(uit_) {}
0109 ~assign() { it = uit.base(); }
0110
0111 private:
0112 IteratorT ⁢
0113 UnputIteratorT const &uit;
0114 };
0115
0116 template <typename IteratorT>
0117 class assign<IteratorT, IteratorT> {
0118 public:
0119 assign(IteratorT &it_, IteratorT const &uit_)
0120 : it(it_), uit(uit_) {}
0121 ~assign() { it = uit; }
0122
0123 private:
0124 IteratorT ⁢
0125 IteratorT const &uit;
0126 };
0127
0128
0129 }
0130
0131
0132 namespace impl {
0133
0134
0135
0136
0137
0138
0139 template <typename ContextT, typename StringT>
0140 inline bool
0141 is_special_macroname (ContextT const & ctx, StringT const &name)
0142 {
0143 if (name.size() < 7)
0144 return false;
0145
0146 if ("defined" == name)
0147 return true;
0148
0149 #if BOOST_WAVE_SUPPORT_HAS_INCLUDE != 0
0150 if (boost::wave::need_has_include(ctx.get_language()) &&
0151 ("__has_include" == name))
0152 return true;
0153 #endif
0154
0155 if ('_' == name[0] && '_' == name[1]) {
0156 StringT str = name.substr(2);
0157
0158 if (str == "cplusplus" || str == "STDC__" ||
0159 str == "TIME__" || str == "DATE__" ||
0160 str == "LINE__" || str == "FILE__" ||
0161 str == "INCLUDE_LEVEL__")
0162 {
0163 return true;
0164 }
0165 }
0166 return false;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175 template <typename TokenT>
0176 inline bool
0177 token_equals(TokenT const &left, TokenT const &right)
0178 {
0179 using namespace boost::wave;
0180
0181 if (IS_CATEGORY(left, ParameterTokenType)) {
0182
0183
0184 token_id id = token_id(right);
0185
0186 return (T_IDENTIFIER == id ||
0187 IS_CATEGORY(id, KeywordTokenType) ||
0188 IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) ||
0189 IS_CATEGORY(id, BoolLiteralTokenType)) &&
0190 left.get_value() == right.get_value();
0191 }
0192
0193
0194 return token_id(left) == token_id(right) && (
0195 IS_CATEGORY(left, WhiteSpaceTokenType) ||
0196 left.get_value() == right.get_value()
0197 );
0198 }
0199
0200
0201
0202
0203
0204
0205 template <typename ContainerT>
0206 inline bool
0207 definition_equals(ContainerT const &definition,
0208 ContainerT const &new_definition)
0209 {
0210 typedef typename ContainerT::const_iterator const_iterator_type;
0211
0212 const_iterator_type first1 = definition.begin();
0213 const_iterator_type last1 = definition.end();
0214 const_iterator_type first2 = new_definition.begin();
0215 const_iterator_type last2 = new_definition.end();
0216
0217 while (first1 != last1 && first2 != last2 && token_equals(*first1, *first2))
0218 {
0219
0220 token_id id1 = next_token<const_iterator_type>::peek(first1, last1, false);
0221 token_id id2 = next_token<const_iterator_type>::peek(first2, last2, false);
0222
0223 if (IS_CATEGORY(id1, WhiteSpaceTokenType) &&
0224 IS_CATEGORY(id2, WhiteSpaceTokenType))
0225 {
0226
0227
0228 skip_whitespace(first1, last1);
0229 skip_whitespace(first2, last2);
0230 }
0231 else if (!IS_CATEGORY(id1, WhiteSpaceTokenType) &&
0232 !IS_CATEGORY(id2, WhiteSpaceTokenType))
0233 {
0234 ++first1;
0235 ++first2;
0236 }
0237 else {
0238
0239 break;
0240 }
0241 }
0242 return (first1 == last1 && first2 == last2) ? true : false;
0243 }
0244
0245
0246
0247
0248
0249
0250 template <typename ContainerT>
0251 inline bool
0252 parameters_equal(ContainerT const ¶meters, ContainerT const &new_parameters)
0253 {
0254 if (parameters.size() != new_parameters.size())
0255 return false;
0256
0257 typedef typename ContainerT::const_iterator const_iterator_type;
0258
0259 const_iterator_type first1 = parameters.begin();
0260 const_iterator_type last1 = parameters.end();
0261 const_iterator_type first2 = new_parameters.begin();
0262 const_iterator_type last2 = new_parameters.end();
0263
0264 while (first1 != last1 && first2 != last2) {
0265
0266 using namespace boost::wave;
0267 if (token_id(*first1) != token_id(*first2) ||
0268 (*first1).get_value() != (*first2).get_value())
0269 {
0270 break;
0271 }
0272 ++first1;
0273 ++first2;
0274 }
0275 return (first1 == last1 && first2 == last2) ? true : false;
0276 }
0277
0278
0279
0280
0281
0282
0283 template <typename ContainerT>
0284 inline void
0285 trim_replacement_list (ContainerT &replacement_list)
0286 {
0287 using namespace boost::wave;
0288
0289
0290 if (replacement_list.size() > 0) {
0291 typename ContainerT::iterator end = replacement_list.end();
0292 typename ContainerT::iterator it = replacement_list.begin();
0293
0294 while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
0295 token_id id(*it);
0296 if (T_PLACEHOLDER != id && T_PLACEMARKER != id) {
0297 typename ContainerT::iterator next = it;
0298 ++next;
0299 replacement_list.erase(it);
0300 it = next;
0301 }
0302 else {
0303 ++it;
0304 }
0305 }
0306 }
0307
0308
0309 if (replacement_list.size() > 0) {
0310 typename ContainerT::reverse_iterator rend = replacement_list.rend();
0311 typename ContainerT::reverse_iterator rit = replacement_list.rbegin();
0312
0313 while (rit != rend && IS_CATEGORY(*rit, WhiteSpaceTokenType))
0314 ++rit;
0315
0316 typename ContainerT::iterator end = replacement_list.end();
0317 typename ContainerT::iterator it = rit.base();
0318
0319 while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
0320 token_id id(*it);
0321 if (T_PLACEHOLDER != id && T_PLACEMARKER != id) {
0322 typename ContainerT::iterator next = it;
0323 ++next;
0324 replacement_list.erase(it);
0325 it = next;
0326 }
0327 else {
0328 ++it;
0329 }
0330 }
0331 }
0332 }
0333
0334
0335
0336
0337
0338
0339 template <typename ContainerT>
0340 inline bool
0341 is_whitespace_only (ContainerT const &argument)
0342 {
0343 typename ContainerT::const_iterator end = argument.end();
0344 for (typename ContainerT::const_iterator it = argument.begin();
0345 it != end; ++it)
0346 {
0347 if (!IS_CATEGORY(*it, WhiteSpaceTokenType))
0348 return false;
0349 }
0350 return true;
0351 }
0352
0353
0354
0355
0356
0357
0358
0359 template <typename ContainerT>
0360 inline bool
0361 is_blank_only (ContainerT const &argument)
0362 {
0363 typename ContainerT::const_iterator end = argument.end();
0364 for (typename ContainerT::const_iterator it = argument.begin();
0365 it != end; ++it)
0366 {
0367 if (!IS_CATEGORY(*it, WhiteSpaceTokenType) &&
0368 (T_PLACEMARKER != token_id(*it)))
0369 return false;
0370 }
0371 return true;
0372 }
0373
0374
0375
0376
0377
0378
0379 template <typename ContainerT>
0380 inline void
0381 remove_placeholders (ContainerT &replacement_list)
0382 {
0383 using namespace boost::wave;
0384
0385
0386 if (replacement_list.size() > 0) {
0387 typename ContainerT::iterator end = replacement_list.end();
0388 typename ContainerT::iterator it = replacement_list.begin();
0389
0390 while (it != end) {
0391 token_id id(*it);
0392 if (T_PLACEHOLDER == id || T_PLACEMARKER == id) {
0393 typename ContainerT::iterator next = it;
0394 ++next;
0395 replacement_list.erase(it);
0396 it = next;
0397 }
0398 else {
0399 ++it;
0400 }
0401 }
0402
0403
0404 if (is_whitespace_only(replacement_list))
0405 trim_replacement_list(replacement_list);
0406 }
0407 }
0408
0409
0410
0411
0412
0413
0414 template <typename ContainerT>
0415 inline void
0416 trim_sequence_left (ContainerT &argument)
0417 {
0418 using namespace boost::wave;
0419
0420
0421 if (argument.size() > 0 &&
0422 IS_CATEGORY(argument.front(), WhiteSpaceTokenType))
0423 {
0424 argument.pop_front();
0425 }
0426 }
0427
0428
0429
0430
0431
0432
0433 template <typename ContainerT>
0434 inline void
0435 trim_sequence_right (ContainerT &argument)
0436 {
0437 using namespace boost::wave;
0438
0439
0440 if (argument.size() > 0 &&
0441 IS_CATEGORY(argument.back(), WhiteSpaceTokenType))
0442 {
0443 argument.pop_back();
0444 }
0445 }
0446
0447
0448
0449
0450
0451
0452
0453 template <typename ContainerT>
0454 inline void
0455 trim_sequence (ContainerT &argument)
0456 {
0457 trim_sequence_left(argument);
0458 trim_sequence_right(argument);
0459 }
0460
0461
0462
0463 template <typename ContextT>
0464 void call_skipped_token_hook(ContextT& ctx,
0465 typename ContextT::token_type const& skipped)
0466 {
0467 ctx.get_hooks().skipped_token(ctx.derived(), skipped);
0468 }
0469
0470
0471
0472
0473
0474
0475 template <typename ContextT, typename IteratorT>
0476 inline bool
0477 skip_to_token(ContextT& ctx, IteratorT &it, IteratorT const &end,
0478 token_id id, bool& seen_newline)
0479 {
0480 using namespace boost::wave;
0481 if (token_id(*it) == id)
0482 return true;
0483
0484
0485 if (++it == end)
0486 return false;
0487
0488 while (IS_CATEGORY(*it, WhiteSpaceTokenType) ||
0489 T_NEWLINE == token_id(*it))
0490 {
0491 if (T_NEWLINE == token_id(*it))
0492 seen_newline = true;
0493
0494
0495 if (++it == end)
0496 return false;
0497 }
0498 return token_id(*it) == id;
0499 }
0500
0501
0502
0503
0504
0505
0506
0507 template <typename IteratorT>
0508 inline std::string
0509 get_full_name(IteratorT const &begin, IteratorT const &end)
0510 {
0511 std::string full_name;
0512 for (IteratorT err_it = begin; err_it != end; ++err_it)
0513 full_name += (*err_it).get_value().c_str();
0514
0515 return full_name;
0516 }
0517
0518
0519
0520
0521
0522
0523
0524
0525 class find_concat_operator {
0526 public:
0527 find_concat_operator(bool &found_) : found_concat(found_) {}
0528
0529 template <typename TokenT>
0530 bool operator()(TokenT const &tok)
0531 {
0532 using namespace boost::wave;
0533 if (T_POUND_POUND == BASE_TOKEN(token_id(tok)))
0534 found_concat = true;
0535 return false;
0536 }
0537
0538 private:
0539 bool &found_concat;
0540 };
0541
0542
0543
0544
0545 template <typename Target, typename Src>
0546 struct to_string_helper
0547 {
0548 typedef Target type;
0549
0550 static Target call(Src const& str)
0551 {
0552 return Target(str.c_str());
0553 }
0554 };
0555
0556
0557 template <typename Src>
0558 struct to_string_helper<Src, Src>
0559 {
0560 typedef Src const& type;
0561
0562 static Src const& call(Src const& str)
0563 {
0564 return str;
0565 }
0566 };
0567
0568 template <typename Target>
0569 struct to_string_helper<Target, char const*>
0570 {
0571 typedef Target type;
0572
0573 static Target call(char const* str)
0574 {
0575 return Target(str);
0576 }
0577 };
0578
0579
0580 }
0581
0582 template <typename Target, typename Src>
0583 inline typename impl::to_string_helper<Target, Src>::type
0584 to_string(Src const& src)
0585 {
0586 return impl::to_string_helper<Target, Src>::call(src);
0587 }
0588
0589
0590 }
0591 }
0592 }
0593
0594
0595 #ifdef BOOST_HAS_ABI_HEADERS
0596 #include BOOST_ABI_SUFFIX
0597 #endif
0598
0599 #endif