expression.hpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*=============================================================================
  2. Copyright (c) 2016 Kohei Takahashi
  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. #ifndef BOOST_PHOENIX_CORE_EXPRESSION_HPP
  7. #define BOOST_PHOENIX_CORE_EXPRESSION_HPP
  8. #include <boost/phoenix/core/limits.hpp>
  9. #include <boost/fusion/sequence/intrinsic/at.hpp>
  10. #include <boost/phoenix/core/as_actor.hpp>
  11. #include <boost/phoenix/core/detail/expression.hpp>
  12. #include <boost/phoenix/core/domain.hpp>
  13. #include <boost/proto/domain.hpp>
  14. #include <boost/proto/make_expr.hpp>
  15. #include <boost/proto/transform/pass_through.hpp>
  16. namespace boost { namespace phoenix
  17. {
  18. template <typename Expr> struct actor;
  19. #ifdef BOOST_PHOENIX_NO_VARIADIC_EXPRESSION
  20. #include <boost/phoenix/core/detail/cpp03/expression.hpp>
  21. #else
  22. template <template <typename> class Actor, typename Tag, typename... A>
  23. struct expr_ext;
  24. // This filter cuts arguments of a template pack after a first void.
  25. // It is necessary because the interface can be used in C++03 style.
  26. template <typename Tag, typename... A>
  27. struct expr_impl;
  28. // Helper template. Used to store filtered argument types.
  29. template <typename... A>
  30. struct expr_arg_types {};
  31. template <typename Tag, typename... A>
  32. struct expr_impl<Tag, expr_arg_types<A...>> : expr_ext<actor, Tag, A...> {};
  33. template <typename Tag, typename... A, typename... T>
  34. struct expr_impl<Tag, expr_arg_types<A...>, void, T...> : expr_ext<actor, Tag, A...> {};
  35. template <typename Tag, typename... A, typename H, typename... T>
  36. struct expr_impl<Tag, expr_arg_types<A...>, H, T...> : expr_impl<Tag, expr_arg_types<A..., H>, T...> {};
  37. template <typename Tag, typename... A>
  38. struct expr : expr_impl<Tag, expr_arg_types<>, A...> {};
  39. template <template <typename> class Actor, typename Tag, typename... A>
  40. struct expr_ext
  41. : proto::transform<expr_ext<Actor, Tag, A...>, int>
  42. {
  43. typedef
  44. typename proto::result_of::make_expr<
  45. Tag
  46. , phoenix_default_domain //proto::basic_default_domain
  47. , typename proto::detail::uncvref<A>::type...
  48. >::type
  49. base_type;
  50. typedef Actor<base_type> type;
  51. typedef typename proto::nary_expr<Tag, A...>::proto_grammar proto_grammar;
  52. static type make(A const&... a)
  53. { //?? actor or Actor??
  54. //Actor<base_type> const e =
  55. actor<base_type> const e =
  56. {
  57. proto::make_expr<Tag, phoenix_default_domain>(a...)
  58. };
  59. return e;
  60. }
  61. template<typename Expr, typename State, typename Data>
  62. struct impl
  63. : proto::pass_through<expr_ext>::template impl<Expr, State, Data>
  64. {};
  65. typedef Tag proto_tag;
  66. };
  67. #endif
  68. }}
  69. #endif