📄 functor.hpp
字号:
// 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_KARMA_FUNCTOR_APR_01_2007_1038AM)#define BOOST_SPIRIT_KARMA_FUNCTOR_APR_01_2007_1038AM#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/auxiliary/functor_holder.hpp>#include <boost/spirit/home/support/auxiliary/meta_function_holder.hpp>#include <boost/spirit/home/support/detail/values.hpp>#include <boost/spirit/home/karma/delimit.hpp>#include <boost/mpl/if.hpp>#include <boost/mpl/lambda.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/type_traits/remove_const.hpp>///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit { namespace karma { template <typename Functor, typename ParameterMF = Functor> class functor_generator; } namespace result_of { template <typename Functor> struct as_generator { typedef karma::functor_generator<Functor> type; }; template <typename Functor, typename ParameterMF> struct as_generator_mf { typedef karma::functor_generator<Functor, ParameterMF> type; }; }}} // boost::spirit///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit { namespace karma{ /////////////////////////////////////////////////////////////////////////// // This struct may be used as a base class for a user defined functor /////////////////////////////////////////////////////////////////////////// struct functor_base { /////////////////////////////////////////////////////////////////////// // The return value of a karma functor is always bool /////////////////////////////////////////////////////////////////////// template <typename Parameter, typename OutputIterator> 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 Context> struct apply { typedef spirit::unused_type type; }; }; /////////////////////////////////////////////////////////////////////////// // The functor generator template may be used to create new generators // without having to dig into the implementation details of Karma /////////////////////////////////////////////////////////////////////////// template <typename Functor, typename ParameterMF> class functor_generator : public proto::extends< typename make_functor_holder< functor_generator<Functor, ParameterMF> const*, functor_generator<Functor, ParameterMF> >::type, functor_generator<Functor, ParameterMF> > { private: typedef functor_generator<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 Context> struct result : mpl::apply<ParameterMF, Context> {}; private: // generate function just delegates to the functor supplied function template <typename OutputIterator, typename Context, typename Parameter> bool generate (OutputIterator& sink, Context& ctx, Parameter const& p) const { // create an attribute if none is supplied typedef typename result<Context>::type parameter_type; typename mpl::if_< is_same<typename remove_const<Parameter>::type, unused_type>, parameter_type, Parameter const& >::type param = spirit::detail::make_value<parameter_type>::call(p); return functor(param, ctx, sink); } friend struct functor_director; public: explicit functor_generator() : base_type(make_tag()) { } functor_generator(Functor const& functor_) : base_type(make_tag()), functor(functor_) { } functor_generator(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_generator generator function may be used to create a functor // generator from a function object (some callable item). // The supplied functor needs to expose // // - an embedded result meta function: // // template <typename Parameter, typename OutputIterator> // 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 Context> // struct apply // { // typedef unspecified type; // }; // // which declares the given type as the expected attribute type for // the generator to create. /////////////////////////////////////////////////////////////////////////// template <typename Functor> inline typename result_of::as_generator<Functor>::type as_generator(Functor const& func) { return functor_generator<Functor>(func); } /////////////////////////////////////////////////////////////////////////// // The as_generator_mf generator function is equivalent to the function // as_generator 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_generator_mf<Functor, ParameterMF>::type as_generator_mf(Functor const& func, ParameterMF const& mf) { return functor_generator<Functor, ParameterMF>(func, mf); } template <typename ParameterMF, typename Functor> inline typename result_of::as_generator_mf<Functor, ParameterMF>::type as_generator_mf(Functor const& func) { return functor_generator<Functor, ParameterMF>(func, ParameterMF()); }}}}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -