identity_transform.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*=============================================================================
  2. Copyright (c) 2001-2007 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #include <boost/phoenix.hpp>
  7. #include <iostream>
  8. #include <sstream>
  9. namespace proto = boost::proto;
  10. namespace phoenix = boost::phoenix;
  11. template <typename Rule>
  12. struct identity_transform;
  13. struct identity_actions
  14. {
  15. template <typename Rule>
  16. struct when : phoenix::call<identity_transform<Rule> > {};
  17. };
  18. template <>
  19. struct identity_actions::when<phoenix::rule::argument>
  20. : proto::call<
  21. identity_transform<phoenix::rule::argument>(proto::_value, phoenix::_context)
  22. > {};
  23. template <>
  24. struct identity_actions::when<phoenix::rule::terminal>
  25. : proto::call<
  26. identity_transform<phoenix::rule::terminal>(proto::_value, phoenix::_context)
  27. > {};
  28. template <>
  29. struct identity_actions::when<phoenix::rule::custom_terminal>
  30. : proto::lazy<
  31. identity_transform<proto::_value>(proto::_value, phoenix::_context)
  32. > {};
  33. template <>
  34. struct identity_transform<phoenix::rule::terminal>
  35. {
  36. typedef std::string result_type;
  37. template <typename Terminal, typename Context>
  38. std::string operator()(Terminal const & terminal, Context) const
  39. {
  40. std::stringstream ss;
  41. ss << "val(" << terminal << ")";
  42. return ss.str();
  43. }
  44. template <typename Context>
  45. std::string operator()(char const * terminal, Context) const
  46. {
  47. std::stringstream ss;
  48. ss << "val(\"" << terminal << "\")";
  49. return ss.str();
  50. }
  51. };
  52. template <typename T>
  53. struct identity_transform<boost::reference_wrapper<T> >
  54. {
  55. typedef std::string result_type;
  56. template <typename Terminal, typename Context>
  57. std::string operator()(Terminal const & terminal, Context) const
  58. {
  59. std::stringstream ss;
  60. ss << "ref(" << terminal << ")";
  61. return ss.str();
  62. }
  63. template <int N, typename Context>
  64. std::string operator()(boost::reference_wrapper<char const *> terminal, Context) const
  65. {
  66. std::stringstream ss;
  67. ss << "ref(\"" << terminal << "\")";
  68. return ss.str();
  69. }
  70. template <int N, typename Context>
  71. std::string operator()(boost::reference_wrapper<char const [N]> terminal, Context) const
  72. {
  73. std::stringstream ss;
  74. ss << "ref(\"" << terminal << "\")";
  75. return ss.str();
  76. }
  77. };
  78. template <>
  79. struct identity_transform<phoenix::rule::argument>
  80. {
  81. typedef std::string result_type;
  82. template <typename N, typename Context>
  83. std::string operator()(N, Context) const
  84. {
  85. std::stringstream ss;
  86. ss << "_" << N::value;
  87. return ss.str();
  88. }
  89. };
  90. template <typename Expr>
  91. void identity(Expr const & expr)
  92. {
  93. std::cout << phoenix::eval(expr, phoenix::context(int(), identity_actions())) << "\n";
  94. }
  95. int main()
  96. {
  97. identity(phoenix::val(8));
  98. identity(phoenix::val("8"));
  99. identity(phoenix::ref("blubb"));
  100. identity(phoenix::arg_names::_1);
  101. }