common.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,588 行 · 第 1/3 页

HPP
1,588
字号
/*=============================================================================    Copyright (c) 2001-2003 Daniel Nuffer    Copyright (c) 2001-2007 Hartmut Kaiser    Revised 2007, Copyright (c) Tobias Schwinger    http://spirit.sourceforge.net/  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)=============================================================================*/#ifndef BOOST_SPIRIT_TREE_COMMON_HPP#define BOOST_SPIRIT_TREE_COMMON_HPP#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)#include <vector>#else#include <list>#endif#if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)#include <boost/pool/pool_alloc.hpp>#endif#include <algorithm>#include <boost/ref.hpp>#include <boost/call_traits.hpp>#include <boost/spirit/home/classic/namespace.hpp>#include <boost/spirit/home/classic/core.hpp>#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)#include <iostream>#include <boost/spirit/home/classic/debug/debug_node.hpp>#endif#include <boost/spirit/home/classic/tree/common_fwd.hpp>namespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGINtemplate <typename T>void swap(tree_node<T>& a, tree_node<T>& b);template <typename T, typename V>void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);namespace impl {    template <typename T>    inline void cp_swap(T& t1, T& t2);}template <typename T>struct tree_node{    typedef T parse_node_t;    #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)    typedef std::allocator<tree_node<T> > allocator_type;#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)    typedef boost::pool_allocator<tree_node<T> > allocator_type;#else    typedef boost::fast_pool_allocator<tree_node<T> > allocator_type;#endif#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)    typedef std::vector<tree_node<T>, allocator_type> children_t;#else    typedef std::list<tree_node<T>, allocator_type> children_t;#endif  // BOOST_SPIRIT_USE_LIST_FOR_TREES    typedef typename children_t::iterator tree_iterator;    typedef typename children_t::const_iterator const_tree_iterator;    T value;    children_t children;    tree_node()        : value()        , children()    {}    explicit tree_node(T const& v)        : value(v)        , children()    {}    tree_node(T const& v, children_t const& c)        : value(v)        , children(c)    {}    void swap(tree_node<T>& x)    {        impl::cp_swap(value, x.value);        impl::cp_swap(children, x.children);    }// Intel V5.0.1 has a problem without this explicit operator=    tree_node &operator= (tree_node const &rhs)    {        tree_node(rhs).swap(*this);        return *this;    }};#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)template <typename T>inline std::ostream&operator<<(std::ostream& o, tree_node<T> const& n){    static int depth = 0;    o << "\n";    for (int i = 0; i <= depth; ++i)    {        o << "\t";    }    o << "(depth = " << depth++ << " value = " << n.value;    int c = 0;    for (typename tree_node<T>::children_t::const_iterator it = n.children.begin();         it != n.children.end(); ++it)    {        o << " children[" << c++ << "] = " << *it;    }    o << ")";    --depth;    return o;}#endif//////////////////////////////////template <typename IteratorT, typename ValueT>struct node_iter_data{    typedef IteratorT iterator_t;    typedef IteratorT /*const*/ const_iterator_t;    node_iter_data()        : first(), last(), is_root_(false), parser_id_(), value_()        {}    node_iter_data(IteratorT const& _first, IteratorT const& _last)        : first(_first), last(_last), is_root_(false), parser_id_(), value_()        {}    void swap(node_iter_data& x)    {        impl::cp_swap(first, x.first);        impl::cp_swap(last, x.last);        impl::cp_swap(parser_id_, x.parser_id_);        impl::cp_swap(is_root_, x.is_root_);        impl::cp_swap(value_, x.value_);    }    IteratorT begin()    {        return first;    }    IteratorT const& begin() const    {        return first;    }    IteratorT end()    {        return last;    }    IteratorT const& end() const    {        return last;    }    bool is_root() const    {        return is_root_;    }    void is_root(bool b)    {        is_root_ = b;    }    parser_id id() const    {        return parser_id_;    }    void id(parser_id r)    {        parser_id_ = r;    }    ValueT const& value() const    {        return value_;    }    void value(ValueT const& v)    {        value_ = v;    }private:    IteratorT first, last;    bool is_root_;    parser_id parser_id_;    ValueT value_;public:};#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)// value is default nil_t, so provide an operator<< for nil_tinline std::ostream&operator<<(std::ostream& o, nil_t const&){    return o;}template <typename IteratorT, typename ValueT>inline std::ostream&operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n){    o << "(id = " << n.id() << " text = \"";    typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t        iterator_t;    for (iterator_t it = n.begin(); it != n.end(); ++it)        impl::token_printer(o, *it);    o << "\" is_root = " << n.is_root()        << /*" value = " << n.value() << */")";    return o;}#endif//////////////////////////////////template <typename IteratorT = char const*, typename ValueT = nil_t>struct node_val_data{    typedef        typename boost::detail::iterator_traits<IteratorT>::value_type        value_type;#if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)    typedef std::allocator<value_type> allocator_type;#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)    typedef boost::pool_allocator<value_type> allocator_type;#else    typedef boost::fast_pool_allocator<value_type> allocator_type;#endif#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)    typedef std::vector<value_type, allocator_type> container_t;#else    typedef std::list<value_type, allocator_type> container_t;#endif    typedef typename container_t::iterator iterator_t;    typedef typename container_t::const_iterator const_iterator_t;    node_val_data()        : text(), is_root_(false), parser_id_(), value_()        {}#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)    node_val_data(IteratorT const& _first, IteratorT const& _last)        : text(), is_root_(false), parser_id_(), value_()        {            std::copy(_first, _last, std::inserter(text, text.end()));        }    // This constructor is for building text out of iterators    template <typename IteratorT2>    node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)        : text(), is_root_(false), parser_id_(), value_()        {            std::copy(_first, _last, std::inserter(text, text.end()));        }#else    node_val_data(IteratorT const& _first, IteratorT const& _last)        : text(_first, _last), is_root_(false), parser_id_(), value_()        {}    // This constructor is for building text out of iterators    template <typename IteratorT2>    node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)        : text(_first, _last), is_root_(false), parser_id_(), value_()        {}#endif    void swap(node_val_data& x)    {        impl::cp_swap(text, x.text);        impl::cp_swap(is_root_, x.is_root_);        impl::cp_swap(parser_id_, x.parser_id_);        impl::cp_swap(value_, x.value_);    }    typename container_t::iterator begin()    {        return text.begin();    }    typename container_t::const_iterator begin() const    {        return text.begin();    }    typename container_t::iterator end()    {        return text.end();    }    typename container_t::const_iterator end() const    {        return text.end();    }    bool is_root() const    {        return is_root_;    }    void is_root(bool b)    {        is_root_ = b;    }    parser_id id() const    {        return parser_id_;    }    void id(parser_id r)    {        parser_id_ = r;    }    ValueT const& value() const    {        return value_;    }    void value(ValueT const& v)    {        value_ = v;    }private:    container_t text;    bool is_root_;    parser_id parser_id_;    ValueT value_;};#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)template <typename IteratorT, typename ValueT>inline std::ostream&operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n){    o << "(id = " << n.id() << " text = \"";    typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t        iterator_t;    for (iterator_t it = n.begin(); it != n.end(); ++it)        impl::token_printer(o, *it);    o << "\" is_root = " << n.is_root()        << " value = " << n.value() << ")";    return o;}#endiftemplate <typename T>inline voidswap(tree_node<T>& a, tree_node<T>& b){    a.swap(b);}template <typename T, typename V>inline voidswap(node_iter_data<T, V>& a, node_iter_data<T, V>& b){    a.swap(b);}//////////////////////////////////template <typename ValueT>class node_iter_data_factory{public:    // This inner class is so that node_iter_data_factory can simulate    // a template template parameter    template <typename IteratorT>    class factory    {    public:        typedef IteratorT iterator_t;        typedef node_iter_data<iterator_t, ValueT> node_t;        static node_t create_node(iterator_t const& first, iterator_t const& last,                bool /*is_leaf_node*/)        {            return node_t(first, last);        }        static node_t empty_node()        {            return node_t();        }        // precondition: ContainerT contains a tree_node<node_t>.  And all        // iterators in the container point to the same sequence.        template <typename ContainerT>        static node_t group_nodes(ContainerT const& nodes)        {            return node_t(nodes.begin()->value.begin(),                    nodes.back().value.end());        }    };};//////////////////////////////////template <typename ValueT>class node_val_data_factory {public:    // This inner class is so that node_val_data_factory can simulate    // a template template parameter    template <typename IteratorT>    class factory    {    public:        typedef IteratorT iterator_t;        typedef node_val_data<iterator_t, ValueT> node_t;        static node_t create_node(iterator_t const& first, iterator_t const& last,                bool is_leaf_node)        {            if (is_leaf_node)                return node_t(first, last);            else                return node_t();        }        static node_t empty_node()        {            return node_t();        }        template <typename ContainerT>        static node_t group_nodes(ContainerT const& nodes)        {            typename node_t::container_t c;            typename ContainerT::const_iterator i_end = nodes.end();            // copy all the nodes text into a new one            for (typename ContainerT::const_iterator i = nodes.begin();                 i != i_end; ++i)            {                // See docs: reduced_node_d cannot be used with a                // rule inside the [].                assert(i->children.size() == 0);                c.insert(c.end(), i->value.begin(), i->value.end());            }            return node_t(c.begin(), c.end());        }    };};//////////////////////////////////template <typename ValueT>class node_all_val_data_factory{public:    // This inner class is so that node_all_val_data_factory can simulate    // a template template parameter    template <typename IteratorT>    class factory    {    public:        typedef IteratorT iterator_t;        typedef node_val_data<iterator_t, ValueT> node_t;        static node_t create_node(iterator_t const& first, iterator_t const& last,                bool /*is_leaf_node*/)        {            return node_t(first, last);        }        static node_t empty_node()        {            return node_t();        }        template <typename ContainerT>        static node_t group_nodes(ContainerT const& nodes)        {            typename node_t::container_t c;            typename ContainerT::const_iterator i_end = nodes.end();            // copy all the nodes text into a new one            for (typename ContainerT::const_iterator i = nodes.begin();                    i != i_end; ++i)            {                assert(i->children.size() == 0);                c.insert(c.end(), i->value.begin(), i->value.end());            }            return node_t(c.begin(), c.end());        }    };};namespace impl {    ///////////////////////////////////////////////////////////////////////////    // can't call unqualified swap from within classname::swap    // as Koenig lookup rules will find only the classname::swap    // member function not the global declaration, so use cp_swap    // as a forwarding function (JM):#if __GNUC__ == 2    using ::std::swap;#endif    template <typename T>    inline void cp_swap(T& t1, T& t2)    {        using std::swap;        using BOOST_SPIRIT_CLASSIC_NS::swap;        using boost::swap;

⌨️ 快捷键说明

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