File indexing completed on 2025-10-30 08:37:00
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