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

📄 attribute_transform.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
字号:
/*=============================================================================    Copyright (c) 2001-2007 Joel de Guzman    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)=============================================================================*/#if !defined(BOOST_SPIRIT_ATTRIBUTE_TRANSFORM_DEC_17_2007_0718AM)#define BOOST_SPIRIT_ATTRIBUTE_TRANSFORM_DEC_17_2007_0718AM#include <boost/spirit/home/support/unused.hpp>#include <boost/spirit/home/support/component.hpp>#include <boost/spirit/home/support/attribute_of.hpp>#include <boost/spirit/home/support/detail/values.hpp>#include <boost/fusion/include/vector.hpp>#include <boost/fusion/include/is_sequence.hpp>#include <boost/variant/variant_fwd.hpp>#include <boost/fusion/include/transform.hpp>#include <boost/fusion/include/filter_if.hpp>#include <boost/mpl/if.hpp>#include <boost/type_traits/is_same.hpp>namespace boost { namespace spirit{    // Generalized attribute transformation utilities for Qi parsers    namespace traits    {        using boost::spirit::detail::not_is_variant;        // Here, we provide policies for stripping single element fusion        // sequences. Add more specializations as needed.        template <typename T, typename IsSequence, typename Enable = void>        struct strip_single_element_sequence        {            typedef T type;        };        template <typename T>        struct strip_single_element_sequence<            fusion::vector<T>, mpl::false_,            typename boost::enable_if<not_is_variant<T> >::type        >        {            //  Strips single element fusion vectors into its 'naked'            //  form: vector<T> --> T            typedef T type;        };        template <typename T>        struct strip_single_element_sequence<            fusion::vector<T>, mpl::true_,            typename boost::enable_if<not_is_variant<T> >::type        >        {            //  Strips single element fusion vectors into its 'naked'            //  form: vector<T> --> T, but does so only if T is not a fusion             //  sequence itself            typedef typename                 mpl::if_<                    fusion::traits::is_sequence<T>,                    fusion::vector<T>,                    T                >::type             type;        };        template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename IsSequence>        struct strip_single_element_sequence<                fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >               , IsSequence            >        {            //  Exception: Single element variants are not stripped!            typedef fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > type;        };    }    // Use this when building heterogeneous fusion sequences    // Note:    //    //      Director should have these nested metafunctions    //    //      1:  build_container<All, Filtered>    //    //          All: all child attributes    //          Filtered: all child attributes except unused    //    //      2:  transform_child<T>    //    //          T: child attribute    //    template <        typename Director, typename Component      , typename Iterator, typename Context      , typename IsSequence = mpl::false_>    struct build_fusion_sequence    {        template <            typename Domain, typename Director_          , typename Iterator_, typename Context_>        struct child_attribute        {            template <typename T>            struct result;            template <typename F, typename ChildComponent>            struct result<F(ChildComponent)>            {                typedef typename                    Director_::template transform_child<                        typename traits::attribute_of<                            Domain, ChildComponent, Context_, Iterator_>::type                    >::type                type;            };        };        // Compute the list of attributes of all sub-parsers        typedef            typename fusion::result_of::transform<                typename Component::elements_type              , child_attribute<                    typename Component::domain, Director, Iterator, Context>            >::type        all;        // Compute the list of all *used* attributes of sub-parsers        // (filter all unused parsers from the list)        typedef            typename fusion::result_of::filter_if<                all              , spirit::traits::is_not_unused<mpl::_>            >::type        filtered;        // Ask the director to build the actual fusion sequence.        // But *only if* the filtered sequence is not empty. i.e.        // if the sequence has all unused elements, our result        // will also be unused.        typedef            typename mpl::eval_if<                fusion::result_of::empty<filtered>              , mpl::identity<unused_type>              , typename Director::template build_container<all, filtered>            >::type        attribute_sequence;        // Finally, strip single element sequences into its        // naked form (e.g. vector<T> --> T)        typedef typename            traits::strip_single_element_sequence<attribute_sequence, IsSequence>::type        type;    };    // Use this when building homogeneous containers. Component    // is assumed to be a unary. Note:    //    //      Director should have this nested metafunction    //    //      1:  build_attribute_container<T>    //    //          T: the data-type for the container    //    template <        typename Director, typename Component      , typename Iterator, typename Context>    struct build_container    {        // Get the component's subject.        typedef typename            result_of::subject<Component>::type        subject_type;        // Get the subject's attribute        typedef typename            traits::attribute_of<                typename Component::domain, subject_type, Context, Iterator>::type        attr_type;        // If attribute is unused_type, return it as it is.        // If not, then ask the director to build the actual        // container for the attribute type.        typedef typename            mpl::if_<                is_same<unused_type, attr_type>              , unused_type              , typename Director::template                    build_attribute_container<attr_type>::type            >::type        type;    };}}#endif

⌨️ 快捷键说明

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