// Copyright (c) 2001-2008 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 #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace qi { template class functor_parser; } namespace result_of { template struct as_parser { typedef qi::functor_parser type; }; template struct as_parser_mf { typedef qi::functor_parser 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 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 struct apply { typedef spirit::unused_type type; }; }; /////////////////////////////////////////////////////////////////////////// template class functor_parser : public proto::extends< typename make_functor_holder< functor_parser const*, functor_parser >::type, functor_parser > { private: typedef functor_parser self_type; typedef typename make_functor_holder::type functor_tag; typedef proto::extends base_type; public: template struct result : mpl::apply {}; private: // parse function just delegates to the functor supplied function template bool parse (Iterator& first, Iterator const& last, Context& ctx, Attribute& attr_) const { // create an attribute if none is supplied typedef typename result::type attr_type; typename mpl::if_< is_same::type, unused_type>, attr_type, Attribute& >::type attr = spirit::detail::make_value::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 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 // struct result // { // typedef bool type; // }; // // which declares 'bool' as the result type of the defined function // operator and // // - an embedded apply meta function: // // template // struct apply // { // typedef unspecified type; // }; // // which declares the given type as the expected parameter type for // the generator to create. /////////////////////////////////////////////////////////////////////////// template inline typename result_of::as_parser::type as_parser(Functor const& func) { return functor_parser(func); } /////////////////////////////////////////////////////////////////////////// // The as_parser_mf generator function is equivalent to the function // as_parser above except that the user has explicitly to specify a // type exposing an embedded apply meta function declaring the expected // parameter type for the generator to create. /////////////////////////////////////////////////////////////////////////// template inline typename result_of::as_parser_mf::type as_parser_mf(Functor const& func, ParameterMF const& mf) { return functor_parser(func, mf); } template inline typename result_of::as_parser_mf::type as_parser_mf(Functor const& func) { return functor_parser(func, ParameterMF()); } }}} #endif