Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > b03c44838559deaeff848c57e893606a > files > 1258

boost-examples-1.48.0-14.fc17.noarch.rpm


#include <boost/phoenix.hpp>

#include <iostream>
#include <sstream>

namespace proto = boost::proto;
namespace phoenix = boost::phoenix;

template <typename Rule>
struct identity_transform;

struct identity_actions
{
    template <typename Rule>
    struct when : phoenix::call<identity_transform<Rule> > {};
};

template <>
struct identity_actions::when<phoenix::rule::argument>
    : proto::call<
        identity_transform<phoenix::rule::argument>(proto::_value, phoenix::_context)
    > {};

template <>
struct identity_actions::when<phoenix::rule::terminal>
    : proto::call<
        identity_transform<phoenix::rule::terminal>(proto::_value, phoenix::_context)
    > {};

template <>
struct identity_actions::when<phoenix::rule::custom_terminal>
    : proto::lazy<
        identity_transform<proto::_value>(proto::_value, phoenix::_context)
    > {};

template <>
struct identity_transform<phoenix::rule::terminal>
{
    typedef std::string result_type;

    template <typename Terminal, typename Context>
    std::string operator()(Terminal const & terminal, Context) const
    {
        std::stringstream ss;
        ss << "val(" << terminal << ")";
        return ss.str();
    }

    template <typename Context>
    std::string operator()(char const * terminal, Context) const
    {
        std::stringstream ss;
        ss << "val(\"" << terminal << "\")";
        return ss.str();
    }
};

template <typename T>
struct identity_transform<boost::reference_wrapper<T> >
{
    typedef std::string result_type;

    template <typename Terminal, typename Context>
    std::string operator()(Terminal const & terminal, Context) const
    {
        std::stringstream ss;
        ss << "ref(" << terminal << ")";
        return ss.str();
    }


    template <int N, typename Context>
    std::string operator()(boost::reference_wrapper<char const *> terminal, Context) const
    {
        std::stringstream ss;
        ss << "ref(\"" << terminal << "\")";
        return ss.str();
    }
    
    template <int N, typename Context>
    std::string operator()(boost::reference_wrapper<char const [N]> terminal, Context) const
    {
        std::stringstream ss;
        ss << "ref(\"" << terminal << "\")";
        return ss.str();
    }
};

template <>
struct identity_transform<phoenix::rule::argument>
{
    typedef std::string result_type;

    template <typename N, typename Context>
    std::string operator()(N, Context) const
    {
        std::stringstream ss;
        ss << "_" << N::value;
        return ss.str();
    }
};


template <typename Expr>
void identity(Expr const & expr)
{
    std::cout << phoenix::eval(expr, phoenix::context(int(), identity_actions())) << "\n";
}

int main()
{

    identity(phoenix::val(8));
    identity(phoenix::val("8"));
    identity(phoenix::ref("blubb"));
    identity(phoenix::arg_names::_1);
}