⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp_macromap_utils.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library

    Token sequence analysis and transformation helper functions
    
    http://www.boost.org/

    Copyright (c) 2001-2005 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_UTIL_HPP_HK041119)
#define CPP_MACROMAP_UTIL_HPP_HK041119

#include <boost/assert.hpp>

#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>

///////////////////////////////////////////////////////////////////////////////
//
// This file contains the definition of several token sequence analyse 
// and transformation utility functions needed during macro handling.
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {

///////////////////////////////////////////////////////////////////////////////
namespace on_exit {

    ///////////////////////////////////////////////////////////////////////////
    //
    //  On destruction pop the first element of the list given as the argument 
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ContainerT>
    class pop_front {
    public:
        pop_front(ContainerT &list_) : list(list_) {}
        ~pop_front() { list.pop_front(); }
    
    private:
        ContainerT &list;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Append a given list to the list given as argument 
    //  On destruction pop the first element of the list given as argument 
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ContainerT>
    class splice_pop_front {
    public:
        splice_pop_front(ContainerT &list_, ContainerT &queue) 
        :   list(list_) 
        {
            list.splice(list.end(), queue);
        }
        ~splice_pop_front() { list.pop_front(); }

    private:
        ContainerT &list;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  On destruction reset a referenced value to its initial state
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename TypeT>
    class reset {
    public:
        reset(TypeT &target_value_, TypeT new_value)
        :   target_value(target_value_), old_value(target_value_)
        {
            target_value_ = new_value;
        }
        ~reset() { target_value = old_value; }

    private:
        TypeT &target_value;
        TypeT old_value;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  On destruction assign the given iterator back
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT, typename UnputIteratorT>
    class assign {
    public:
        assign(IteratorT &it_, UnputIteratorT const &uit_) 
        :   it(it_), uit(uit_) {}
        ~assign() { it = uit.base(); }

    private:
        IteratorT &it;
        UnputIteratorT const &uit;
    };

    template <typename IteratorT>
    class assign<IteratorT, IteratorT> {
    public:
        assign(IteratorT &it_, IteratorT const &uit_) 
        :   it(it_), uit(uit_) {}
        ~assign() { it = uit; }

    private:
        IteratorT &it;
        IteratorT const &uit;
    };

///////////////////////////////////////////////////////////////////////////////
}   // namespace on_exit

///////////////////////////////////////////////////////////////////////////////
namespace impl {

///////////////////////////////////////////////////////////////////////////////
//
//  Test, whether a given identifier resolves to a predefined name
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT>
inline bool 
is_special_macroname (StringT const &name)
{
    if (name.size() < 7)
        return false;
        
    if ("defined" == name)
        return true;
        
    if ('_' == name[0] && '_' == name[1]) {
    StringT str = name.substr(2);
    
        if (str == "cplusplus"  || str == "STDC__" || 
            str == "TIME__"     || str == "DATE__" ||
            str == "LINE__"     || str == "FILE__" ||
            str == "INCLUDE_LEVEL__")
        {
            return true;
        }
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////////
//
//  Test, whether a given identifier resolves to a operator name
//
///////////////////////////////////////////////////////////////////////////////
//template <typename StringT>
//inline bool 
//is_operator_macroname (StringT const &name)
//{
//    if (name.size() < 2 || name.size() > 6)
//        return false;
//        
//    if (str == "and"    || str == "and_eq" || 
//        str == "bitand" || str == "bitor" ||
//        str == "compl"  || 
//        str == "not"    || str == "not_eq" || 
//        str == "or"     || str == "or_eq" || 
//        str == "xor"    || str == "xor_eq")
//    {
//        return true;
//    }
//    return false;
//}

///////////////////////////////////////////////////////////////////////////////
//
//  Test, whether two tokens are to be considered equal (different sequences
//  of whitespace are considered to be equal)
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
inline bool 
token_equals(TokenT const &left, TokenT const &right)
{
    using namespace boost::wave;
    
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
    if (T_PARAMETERBASE == token_id(left) || 
        T_EXTPARAMETERBASE == token_id(left)) 
#else
    if (T_PARAMETERBASE == token_id(left))
#endif 
    {
    //  if the existing token is of type T_PARAMETERBASE, then the right token 
    //  must be of type T_IDENTIFIER or a keyword
    token_id id = token_id(right);
     
        return (T_IDENTIFIER == id || 
                IS_CATEGORY(id, KeywordTokenType) ||
                IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType)) && 
            left.get_value() == right.get_value();
    }

    // if the left token has whitespace, the value is irrelevant
    return token_id(left) == token_id(right) && (
            IS_CATEGORY(left, WhiteSpaceTokenType) ||
            left.get_value() == right.get_value()
        );
}

///////////////////////////////////////////////////////////////////////////////
//
//  Tests, whether two macro definitions are equal
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline bool 
definition_equals(ContainerT const &definition, 
    ContainerT const &new_definition)
{
    typedef typename ContainerT::const_iterator const_iterator_type;
    
const_iterator_type first1 = definition.begin();
const_iterator_type last1 = definition.end();
const_iterator_type first2 = new_definition.begin();
const_iterator_type last2 = new_definition.end();
    
    while (first1 != last1 && token_equals(*first1, *first2)) {
    // skip whitespace, if both sequences have a whitespace next
    token_id id1 = next_token<const_iterator_type>::peek(first1, last1, false);
    token_id id2 = next_token<const_iterator_type>::peek(first2, last2, false);

        if (IS_CATEGORY(id1, WhiteSpaceTokenType) && 
            IS_CATEGORY(id2, WhiteSpaceTokenType)) 
        {
        // all consecutive whitespace tokens count as one whitespace
        // adjust first1 and first2 accordingly
            skip_whitespace(first1, last1);
            skip_whitespace(first2, last2);
        }
        else if (!IS_CATEGORY(id1, WhiteSpaceTokenType) && 
                 !IS_CATEGORY(id2, WhiteSpaceTokenType)) 
        {
            ++first1;
            ++first2;
        }
        else {
        // the sequences differ
            break;
        }
    }
    return (first1 == last1 && first2 == last2) ? true : false;
}

///////////////////////////////////////////////////////////////////////////////
//
//  Tests, whether two given sets of macro parameters are equal
//
///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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