/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman 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) ==============================================================================*/ #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); }