/*============================================================================= Boost.Wave: A Standard compliant C++ preprocessor library http://www.boost.org/ Copyright (c) 2001-2012 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(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED) #define MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED #include #include #include #include #include #if BOOST_WAVE_SERIALIZATION != 0 #include #include #include #endif #include // 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 { /////////////////////////////////////////////////////////////////////////////// // // macro_definition // // This class containes all infos for a defined macro. // /////////////////////////////////////////////////////////////////////////////// template struct macro_definition { typedef std::vector parameter_container_type; typedef ContainerT definition_container_type; typedef typename parameter_container_type::const_iterator const_parameter_iterator_t; typedef typename definition_container_type::const_iterator const_definition_iterator_t; macro_definition(TokenT const &token_, bool has_parameters, bool is_predefined_, long uid_) : macroname(token_), uid(uid_), is_functionlike(has_parameters), replaced_parameters(false), is_available_for_replacement(true), is_predefined(is_predefined_) #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 , has_ellipsis(false) #endif , use_count(0) { } // generated copy constructor // generated destructor // generated assignment operator // Replace all occurrences of the parameters throughout the macrodefinition // with special parameter tokens to simplify later macro replacement. // Additionally mark all occurrences of the macro name itself throughout // the macro definition void replace_parameters() { using namespace boost::wave; if (!replaced_parameters) { typename definition_container_type::iterator end = macrodefinition.end(); typename definition_container_type::iterator it = macrodefinition.begin(); for (/**/; it != end; ++it) { token_id id = *it; if (T_IDENTIFIER == id || IS_CATEGORY(id, KeywordTokenType) || IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) || IS_CATEGORY(id, OperatorTokenType)) { // may be a parameter to replace const_parameter_iterator_t cend = macroparameters.end(); const_parameter_iterator_t cit = macroparameters.begin(); for (typename parameter_container_type::size_type i = 0; cit != cend; ++cit, ++i) { if ((*it).get_value() == (*cit).get_value()) { (*it).set_token_id(token_id(T_PARAMETERBASE+i)); break; } #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 else if (T_ELLIPSIS == token_id(*cit) && "__VA_ARGS__" == (*it).get_value()) { // __VA_ARGS__ requires special handling (*it).set_token_id(token_id(T_EXTPARAMETERBASE+i)); break; } #endif } } } #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 // we need to know, if the last of the formal arguments is an ellipsis if (macroparameters.size() > 0 && T_ELLIPSIS == token_id(macroparameters.back())) { has_ellipsis = true; } #endif replaced_parameters = true; // do it only once } } TokenT macroname; // macro name parameter_container_type macroparameters; // formal parameters definition_container_type macrodefinition; // macro definition token sequence long uid; // unique id of this macro bool is_functionlike; bool replaced_parameters; bool is_available_for_replacement; bool is_predefined; #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 bool has_ellipsis; #endif boost::detail::atomic_count use_count; #if BOOST_WAVE_SERIALIZATION != 0 // default constructor is needed for serialization only macro_definition() : uid(0), is_functionlike(false), replaced_parameters(false), is_available_for_replacement(false), is_predefined(false) #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 , has_ellipsis(false) #endif , use_count(0) {} private: friend class boost::serialization::access; template void serialize(Archive &ar, const unsigned int version) { using namespace boost::serialization; ar & make_nvp("name", macroname); ar & make_nvp("parameters", macroparameters); ar & make_nvp("definition", macrodefinition); ar & make_nvp("uid", uid); ar & make_nvp("is_functionlike", is_functionlike); ar & make_nvp("has_replaced_parameters", replaced_parameters); ar & make_nvp("is_available_for_replacement", is_available_for_replacement); ar & make_nvp("is_predefined", is_predefined); #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 ar & make_nvp("has_ellipsis", has_ellipsis); #endif } #endif }; #if BOOST_WAVE_SERIALIZATION == 0 /////////////////////////////////////////////////////////////////////////////// template inline void intrusive_ptr_add_ref(macro_definition* p) { ++p->use_count; } template inline void intrusive_ptr_release(macro_definition* p) { if (--p->use_count == 0) delete p; } #endif /////////////////////////////////////////////////////////////////////////////// } // namespace util } // namespace wave } // namespace boost // the suffix header occurs after all of the code #ifdef BOOST_HAS_ABI_HEADERS #include BOOST_ABI_SUFFIX #endif #endif // !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)