欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

cpp_macromap.hpp

Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
HPP
第 1 页 / 共 5 页
字号:
        // 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 &parameter_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 &parameter_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 &macrodef,    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 + -