| // Copyright (c) 2001-2009 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(BOOST_SPIRIT_FUNCTOR_APR_01_2007_0817AM) |
| #define BOOST_SPIRIT_FUNCTOR_APR_01_2007_0817AM |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| #pragma once // MS compatible compilers support #pragma once |
| #endif |
| |
| #include <boost/spirit/home/support/component.hpp> |
| #include <boost/spirit/home/support/unused.hpp> |
| #include <boost/spirit/home/support/detail/values.hpp> |
| #include <boost/spirit/home/support/auxiliary/functor_holder.hpp> |
| #include <boost/spirit/home/support/auxiliary/meta_function_holder.hpp> |
| #include <boost/spirit/home/qi/skip.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| #include <boost/type_traits/remove_const.hpp> |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace boost { namespace spirit |
| { |
| namespace qi |
| { |
| template <typename Functor, typename ParameterMF = Functor> |
| class functor_parser; |
| } |
| |
| namespace result_of |
| { |
| template <typename Functor> |
| struct as_parser |
| { |
| typedef qi::functor_parser<Functor> type; |
| }; |
| |
| template <typename ParameterMF, typename Functor> |
| struct as_parser_mf |
| { |
| typedef qi::functor_parser<Functor, ParameterMF> type; |
| }; |
| } |
| |
| }} // boost::spirit |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace boost { namespace spirit { namespace qi |
| { |
| /////////////////////////////////////////////////////////////////////////// |
| // This struct may be used as a base class for a user defined functor |
| /////////////////////////////////////////////////////////////////////////// |
| struct functor_base |
| { |
| /////////////////////////////////////////////////////////////////////// |
| // The return value of a qi functor is always bool |
| /////////////////////////////////////////////////////////////////////// |
| template <typename Attribute, typename Iterator, typename Context> |
| struct result |
| { |
| typedef bool type; |
| }; |
| |
| // FIXME: It will be possible to specify the return value as a typedef, but for |
| // that Phoenix will have to be fixed. |
| // typedef bool result_type; |
| |
| /////////////////////////////////////////////////////////////////////// |
| // The expected parameter type of a functor has to be defined using a |
| // embedded apply metafunction. Normally this will be overloaded by |
| // the derived class, but the default is unused type. |
| /////////////////////////////////////////////////////////////////////// |
| template <typename Iterator, typename Context> |
| struct apply |
| { |
| typedef spirit::unused_type type; |
| }; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Functor, typename ParameterMF> |
| class functor_parser |
| : public proto::extends< |
| typename make_functor_holder< |
| functor_parser<Functor, ParameterMF> const*, |
| functor_parser<Functor, ParameterMF> |
| >::type, |
| functor_parser<Functor, ParameterMF> |
| > |
| { |
| private: |
| typedef functor_parser<Functor, ParameterMF> self_type; |
| typedef typename |
| make_functor_holder<self_type const*, self_type>::type |
| functor_tag; |
| typedef proto::extends<functor_tag, self_type> base_type; |
| |
| public: |
| template <typename Iterator, typename Context> |
| struct result |
| : mpl::apply<ParameterMF, Iterator, Context> |
| {}; |
| |
| private: |
| // parse function just delegates to the functor supplied function |
| template <typename Iterator, typename Context, typename Attribute> |
| bool |
| parse (Iterator& first, Iterator const& last, Context& ctx, |
| Attribute& attr_) const |
| { |
| // create an attribute if none is supplied |
| typedef typename result<Iterator, Context>::type attr_type; |
| typename mpl::if_< |
| is_same<typename remove_const<Attribute>::type, unused_type>, |
| attr_type, |
| Attribute& |
| >::type |
| attr = spirit::detail::make_value<attr_type>::call(attr_); |
| |
| return functor(attr, ctx, first, last); |
| } |
| |
| friend struct functor_director; |
| |
| public: |
| explicit functor_parser() |
| : base_type(make_tag()) |
| { |
| } |
| |
| functor_parser(Functor const& functor_) |
| : base_type(make_tag()), functor(functor_) |
| { |
| } |
| |
| functor_parser(Functor const& functor_, ParameterMF const& mf) |
| : base_type(make_tag()), functor(functor_), mf_(mf) |
| { |
| } |
| |
| private: |
| functor_tag make_tag() const |
| { |
| functor_tag xpr = {{ this }}; |
| return xpr; |
| } |
| |
| Functor functor; |
| meta_function_holder<Functor, ParameterMF> mf_; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // The as_parser generator function may be used to create a functor |
| // parser from a function object (some callable item). |
| // The supplied functor needs to expose |
| // |
| // - an embedded result meta function: |
| // |
| // template <typename Attribute, typename Iterator, typename Context> |
| // struct result |
| // { |
| // typedef bool type; |
| // }; |
| // |
| // which declares 'bool' as the result type of the defined function |
| // operator and |
| // |
| // - an embedded apply meta function: |
| // |
| // template <typename Iterator, typename Context> |
| // struct apply |
| // { |
| // typedef unspecified type; |
| // }; |
| // |
| // which declares the given type as the expected attribute type for |
| // the parser to create. |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Functor> |
| inline typename result_of::as_parser<Functor>::type |
| as_parser(Functor const& func) |
| { |
| return functor_parser<Functor>(func); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // The as_parser_mf generator function is equivalent to the function |
| // as_parser above except that the user has to explicitly specify a |
| // type exposing an embedded apply meta function declaring the expected |
| // parameter type for the generator to create. |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename ParameterMF, typename Functor> |
| inline typename result_of::as_parser_mf<ParameterMF, Functor>::type |
| as_parser_mf(Functor const& func, ParameterMF const& mf) |
| { |
| return functor_parser<Functor, ParameterMF>(func, mf); |
| } |
| |
| template <typename ParameterMF, typename Functor> |
| inline typename result_of::as_parser_mf<ParameterMF, Functor>::type |
| as_parser_mf(Functor const& func) |
| { |
| return functor_parser<Functor, ParameterMF>(func, ParameterMF()); |
| } |
| |
| }}} |
| |
| #endif |