cpp_macromap.hpp
字号:
// of 'true' and 'false' // all remaining identifiers and keywords, except for true and false, // are replaced with the pp-number 0 (C++ standard 16.1.4, [cpp.cond]) return act_token = token_type(T_INTLIT, T_TRUE != id ? "0" : "1", (*first++).get_position()); } else { act_token = *first; ++first; return act_token; } } return act_token = token_type(); // eoi}///////////////////////////////////////////////////////////////////////////////// // collect_arguments(): collect the actual arguments of a macro invocation//// return the number of successfully detected non-empty arguments/////////////////////////////////////////////////////////////////////////////////#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0template <typename ContextT>template <typename IteratorT, typename ContainerT, typename SizeT>inline typename std::vector<ContainerT>::size_type macromap<ContextT>::collect_arguments (token_type const curr_token, std::vector<ContainerT> &arguments, IteratorT &next, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline)#elsetemplate <typename ContextT>template <typename IteratorT, typename ContainerT, typename SizeT>inline typename std::vector<ContainerT>::size_type macromap<ContextT>::collect_arguments (token_type const curr_token, std::vector<ContainerT> &arguments, IteratorT &next, IteratorT &endparen, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline)#endif{ using namespace boost::wave; arguments.push_back(ContainerT()); // collect the actual argumentstypename std::vector<ContainerT>::size_type count_arguments = 0;int nested_parenthesis_level = 1;ContainerT *argument = &arguments[0];bool was_whitespace = false;token_type startof_argument_list = *next; while (++next != end && nested_parenthesis_level) { token_id id = token_id(*next); if (0 == parameter_count && !IS_CATEGORY((*next), WhiteSpaceTokenType) && id != T_NEWLINE && id != T_RIGHTPAREN && id != T_LEFTPAREN) { // there shouldn't be any arguments BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_many_macroarguments, curr_token.get_value().c_str(), main_pos); return 0; } switch (static_cast<unsigned int>(id)) { case T_LEFTPAREN: ++nested_parenthesis_level; argument->push_back(*next); was_whitespace = false; break; case T_RIGHTPAREN: { if (--nested_parenthesis_level >= 1) argument->push_back(*next); else { // found closing parenthesis// trim_sequence(argument);#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 endparen = next;#endif if (parameter_count > 0) { if (argument->empty() || impl::is_whitespace_only(*argument)) {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { // store a placemarker as the argument argument->push_back(token_type(T_PLACEMARKER, "\xA7", (*next).get_position())); ++count_arguments; }#endif } else { ++count_arguments; } } } was_whitespace = false; } break; case T_COMMA: if (1 == nested_parenthesis_level) { // next parameter// trim_sequence(argument); if (argument->empty() || impl::is_whitespace_only(*argument)) {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { // store a placemarker as the argument argument->push_back(token_type(T_PLACEMARKER, "\xA7", (*next).get_position())); ++count_arguments; }#endif } else { ++count_arguments; } arguments.push_back(ContainerT()); // add new arg argument = &arguments[arguments.size()-1]; } else { // surrounded by parenthesises, so store to current argument argument->push_back(*next); } was_whitespace = false; break; case T_NEWLINE: seen_newline = true; /* fall through */ case T_SPACE: case T_SPACE2: case T_CCOMMENT: if (!was_whitespace) argument->push_back(token_type(T_SPACE, " ", (*next).get_position())); was_whitespace = true; break; // skip whitespace case T_PLACEHOLDER: break; // ignore placeholder default: argument->push_back(*next); was_whitespace = false; break; } } if (nested_parenthesis_level >= 1) { // missing ')': improperly terminated macro invocation BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, improperly_terminated_macro, "missing ')'", main_pos); return 0; }// if no argument was expected and we didn't find any, than remove the empty // element if (0 == parameter_count && 0 == count_arguments) { BOOST_ASSERT(1 == arguments.size()); arguments.clear(); } return count_arguments;} ///////////////////////////////////////////////////////////////////////////////// // expand_whole_tokensequence//// fully expands a given token sequence /////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename IteratorT, typename ContainerT>inline voidmacromap<ContextT>::expand_whole_tokensequence(ContainerT &expanded, IteratorT &first, IteratorT const &last, bool expand_operator_defined){ typedef impl::gen_unput_queue_iterator<IteratorT, token_type, ContainerT> gen_type; typedef typename gen_type::return_type iterator_type;iterator_type first_it = gen_type::generate(first);iterator_type last_it = gen_type::generate(last);on_exit::assign<IteratorT, iterator_type> on_exit(first, first_it);ContainerT pending_queue;bool seen_newline; while (!pending_queue.empty() || first_it != last_it) { expanded.push_back( expand_tokensequence_worker(pending_queue, first_it, last_it, seen_newline, expand_operator_defined) ); }// should have returned all expanded tokens BOOST_ASSERT(pending_queue.empty()/* && unput_queue.empty()*/);}///////////////////////////////////////////////////////////////////////////////// // expand_argument//// fully expands the given argument of a macro call /////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename ContainerT>inline void macromap<ContextT>::expand_argument ( typename std::vector<ContainerT>::size_type arg, std::vector<ContainerT> &arguments, std::vector<ContainerT> &expanded_args, bool expand_operator_defined, std::vector<bool> &has_expanded_args){ if (!has_expanded_args[arg]) { // expand the argument only once typedef typename std::vector<ContainerT>::value_type::iterator argument_iterator_type; argument_iterator_type begin_it = arguments[arg].begin(); argument_iterator_type end_it = arguments[arg].end(); expand_whole_tokensequence(expanded_args[arg], begin_it, end_it, expand_operator_defined); impl::remove_placeholders(expanded_args[arg]); has_expanded_args[arg] = true; }} ///////////////////////////////////////////////////////////////////////////////// // expand_replacement_list//// fully expands the replacement list of a given macro with the // actual arguments/expanded arguments// handles the '#' [cpp.stringize] and the '##' [cpp.concat] operator/////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename ContainerT>inline voidmacromap<ContextT>::expand_replacement_list( macro_definition_type const ¯odef, std::vector<ContainerT> &arguments, bool expand_operator_defined, ContainerT &expanded){ using namespace boost::wave; typedef typename macro_definition_type::const_definition_iterator_t macro_definition_iter_t;std::vector<ContainerT> expanded_args(arguments.size());std::vector<bool> has_expanded_args(arguments.size());bool seen_concat = false;bool adjacent_concat = false;bool adjacent_stringize = false; macro_definition_iter_t cend = macrodef.macrodefinition.end(); for (macro_definition_iter_t cit = macrodef.macrodefinition.begin(); cit != cend; ++cit) { bool use_replaced_arg = true; token_id base_id = BASE_TOKEN(token_id(*cit)); if (T_POUND_POUND == base_id) { // concatenation operator adjacent_concat = true; seen_concat = true; } else if (T_POUND == base_id) { // stringize operator adjacent_stringize = true; } else { if (adjacent_stringize || adjacent_concat || T_POUND_POUND == impl::next_token<macro_definition_iter_t> ::peek(cit, cend)) { use_replaced_arg = false; } if (adjacent_concat) // spaces after '##' ? adjacent_concat = IS_CATEGORY(*cit, WhiteSpaceTokenType); } if (IS_CATEGORY((*cit), ParameterTokenType)) { // copy argument 'i' instead of the parameter token i typename ContainerT::size_type i;#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 bool is_ellipsis = false; if (IS_EXTCATEGORY((*cit), ExtParameterTokenType)) { BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language())); i = token_id(*cit) - T_EXTPARAMETERBASE; is_ellipsis = true; } else #endif { i = token_id(*cit) - T_PARAMETERBASE; } BOOST_ASSERT(i < arguments.size()); if (use_replaced_arg) { #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (is_ellipsis) { position_type const &pos = (*cit).get_position(); BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language())); // ensure all variadic arguments to be expanded for (typename vector<ContainerT>::size_type arg = i; arg < expanded_args.size(); ++arg) { expand_argument(arg, arguments, expanded_args, expand_operator_defined, has_expanded_args); } impl::replace_ellipsis(expanded_args, i, expanded, pos); } else #endif { // ensure argument i to be expanded expand_argument(i, arguments, expanded_args, expand_operator_defined, has_expanded_args); // replace argument ContainerT const &arg = expanded_args[i]; std::copy(arg.begin(), arg.end(), std::inserter(expanded, expanded.end())); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -