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

cpp_macromap.hpp

Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
HPP
第 1 页 / 共 5 页
字号:
/*=============================================================================    Boost.Wave: A Standard compliant C++ preprocessor library    Macro expansion engine        http://www.boost.org/    Copyright (c) 2001-2008 Hartmut Kaiser. Distributed under the Boost    Software License, Version 1.0. (See accompanying file    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#if !defined(CPP_MACROMAP_HPP_CB8F51B0_A3F0_411C_AEF4_6FF631B8B414_INCLUDED)#define CPP_MACROMAP_HPP_CB8F51B0_A3F0_411C_AEF4_6FF631B8B414_INCLUDED#include <cstdlib>#include <cstdio>#include <ctime>#include <list>#include <map>#include <set>#include <vector>#include <iterator>#include <algorithm>#include <boost/assert.hpp>#include <boost/wave/wave_config.hpp>#if BOOST_WAVE_SERIALIZATION != 0#include <boost/serialization/serialization.hpp>#include <boost/serialization/shared_ptr.hpp>#endif#include <boost/filesystem/path.hpp>#include <boost/wave/util/time_conversion_helper.hpp>#include <boost/wave/util/unput_queue_iterator.hpp>#include <boost/wave/util/macro_helpers.hpp>#include <boost/wave/util/macro_definition.hpp>#include <boost/wave/util/symbol_table.hpp>#include <boost/wave/util/cpp_macromap_utils.hpp>#include <boost/wave/util/cpp_macromap_predef.hpp>#include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>#include <boost/wave/wave_version.hpp>#include <boost/wave/cpp_exceptions.hpp>#include <boost/wave/language_support.hpp>// this must occur after all of the includes and before any code appears#ifdef BOOST_HAS_ABI_HEADERS#include BOOST_ABI_PREFIX#endif///////////////////////////////////////////////////////////////////////////////namespace boost { namespace wave { namespace util {///////////////////////////////////////////////////////////////////////////////////  macromap// //      This class holds all currently defined macros and on demand expands //      those macro definitions /////////////////////////////////////////////////////////////////////////////////template <typename ContextT>class macromap {    typedef macromap<ContextT>                      self_type;    typedef typename ContextT::token_type           token_type;    typedef typename token_type::string_type        string_type;    typedef typename token_type::position_type      position_type;            typedef typename ContextT::token_sequence_type  definition_container_type;    typedef std::vector<token_type>                 parameter_container_type;        typedef macro_definition<token_type, definition_container_type>         macro_definition_type;    typedef symbol_table<string_type, macro_definition_type>         defined_macros_type;    typedef typename defined_macros_type::value_type::second_type         macro_ref_type;public:    macromap(ContextT &ctx_)     :   current_macros(0), defined_macros(new defined_macros_type(1)),         main_pos("", 0), ctx(ctx_), macro_uid(1)    {        current_macros = defined_macros.get();    }    ~macromap() {}//  Add a new macro to the given macro scope    bool add_macro(token_type const &name, bool has_parameters,         parameter_container_type &parameters,         definition_container_type &definition, bool is_predefined = false,         defined_macros_type *scope = 0);//  Tests, whether the given macro name is defined in the given macro scope    bool is_defined(string_type const &name,         typename defined_macros_type::iterator &it,         defined_macros_type *scope = 0) const;        // expects a token sequence as its parameters    template <typename IteratorT>    bool is_defined(IteratorT const &begin, IteratorT const &end) const;    // expects an arbitrary string as its parameter    bool is_defined(string_type const &str) const;//  Get the macro definition for the given macro scope    bool get_macro(string_type const &name, bool &has_parameters,         bool &is_predefined, position_type &pos,         parameter_container_type &parameters,         definition_container_type &definition,         defined_macros_type *scope = 0) const;        //  Remove a macro name from the given macro scope    bool remove_macro(string_type const &name, position_type const& pos,         bool even_predefined = false);        template <typename IteratorT, typename ContainerT>    token_type const &expand_tokensequence(IteratorT &first,         IteratorT const &last, ContainerT &pending, ContainerT &expanded,         bool& seen_newline, bool expand_operator_defined);//  Expand all macros inside the given token sequence    template <typename IteratorT, typename ContainerT>    void expand_whole_tokensequence(ContainerT &expanded,         IteratorT &first, IteratorT const &last,         bool expand_operator_defined);//  Init the predefined macros (add them to the given scope)    void init_predefined_macros(char const *fname = "<Unknown>",         defined_macros_type *scope = 0, bool at_global_scope = true);    void predefine_macro(defined_macros_type *scope, string_type const &name,         token_type const &t);        //  Init the internal macro symbol namespace    void reset_macromap();    position_type &get_main_pos() { return main_pos; }//  interface for macro name introspection    typedef typename defined_macros_type::name_iterator name_iterator;    typedef typename defined_macros_type::const_name_iterator const_name_iterator;        name_iterator begin()         { return defined_macros_type::make_iterator(current_macros->begin()); }    name_iterator end()         { return defined_macros_type::make_iterator(current_macros->end()); }    const_name_iterator begin() const        { return defined_macros_type::make_iterator(current_macros->begin()); }    const_name_iterator end() const        { return defined_macros_type::make_iterator(current_macros->end()); }     protected://  Helper functions for expanding all macros in token sequences    template <typename IteratorT, typename ContainerT>    token_type const &expand_tokensequence_worker(ContainerT &pending,         unput_queue_iterator<IteratorT, token_type, ContainerT> &first,         unput_queue_iterator<IteratorT, token_type, ContainerT> const &last,         bool& seen_newline, bool expand_operator_defined);//  Collect all arguments supplied to a macro invocation#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0    template <typename IteratorT, typename ContainerT, typename SizeT>    typename std::vector<ContainerT>::size_type collect_arguments (        token_type const curr_token, std::vector<ContainerT> &arguments,         IteratorT &next, IteratorT const &end, SizeT const &parameter_count,        bool& seen_newline);#else    template <typename IteratorT, typename ContainerT, typename SizeT>    typename std::vector<ContainerT>::size_type 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//  Expand a single macro name    template <typename IteratorT, typename ContainerT>    bool expand_macro(ContainerT &pending, token_type const &name,         typename defined_macros_type::iterator it,         IteratorT &first, IteratorT const &last,         bool& seen_newline, bool expand_operator_defined,        defined_macros_type *scope = 0, ContainerT *queue_symbol = 0);//  Expand a predefined macro (__LINE__, __FILE__ and __INCLUDE_LEVEL__)    template <typename ContainerT>    bool expand_predefined_macro(token_type const &curr_token,         ContainerT &expanded);//  Expand a single macro argument    template <typename ContainerT>    void 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);//  Expand the replacement list (replaces parameters with arguments)    template <typename ContainerT>    void expand_replacement_list(        macro_definition_type const &macrodefinition,        std::vector<ContainerT> &arguments,         bool expand_operator_defined, ContainerT &expanded);//  Rescans the replacement list for macro expansion    template <typename IteratorT, typename ContainerT>    void rescan_replacement_list(token_type const &curr_token,         macro_definition_type &macrodef, ContainerT &replacement_list,         ContainerT &expanded, bool expand_operator_defined,        IteratorT &nfirst, IteratorT const &nlast);//  Resolves the operator defined() and replces the token with "0" or "1"    template <typename IteratorT, typename ContainerT>    token_type const &resolve_defined(IteratorT &first, IteratorT const &last,        ContainerT &expanded);        //  Resolve operator _Pragma or the #pragma directive    template <typename IteratorT, typename ContainerT>    bool resolve_operator_pragma(IteratorT &first,         IteratorT const &last, ContainerT &expanded, bool& seen_newline);//  Handle the concatenation operator '##'     template <typename ContainerT>    bool concat_tokensequence(ContainerT &expanded);    template <typename ContainerT>    bool is_valid_concat(string_type new_value,         position_type const &pos, ContainerT &rescanned);    #if BOOST_WAVE_SERIALIZATION != 0public:    BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);    BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);private:    friend class boost::serialization::access;    template<typename Archive>    void save(Archive &ar, const unsigned int version) const    {        using namespace boost::serialization;        ar & make_nvp("defined_macros", defined_macros);    }    template<typename Archive>    void load(Archive &ar, const unsigned int loaded_version)    {        using namespace boost::serialization;        if (version != (loaded_version & ~version_mask)) {            BOOST_WAVE_THROW(preprocess_exception, incompatible_config,                 "cpp_context state version", get_main_pos());        }        ar & make_nvp("defined_macros", defined_macros);        current_macros = defined_macros.get();    }    BOOST_SERIALIZATION_SPLIT_MEMBER()#endifprivate:    defined_macros_type *current_macros;                   // current symbol table    boost::shared_ptr<defined_macros_type> defined_macros; // global symbol table    token_type act_token;       // current token    position_type main_pos;     // last token position in the pp_iterator    string_type base_name;      // the name to be expanded by __BASE_FILE__    ContextT &ctx;              // context object associated with the macromap    long macro_uid;    predefined_macros predef;   // predefined macro support};//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //  add_macro(): adds a new macro to the macromap/////////////////////////////////////////////////////////////////////////////////template <typename ContextT>inline bool macromap<ContextT>::add_macro(token_type const &name, bool has_parameters,     parameter_container_type &parameters, definition_container_type &definition,     bool is_predefined, defined_macros_type *scope){    if (!is_predefined && impl::is_special_macroname (name.get_value())) {    // exclude special macro names        BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception,             illegal_redefinition, name.get_value().c_str(), main_pos,             name.get_value().c_str());        return false;    }    if (boost::wave::need_variadics(ctx.get_language()) &&         "__VA_ARGS__" == name.get_value())     {    // can't use __VA_ARGS__ as a macro name        BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception,             bad_define_statement_va_args, name.get_value().c_str(), main_pos,             name.get_value().c_str());        return false;    }    if (AltExtTokenType == (token_id(name) & ExtTokenOnlyMask)) {    // exclude special operator names        BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception,             illegal_operator_redefinition, name.get_value().c_str(), main_pos,            name.get_value().c_str());        return false;    }    // try to define the new macrodefined_macros_type *current_scope = scope ? scope : current_macros;typename defined_macros_type::iterator it = current_scope->find(name.get_value());    if (it != current_scope->end()) {    // redefinition, should not be different        macro_definition_type* macrodef = (*it).second.get();        if (macrodef->is_functionlike != has_parameters ||            !impl::parameters_equal(macrodef->macroparameters, parameters) ||            !impl::definition_equals(macrodef->macrodefinition, definition))        {            BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception,                 macro_redefinition, name.get_value().c_str(), main_pos,                 name.get_value().c_str());        }        return false;    }// test the validity of the parameter names    if (has_parameters) {        std::set<typename token_type::string_type> names;            typedef typename parameter_container_type::iterator             parameter_iterator_type;        typedef typename std::set<typename token_type::string_type>::iterator             name_iterator_type;                    parameter_iterator_type end = parameters.end();        for (parameter_iterator_type itp = parameters.begin(); itp != end; ++itp)         {        name_iterator_type pit = names.find((*itp).get_value());                    if (pit != names.end()) {

⌨️ 快捷键说明

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