211 lines
7.4 KiB
C++
Executable File
211 lines
7.4 KiB
C++
Executable File
// 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 <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 parameter type for
|
|
// the generator 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 explicitly to 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
|