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

cpp_macromap.hpp

Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
HPP
第 1 页 / 共 5 页
字号:
            else if (adjacent_stringize &&                     !IS_CATEGORY(*cit, WhiteSpaceTokenType))             {            // stringize the current argument                BOOST_ASSERT(!arguments[i].empty());                            // safe a copy of the first tokens position (not a reference!)            position_type pos ((*arguments[i].begin()).get_position());#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0                if (is_ellipsis && boost::wave::need_variadics(ctx.get_language())) {                    impl::trim_sequence_left(arguments[i]);                    impl::trim_sequence_right(arguments.back());                    expanded.push_back(token_type(T_STRINGLIT,                         impl::as_stringlit(arguments, i, pos), pos));                }                else #endif                 {                    impl::trim_sequence(arguments[i]);                    expanded.push_back(token_type(T_STRINGLIT,                         impl::as_stringlit(arguments[i], pos), pos));                }                adjacent_stringize = false;            }            else {            // simply copy the original argument (adjacent '##' or '#')#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0                if (is_ellipsis) {                position_type const &pos = (*cit).get_position();                    impl::trim_sequence_left(arguments[i]);                    impl::trim_sequence_right(arguments.back());                    BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language()));                    impl::replace_ellipsis(arguments, i, expanded, pos);                }                else#endif                {                ContainerT &arg = arguments[i];                                    impl::trim_sequence(arg);                    std::copy(arg.begin(), arg.end(),                         std::inserter(expanded, expanded.end()));                }            }        }        else if (!adjacent_stringize || T_POUND != base_id) {        // insert the actual replacement token (if it is not the '#' operator)            expanded.push_back(*cit);        }    }    if (adjacent_stringize) {    // error, '#' should not be the last token        BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_operator,            "stringize ('#')", main_pos);        return;    }        // handle the cpp.concat operator    if (seen_concat)        concat_tokensequence(expanded);}///////////////////////////////////////////////////////////////////////////////////  rescan_replacement_list////    As the name implies, this function is used to rescan the replacement list //    after the first macro substitution phase./////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename IteratorT, typename ContainerT>inline void macromap<ContextT>::rescan_replacement_list(token_type const &curr_token,     macro_definition_type &macro_def, ContainerT &replacement_list,     ContainerT &expanded, bool expand_operator_defined,    IteratorT &nfirst, IteratorT const &nlast){    if (!replacement_list.empty()) {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0    // remove the placemarkers        if (boost::wave::need_variadics(ctx.get_language())) {        typename ContainerT::iterator end = replacement_list.end();        typename ContainerT::iterator it = replacement_list.begin();                    while (it != end) {                using namespace boost::wave;                if (T_PLACEMARKER == token_id(*it)) {                typename ContainerT::iterator placemarker = it;                                    ++it;                    replacement_list.erase(placemarker);                }                else {                    ++it;                }            }        }#endif    // rescan the replacement list, during this rescan the current macro under    // expansion isn't available as an expandable macro    on_exit::reset<bool> on_exit(macro_def.is_available_for_replacement, false);    typename ContainerT::iterator begin_it = replacement_list.begin();    typename ContainerT::iterator end_it = replacement_list.end();            expand_whole_tokensequence(expanded, begin_it, end_it,             expand_operator_defined);                 // trim replacement list, leave placeholder tokens untouched        impl::trim_replacement_list(expanded);    }        if (expanded.empty()) {    // the resulting replacement list should contain at least a placeholder    // token        expanded.push_back(token_type(T_PLACEHOLDER, "_", curr_token.get_position()));    }}///////////////////////////////////////////////////////////////////////////////// //  expand_macro(): expands a defined macro////      This functions tries to expand the macro, to which points the 'first'//      iterator. The functions eats up more tokens, if the macro to expand is//      a function-like macro./////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename IteratorT, typename ContainerT>inline bool macromap<ContextT>::expand_macro(ContainerT &expanded,     token_type const &curr_token, typename defined_macros_type::iterator it,     IteratorT &first, IteratorT const &last,     bool& seen_newline, bool expand_operator_defined,     defined_macros_type *scope, ContainerT *queue_symbol) {    using namespace boost::wave;        if (0 == scope) scope = current_macros;        BOOST_ASSERT(T_IDENTIFIER == token_id(curr_token) ||        IS_CATEGORY(token_id(curr_token), KeywordTokenType) ||        IS_EXTCATEGORY(token_id(curr_token), OperatorTokenType|AltExtTokenType) ||        IS_CATEGORY(token_id(curr_token), BoolLiteralTokenType));            if (it == scope->end()) {        ++first;    // advance    // try to expand a predefined macro (__FILE__, __LINE__ or __INCLUDE_LEVEL__)        if (expand_predefined_macro(curr_token, expanded))            return false;            // not defined as a macro        if (0 != queue_symbol) {            expanded.splice(expanded.end(), *queue_symbol);        }        else {            expanded.push_back(curr_token);        }        return false;    }// ensure the parameters to be replaced with special parameter tokensmacro_definition_type &macro_def = *(*it).second.get();    macro_def.replace_parameters();// test if this macro is currently available for replacement    if (!macro_def.is_available_for_replacement) {    // this macro is marked as non-replaceable    // copy the macro name itself        if (0 != queue_symbol) {            queue_symbol->push_back(token_type(T_NONREPLACABLE_IDENTIFIER,                curr_token.get_value(), curr_token.get_position()));            expanded.splice(expanded.end(), *queue_symbol);        }        else {            expanded.push_back(token_type(T_NONREPLACABLE_IDENTIFIER,                curr_token.get_value(), curr_token.get_position()));        }        ++first;        return false;    }// try to replace the current identifier as a function-like macroContainerT replacement_list;    if (T_LEFTPAREN == impl::next_token<IteratorT>::peek(first, last)) {    // called as a function-like macro         impl::skip_to_token(first, last, T_LEFTPAREN, seen_newline);        #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0        IteratorT seqstart = first;        IteratorT seqend = first;#endif        if (macro_def.is_functionlike) {        // defined as a function-like macro                // collect the arguments        std::vector<ContainerT> arguments;#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0        typename std::vector<ContainerT>::size_type count_args =             collect_arguments (curr_token, arguments, first, last,                 macro_def.macroparameters.size(), seen_newline);#else        typename std::vector<ContainerT>::size_type count_args =             collect_arguments (curr_token, arguments, first, seqend, last,                 macro_def.macroparameters.size(), seen_newline);#endif        // verify the parameter count            if (count_args < macro_def.macroparameters.size() ||                arguments.size() < macro_def.macroparameters.size())             {                if (count_args != arguments.size()) {                // must been at least one empty argument in C++ mode                    BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                         empty_macroarguments, curr_token.get_value().c_str(),                         main_pos);                }                else {                // too few macro arguments                    BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                         too_few_macroarguments, curr_token.get_value().c_str(),                         main_pos);                }                return false;            }                        if (count_args > macro_def.macroparameters.size() ||                arguments.size() > macro_def.macroparameters.size())             {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0                if (!macro_def.has_ellipsis) #endif                 {                // too many macro arguments                    BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                         too_many_macroarguments,                         curr_token.get_value().c_str(), main_pos);                    return false;                }            }                        // inject tracing support#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0            ctx.get_hooks().expanding_function_like_macro(                macro_def.macroname, macro_def.macroparameters,                 macro_def.macrodefinition, curr_token, arguments);#else            if (ctx.get_hooks().expanding_function_like_macro(ctx.derived(),                     macro_def.macroname, macro_def.macroparameters,                     macro_def.macrodefinition, curr_token, arguments,                    seqstart, seqend))            {                // do not expand this macro, just copy the whole sequence                 std::copy(seqstart, first,                     std::inserter(replacement_list, replacement_list.end()));                return false;           // no further preprocessing required            }#endif        // expand the replacement list of this macro            expand_replacement_list(macro_def, arguments, expand_operator_defined,                replacement_list);        }        else {        // defined as an object-like macro#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0            ctx.get_hooks().expanding_object_like_macro(                macro_def.macroname, macro_def.macrodefinition, curr_token);#else            if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(),                   macro_def.macroname, macro_def.macrodefinition, curr_token))            {                // do not expand this macro, just copy the whole sequence                 replacement_list.push_back(curr_token);                ++first;                // skip macro name                return false;           // no further preprocessing required            }#endif        bool found = false;        impl::find_concat_operator concat_tag(found);                    std::remove_copy_if(macro_def.macrodefinition.begin(),                 macro_def.macrodefinition.end(),                 std::inserter(replacement_list, replacement_list.end()),                concat_tag);                        // handle concatenation operators            if (found && !concat_tokensequence(replacement_list))                return false;        }    }    else {    // called as an object like macro        if ((*it).second->is_functionlike) {        // defined as a function-like macro            if (0 != queue_symbol) {                queue_symbol->push_back(curr_token);                expanded.splice(expanded.end(), *queue_symbol);            }            else {                expanded.push_back(curr_token);            }            ++first;                // skip macro name            return false;           // no further preprocessing required        }        else {        // defined as an object-like macro (expand it)#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0            ctx.get_hooks().expanding_object_like_macro(                macro_def.macroname, macro_def.macrodefinition, curr_token);#else            if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(),                   macro_def.macroname, macro_def.macrodefinition, curr_token))            {                // do not expand this macro, just copy the whole sequence                 replacement_list.push_back(curr_token);                ++first;                // skip macro name                return false;           // no further preprocessing required            }#endif        bool found = false;        impl::find_concat_operator concat_tag(found);                    std::remove_copy_if(macro_def.macrodefinition.begin(),                 macro_def.macrodefinition.end(),                 std::inserter(replacement_list, replacement_list.end()),                concat_tag);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -